From a3772fb0d46a99641b0713e669fcb47c364f20bd Mon Sep 17 00:00:00 2001 From: Thomas Hindoe Paaboel Andersen Date: Tue, 18 Feb 2014 21:09:05 +0100 Subject: [PATCH] machinectl: add bash completion (cherry picked from commit e56056e93d33619a3acf13e483900b4f8938228f) Default to --no-legend if !on_tty(). Conflicts: man/machinectl.xml src/machine/machinectl.c --- Makefile.am | 3 ++ man/machinectl.xml | 8 ++++ shell-completion/bash/machinectl | 97 ++++++++++++++++++++++++++++++++++++++++ src/machine/machinectl.c | 24 +++++++--- 4 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 shell-completion/bash/machinectl diff --git a/Makefile.am b/Makefile.am index 6233a7f..033bbfa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3726,6 +3726,9 @@ machinectl_LDADD = \ rootbin_PROGRAMS += \ machinectl +dist_bashcompletion_DATA += \ + shell-completion/bash/machinectl + test_machine_tables_SOURCES = \ src/machine/test-machine-tables.c diff --git a/man/machinectl.xml b/man/machinectl.xml index bb88395..f00d212 100644 --- a/man/machinectl.xml +++ b/man/machinectl.xml @@ -130,6 +130,14 @@ + + + Do not print the legend, + i.e. the column headers and the + footer. + + + Do not query the user diff --git a/shell-completion/bash/machinectl b/shell-completion/bash/machinectl new file mode 100644 index 0000000..3789492 --- /dev/null +++ b/shell-completion/bash/machinectl @@ -0,0 +1,97 @@ +# machinectl(1) completion -*- shell-script -*- +# +# This file is part of systemd. +# +# Copyright 2014 Thomas H.P. Andersen +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see . + +__contains_word() { + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done +} + +__get_machines() { + local a b + machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; }; +} + +_machinectl() { + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} + local i verb comps + + local -A OPTS=( + [STANDALONE]='--all -a --full --help -h --no-ask-password --no-legend --no-pager --version' + [ARG]='--host -H --kill-who -M --machine --property -p --signal -s' + ) + + local -A VERBS=( + [STANDALONE]='list' + [MACHINES]='status show terminate kill reboot login' + ) + + _init_completion || return + + for ((i=0; i <= COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && + ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if __contains_word "$prev" ${OPTS[ARG]}; then + case $prev in + --signal|-s) + comps=$(compgen -A signal) + ;; + --kill-who) + comps='all leader' + ;; + --host|-H) + comps=$(compgen -A hostname) + ;; + --machine|-M) + comps=$( __get_machines ) + ;; + --property|-p) + comps='' + ;; + esac + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 + fi + + if [[ "$cur" = -* ]]; then + COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) + return 0 + fi + + if [[ -z $verb ]]; then + comps=${VERBS[*]} + + elif __contains_word "$verb" ${VERBS[STANDALONE]}; then + comps='' + + elif __contains_word "$verb" ${VERBS[MACHINES]}; then + comps=$( __get_machines ) + fi + + COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) + return 0 +} + +complete -F _machinectl machinectl diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 97c2193..88cf8d5 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -43,6 +43,7 @@ static char **arg_property = NULL; static bool arg_all = false; static bool arg_full = false; static bool arg_no_pager = false; +static bool arg_legend = true; static const char *arg_kill_who = NULL; static int arg_signal = SIGTERM; static enum transport { @@ -90,11 +91,11 @@ static int list_machines(DBusConnection *bus, char **args, unsigned n) { return -EIO; } - dbus_message_iter_recurse(&iter, &sub); - - if (on_tty()) + if (arg_legend) printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE"); + dbus_message_iter_recurse(&iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { const char *name, *class, *service, *object; @@ -120,7 +121,7 @@ static int list_machines(DBusConnection *bus, char **args, unsigned n) { dbus_message_iter_next(&sub); } - if (on_tty()) + if (arg_legend) printf("\n%u machines listed.\n", k); return 0; @@ -559,10 +560,12 @@ static int help(void) { " --kill-who=WHO Who to send signal to\n" " -l --full Do not ellipsize output\n" " -s --signal=SIGNAL Which signal to send\n" - " --no-ask-password Don't prompt for password\n" " -H --host=[USER@]HOST Show information for remote host\n" " -P --privileged Acquire privileges before execution\n" - " --no-pager Do not pipe output into a pager\n\n" + " --no-pager Do not pipe output into a pager\n" + " --no-legend Do not show the headers and footers\n" + " --no-ask-password Don't prompt for password\n\n" + "Commands:\n" " list List running VMs and containers\n" " status [NAME...] Show VM/container status\n" @@ -579,6 +582,7 @@ static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_NO_PAGER, + ARG_NO_LEGEND, ARG_KILL_WHO, ARG_NO_ASK_PASSWORD, }; @@ -590,6 +594,7 @@ static int parse_argv(int argc, char *argv[]) { { "all", no_argument, NULL, 'a' }, { "full", no_argument, NULL, 'l' }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, { "kill-who", required_argument, NULL, ARG_KILL_WHO }, { "signal", required_argument, NULL, 's' }, { "host", required_argument, NULL, 'H' }, @@ -645,6 +650,10 @@ static int parse_argv(int argc, char *argv[]) { arg_no_pager = true; break; + case ARG_NO_LEGEND: + arg_legend = false; + break; + case ARG_NO_ASK_PASSWORD: arg_ask_password = false; break; @@ -679,6 +688,9 @@ static int parse_argv(int argc, char *argv[]) { } } + if (!on_tty()) + arg_legend = false; + return 1; }