summaryrefslogtreecommitdiffstats
path: root/shell-completion/zsh/_systemctl.in
blob: a5a16b3fdbe1700d341596728bd067839761c419 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
#compdef systemctl
# SPDX-License-Identifier: LGPL-2.1-or-later

(( $+functions[_systemctl_commands] )) || _systemctl_commands()
{
    local expl i

    local -a unit_commands=(
        # Unit Commands
        "list-automounts:List automounts"
        "list-paths:List paths"
        "list-sockets:List sockets"
        "list-timers:List timers"
        "list-units:List units"
        "start:Start (activate) one or more units"
        "stop:Stop (deactivate) one or more units"
        "reload:Reload one or more units"
        "restart:Start or restart one or more units"
        "condrestart:Restart one or more units if active"
        "try-restart:Restart one or more units if active"
        "reload-or-restart:Reload one or more units if possible, otherwise start or restart"
        "force-reload:Reload one or more units if possible, otherwise restart if active"
        "try-reload-or-restart:Reload one or more units if possible, otherwise restart if active"
        "isolate:Start one unit and stop all others"
        "kill:Send signal to processes of a unit"
        "is-active:Check whether units are active"
        "is-failed:Check whether units are failed"
        "status:Show runtime status of one or more units"
        "show:Show properties of one or more units/jobs or the manager"
        "cat:Show the source unit files and drop-ins"
        "set-property:Sets one or more properties of a unit"
        "service-log-level:Get or set the logging threshold for service"
        "service-log-target:Get or set the logging target for service"
        "help:Show documentation for specified units"
        "reset-failed:Reset failed state for all, one, or more units"
        "list-dependencies:Show unit dependency tree"
        "clean:Remove configuration, state, cache, logs or runtime data of units"
        "bind:Bind mount a path from the host into a unit's namespace"
        "mount-image:Mount an image from the host into a unit's namespace"
        "whoami:Determines as part of which unit the command is being invoked"
    )

    local -a machine_commands=(
        # Machine Commands
        "list-machines:List the host and all running local containers"
    )

    local -a unit_file_commands=(
        # Unit File Commands
        "list-unit-files:List installed unit files"
        "enable:Enable one or more unit files"
        "disable:Disable one or more unit files"
        "reenable:Reenable one or more unit files"
        "preset:Enable/disable one or more unit files based on preset configuration"
        "preset-all:Enable/disable all unit files based on preset configuration"
        "is-enabled:Check whether unit files are enabled"
        "mask:Mask one or more units"
        "unmask:Unmask one or more units"
        "link:Link one or more units files into the search path"
        "revert:Revert unit files to their vendor versions"
        "add-wants:Add Wants= dependencies to a unit"
        "add-requires:Add Requires= dependencies to a unit"
        "set-default:Set the default target"
        "get-default:Query the default target"
        "edit:Edit one or more unit files"
    )

    local -a job_commands=(
        # Job Commands
        "list-jobs:List jobs"
        "cancel:Cancel all, one, or more jobs"
    )

    local -a environment_commands=(
        # Environment Commands
        "show-environment:Dump environment"
        "set-environment:Set one or more environment variables"
        "unset-environment:Unset one or more environment variables"
        "import-environment:Import environment variables set on the client"
    )

    local -a manager_state_commands=(
        # Manager State Commands
        "daemon-reload:Reload systemd manager configuration"
        "daemon-reexec:Reexecute systemd manager"
        "log-level:Get or set the log level"
        "log-target:Get or set the log target"
        "service-watchdogs:Get or set the state of software watchdogs"
    )

    local -a system_commands=(
        # System Commands
        "is-system-running:Query overall status of the system"
        "default:Enter system default mode"
        "rescue:Enter system rescue mode"
        "emergency:Enter system emergency mode"
        "halt:Shut down and halt the system"
        "suspend:Suspend the system"
        "poweroff:Shut down and power-off the system"
        "reboot:Shut down and reboot the system"
        "soft-reboot:Shut down and reboot the userspace"
        "kexec:Shut down and reboot the system with kexec"
        "exit:Ask for user instance termination"
        "switch-root:Change root directory"
        "hibernate:Hibernate the system"
        "hybrid-sleep:Hibernate and suspend the system"
        "suspend-then-hibernate:Suspend the system for a period of time, and then hibernate it"
    )

    local -a groups=( unit machine unit_file job environment manager_state system )
    local -a _systemctl_cmds
    for i in $groups; do
        _systemctl_cmds+=( "${(@P)${:-"${i}_commands"}}" )
    done

    if (( CURRENT == 1 )); then
        _tags ${^groups//_/-}-commands
        while _tags; do
            for i in $groups; do
                if _requested ${i//_/-}-commands; then
                    _describe -t ${i//_/-}-commands "${i//_/ } command" ${i}_commands \
                        && ret=0
                fi
            done
        done
    else
        local curcontext="$curcontext"

        cmd="${${_systemctl_cmds[(r)$words[1]:*]%%:*}}"
        # Deal with any aliases
        case $cmd in
            condrestart) cmd="try-restart";;
            force-reload) cmd="try-reload-or-restart";;
        esac

        if (( $#cmd )); then
            curcontext="${curcontext%:*:*}:systemctl-${cmd}:"

            local update_policy
            zstyle -s ":completion:${curcontext}:" cache-policy update_policy
            if [[ -z "$update_policy" ]]; then
                zstyle ":completion:${curcontext}:" cache-policy _systemctl_caching_policy
            fi

            _call_function ret _systemctl_$cmd || _message 'no more arguments'
        else
            _message "unknown systemctl command: $words[1]"
        fi
        return ret
    fi
}

# @todo _systemd-run has a helper with the same name, so we must redefine
__systemctl()
{
    command systemctl $_sys_service_mgr --full --legend=no --no-pager --plain "$@" 2>/dev/null
}


# Fills the unit list
(( $+functions[_systemctl_all_units] )) ||
    _systemctl_all_units()
{
    if _cache_invalid SYS_ALL_UNITS$_sys_service_mgr || ! _retrieve_cache SYS_ALL_UNITS$_sys_service_mgr;
    then
        _sys_all_units=( ${${(f)"$(__systemctl list-units --all)"}%% *} )
        _store_cache SYS_ALL_UNITS$_sys_service_mgr _sys_all_units
    fi
}

# Fills the unit list including all file units
(( $+functions[_systemctl_really_all_units] )) ||
    _systemctl_really_all_units()
{
    local -a all_unit_files;
    local -a really_all_units;
    if _cache_invalid SYS_REALLY_ALL_UNITS$_sys_service_mgr || ! _retrieve_cache SYS_REALLY_ALL_UNITS$_sys_service_mgr;
    then
        all_unit_files=( ${${(f)"$(__systemctl list-unit-files)"}%% *} )
        _systemctl_all_units
        really_all_units=($_sys_all_units $all_unit_files)
        _sys_really_all_units=(${(u)really_all_units})
        _store_cache SYS_REALLY_ALL_UNITS$_sys_service_mgr _sys_really_all_units
    fi
}

(( $+functions[_filter_units_by_property] )) ||
    _filter_units_by_property() {
        local property=$1 value=$2; shift 2
        local -a units; units=("${(q-)@}")
        local -A props
        props=(${(f)"$(_call_program units "$service $_sys_service_mgr show --no-pager --property=\"Id,$property\" -- ${units} 2>/dev/null")"})
        echo -E - "${(@)${(k@)props[(Re)$property=$value]}#Id=}"
    }

(( $+functions[_systemctl_get_non_template_names] )) ||
    _systemctl_get_non_template_names() {
        _systemctl_really_all_units
        print -r - ${_sys_really_all_units:#*@.*}
    }

(( $+functions[_systemctl_get_template_names] )) ||
    _systemctl_get_template_names() {
        local pathkind=systemd-search-${_sys_service_mgr##*--}-unit
        print -r - ${(s-:-)^$(_call_program $pathkind systemd-path $pathkind)}/*@.(${(~j.|.)$(__systemctl --type=help)})(N:t:r)
    }

(( $+functions[_systemctl_active_units] )) ||
    _systemctl_active_units()  {
        local pattern
        if zstyle -T ":completion:$curcontext" use-pattern; then
            pattern="$PREFIX*$SUFFIX"
        fi
        _sys_active_units=(  ${${(f)"$(__systemctl list-units $pattern)"}%% *} )
    }

(( $+functions[_systemctl_startable_units] )) ||
    _systemctl_startable_units(){
        local pattern
        if zstyle -T ":completion:$curcontext" use-pattern; then
            pattern="$PREFIX*$SUFFIX"
        fi
        _sys_startable_units=( $( _filter_units_by_property ActiveState inactive $(
                                      _filter_units_by_property CanStart yes ${${${(f)"$(
      __systemctl list-unit-files --state enabled,enabled-runtime,linked,linked-runtime,static,indirect,disabled,generated,transient $pattern
      __systemctl list-units --state inactive,failed $pattern
    )"}:#*@.*}%%[[:space:]]*}
                                                            )) )
    }

(( $+functions[_systemctl_restartable_units] )) ||
    _systemctl_restartable_units(){
        local pattern
        if zstyle -T ":completion:$curcontext" use-pattern; then
            pattern="$PREFIX*$SUFFIX"
        fi
        _sys_restartable_units=( $( _filter_units_by_property CanStart yes ${${${(f)"$(
    __systemctl list-unit-files --state enabled,disabled,static $pattern
    __systemctl list-units $pattern
  )"}:#*@.*}%%[[:space:]]*} ) )
    }

(( $+functions[_systemctl_failed_units] )) ||
    _systemctl_failed_units()  {_sys_failed_units=( ${${(f)"$(__systemctl list-units --state=failed)"}%% *} ) }

(( $+functions[_systemctl_unit_state] )) ||
    _systemctl_unit_state() {
        setopt localoptions extendedglob
        local pattern
        if zstyle -T ":completion:$curcontext" use-pattern; then
            pattern="$PREFIX*$SUFFIX"
        fi
        typeset -gA _sys_unit_state
        _sys_unit_state=( ${=${${(f)"$(__systemctl list-unit-files $pattern)"}%%[[:space:]]#}% *} )
    }

local fun
# Completion functions for ALL_UNITS
for fun in cat mask ; do
    (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
    {
        _systemctl_really_all_units
        _wanted systemd-units expl unit \
                compadd "$@" -a - _sys_really_all_units
    }
done

# Completion functions for NONTEMPLATE_UNITS
for fun in is-active is-failed is-enabled status show preset help list-dependencies edit revert add-wants add-requires set-property; do
    (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
    {
        _wanted systemd-units expl unit \
                compadd "$@" - $(_systemctl_get_non_template_names)
    }
done

# Completion functions for ENABLED_UNITS
(( $+functions[_systemctl_disable] )) || _systemctl_disable()
{
    local _sys_unit_state; _systemctl_unit_state
    _wanted systemd-units expl 'enabled unit' \
            compadd "$@" - ${(k)_sys_unit_state[(R)enabled]}
}

(( $+functions[_systemctl_reenable] )) || _systemctl_reenable()
{
    local _sys_unit_state; _systemctl_unit_state
    _wanted systemd-units expl 'enabled/disabled unit' \
            compadd "$@" - ${(k)_sys_unit_state[(R)(enabled|disabled)]} $(_systemctl_get_template_names)
}

# Completion functions for DISABLED_UNITS
(( $+functions[_systemctl_enable] )) || _systemctl_enable()
{
    local _sys_unit_state; _systemctl_unit_state
    _wanted systemd-units expl 'disabled unit' \
            compadd "$@" - ${(k)_sys_unit_state[(R)disabled]} $(_systemctl_get_template_names)
}

# Completion functions for FAILED_UNITS
(( $+functions[_systemctl_reset-failed] )) || _systemctl_reset-failed()
{
    local _sys_failed_units; _systemctl_failed_units
    _wanted systemd-units expl 'failed unit' \
            compadd "$@" -a - _sys_failed_units || _message "no failed unit found"
}

# Completion functions for STARTABLE_UNITS
(( $+functions[_systemctl_start] )) || _systemctl_start()
{
    local _sys_startable_units; _systemctl_startable_units
    _wanted systemd-units expl 'startable unit' \
            compadd "$@" - ${_sys_startable_units[*]}
}

# Completion functions for STOPPABLE_UNITS
for fun in stop kill try-restart condrestart ; do
    (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
    {
        local _sys_active_units; _systemctl_active_units
        _wanted systemd-units expl 'stoppable unit' \
                compadd "$@" - $( _filter_units_by_property CanStop yes \
                                                            ${_sys_active_units[*]} )
    }
done

(( $+functions[_systemctl_service-log-level] )) ||
    _systemctl_service-log-level() {
        local -a log_levels=( emerg alert crit err warning notice info debug )
        local _sys_active_units; _systemctl_active_units
        if (( CURRENT == 2 )); then
            _wanted systemd-units expl 'active unit' \
                compadd "$@" -a - _sys_active_units || _message "no units found"
        else
            compadd "$@" -a - log_levels
        fi
}

(( $+functions[_systemctl_service-log-target] )) ||
    _systemctl_service-log-target() {
        local -a log_targets=( console kmsg journal syslog null auto )
        local _sys_active_units; _systemctl_active_units
        if (( CURRENT == 2 )); then
            _wanted systemd-units expl 'active unit' \
                compadd "$@" -a - _sys_active_units || _message "no units found"
        else
            compadd "$@" -a - log_targets
        fi
}

# Completion functions for ISOLATABLE_UNITS
(( $+functions[_systemctl_isolate] )) || _systemctl_isolate()
{
    _systemctl_all_units
    _wanted systemd-units expl 'isolatable unit' \
            compadd "$@" - $( _filter_units_by_property AllowIsolate yes \
                                                        ${_sys_all_units[*]} )
}

# Completion functions for RELOADABLE_UNITS
for fun in reload try-reload-or-restart force-reload ; do
    (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
    {
        local _sys_active_units; _systemctl_active_units
        _wanted systemd-units expl 'reloadable unit' \
                compadd "$@" - $( _filter_units_by_property CanReload yes \
                                                            ${_sys_active_units[*]} )
    }
done

# Completion functions for RESTARTABLE_UNITS
for fun in restart reload-or-restart ; do
    (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
    {
        local _sys_restartable_units; _systemctl_restartable_units
        _wanted systemd-units expl 'restartable unit' \
                compadd "$@" - ${_sys_restartable_units[*]}
    }
done

# Completion functions for MASKED_UNITS
(( $+functions[_systemctl_unmask] )) || _systemctl_unmask()
{
    local _sys_unit_state; _systemctl_unit_state
    _wanted systemd-units expl 'masked unit' \
            compadd "$@" - ${(k)_sys_unit_state[(R)masked]} || _message "no masked units found"
}

# Completion functions for JOBS
(( $+functions[_systemctl_cancel] )) || _systemctl_cancel()
{
    _wanted systemd-jobs expl job \
            compadd "$@" - ${${(f)"$(__systemctl list-jobs)"}%% *} ||
        _message "no jobs found"
}

# Completion functions for TARGETS
(( $+functions[_systemctl_set-default] )) || _systemctl_set-default()
{
    _wanted systemd-targets expl target \
            compadd "$@" - ${${(f)"$(__systemctl list-unit-files --type target --all)"}%% *} ||
        _message "no targets found"
}

# Completion functions for ENVS
for fun in set-environment unset-environment ; do
    (( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
    {
        local fun=$0 ; fun=${fun##_systemctl_}
        local suf
        if [[ "${fun}" = "set-environment" ]]; then
            suf='-S='
        fi
        _wanted systemd-environment expl 'environment variable' \
                compadd "$@" ${suf} - ${${(f)"$(systemctl show-environment)"}%%=*}
    }
done

(( $+functions[_systemctl_import-environment] )) || _systemctl_import-environment()
{
    _parameters
}

(( $+functions[_systemctl_link] )) || _systemctl_link() {
        _sd_unit_files
    }

(( $+functions[_systemctl_switch-root] )) || _systemctl_switch-root() {
        _files
    }

(( $+functions[_systemctl_bind] )) || _systemctl_bind() {
        _files
    }

(( $+functions[_systemctl_mount-image] )) || _systemctl_mount-image() {
        _files
    }

# no systemctl completion for:
#    [STANDALONE]='daemon-reexec daemon-reload default
#                  emergency exit halt kexec list-jobs list-units
#                  list-unit-files poweroff reboot rescue show-environment'

(( $+functions[_systemctl_caching_policy] )) ||
    _systemctl_caching_policy()
{
    # rebuild if cache is more than a day old
    [[ -n $1(#qNmd+1) ]] && return 0

    local pathkind=systemd-search-${1##*--}-unit
    for dir in ${(s-:-)^$(_call_program $pathkind systemd-path $pathkind)}; do
        [[ $dir -nt $1 ]] && return 0
    done

    return 1
}

(( $+functions[_systemctl_unit_states] )) ||
    _systemctl_unit_states() {
        local -a _states
        _states=("${(fo)$(__systemctl --state=help)}")
        _values -s , "${_states[@]}"
    }

(( $+functions[_systemctl_unit_types] )) ||
    _systemctl_unit_types() {
        local -a _types
        _types=("${(fo)$(__systemctl -t help)}")
        _values -s , "${_types[@]}"
    }

(( $+functions[_systemctl_unit_properties] )) ||
    _systemctl_unit_properties() {
		local -a _sys_all_properties=( ${(f)"$({{LIBEXECDIR}}/systemd --no-pager --dump-bus-properties 2>/dev/null)"} )
        _wanted systemd-unit-properties expl 'unit property' \
			_values -s , "${_sys_all_properties[@]}"
    }

(( $+functions[_systemctl_job_modes] )) ||
    _systemctl_job_modes() {
        local -a _modes
        _modes=(fail replace replace-irreversibly isolate ignore-dependencies ignore-requirements flush)
        _values -s , "${_modes[@]}"
    }

(( $+functions[_systemctl_timestamp] )) ||
    _systemctl_timestamp() {
        local -a _styles
        _styles=(help pretty us µs utc us+utc µs+utc)
        _values -s , "${_styles[@]}"
    }

(( $+functions[_systemctl_check_inhibitors] )) ||
    _systemctl_check_inhibitors() {
        local -a _modes
        _modes=(auto yes no)
        _values -s , "${_modes[@]}"
    }

# Build arguments for "systemctl" to be used in completion.
# Use the last mode, or --system (they are exclusive and the last one is used).
local _sys_service_mgr=${words[(R)(--user|--system)]:---system}
_arguments -s \
    '(- *)'{-h,--help}'[Show help]' \
    '(- *)--version[Show package version]' \
    '(-t --type)'{-t+,--type=}'[List only units of a particular type]:unit type:_systemctl_unit_types' \
    '--state=[Display units in the specified state]:unit state:_systemctl_unit_states' \
    '--job-mode=[Specify how to deal with other jobs]:mode:_systemctl_job_modes' \
    '(-p --property)'{-p+,--property=}'[Show only properties by specific name]:unit property:_systemctl_unit_properties' \
    '(-a --all)'{-a,--all}'[Show all units/properties, including dead/empty ones]' \
    '--reverse[Show reverse dependencies]' \
    '--after[Show units ordered after]' \
    '--before[Show units ordered before]' \
    '(-l --full)'{-l,--full}"[Don't ellipsize unit names on output]" \
    '--show-types[When showing sockets, show socket type]' \
    '--check-inhibitors[Specify if inhibitors should be checked]:mode:_systemctl_check_inhibitors' \
    '(-q --quiet)'{-q,--quiet}'[Suppress output]' \
    '--no-warn[Suppress several warnings shown by default]' \
    '--no-block[Do not wait until operation finished]' \
    '--legend=no[Do not print a legend, i.e. the column headers and the footer with hints]' \
    '--no-pager[Do not pipe output into a pager]' \
    '--system[Connect to system manager]' \
    '--user[Connect to user service manager]' \
    "--no-wall[Don't send wall message before halt/power-off/reboot]" \
    '--global[Enable/disable/mask default user unit files globally]' \
    "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \
    '--no-ask-password[Do not ask for system passwords]' \
    '--kill-whom=[Whom to send signal to]:killwhom:(main control all)' \
    '(-s --signal)'{-s+,--signal=}'[Which signal to send]:signal:_signals' \
    '(-f --force)'{-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \
    '--root=[Enable/disable/mask unit files in the specified root directory]:directory:_directories' \
    '--runtime[Enable/disable/mask unit files only temporarily until next reboot]' \
    '(-H --host)'{-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \
    '(-P --privileged)'{-P,--privileged}'[Acquire privileges before execution]' \
    '(-n --lines)'{-n+,--lines=}'[Journal entries to show]:number of entries' \
    '(-o --output)'{-o+,--output=}'[Change journal output mode]:modes:_sd_outputmodes' \
    '--firmware-setup[Tell the firmware to show the setup menu on next boot]' \
    '--plain[When used with list-dependencies, print output as a list]' \
    '--failed[Show failed units]' \
    '--timestamp=[Change format of printed timestamps]:style:_systemctl_timestamp' \
    '*::systemctl command:_systemctl_commands'