Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [PATCH] _virsh (Was: Re: zsh virsh completion)



On 22 Jul, Daniel Shahaf wrote:
> In principle, I fully agree with you, with two differences:
>
> First, in addition to 'zstyle -t … gain-root' and
> '(( $+funcstack[(r)_sudo] ))' as the conditions for invoking sudo,
> I think a third alternative is to use _call_program and let the user set
> the 'command' style to '-sudo'.

It'd be best to put such logic in _call_program and _sudo so that
it doesn't get duplicated in lots of places.

> Secondly, you don't touch on what we would do when the 'gain-root' style
> is unset.  Given Marko's later email that virt-admin is not usable by
> non-root users, perhaps we should do this:

I'd suggest that it doesn't do anything special. Just run virsh
list. Testing EUID might be correct but you can't actually be sure
it won't work, perhaps due to groups or some RBAC mechanism. If it
doesn't you'd end up with a message like:
  No matches for: `domains'
In some cases, _wanted -x should perhaps be used.

Putting the logic in _call_program also has an impact on this
question because while virt-admin might be unusable to non-root
users, some other commands might be partially usable. sudo may
just allow it to get more matches.

How about something like the following? _sudo sets the _comp_priv_prefix
variable to provide a prefix to match those for the current
command-line. If _call_program is called with -p, it will default
to using this prefix unless overridden, either by a gain-privs style
or the command style with a - prefix.

This doesn't include an (( EUID )) check because it might be applicable
where permissions other than root are gained. It'd perhaps be useful if
the -p option to _call_program also caused it to add something to
$curcontext when looking up the command style but I'm not sure where
that could be done as we already have the tag and argument fields
filled. Any ideas?

Besides -u/--user, are other sudo options needed?

Oliver

diff --git a/Completion/Base/Core/_main_complete b/Completion/Base/Core/_main_complete
index 9c4cfac..c292ce7 100644
--- a/Completion/Base/Core/_main_complete
+++ b/Completion/Base/Core/_main_complete
@@ -38,6 +38,7 @@ local func funcs ret=1 tmp _compskip format nm call match min max i num\
       _saved_colors="$ZLS_COLORS" \
       _saved_colors_set=${+ZLS_COLORS} \
       _ambiguous_color=''
+local -a _comp_priv_prefix
 
 # _precommand sets this to indicate we are following a precommand modifier
 local -a precommands
diff --git a/Completion/Base/Utility/_call_program b/Completion/Base/Utility/_call_program
index 010e094..f61180a 100644
--- a/Completion/Base/Utility/_call_program
+++ b/Completion/Base/Utility/_call_program
@@ -1,6 +1,13 @@
 #autoload +X
 
 local tmp err_fd=-1
+local -a prefix
+
+if [[ "$1" = -p ]]; then
+  shift
+  zstyle -T ":completion:${curcontext}:${1}" gain-privs &&
+      prefix=( $_comp_priv_prefix )
+fi
 
 if (( ${debug_fd:--1} > 2 )) || [[ ! -t 2 ]]
 then exec {err_fd}>&2	# debug_fd is saved stderr, 2 is trace or redirect
@@ -13,10 +20,10 @@ if zstyle -s ":completion:${curcontext}:${1}" command tmp; then
   if [[ "$tmp" = -* ]]; then
     eval "$tmp[2,-1]" "$argv[2,-1]"
   else
-    eval "$tmp"
+    eval $prefix "$tmp"
   fi
 else
-  eval "$argv[2,-1]"
+  eval $prefix "$argv[2,-1]"
 fi 2>&$err_fd
 
 } always {
diff --git a/Completion/Unix/Command/_libvirt b/Completion/Unix/Command/_libvirt
index c855ac9..98c6a95 100644
--- a/Completion/Unix/Command/_libvirt
+++ b/Completion/Unix/Command/_libvirt
@@ -96,7 +96,7 @@ case $state in
     done
     [[ -z $cmd ]] && return 1
     if [[ -z $_cache_virsh_cmdopts[$cmd] ]]; then
-      _cache_virsh_cmdopts[$cmd]=${(M)${${${${=${(f)"$(_call_program virsh virsh help $cmd 2>&1)"}}/\[}/\]}/\;}:#-[-0-9A-Za-z]*}
+      _cache_virsh_cmdopts[$cmd]=${(M)${${${${=${(f)"$(_call_program options virsh help $cmd 2>&1)"}}/\[}/\]}/\;}:#-[-0-9A-Za-z]*}
     fi
     _values -w options ${=_cache_virsh_cmdopts[$cmd]} && ret=0
   ;;
@@ -110,7 +110,7 @@ case $state in
     done
     [[ -z $cmd ]] && return 1
     if [[ $words[-2] == --server ]]; then
-      _values servers ${=${(S)${${(f)$(sudo virt-admin srv-list)}##*--- }//[0-9]* }} && return 0
+      _values servers ${=${(S)${${(f)$(_call_program -p servers virt-admin srv-list)}##*--- }//[0-9]* }} && return 0
     fi
     if [[ $words[-2] == --client ]]; then
       local srv
@@ -118,10 +118,10 @@ case $state in
         [[ $words[$i] == --server ]] && srv=$words[$i+1] && break
       done
       [[ -z $srv ]] && return 1
-      _values servers ${=${${(f):-"$(sudo virt-admin srv-clients-list --server $srv)"}/ [a-z]*}//[^0-9]} && return 0
+      _values servers ${=${${(f):-"$(_call_program -p servers virt-admin srv-clients-list --server $srv)"}/ [a-z]*}//[^0-9]} && return 0
     fi
     if [[ -z $_cache_virt_admin_cmdopts[$cmd] ]]; then
-      _cache_virt_admin_cmdopts[$cmd]=${(M)${${${${=${(f)"$(_call_program virt-admin virt-admin help $cmd 2>&1)"}}/\[}/\]}/\;}:#-[-0-9A-Za-z]*}
+      _cache_virt_admin_cmdopts[$cmd]=${(M)${${${${=${(f)"$(_call_program options virt-admin help $cmd 2>&1)"}}/\[}/\]}/\;}:#-[-0-9A-Za-z]*}
     fi
     [[ -n $_cache_virt_admin_cmdopts[$cmd] ]] && \
       _values -w options ${=_cache_virt_admin_cmdopts[$cmd]} && ret=0
diff --git a/Completion/Unix/Command/_sudo b/Completion/Unix/Command/_sudo
index 63ac37f..1ceefa2 100644
--- a/Completion/Unix/Command/_sudo
+++ b/Completion/Unix/Command/_sudo
@@ -48,7 +48,7 @@ else
     '(-H --set-home -i --login -s --shell -e --edit)'{-H,--set-home}"[set HOME variable to target user's home dir]" \
     '(-P --preserve-groups -i -login -s --shell -e --edit)'{-P,--preserve-groups}"[preserve group vector instead of setting to target's]" \
     '(-)1:command: _command_names -e'
-    '*::arguments: _normal'
+    '*::arguments:{ _comp_priv_prefix=( $words[1] -n ${(kv)opt_args[(I)(-u|--user)]} ) ; _normal }'
   )
 fi
 



Messages sorted by: Reverse Date, Date, Thread, Author