1# hostctl(1) completion                               -*- shell-script -*-
2# SPDX-License-Identifier: LGPL-2.1-or-later
3#
4# This file is part of systemd.
5#
6# systemd is free software; you can redistribute it and/or modify it
7# under the terms of the GNU Lesser General Public License as published by
8# the Free Software Foundation; either version 2.1 of the License, or
9# (at your option) any later version.
10#
11# systemd is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14# General Public License for more details.
15#
16# You should have received a copy of the GNU Lesser General Public License
17# along with systemd; If not, see <http://www.gnu.org/licenses/>.
18
19__contains_word () {
20    local w word=$1; shift
21    for w in "$@"; do
22        [[ $w = "$word" ]] && return
23    done
24}
25
26__get_machines() {
27    local a b
28    machinectl list --full --no-legend --no-pager 2>/dev/null |
29        { while read a b; do echo " $a"; done; };
30}
31
32__get_homes() {
33    homectl --no-pager --no-legend list 2>/dev/null
34}
35
36_homectl() {
37    local i verb comps
38    local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
39
40    local -A OPTS=(
41        [STANDALONE]='-h --help --version
42                     --no-pager --no-legend --no-ask-password
43                     -j -E -P'
44        [ARG]='      -H --host
45                     -M --machine
46                        --identity
47                        --json
48                        --export-format
49                     -c --real-name
50                        --realm
51                        --email-address
52                        --location
53                        --icon-name
54                     -d --home-dir
55                        --uid
56                     -G --member-of
57                        --skel
58                        --shell
59                        --setenv
60                        --timezone
61                        --language
62                        --ssh-authorized-keys
63                        --pkcs11-token-uri
64                        --locked
65                        --not-before
66                        --not-after
67                        --rate-limit-interval
68                        --rate-limit-burst
69                        --password-hint
70                        --enforce-password-policy
71                        --password-change-now
72                        --password-change-min
73                        --password-change-max
74                        --password-change-warn
75                        --password-change-inactive
76                        --disk-size
77                        --access-mode
78                        --umask
79                        --nice
80                        --rlimit
81                        --tasks-max
82                        --memory-high
83                        --memory-max
84                        --cpu-weight
85                        --io-weight
86                        --storage
87                        --image-path
88                        --fs-type
89                        --luks-discard
90                        --luks-offline-discard
91                        --luks-cipher
92                        --luks-cipher-mode
93                        --luks-volume-key-size
94                        --luks-pbkdf-type
95                        --luks-pbkdf-hash-algorithm
96                        --luks-pbkdf-time-cost
97                        --luks-pbkdf-memory-cost
98                        --luks-pbkdf-parallel-threads
99                        --nosuid
100                        --nodev
101                        --noexec
102                        --cifs-domain
103                        --cifs-user-name
104                        --cifs-service
105                        --stop-delay
106                        --kill-processes
107                        --auto-login'
108    )
109
110    if __contains_word "$prev" ${OPTS[ARG]}; then
111        case $prev in
112            --host|-H)
113                comps=$(compgen -A hostname)
114                ;;
115            --machine|-M)
116                comps=$( __get_machines )
117                ;;
118            --identity|--image-path)
119                comps=$(compgen -A file -- "$cur" )
120                compopt -o filenames
121                ;;
122            --json)
123                comps='pretty short off'
124                ;;
125            --export-format)
126                comps='full stripped minimal'
127                ;;
128            --locked|--enforce-password-policy|--password-change-now|--luks-discard|--luks-offline-discard|--nosuid|--nodev|--noexec|--kill-processes|--auto-login)
129                comps='yes no'
130                ;;
131            -d|--home-dir|--skel)
132                comps=$(compgen -A directory -- "$cur" )
133                compopt -o dirnames
134                ;;
135            -G|--member-of)
136                comps=$(compgen -A group -- "$cur" )
137                ;;
138            --shell)
139                comps=$(cat /etc/shells)
140                ;;
141            --fs-type)
142                comps='btrfs ext4 xfs'
143                ;;
144            --cifs-user-name)
145                comps=$(compgen -A user -- "$cur" )
146                ;;
147        esac
148        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
149        return 0
150    fi
151
152    if [[ "$cur" = -* ]]; then
153        COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
154        return 0
155    fi
156
157    local -A VERBS=(
158        [STANDALONE]='list lock-all'
159        [CREATE]='create'
160        [NAMES]='activate deactivate inspect authenticate remove lock unlock'
161        [NAME]='update passwd'
162        [RESIZE]='resize'
163        [WITH]='with'
164    )
165
166    for ((i=0; i < COMP_CWORD; i++)); do
167        if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]}; then
168            verb=${COMP_WORDS[i]}
169            break
170        fi
171    done
172
173    if [[ -z ${verb-} ]]; then
174        comps=${VERBS[*]}
175    elif __contains_word "$verb" ${VERBS[NAME]}; then
176        comps=$(__get_homes)
177    elif __contains_word "$verb" ${VERBS[NAMES]}; then
178        comps=$(__get_homes)
179    elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[CREATE]} ${VERBS[RESIZE]}; then
180        comps=$(__get_homes)
181    elif __contains_word "$verb" ${VERBS[WITH]}; then
182        comps=$(__get_homes)
183    fi
184
185    COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
186    return 0
187}
188
189complete -F _homectl homectl
190