forked from OpenIndiana/openindiana-completions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsvcadm
210 lines (187 loc) · 7.08 KB
/
svcadm
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
# OpenIndiana svcadm(1M) & svcs(1) completions -*- shell-script -*-
# ------------------------------------------------------------------------------
# Copyright 2006 Yann Rouillard <[email protected]>
# Portions copyright 2013, Nexenta Systems, Inc.
# Copyright (c) 2018, Michal Nowak <[email protected]>
# svcadm accepts any complete FMRI or abbreviated FMRI
# - a complete FMRI is svc:/foo/bar/bar/baz,
# - abbreviated FMRI are foo/bar/bar/baz, bar/bar/baz, bar/baz or baz.
#
# The goal of this function is to propose all alternatives,
# but to not clutter the interface with all completions, we will only
# cut every completion alternative at the next slash.
#
# For exeaple, if the user types <nothing><tab>, for the svc://foo/bar/bar/baz
# we will propose the following completion: foo/, bar/, and baz.
# If the user types <b><tab>, we will propose: bar/ and baz.
# If the user types <bar/><tab>, we will propose: bar/bar/ and bar/baz.
#
# By default, the function proposes only abbreviated completions except
# if the user already types 'svc:'. In that case we will propose only
# the complete FMRI beginning with the pattern.
# Provide running zone names
_gen_zoneadm_list()
{
if [[ ${prev} =~ "-z" ]]; then
local zones="$(zoneadm list -n)"
COMPREPLY=( $(compgen -W "${zones}" -- ${cur}) )
fi
}
_smf_complete_fmri()
{
local cur="$1" prefix="$2"
local cur_prefix fmri fmri_list=""
local exact_mode pattern
if [[ "$cur" == $prefix* ]]; then
[[ "$cur" == $prefix ]] && cur+="/"
pattern="$cur*"
exact_mode=1
else
pattern="$prefix*/$cur*"
fi
cur_prefix="${cur%"${cur##*/}"}"
for fmri in $(svcs -H -o FMRI "$pattern" 2>/dev/null); do
local fmri_part_list fmri_part
if [[ -z "$exact_mode" ]]; then
fmri=${fmri#$prefix/}
# We generate all possibles abbreviations for the FMRI
# no need to have a generic loop as we will have a finite
# number of components.
local OIFS="$IFS"; IFS="/"; set -- $fmri; IFS="$OIFS"
case $# in
1) fmri_part_list=" $1";;
2) fmri_part_list=" $2 $1/$2";;
3) fmri_part_list=" $3 $2/$3 $1/$2/$3";;
4) fmri_part_list=" $4 $3/$4 $2/$3/$4 $1/$2/$3/$4";;
esac
else
fmri_part_list="$fmri"
fi
# Here we make sure the completions begin with the pattern and
# we cut them at the first slash.
for fmri_part in $fmri_part_list; do
[[ "$fmri_part" == $cur* ]] || continue
local first_part=${fmri_part#$cur_prefix}
first_part=$cur_prefix${first_part%%/*}
[[ "$first_part" != "$fmri_part" ]] && first_part+="/"
fmri_list+=" $first_part"
done
done
COMPREPLY=( $fmri_list )
# Here we want to detect if there is only one completion proposed and that
# it ends with a slash. That means the user will still have to complete
# after, so we save him one tab keystroke by immediately proposing the
# next completion alternatives.
local i=${#COMPREPLY[*]}
if [[ $i -gt 0 ]] && [[ "${COMPREPLY[$((--i))]}" == */ ]]; then
# We have to iterate throught the list as we may have duplicates.
while [[ $i -ne 0 ]]; do
[[ "${COMPREPLY[$i]}" != "${COMPREPLY[$((i - 1))]}" ]] && break
((i--))
done
if [[ $i -eq 0 ]]; then
_smf_complete_fmri "${COMPREPLY[0]}" "$prefix"
return
fi
fi
# Work-around bash_completion issue where bash interprets a colon
# as a separator, borrowed from maven completion code which borrowed
# it from darcs completion code :).
local colonprefixes=${cur%"${cur##*:}"}
local i=${#COMPREPLY[*]}
while [ $((--i)) -ge 0 ]; do
COMPREPLY[$i]=${COMPREPLY[$i]#"$colonprefixes"}
done
}
_svcadm()
{
local cur prev words cword line
line="${COMP_LINE}"
_init_completion -n : || return
local states="uninitialized offline online degraded maintenance disabled legacy-run"
local command_list="enable disable restart refresh clear mark milestone"
local command i
for (( i=1; i < $cword; i++ )); do
if [[ ${words[i]} == @(enable|disable|restart|refresh|clear|mark|milestone) ]]; then
command=${words[i]}
fi
done
if [[ -z "$command" ]]; then
# svcadm [-S state]...
if [[ ${prev} == -S ]]; then
COMPREPLY=( $(compgen -W "${states}" -- ${cur}) )
elif [[ ${cur} == -* ]]; then
if [[ "$(zonename)" == "global" ]]; then
zones="-Z -z"
fi
COMPREPLY=( $(compgen -W "-S -v ${zones}" -- ${cur}) )
else
# svcadm [-v] milestone [-d] milestone_FMRI
if [[ ${line} =~ -S ]]; then
command_list="$(echo ${command_list} | sed -e 's/milestone//')"
fi
COMPREPLY=( $(compgen -W "${command_list}" -- ${cur}) )
fi
else
if [[ ${cur} == -* ]]; then
case "$command" in
enable)
# enable [-rst]
COMPREPLY=( $(compgen -W "-r -s -t" -- ${cur}) );;
disable)
# disable [-st]
COMPREPLY=( $(compgen -W "-s -t" -- ${cur}) );;
mark)
# mark [-It]
COMPREPLY=( $(compgen -W "-I -t" -- ${cur}) );;
milestone)
# milestone [-d]
COMPREPLY=( $(compgen -W "-d" -- ${cur}) );;
esac
else
if [[ "$command" == "mark" ]] && [[ "$prev" != @(degraded|maintenance) ]]; then
COMPREPLY=( $(compgen -W "degraded maintenance" -- ${cur}) )
elif [[ "$command" == "milestone" ]]; then
_smf_complete_fmri "${cur}" "svc:/milestone"
else
_smf_complete_fmri "${cur}" "svc:"
fi
fi
fi
_gen_zoneadm_list
}
_svcs()
{
local cur prev
local svcs_cols="ctid desc fmri inst nsta nstate scope svc sta state stime"
cur=${COMP_WORDS[COMP_CWORD]}
prev="${COMP_WORDS[COMP_CWORD-1]}"
case "$prev" in
-o|-s|-S)
# -o col[,col]... -s col -S col
COMPREPLY=($(compgen -W "$svcs_cols" -- "${cur##*,}"))
local existing_opts=$(expr "$cur" : '\(.*,\)')
if [[ -n "$existing_opts" ]]; then
COMPREPLY=( "${COMPREPLY[@]/#/${existing_opts}}" )
fi
if [[ ${prev} == -o ]]; then
compopt -o nospace
fi
return
;;
esac
if [[ $cur == -* ]]; then
# zone options are usable only in global zone
if [[ "$(zonename)" == "global" ]]; then
zones="-Z -z"
fi
COMPREPLY=( $(compgen -W "-? -a -H -p -o -s -S -d -D -R -l -L -v -x $zones" -- "${cur}") )
else
_smf_complete_fmri "${cur}" "svc:"
fi
_gen_zoneadm_list
}
complete -F _svcadm svcadm
complete -F _svcs svcs
# ex: filetype=sh
# vim: tabstop=2 shiftwidth=2 expandtab smartindent