_docker 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. #compdef docker
  2. #
  3. # zsh completion for docker (http://docker.com)
  4. #
  5. # version: 0.3.0
  6. # github: https://github.com/felixr/docker-zsh-completion
  7. #
  8. # contributors:
  9. # - Felix Riedel
  10. # - Vincent Bernat
  11. #
  12. # license:
  13. #
  14. # Copyright (c) 2013, Felix Riedel
  15. # All rights reserved.
  16. #
  17. # Redistribution and use in source and binary forms, with or without
  18. # modification, are permitted provided that the following conditions are met:
  19. # * Redistributions of source code must retain the above copyright
  20. # notice, this list of conditions and the following disclaimer.
  21. # * Redistributions in binary form must reproduce the above copyright
  22. # notice, this list of conditions and the following disclaimer in the
  23. # documentation and/or other materials provided with the distribution.
  24. # * Neither the name of the <organization> nor the
  25. # names of its contributors may be used to endorse or promote products
  26. # derived from this software without specific prior written permission.
  27. #
  28. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  29. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30. # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. # DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  32. # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  33. # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  35. # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. #
  39. __docker_get_containers() {
  40. local kind expl
  41. declare -a running stopped lines args
  42. kind=$1
  43. shift
  44. [[ $kind = (stopped|all) ]] && args=($args -a)
  45. lines=(${(f)"$(_call_program commands docker ps ${args})"})
  46. # Parse header line to find columns
  47. local i=1 j=1 k header=${lines[1]}
  48. declare -A begin end
  49. while (( $j < ${#header} - 1 )) {
  50. i=$(( $j + ${${header[$j,-1]}[(i)[^ ]]} - 1))
  51. j=$(( $i + ${${header[$i,-1]}[(i) ]} - 1))
  52. k=$(( $j + ${${header[$j,-1]}[(i)[^ ]]} - 2))
  53. begin[${header[$i,$(($j-1))]}]=$i
  54. end[${header[$i,$(($j-1))]}]=$k
  55. }
  56. lines=(${lines[2,-1]})
  57. # Container ID
  58. local line
  59. local s
  60. for line in $lines; do
  61. s="${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}"
  62. s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
  63. s="$s, ${${${line[$begin[IMAGE],$end[IMAGE]]}/:/\\:}%% ##}"
  64. if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
  65. stopped=($stopped $s)
  66. else
  67. running=($running $s)
  68. fi
  69. done
  70. # Names
  71. local name
  72. local -a names
  73. for line in $lines; do
  74. names=(${(ps:,:)${${line[${begin[NAMES]},-1]}%% *}})
  75. for name in $names; do
  76. s="${name}:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
  77. s="$s, ${${${line[$begin[IMAGE],$end[IMAGE]]}/:/\\:}%% ##}"
  78. if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
  79. stopped=($stopped $s)
  80. else
  81. running=($running $s)
  82. fi
  83. done
  84. done
  85. [[ $kind = (running|all) ]] && _describe -t containers-running "running containers" running
  86. [[ $kind = (stopped|all) ]] && _describe -t containers-stopped "stopped containers" stopped
  87. }
  88. __docker_stoppedcontainers() {
  89. __docker_get_containers stopped "$@"
  90. }
  91. __docker_runningcontainers() {
  92. __docker_get_containers running "$@"
  93. }
  94. __docker_containers () {
  95. __docker_get_containers all "$@"
  96. }
  97. __docker_images () {
  98. local expl
  99. declare -a images
  100. images=(${${${${(f)"$(_call_program commands docker images)"}[2,-1]}/ ##/\\:}%% *})
  101. images=(${${images%\\:<none>}#<none>} ${${${(f)"$(_call_program commands docker images)"}[2,-1]}/(#b)([^ ]##) ##([^ ]##) ##([^ ]##)*/${match[3]}:${(r:15:: :::)match[2]} in ${match[1]}})
  102. _describe -t docker-images "images" images
  103. }
  104. __docker_tags() {
  105. local expl
  106. declare -a tags
  107. tags=(${${${${${(f)"$(_call_program commands docker images)"}#* }## #}%% *}[2,-1]})
  108. _describe -t docker-tags "tags" tags
  109. }
  110. __docker_repositories_with_tags() {
  111. if compset -P '*:'; then
  112. __docker_tags
  113. else
  114. __docker_repositories -qS ":"
  115. fi
  116. }
  117. __docker_search() {
  118. # declare -a dockersearch
  119. local cache_policy
  120. zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
  121. if [[ -z "$cache_policy" ]]; then
  122. zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy
  123. fi
  124. local searchterm cachename
  125. searchterm="${words[$CURRENT]%/}"
  126. cachename=_docker-search-$searchterm
  127. local expl
  128. local -a result
  129. if ( [[ ${(P)+cachename} -eq 0 ]] || _cache_invalid ${cachename#_} ) \
  130. && ! _retrieve_cache ${cachename#_}; then
  131. _message "Searching for ${searchterm}..."
  132. result=(${${${(f)"$(_call_program commands docker search ${searchterm})"}%% *}[2,-1]})
  133. _store_cache ${cachename#_} result
  134. fi
  135. _wanted dockersearch expl 'available images' compadd -a result
  136. }
  137. __docker_caching_policy()
  138. {
  139. oldp=( "$1"(Nmh+1) ) # 1 hour
  140. (( $#oldp ))
  141. }
  142. __docker_repositories () {
  143. local expl
  144. declare -a repos
  145. repos=(${${${(f)"$(_call_program commands docker images)"}%% *}[2,-1]})
  146. _describe -t docker-repos "repositories" repos "$@"
  147. }
  148. __docker_commands () {
  149. # local -a _docker_subcommands
  150. local cache_policy
  151. zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
  152. if [[ -z "$cache_policy" ]]; then
  153. zstyle ":completion:${curcontext}:" cache-policy __docker_caching_policy
  154. fi
  155. if ( [[ ${+_docker_subcommands} -eq 0 ]] || _cache_invalid docker_subcommands) \
  156. && ! _retrieve_cache docker_subcommands;
  157. then
  158. local -a lines
  159. lines=(${(f)"$(_call_program commands docker 2>&1)"})
  160. _docker_subcommands=(${${${lines[$((${lines[(i)Commands:]} + 1)),${lines[(I) *]}]}## #}/ ##/:})
  161. _docker_subcommands=($_docker_subcommands 'help:Show help for a command')
  162. _store_cache docker_subcommands _docker_subcommands
  163. fi
  164. _describe -t docker-commands "docker command" _docker_subcommands
  165. }
  166. __docker_subcommand () {
  167. local -a _command_args
  168. case "$words[1]" in
  169. (attach)
  170. _arguments \
  171. '--no-stdin[Do not attach stdin]' \
  172. '--sig-proxy[Proxy all received signals to the process (non-TTY mode only)]' \
  173. ':containers:__docker_runningcontainers'
  174. ;;
  175. (build)
  176. _arguments \
  177. '--force-rm[Always remove intermediate containers]' \
  178. '--no-cache[Do not use cache when building the image]' \
  179. {-q,--quiet}'[Suppress verbose build output]' \
  180. '--rm[Remove intermediate containers after a successful build]' \
  181. {-t,--tag=-}'[Repository, name and tag to be applied]:repository:__docker_repositories_with_tags' \
  182. ':path or URL:_directories'
  183. ;;
  184. (commit)
  185. _arguments \
  186. {-a,--author=-}'[Author]:author: ' \
  187. {-m,--message=-}'[Commit message]:message: ' \
  188. {-p,--pause}'[Pause container during commit]' \
  189. '--run=-[Configuration automatically applied when the image is run]:configuration: ' \
  190. ':container:__docker_containers' \
  191. ':repository:__docker_repositories_with_tags'
  192. ;;
  193. (cp)
  194. _arguments \
  195. ':container:->container' \
  196. ':hostpath:_files'
  197. case $state in
  198. (container)
  199. if compset -P '*:'; then
  200. _files
  201. else
  202. __docker_containers -qS ":"
  203. fi
  204. ;;
  205. esac
  206. ;;
  207. (diff|export)
  208. _arguments '*:containers:__docker_containers'
  209. ;;
  210. (events)
  211. _arguments \
  212. '--since=-[Events created since this timestamp]:timestamp: ' \
  213. '--until=-[Events created until this timestamp]:timestamp: '
  214. ;;
  215. (exec)
  216. _arguments \
  217. {-d,--detach}'[Detached mode: leave the container running in the background]' \
  218. {-i,--interactive}'[Keep stdin open even if not attached]' \
  219. {-t,--tty}'[Allocate a pseudo-tty]' \
  220. ':containers:__docker_runningcontainers'
  221. ;;
  222. (history)
  223. _arguments \
  224. '--no-trunc[Do not truncate output]' \
  225. {-q,--quiet}'[Only show numeric IDs]' \
  226. '*:images:__docker_images'
  227. ;;
  228. (images)
  229. _arguments \
  230. {-a,--all}'[Show all images]' \
  231. '*'{-f,--filter=-}'[Filter values]:filter: ' \
  232. '--no-trunc[Do not truncate output]' \
  233. {-q,--quiet}'[Only show numeric IDs]' \
  234. '--tree[Output graph in tree format]' \
  235. '--viz[Output graph in graphviz format]' \
  236. ':repository:__docker_repositories'
  237. ;;
  238. (inspect)
  239. _arguments \
  240. {-f,--format=-}'[Format the output using the given go template]:template: ' \
  241. '*:containers:__docker_containers'
  242. ;;
  243. (import)
  244. _arguments \
  245. ':URL:(- http:// file://)' \
  246. ':repository:__docker_repositories_with_tags'
  247. ;;
  248. (info)
  249. ;;
  250. (import)
  251. _arguments \
  252. ':URL:(- http:// file://)' \
  253. ':repository:__docker_repositories_with_tags'
  254. ;;
  255. (insert)
  256. _arguments '1:containers:__docker_containers' \
  257. '2:URL:(http:// file://)' \
  258. '3:file:_files'
  259. ;;
  260. (kill)
  261. _arguments \
  262. {-s,--signal=-}'[Signal to send]:signal:_signals' \
  263. '*:containers:__docker_runningcontainers'
  264. ;;
  265. (load)
  266. _arguments \
  267. {-i,--input=-}'[Read from tar archive file]:tar:_files'
  268. ;;
  269. (login)
  270. _arguments \
  271. {-e,--email=-}'[Email]:email: ' \
  272. {-p,--password=-}'[Password]:password: ' \
  273. {-u,--user=-}'[Username]:username: ' \
  274. ':server: '
  275. ;;
  276. (logout)
  277. _arguments \
  278. ':server: '
  279. ;;
  280. (logs)
  281. _arguments \
  282. {-f,--follow}'[Follow log output]' \
  283. {-t,--timestamps}'[Show timestamps]' \
  284. '*:containers:__docker_containers'
  285. ;;
  286. (port)
  287. _arguments \
  288. '1:containers:__docker_runningcontainers' \
  289. '2:port:_ports'
  290. ;;
  291. (pause|unpause)
  292. _arguments \
  293. '1:containers:__docker_runningcontainers'
  294. ;;
  295. (start)
  296. _arguments \
  297. {-a,--attach}'[Attach container'"'"'s stdout/stderr and forward all signals]' \
  298. {-i,--interactive}'[Attach container'"'"'s stding]' \
  299. '*:containers:__docker_stoppedcontainers'
  300. ;;
  301. (rm)
  302. _arguments \
  303. {-f,--force}'[Force removal]' \
  304. {-l,--link}'[Remove the specified link and not the underlying container]' \
  305. {-v,--volumes}'[Remove the volumes associated to the container]' \
  306. '*:containers:__docker_stoppedcontainers'
  307. ;;
  308. (rmi)
  309. _arguments \
  310. {-f,--force}'[Force removal]' \
  311. '--no-prune[Do not delete untagged parents]' \
  312. '*:images:__docker_images'
  313. ;;
  314. (restart|stop)
  315. _arguments \
  316. {-t,--time=-}'[Number of seconds to try to stop for before killing the container]:seconds to before killing:(1 5 10 30 60)' \
  317. '*:containers:__docker_runningcontainers'
  318. ;;
  319. (top)
  320. _arguments \
  321. '1:containers:__docker_runningcontainers' \
  322. '(-)*:: :->ps-arguments'
  323. case $state in
  324. (ps-arguments)
  325. _ps
  326. ;;
  327. esac
  328. ;;
  329. (ps)
  330. _arguments \
  331. {-a,--all}'[Show all containers]' \
  332. '--before=-[Show only container created before...]:containers:__docker_containers' \
  333. '*'{-f,--filter=-}'[Filter values]:filter: ' \
  334. {-l,--latest}'[Show only the latest created container]' \
  335. '-n[Show n last created containers, include non-running one]:n:(1 5 10 25 50)' \
  336. '--no-trunc[Do not truncate output]' \
  337. {-q,--quiet}'[Only show numeric IDs]' \
  338. {-s,--size}'[Display total file sizes]' \
  339. '--since=-[Show only containers created since...]:containers:__docker_containers'
  340. ;;
  341. (tag)
  342. _arguments \
  343. {-f,--force}'[force]'\
  344. ':image:__docker_images'\
  345. ':repository:__docker_repositories_with_tags'
  346. ;;
  347. (create|run)
  348. _arguments \
  349. {-a,--attach}'[Attach to stdin, stdout or stderr]' \
  350. '*--add-host=-[Add a custom host-to-IP mapping]:host\:ip mapping: ' \
  351. {-c,--cpu-shares=-}'[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)' \
  352. '*--cap-add=-[Add Linux capabilities]:capability: ' \
  353. '*--cap-drop=-[Drop Linux capabilities]:capability: ' \
  354. '--cidfile=-[Write the container ID to the file]:CID file:_files' \
  355. '--cpuset=-[CPUs in which to allow execution]:CPU set: ' \
  356. {-d,--detach}'[Detached mode: leave the container running in the background]' \
  357. '*--device=-[Add a host device to the container]:device:_files' \
  358. '*--dns=-[Set custom dns servers]:dns server: ' \
  359. '*--dns-search=-[Set custom DNS search domains]:dns domains: ' \
  360. '*'{-e,--environment=-}'[Set environment variables]:environment variable: ' \
  361. '--entrypoint=-[Overwrite the default entrypoint of the image]:entry point: ' \
  362. '*--env-file=-[Read environment variables from a file]:environment file:_files' \
  363. '*--expose=-[Expose a port from the container without publishing it]: ' \
  364. {-h,--hostname=-}'[Container host name]:hostname:_hosts' \
  365. {-i,--interactive}'[Keep stdin open even if not attached]' \
  366. '*--link=-[Add link to another container]:link:->link' \
  367. '*--lxc-conf=-[Add custom lxc options]:lxc options: ' \
  368. '-m[Memory limit (in bytes)]:limit: ' \
  369. '--name=-[Container name]:name: ' \
  370. '--net=-[Network mode]:network mode:(bridge none container: host)' \
  371. {-P,--publish-all}'[Publish all exposed ports]' \
  372. '*'{-p,--publish=-}'[Expose a container'"'"'s port to the host]:port:_ports' \
  373. '--privileged[Give extended privileges to this container]' \
  374. '--restart=-[Restart policy]:restart policy:(no on-failure always)' \
  375. '--rm[Remove intermediate containers when it exits]' \
  376. '*--security-opt=-[Security options]:security option: ' \
  377. '--sig-proxy[Proxy all received signals to the process (non-TTY mode only)]' \
  378. {-t,--tty}'[Allocate a pseudo-tty]' \
  379. {-u,--user=-}'[Username or UID]:user:_users' \
  380. '*-v[Bind mount a volume]:volume: '\
  381. '*--volumes-from=-[Mount volumes from the specified container]:volume: ' \
  382. {-w,--workdir=-}'[Working directory inside the container]:directory:_directories' \
  383. '(-):images:__docker_images' \
  384. '(-):command: _command_names -e' \
  385. '*::arguments: _normal'
  386. case $state in
  387. (link)
  388. if compset -P '*:'; then
  389. _wanted alias expl 'Alias' compadd -E ""
  390. else
  391. __docker_runningcontainers -qS ":"
  392. fi
  393. ;;
  394. esac
  395. ;;
  396. (pull|search)
  397. _arguments ':name:__docker_search'
  398. ;;
  399. (push)
  400. _arguments ':images:__docker_images'
  401. ;;
  402. (save)
  403. _arguments \
  404. {-o,--output=-}'[Write to file]:file:_files' \
  405. ':images:__docker_images'
  406. ;;
  407. (wait)
  408. _arguments ':containers:__docker_runningcontainers'
  409. ;;
  410. (help)
  411. _arguments ':subcommand:__docker_commands'
  412. ;;
  413. (*)
  414. _message 'Unknown sub command'
  415. esac
  416. }
  417. _docker () {
  418. # Support for subservices, which allows for `compdef _docker docker-shell=_docker_containers`.
  419. # Based on /usr/share/zsh/functions/Completion/Unix/_git without support for `ret`.
  420. if [[ $service != docker ]]; then
  421. _call_function - _$service
  422. return
  423. fi
  424. local curcontext="$curcontext" state line
  425. typeset -A opt_args
  426. _arguments -C \
  427. '-H[tcp://host:port to bind/connect to]:socket: ' \
  428. '(-): :->command' \
  429. '(-)*:: :->option-or-argument'
  430. if (( CURRENT == 1 )); then
  431. fi
  432. case $state in
  433. (command)
  434. __docker_commands
  435. ;;
  436. (option-or-argument)
  437. curcontext=${curcontext%:*:*}:docker-$words[1]:
  438. __docker_subcommand
  439. ;;
  440. esac
  441. }
  442. _docker "$@"
  443. # Local Variables:
  444. # mode: Shell-Script
  445. # sh-indentation: 4
  446. # indent-tabs-mode: nil
  447. # sh-basic-offset: 4
  448. # End:
  449. # vim: ft=zsh sw=4 ts=4 et