├── lxd-completion-zsh.plugin.zsh ├── LICENSE ├── _lxd ├── README.md └── _lxc /lxd-completion-zsh.plugin.zsh: -------------------------------------------------------------------------------- 1 | 0=${(%):-%N} 2 | source ${0:A:h}/_lxc 3 | source ${0:A:h}/_lxd 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 endaaman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /_lxd: -------------------------------------------------------------------------------- 1 | #compdef lxd 2 | 3 | # _lxd 4 | # 5 | # Copyright (c) 2020 endaaman 6 | # 7 | # This software may be modified and distributed under the terms 8 | # of the MIT license. See the LICENSE file for details. 9 | 10 | _lxd() { 11 | _arguments -C \ 12 | '1: :__lxd_commands' \ 13 | '*: :__lxd_global_flags' 14 | } 15 | 16 | 17 | __lxd_global_flags() { 18 | local -a _c 19 | _c=( 20 | {-d,--debug}':Show all debug messages' 21 | '--group:The group of users that will be allowed to talk to LXD' 22 | {-h,--help}':Print help' 23 | '--logfile:Path to the log file' 24 | '--syslog:Log to syslog' 25 | '--trace:Log tracing targets' 26 | ) 27 | _describe -o -t global_options 'Flags' _c 28 | } 29 | 30 | 31 | 32 | __lxd_commands() { 33 | local -a _c 34 | _c=( 35 | 'activateifneeded:Check if LXD should be started' 36 | 'cluster:Low-level cluster administration commands' 37 | 'help:Help about any command' 38 | 'import:Import existing containers' 39 | 'init:Configure the LXD daemon' 40 | 'shutdown:Tell LXD to shutdown all containers and exit' 41 | 'version:Show the server version' 42 | 'waitready:Wait for LXD to be ready to process requests' 43 | ) 44 | _describe -t commands 'Commands' _c 45 | } 46 | 47 | compdef _lxd lxd 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lxd-completion-zsh 2 | 3 | Zsh completion for `lxc` and `lxd` commands of [LXD](https://linuxcontainers.org/lxd/). 4 | 5 | ![screenshot](http://static.endaaman.me/images/github/lxd-completion.png) 6 | 7 | ## Installation 8 | 9 | ### Using a plugin manager (recommended) 10 | 11 | This way is recommended. The `lxc` command updates frequently and this repository as its completion does the same. Therefore, using a plugin manager, you can get the immediate updates when I apply them. 12 | 13 | [Antigen](https://github.com/zsh-users/antigen) 14 | 15 | ```sh 16 | antigen bundle 'endaaman/lxd-completion-zsh' 17 | ``` 18 | 19 | [zplug](https://github.com/zplug/zplug) 20 | 21 | ```sh 22 | zplug 'endaaman/lxd-completion-zsh' 23 | ``` 24 | 25 | ### [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh) 26 | 27 | 28 | 1. Clone this repository in oh-my-zsh's plugins directory: 29 | 30 | ```sh 31 | git clone https://github.com/endaaman/lxd-completion-zsh ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/lxd-completion-zsh 32 | ``` 33 | 34 | 2. Activate the plugin in ~/.zshrc: 35 | 36 | ```sh 37 | plugins=( [plugins...] lxd-completion-zsh) 38 | ``` 39 | 40 | 3. Restart zsh (such as by opening a new instance of your terminal emulator). 41 | 42 | ### Manually 43 | 44 | Put `_lxc` file into `$fpath` directory (e.g. defining `fpath=(~/.zsh/completion $fpath)`, place it in `~/.zsh/completion`) 45 | 46 | ## License 47 | 48 | MIT 49 | -------------------------------------------------------------------------------- /_lxc: -------------------------------------------------------------------------------- 1 | #compdef lxc 2 | 3 | # _lxc 4 | # 5 | # Copyright (c) 2017 endaaman 6 | # 7 | # This software may be modified and distributed under the terms 8 | # of the MIT license. See the LICENSE file for details. 9 | 10 | _lxc() { 11 | local context curcontext=$curcontext state line 12 | local selected_container 13 | declare -A opt_args 14 | 15 | local opt_container_control=( 16 | '--all[Run command against all containers]' \ 17 | '--stateful[Store the container state (only for stop)]' \ 18 | '--stateless[Ignore the container state (only for start)]' \ 19 | ) 20 | 21 | _arguments -C \ 22 | '--all[Print less common commands]' \ 23 | '--version[Show client version]' \ 24 | '1: :__lxc_commands' \ 25 | '*:: :->args' 26 | case $state in 27 | (args) 28 | case $words[1] in 29 | (alias) 30 | case $words[2] in 31 | (remove|rename) 32 | _arguments -C \ 33 | '2:containers:__lxc_aliases' 34 | ;; 35 | esac 36 | _arguments -C \ 37 | '1: :__lxc_alias_commands' 38 | ;; 39 | (cluster) 40 | _arguments -C \ 41 | '1: :__lxc_cluster_commands' 42 | ;; 43 | (config) 44 | case $words[2] in 45 | (get) 46 | _arguments -C \ 47 | '2:containers:__lxc_containers_all' 48 | ;; 49 | (set) 50 | _arguments -C \ 51 | '2:containers:__lxc_containers_all' 52 | ;; 53 | (unset) 54 | _arguments -C \ 55 | '2:containers:__lxc_containers_all' 56 | ;; 57 | (show) 58 | _arguments -C \ 59 | '2:containers:__lxc_containers_all' 60 | ;; 61 | (edit) 62 | _arguments -C \ 63 | '2:containers:__lxc_containers_all' 64 | ;; 65 | (metadata) 66 | case $words[3] in 67 | (show) 68 | _arguments -C \ 69 | '3:containers:__lxc_containers_all' 70 | ;; 71 | (edit) 72 | _arguments -C \ 73 | '3:containers:__lxc_containers_all' 74 | ;; 75 | esac 76 | _arguments -C \ 77 | '2: :__lxc_config_metadata_commands' 78 | ;; 79 | (template) 80 | case $words[3] in 81 | (list) 82 | _arguments -C \ 83 | '3:containers:__lxc_containers_all' 84 | ;; 85 | (show|edit|delete) 86 | if [ $#words[@] -gt 4 ]; then 87 | _arguments -C \ 88 | "*:Templates:($(__get_lxc_templates_by_container $words[4]))" 89 | fi 90 | _arguments -C \ 91 | '3:containers:__lxc_containers_all' 92 | ;; 93 | (create) 94 | _arguments -C \ 95 | '3:containers:__lxc_containers_all' 96 | ;; 97 | esac 98 | _arguments -C \ 99 | '2: :__lxc_config_template_commands' 100 | ;; 101 | (device) 102 | case $words[3] in 103 | (add) 104 | # lxc config device add = 105 | # 3 4 5 6 106 | if [ $#words[@] -gt 6 ]; then 107 | _arguments -C \ 108 | "*:key-values:_sep_parts '$(__get_lxc_keys_by_device $words[6])' = '($(ls))'" 109 | fi 110 | _arguments -C \ 111 | '3:containers:__lxc_containers_all' \ 112 | '4: :_files' \ 113 | '5:device type:__lxc_device_types' 114 | ;; 115 | (get|unset) 116 | if [ $#words[@] -eq 6 ]; then 117 | local type=$(lxc config device get $words[4] $words[5] type) 118 | _arguments -C "*:key-values:($(__get_lxc_keys_by_device $type))" 119 | fi 120 | selected_container=$words[4] 121 | _arguments -C \ 122 | '3:containers:__lxc_containers_all' \ 123 | '4:devices:__lxc_devices_by_container' \ 124 | ;; 125 | # lxc config device set = 126 | # 3 4 5 6 127 | (set) 128 | if [ $#words[@] -eq 6 ]; then 129 | local type=$(lxc config device get $words[4] $words[5] type) 130 | _arguments -C \ 131 | "*:key-values:_sep_parts '$(__get_lxc_keys_by_device $type)' = ($(ls))" \ 132 | '7:files:_files' 133 | fi 134 | selected_container=$words[4] 135 | _arguments -C \ 136 | '3:containers:__lxc_containers_all' \ 137 | '4:devices:__lxc_devices_by_container' \ 138 | ;; 139 | (override) 140 | if [ $#words[@] -gt 5 ]; then 141 | local type=$(lxc config device get $words[4] $words[5] type) 142 | _arguments -C \ 143 | "*:key-values:_sep_parts '$(__get_lxc_keys_by_device $type)' =" 144 | fi 145 | selected_container=$words[4] 146 | _arguments -C \ 147 | '3:containers:__lxc_containers_all' \ 148 | '4:devices:__lxc_devices_by_container' \ 149 | ;; 150 | (show|list) 151 | _arguments -C \ 152 | '3:containers:__lxc_containers_all' \ 153 | ;; 154 | (remove) 155 | selected_container=$words[4] 156 | _arguments -C \ 157 | '3:containers:__lxc_containers_all' \ 158 | '4:devices:__lxc_devices_by_container' \ 159 | ;; 160 | esac 161 | _arguments -C \ 162 | '2: :__lxc_config_device_commands' 163 | ;; 164 | (trust) 165 | _arguments -C \ 166 | '2: :__lxc_config_trust_commands' 167 | case $words[3] in 168 | (list|add|remove) 169 | # complete remote 170 | ;; 171 | esac 172 | ;; 173 | esac 174 | _arguments -C \ 175 | '1: :__lxc_config_commands' \ 176 | '--expanded[Show the expanded configuration]' 177 | ;; 178 | (console) 179 | _arguments -C \ 180 | '1:containers:__lxc_containers_running' 181 | ;; 182 | (copy) 183 | _arguments -C \ 184 | {-c,--config}'[Config key/value to apply to the new instance]' \ 185 | {-d,--device}'[New key/value to apply to a specific device]' \ 186 | {-e,--ephemeral}'[Ephemeral instance]' \ 187 | '--instance-only[Copy the instance without its snapshots]' \ 188 | '--mode[Transfer mode. One of pull (default), push or relay (default "pull")]' \ 189 | '--no-rofiles[Create the instance with no profiles applied]' \ 190 | {-p,--profile}'[Profile to apply to the new instance]' \ 191 | '--refresh[Perform an incremental copy]' \ 192 | '--stateless[Copy a stateful instance stateless]' \ 193 | {-s,--storage}'[Storage pool name]' \ 194 | '--target[Cluster member name]' \ 195 | '--target-project[Copy to a project different from the source]' 196 | ;; 197 | (delete) 198 | _arguments -C \ 199 | '*:containers:__lxc_containers_stopped' 200 | ;; 201 | (exec) 202 | _arguments -C \ 203 | '1:containers:__lxc_containers_running' \ 204 | '--cwd[Directory to run the command in (default /root)]' \ 205 | {-n,--disable-stdin}'[Disable stdin (reads from /dev/null)]' \ 206 | '--env[Environment variable to set (e.g. HOME=/home/foo)]' \ 207 | {-t,--force-interactive}'[Force pseudo-terminal allocation]' \ 208 | {-T,--force-noninteractive}'[Disable pseudo-terminal allocation]' \ 209 | '--group[Group ID to run the command as (default 0)]' \ 210 | '--mode[Override the terminal mode (auto, interactive or non-interactive) (default "auto")]' \ 211 | '--user[User ID to run the command as (default 0)]' 212 | ;; 213 | (export) 214 | _arguments -C \ 215 | '--compression[Define a compression algorithm: for backup or none]' \ 216 | '--instance-only[Whether or not to only backup the instance (without snapshots)]' \ 217 | '--optimized-storage[Use storage driver optimized format (can only be restored on a similar pool)]' 218 | ;; 219 | (file) 220 | case $words[2] in 221 | (push) 222 | _arguments -C \ 223 | '2:files:_files' \ 224 | '3:containers:__lxc_containers_all' 225 | ;; 226 | (pull) 227 | _arguments -C \ 228 | '2:containers:__lxc_containers_all' \ 229 | '3:files:_files' 230 | ;; 231 | (edit) 232 | _arguments -C \ 233 | '2:containers:__lxc_containers_all' 234 | ;; 235 | (delete) 236 | _arguments -C \ 237 | '*:containers:__lxc_containers_all' 238 | ;; 239 | esac 240 | _arguments -C \ 241 | '1: :__lxc_file_commands' \ 242 | "--gid=[Set the file's gid on push]" \ 243 | "--uid=[Set the file's uid on push]" \ 244 | "--mode=[Set the file's perms on push]" \ 245 | ''{-p,--create-dirs}'[Create any directories necessary]' \ 246 | ''{-r,--recursive}'[Recursively push or pull files]' 247 | ;; 248 | (help) 249 | _arguments -C \ 250 | '1: :__lxc_commands' 251 | ;; 252 | (image) 253 | case $words[2] in 254 | (alias) 255 | case $words[3] in 256 | (create) 257 | _arguments -C \ 258 | '4: :__lxc_images_as_fingerprint' 259 | ;; 260 | (list) 261 | _arguments -C \ 262 | '4: :()' \ 263 | '--format=[Format (csv|json|table|yaml) (default "table")]:Format:(csv json table yaml)' 264 | ;; 265 | (delete|rename) 266 | _arguments -C \ 267 | '3: :__lxc_images_as_alias' 268 | ;; 269 | esac 270 | _arguments -C \ 271 | '2: :__lxc_image_alias_commands' 272 | ;; 273 | (delete|refresh) 274 | _arguments -C \ 275 | '*: :__lxc_images_as_fingerprint' 276 | ;; 277 | (edit|show|info|export) 278 | _arguments -C \ 279 | '2: :__lxc_images_as_fingerprint' 280 | ;; 281 | (copy) 282 | _arguments -C \ 283 | '2: :__lxc_remotes' 284 | ;; 285 | (import) 286 | _arguments -C \ 287 | '2: :_files' 288 | ;; 289 | (list) 290 | l="'Columns' 'l[Shortest image alias (and optionally number of other aliases)]' \ 291 | 'L[Newline-separated list of all image aliases]' 'f[Fingerprint]' \ 292 | 'p[Whether image is public]' 'd[Description]' 'a[Architecture]' \ 293 | 's[Size]' 'u[Upload date]'" 294 | _arguments -C \ 295 | '3: :()' \ 296 | {-c,--columns=}"[Columns (default lfpdasu)]:Columns:_values -s '' $l" \ 297 | '--format=[Format (csv|json|table|yaml) (default "table")]:Format:(csv json table yaml)' 298 | ;; 299 | esac 300 | _arguments -C \ 301 | '1: :__lxc_image_commands' 302 | ;; 303 | (import) 304 | _arguments -C \ 305 | '1: :_files' \ 306 | {-s,--storage=}'[Storage pool name]' 307 | ;; 308 | (info) 309 | _arguments -C \ 310 | '1:containers:__lxc_containers_all' \ 311 | '--resources[Show the resources available to the server]' \ 312 | "--show-log[Show the container's last 100 log lines?]" \ 313 | '--target[Cluster member name]' 314 | ;; 315 | (launch|init) 316 | _arguments -C \ 317 | '1: :__lxc_images' \ 318 | {-c,--config=}'[Config key/value to apply to the new container (= map\[\])]' \ 319 | '--console=[Immediately attach to the console]' \ 320 | '--empty[Create an empty instance]' \ 321 | {-e,--ephemeral}'[Ephemeral container]' \ 322 | {-n,--network=}'[Network name]' \ 323 | '--no-profiles[Create the instance with no profiles applied]' \ 324 | {-p,--profile=}'[Profile to apply to the new container]' \ 325 | {-s,--storage=}'[Storage pool name]' \ 326 | '--target=[Node name]' \ 327 | {-t,--type=}'[Instance type]' \ 328 | '--vm[Create a virtual machine]' 329 | ;; 330 | (list) 331 | # c.f https://github.com/lxc/lxd/blob/master/lxc/list.go 332 | local _l="'Columns' '4[IPv4 address]' '6[IPv6 address]' 'a[Architecture]' 'b[Storage pool]' \ 333 | 'c[Creation date]' 'd[Description]' 'l[Last used date]' 'n[Name]' 'N[Number of Processes]' \ 334 | \"p[PID of the container's init process]\" 'P[Profiles]' 's[State]' \ 335 | 'S[Number of snapshots]' 't[Type (persistent or ephemeral)]' \ 336 | 'L[Location of the container (e.g. its cluster member)]'" 337 | _arguments -C \ 338 | {-c,--columns=}"[Columns (default: ns46tSL)]:Columns:_values -s '' $_l" \ 339 | '--fast[Fast mode (same as --columns=nsacPt)]' \ 340 | '--format=[Format (csv|json|table|yaml) (default "table")]:Format:(csv json table yaml)' \ 341 | '--no-alias[Ignore aliases when determining what command to run]' 342 | ;; 343 | (manpage) 344 | _arguments -C \ 345 | '1:Directory to put manpage to:_files' 346 | ;; 347 | (monitor) 348 | _arguments -C \ 349 | '1: :__lxc_containers_all' \ 350 | '--loglevel=[Minimum level for log messages]:Log level:(info)' \ 351 | '--pretty[Pretty rendering]' \ 352 | '--type=[Event type to listen for]:Type:(lifecycle logging)' 353 | ;; 354 | (move) 355 | _arguments -C \ 356 | {-c,--config}'[Config key/value to apply to the target instance]' \ 357 | {-d,--device}'[New key/value to apply to a specific device]' \ 358 | '--instance-only[Move the instance without its snapshots]' \ 359 | '--mode{Transfer mode. One of pull (default), push or relay. (default "pull")}' \ 360 | '--no-profiles[Unset all profiles on the target instance]' \ 361 | {-p,--profile}'[Profile to apply to the target instance]' \ 362 | --stateless'[Copy a stateful instance stateless]' \ 363 | {-s,--storage}'[Storage pool name]' \ 364 | '--target[Cluster member name]' \ 365 | '--target-project[Copy to a project different from the source]' 366 | ;; 367 | (network) 368 | _arguments -C \ 369 | '1: :__lxc_network_commands' 370 | ;; 371 | (operation) 372 | # TODO: complete operation items 373 | _arguments -C \ 374 | '1: :__lxc_operation_commands' 375 | ;; 376 | (pause) 377 | _arguments -C \ 378 | '1: :__lxc_containers_running' \ 379 | '--all[Run command against all containers]' 380 | ;; 381 | (project) 382 | case $words[2] in 383 | (edit|delete|switch|rename|show|get|set) 384 | _arguments -C \ 385 | '2: :__lxc_projects' 386 | ;; 387 | (list|ls) 388 | _arguments -C \ 389 | '3: :()' \ 390 | '--format=[Format (csv|json|table|yaml) (default "table")]:Format:(csv json table yaml)' 391 | ;; 392 | esac 393 | _arguments -C \ 394 | '1: :__lxc_project_commands' 395 | ;; 396 | (profile) 397 | case $words[2] in 398 | (add) 399 | _arguments -C \ 400 | '2: :__lxc_containers_all' \ 401 | '3: :__lxc_profiles' \ 402 | ;; 403 | (assign|apply) 404 | _arguments -C \ 405 | '2: :__lxc_containers_all' \ 406 | "3: :_values -s , Profiles $(__get_lxc_profiles)" 407 | ;; 408 | (copy|cp) 409 | _arguments -C \ 410 | '2: :__lxc_profiles' \ 411 | '3: :__lxc_profiles' 412 | ;; 413 | (delete|rm|edit|show) 414 | _arguments -C \ 415 | '2: :__lxc_profiles' 416 | ;; 417 | (get|set|unset) 418 | # TODO: complete profile keys 419 | _arguments -C \ 420 | '2: :__lxc_profiles' 421 | ;; 422 | (list|ls) 423 | # TODO: complete container profiles 424 | _arguments -C \ 425 | '2: :__lxc_remotes' 426 | ;; 427 | (rename|mv) 428 | # TODO: complete container profiles 429 | _arguments -C \ 430 | '2: :__lxc_profiles' 431 | ;; 432 | esac 433 | _arguments -C \ 434 | '1: :__lxc_profile_commands' 435 | ;; 436 | (publish) 437 | # TODO: complete publish 438 | _arguments -C \ 439 | '1: :__lxc_containers_all' 440 | ;; 441 | (query) 442 | _arguments -C \ 443 | {-d,--data}'[Input data]' \ 444 | '--raw[Print the raw response]' \ 445 | {-X,--request}'[Action (defaults to GET) (default "GET")]' \ 446 | '--wait[Wait for the operation to complete]' 447 | ;; 448 | (remote) 449 | case $words[2] in 450 | (set-default|set-url|rename|remove) 451 | _arguments -C \ 452 | '2: :__lxc_remotes' 453 | ;; 454 | (add) 455 | _arguments -C \ 456 | '2: :()' \ 457 | '--accept-certificate[Accept certificate]' \ 458 | '--auth-type=[Server authentication type (tls or macaroons)]:Auth type:(tls macaroons)' \ 459 | '--password[Remote admin password]' \ 460 | '--protocol=[Server protocol (lxd or simplestreams)]:Protocol:(tls macaroons)' \ 461 | '--public[Public image server]' 462 | ;; 463 | esac 464 | _arguments -C \ 465 | '1: :__lxc_remote_commands' 466 | ;; 467 | (rename) 468 | _arguments -C \ 469 | '1:containers:__lxc_containers_stopped' \ 470 | ;; 471 | (restart) 472 | _arguments -C \ 473 | '*:containers:__lxc_containers_running' \ 474 | {-f,--force}'[Force the container to shutdown]' \ 475 | '--timeout[Time to wait for the container before killing it]' \ 476 | $opt_container_control 477 | ;; 478 | (restore) 479 | _arguments -C \ 480 | '1:containers:__lxc_containers_all' \ 481 | '--stateful[Store the container state (only for stop)]' 482 | ;; 483 | (shell) 484 | _arguments -C \ 485 | '1:containers:__lxc_containers_running' \ 486 | '--cwd[Directory to run the command in (default /root)]' \ 487 | {-n,--disable-stdin}'[Disable stdin (reads from /dev/null)]' \ 488 | '--env[Environment variable to set (e.g. HOME=/home/foo)]' \ 489 | {-t,--force-interactive}'[Force pseudo-terminal allocation]' \ 490 | {-T,--force-noninteractive}'[Disable pseudo-terminal allocation]' \ 491 | '--group[Group ID to run the command as (default 0)]' \ 492 | '--mode[Override the terminal mode (auto, interactive or non-interactive) (default "auto")]' \ 493 | '--user[User ID to run the command as (default 0)]' 494 | ;; 495 | (snapshot) 496 | _arguments -C \ 497 | '1:containers:__lxc_containers_all' 498 | ;; 499 | (start) 500 | _arguments -C \ 501 | '*:containers:__lxc_containers_stopped' \ 502 | $opt_container_control 503 | ;; 504 | (stop) 505 | _arguments -C \ 506 | '*:containers:__lxc_containers_running' \ 507 | '--timeout[Time to wait for the container before killing it (= -1)]' \ 508 | {-f,--force}'[Force the container to shutdown]' \ 509 | $opt_container_control 510 | ;; 511 | (storage) 512 | case $words[2] in 513 | (delete|edit|get|info|set|unset) 514 | _arguments -C \ 515 | '2: :__lxc_storages' 516 | ;; 517 | (volume) 518 | case $words[3] in 519 | (list) 520 | _arguments -C \ 521 | '3: :__lxc_storages' 522 | ;; 523 | esac 524 | _arguments -C \ 525 | '2: :__lxc_storage_volume_commands' 526 | ;; 527 | esac 528 | _arguments -C \ 529 | '1: :__lxc_storage_commands' 530 | ;; 531 | (version) 532 | # nop 533 | ;; 534 | esac 535 | ;; 536 | esac 537 | _arguments -C -A '-*' \ 538 | '*: :__lxc_global_flags' 539 | return 0 540 | } 541 | 542 | __lxc_global_flags() { 543 | local -a _l=( 544 | '--debug:Show all debug messages' 545 | '--force-local:Force using the local unix socket' 546 | {-h,--help}':Print help' 547 | '--project:Override the source project' 548 | {-q,--quiet}":Don't show progress information" 549 | {-v,--verbose}':Show all information messages' 550 | # '--version:Print version number' 551 | ) 552 | _describe -o -t global_options 'global option' _l 553 | } 554 | 555 | __lxc_commands() { 556 | local -a _l=( 557 | 'alias:Manage command aliases' 558 | 'cluster:Manage cluster nodes' 559 | 'config:Change container or server configuration options' 560 | "console:Interact with the container's console device and log" 561 | 'copy:Copy containers within or in between LXD instances' 562 | 'delete:Delete containers and snapshots' 563 | 'exec:Execute commands in containers' 564 | 'export:Export instance backups' 565 | 'file:Manage files in containers' 566 | 'help:Help about any command' 567 | # 'finger:Check if the LXD server is alive' # old sub command 568 | 'image:Manipulate container images' 569 | 'import:Import instance backups' 570 | 'info:Show container or server information' 571 | 'init:Create containers from images' 572 | 'launch:Create and start containers from images' 573 | 'list:List the existing containers' 574 | 'manpage:Generate all the LXD manpages' 575 | 'monitor:Monitor a local or remote LXD server' 576 | 'move:Move containers within or in between LXD instances' 577 | 'network:Manage and attach containers to networks' 578 | 'operation:List, show and delete background operations' 579 | 'pause:Pause containers' 580 | 'profile:Manage container configuration profiles' 581 | 'project:Manage projects' 582 | 'publish:Publish containers as images' 583 | 'query:Send a raw query to LXD' 584 | 'remote:Manage the list of remote LXD servers' 585 | 'rename:Rename a container or snapshot' 586 | 'restart:Restart containers' 587 | 'restore:Restore containers from snapshots' 588 | 'snapshot:Create container snapshots' 589 | 'shell:Execute commands in instances' 590 | 'start:Start containers' 591 | 'stop:Stop containers' 592 | 'storage:Manage storage pools and volumes' 593 | 'version:Print the version number of this client tool' 594 | ) 595 | _describe -t commands Commands _l 596 | } 597 | 598 | __lxc_alias_commands() { 599 | local -a _l=( 600 | 'add:Add a new alias pointing to .' 601 | 'remove:Remove the alias .' 602 | 'list:List all the aliases.' 603 | 'rename:Rename remote to .' 604 | ) 605 | _describe -t commands 'Alias commands' _l 606 | } 607 | 608 | __lxc_cluster_commands() { 609 | local -a _l=( 610 | 'edit:Edit cluster member configurations as YAML' 611 | 'enable:Enable clustering on a single non-clustered LXD server' 612 | 'list:List all the cluster members' 613 | 'remove:Remove a member from the cluster' 614 | 'rename:Rename a cluster member' 615 | 'show:Show details of a cluster member' 616 | ) 617 | _describe -t commands 'Cluster commands' _l 618 | } 619 | 620 | __lxc_config_commands() { 621 | local -a _l=( 622 | 'get:Get container or server configuration key' 623 | 'set:Set container or server configuration key' 624 | 'unset:Unset container or server configuration key' 625 | 'show:Show container or server configuration' 626 | 'edit:Edit container or server configuration key' 627 | 'metadata:Container metadata' 628 | 'template:Container templates' 629 | 'device:Device management' 630 | 'trust:Client trust store management' 631 | ) 632 | _describe -t commands 'Config commands' _l 633 | } 634 | 635 | __lxc_config_device_commands() { 636 | local -a _l=( 637 | 'add:Add a device to a container' 638 | 'get:Get a device property' 639 | 'set:Set a device property' 640 | 'unset:Unset a device property' 641 | 'override:Copy a profile inherited device into local container config' 642 | 'list:List devices for container' 643 | 'show:Show full device details for container' 644 | 'remove:Remove device from container' 645 | ) 646 | _describe -t commands 'Config device commands' _l 647 | } 648 | 649 | 650 | __lxc_config_metadata_commands() { 651 | local -a _l 652 | _c=( 653 | 'show:Show the container metadata.yaml content' 654 | 'edit:Edit the container metadata.yaml, either by launching external editor or reading STDIN' 655 | ) 656 | _describe -t commands 'Config metadata commands' _l 657 | } 658 | 659 | __lxc_config_template_commands() { 660 | local -a _l=( 661 | 'list:List the names of template files for a container.' 662 | 'show:Show the content of a template file for a container' 663 | 'create:Add an empty template file for a container' 664 | 'edit:Edit the content of a template file for a container, either by launching external editor or reading STDIN' 665 | 'delete:Delete a template file for a container' 666 | 667 | ) 668 | _describe -t commands 'Config template commands' _l 669 | } 670 | 671 | __lxc_config_trust_commands() { 672 | local -a _l=( 673 | 'list:List all trusted certs' 674 | 'add:Add certfile.crt to trusted hosts' 675 | 'remove:Remove the cert from trusted hosts' 676 | ) 677 | _describe -t commands 'Config trust commands' _l 678 | } 679 | 680 | __lxc_file_commands() { 681 | local -a _l=( 682 | 'pull:Pull file from container' 683 | 'push:Push file to container' 684 | 'delete:Delete files in containers.' 685 | 'edit:Edit files in containers using the default text editor' 686 | ) 687 | _describe -t commands 'File commands' _l 688 | } 689 | 690 | __lxc_image_commands() { 691 | local -a _l=( 692 | 'copy:Copy an image from one LXD daemon to another over the network' 693 | 'delete:Delete one or more images from the LXD image store' 694 | 'import:Import images into the image store' 695 | 'export:Export an image from the LXD image store into a distributable tarball' 696 | 'info:Print everything LXD knows about a given image' 697 | 'list:List images in the LXD image store. Filters may be of the' 698 | 'show:Yaml output of the user modifiable properties of an image' 699 | 'edit:Edit image, either by launching external editor or reading STDIN' 700 | 'alias:Manage alias for image in the LXD image store' 701 | 'refresh:Refresh images' 702 | ) 703 | _describe -t commands 'Image commands' _l 704 | } 705 | 706 | __lxc_image_alias_commands() { 707 | local -a _l=( 708 | 'create:Create aliases for existing images' 709 | 'rename:Rename aliases' 710 | 'delete:Delete image alias' 711 | 'list:List image aliases' 712 | ) 713 | _describe -t commands 'Image alias commands' _l 714 | } 715 | 716 | __lxc_profile_commands() { 717 | local -a _l=( 718 | 'add:Add profiles to containers' 719 | 'assign:Assign sets of profiles to containers' 720 | 'copy:Copy profiles' 721 | 'create:Create profiles' 722 | 'delete:Delete profiles' 723 | 'device:Manage container devices' 724 | 'edit:Edit profile configurations as YAML' 725 | 'get:Get values for profile configuration keys' 726 | 'list:List profiles' 727 | 'remove:Remove profiles from containers' 728 | 'rename:Rename profiles' 729 | 'set:Set profile configuration keys' 730 | 'show:Show profile configurations' 731 | 'unset:Unset profile configuration keys' 732 | ) 733 | _describe -t commands 'Profile commands' _l 734 | } 735 | 736 | __lxc_remote_commands() { 737 | local -a _l=( 738 | 'add:Add the remote at ' 739 | 'remove:Remove the remote ' 740 | 'list:List all remotes' 741 | 'rename:Rename remote to ' 742 | "set-url:Update 's url to " 743 | 'set-default:Set the default remote' 744 | 'get-default:Print the default remote' 745 | ) 746 | _describe -t commands 'Remote commands' _l 747 | } 748 | 749 | __lxc_network_commands() { 750 | local -a _l=( 751 | 'attach:Attach network interfaces to containers' 752 | 'attach-profile:Attach network interfaces to profiles' 753 | 'create:Create new networks' 754 | 'delete:Delete networks' 755 | 'detach:Detach network interfaces from containers' 756 | 'detach-profile:Detach network interfaces from profiles' 757 | 'edit:Edit network configurations as YAML' 758 | 'get:Get values for network configuration keys' 759 | 'info:Get runtime information on networks' 760 | 'list:List available networks' 761 | 'list-leases:List DHCP leases' 762 | 'rename:Rename networks' 763 | 'set:Set network configuration keys' 764 | 'show:Show network configurations' 765 | 'unset:Unset network configuration keys' 766 | ) 767 | _describe -t commands 'Network commands' _l 768 | } 769 | 770 | __lxc_operation_commands() { 771 | local -a _l=( 772 | 'delete:Delete a background operation (will attempt to cancel)' 773 | 'list:List background operations' 774 | 'show:Show details on a background operation' 775 | ) 776 | _describe -t commands 'Operation commands' _l 777 | } 778 | 779 | __lxc_storage_commands() { 780 | local -a _l=( 781 | 'create:Create storage pools' 782 | 'delete:Delete storage pools' 783 | 'edit:Edit storage pool configurations as YAML' 784 | 'get:Get values for storage pool configuration keys' 785 | 'info:Show useful information about storage pools' 786 | 'list:List available storage pools' 787 | 'set:Set storage pool configuration keys' 788 | 'show:Show storage pool configurations and resources' 789 | 'unset:Unset storage pool configuration keys' 790 | 'volume:Manage storage volumes' 791 | ) 792 | _describe -t commands 'Storage commands' _l 793 | } 794 | 795 | __lxc_storage_volume_commands() { 796 | local -a _l=( 797 | 'attach:Attach new storage volumes to containers' 798 | 'attach-profile:Attach new storage volumes to profiles' 799 | 'copy:Copy storage volumes' 800 | 'create:Create new custom storage volumes' 801 | 'delete:Delete storage volumes' 802 | 'detach:Detach storage volumes from containers' 803 | 'detach-profile Detach storage volumes from profiles' 804 | 'edit:Edit storage volume configurations as YAML' 805 | 'get:Get values for storage volume configuration keys' 806 | 'list:List storage volumes' 807 | 'move:Move storage volumes between pools' 808 | 'rename:Rename storage volumes and storage volume snapshots' 809 | 'restore:Restore storage volume snapshots' 810 | 'set:Set storage volume configuration keys' 811 | 'show:Show storage volum configurations' 812 | 'snapshot:Snapshot storage volumes' 813 | 'unset:Unset storage volume configuration keys' 814 | ) 815 | _describe -t commands 'Storage volume commands' _l 816 | } 817 | 818 | __lxc_project_commands() { 819 | local -a _l=( 820 | 'create:Create projects' 821 | 'delete:Delete projects' 822 | 'edit:Edit project configurations as YAML' 823 | 'get:Get values for project configuration keys' 824 | 'list:List projects' 825 | 'rename:Rename projects' 826 | 'set:Set project configuration keys' 827 | 'show:Show project options' 828 | 'switch:Switch the current project' 829 | 'unset:Unset project configuration keys' 830 | ) 831 | _describe -t commands 'Project commands' _l 832 | } 833 | 834 | __lxc_devices_by_container () { 835 | local -a _l=(${(f)"$(_call_program devices lxc config device list $selected_container)"}) 836 | _describe "Devices of $selected_container" _l 837 | } 838 | 839 | __lxc_list_columns () { 840 | local -a _l=( 841 | '4:IPv4 address' 842 | '6:IPv6 address' 843 | 'a:Architecture' 844 | 'b:Storage pool' 845 | 'c:Creation date' 846 | 'd:Description' 847 | 'l:Last used date' 848 | 'n:Name' 849 | 'N:Number of Processes' 850 | "p:PID of the container's init process" 851 | 'P:Profiles' 852 | 's:State' 853 | 'S:Number of snapshots' 854 | 't:Type (persistent or ephemeral)' 855 | 'L:Location of the container (e.g. its cluster member)' 856 | ) 857 | _describe "Columns" _l 858 | } 859 | 860 | __lxc_device_types () { 861 | local -a _l=( 862 | 'none:Inheritance blocker' 863 | 'nic:Network interface' 864 | 'disk:Mountpoint inside the container' 865 | 'unix-char:Unix character device' 866 | 'unix-block:Unix block device' 867 | 'usb:USB device' 868 | 'gpu:GPU device' 869 | 'infiniband:Infiniband device' 870 | 'proxy:Proxy device' 871 | ) 872 | _describe 'Device types' _l 873 | } 874 | 875 | __lxc_containers_running () { 876 | local -a _l=(${(@f)"$(_call_program containers lxc list --fast | tail -n +4 | awk '{print $2 $4}' | grep -E 'RUNNING$' | sed -e "s/RUNNING//")"}) 877 | _describe -t containers 'Running Containers' _l 878 | } 879 | 880 | __lxc_containers_stopped () { 881 | local -a _l=(${(@f)"$(_call_program containers lxc list --fast | tail -n +4 | awk '{print $2 $4}' | grep -E 'STOPPED$' | sed -e "s/STOPPED//")"}) 882 | _describe -t containers 'Stopped containers' _l 883 | } 884 | 885 | __lxc_containers_all () { 886 | local -a _l=(${(@f)"$(_call_program containers lxc list --fast | tail -n +4 | awk '{print $2}' | grep -E -v '^(\||^$)')"}) 887 | _describe -t containers 'All containers' _l 888 | } 889 | 890 | __lxc_images_as_fingerprint () { 891 | # local -a _l=(${(@f)"$(_call_program images lxc image list | tail -n +4 | egrep -e '^\|' | awk '{split($0,a,"|"); for(i in a){ sub(/^[ \t]+/,"",a[i]);sub(/[ \t]+$/,"",a[i]);}; (a[2]=="") ? b=" (not aliased)" : b=" (aliased as " a[2] ")" ; print a[3] ":" a[5] b }' )"}) 892 | 893 | local -a _l 894 | _call_program images lxc image list --format=csv | sed -e 's/:/\\:/g' | while read line 895 | do 896 | local alias=$(echo $line| cut -d ',' -f 1) 897 | if [ -n "$alias" ]; then 898 | suffix="$alias" 899 | else 900 | suffix='(not aliased)' 901 | fi 902 | _l=($_l "$(echo $line | awk -F ',' '{printf "%s:%-44s -- ",$2,$4}')$suffix") 903 | done 904 | 905 | _describe -t images_as_fingerprint 'Images as fingerprint' _l 906 | } 907 | 908 | __lxc_images_as_alias () { 909 | # local -a _l=(${(@f)"$(_call_program images lxc image alias list | tail -n +4 | egrep -e '^\|' | awk '{split($0,a,"|"); for(i in a){ sub(/^[ \t]+/,"",a[i]);sub(/[ \t]+$/,"",a[i]);}; (a[4]=="") ? b="" : b=" - " a[4] ;print a[2] ":" a[3] b }' )"}) 910 | 911 | local -a _l 912 | _call_program images lxc image list --format=csv | sed -e 's/:/\\:/g' | while read line 913 | do 914 | local alias=$(echo $line| cut -d ',' -f 1) 915 | if [ -n "$alias" ]; then 916 | _l=($_l "$(echo $line | awk -F ',' '{printf "%s: %s -- %s",$1,$2,$4}')") 917 | fi 918 | done 919 | _describe -t images_as_alias 'Images as alias' _l 920 | } 921 | 922 | __lxc_images () { 923 | __lxc_images_as_alias 924 | __lxc_images_as_fingerprint 925 | } 926 | 927 | __lxc_aliases () { 928 | local -a _l=(${(@f)"$(_call_program aliases lxc alias list | tail -n +4 | grep -E '^\|' | awk '{print $2 ":" $4}')"}) 929 | _describe -t aliases 'Aliases' _l 930 | } 931 | 932 | __lxc_remotes () { 933 | local -a _l=(${(@f)"$(_call_program remotes lxc remote list | tail -n +4 | grep -E -e '^\|' | sed -e 's/(default)//' | awk '{print $2 ":" $4}')"}) 934 | _describe -t remotes 'Remotes' _l 935 | } 936 | 937 | __lxc_profiles () { 938 | local -a _l=(${(@f)"$(_call_program profiles lxc profile list | tail -n +4 | grep -E -e '^\|' | awk '{print $2 ":used by " $4 " containers" }' )"}) 939 | _describe -t profiles 'Profiles' _l 940 | } 941 | 942 | __lxc_projects() { 943 | local -a _l=(${(@f)"$(_call_program profiles lxc project list --format=csv | cut -d ',' -f 1 | sed -e 's/ (current)/:current/')"}) 944 | _describe -t profiles 'Projects' _l 945 | } 946 | 947 | __lxc_storages () { 948 | local -a _l=(${(@f)"$(_call_program profiles lxc storage list | tail -n +4 | grep -E -e '^\|' | awk '{print $2 }')"}) 949 | _describe -t storages 'Storages' _l 950 | } 951 | 952 | __get_lxc_keys_by_device () { 953 | typeset -A hash 954 | hash[nic]="(nictype limits.ingress limits.egress limits.max name host_name hwaddr mtu \ 955 | parent vlan ipv4.address ipv6.address security.mac_filtering maas.subnet.ipv4 maas.subnet.ipv6)" 956 | hash[infiniband]="(nictype name hwaddr mtu parent)" 957 | hash[disk]="(limits.read limits.write limits.max path source optional readonly size recursive pool)" 958 | hash[unix-char]="(source path major minor uid gid mode required)" 959 | hash[unix-block]="(source path major minor uid gid mode required)" 960 | hash[usb]="(vendorid productid uid gid mode required)" 961 | hash[gpu]="(vendorid productid id pci uid gid mode)" 962 | hash[proxy]="(listen bind connect)" 963 | echo "$hash[$1]" 964 | } 965 | 966 | __get_lxc_templates_by_container () { 967 | lxc config template list $1 | tail -n +4 | grep -E '^\|' | awk '{print $2}' 968 | } 969 | 970 | __get_lxc_profiles () { 971 | lxc profile list | tail -n +4 | grep -E -e '^\|' | awk '{print $2}' | paste -sd " " 972 | } 973 | 974 | compdef _lxc lxc 975 | --------------------------------------------------------------------------------