[systemd-commits] 3 commits - TODO man/busctl.xml shell-completion/bash src/libsystemd

Lennart Poettering lennart at kemper.freedesktop.org
Tue Dec 23 13:44:45 PST 2014


 TODO                           |    4 -
 man/busctl.xml                 |    6 +-
 shell-completion/bash/busctl   |  109 +++++++++++++++++++++++++++++++++++++----
 src/libsystemd/sd-bus/busctl.c |   26 ++++++++-
 4 files changed, 127 insertions(+), 18 deletions(-)

New commits:
commit 243399a68074d7718e4f3c59af913abbf37c718c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Dec 23 21:36:14 2014 +0100

    update TODO

diff --git a/TODO b/TODO
index fdc37b1..af7863c 100644
--- a/TODO
+++ b/TODO
@@ -51,8 +51,6 @@ Features:
 
 * add transparent btrfs pool in a loopback file in /var if btrfs operations (such as systemd-import pull-dkr) are used and /var is not a btrfs file system
 
-* machined: open up certain commands to unprivileged clients via polkit
-
 * hostnamectl: show root image uuid
 
 * sysfs set api in libudev is not const
@@ -62,8 +60,6 @@ Features:
 
 * port libmount hookup to use API's own inotify interface, as soon as that is table in libmount
 
-* bash completion for busctl, to make it truly useful
-
 * journald: broken file systems are real (btrfs), we need to handle
   SIGBUS in some way if we cannot write or read from the disk.
   https://bugzilla.redhat.com/show_bug.cgi?id=1151848

commit e275f5e20457550e8fbed32e4bd5a033b248d69c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Dec 23 22:43:16 2014 +0100

    shell-completion: add full support for completing busctl command lines, with services, objects, interfaces, members, and signatures

diff --git a/shell-completion/bash/busctl b/shell-completion/bash/busctl
index 49520e4..6a770b1 100644
--- a/shell-completion/bash/busctl
+++ b/shell-completion/bash/busctl
@@ -30,25 +30,62 @@ __get_machines() {
         machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
 }
 
-__get_endpoints() {
+__get_busnames() {
         local mode=$1
         local a b
         busctl $mode list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
 }
 
+__get_objects() {
+        local mode=$1
+        local busname=$2
+        local a b
+        busctl $mode tree --list --no-legend --no-pager $busname | { while read a b; do echo " $a"; done; };
+}
+
+__get_interfaces() {
+        local mode=$1
+        local busname=$2
+        local path=$3
+        local a b
+        busctl $mode introspect --list --no-legend --no-pager $busname $path | { while read a b c; do [[ "$b" == "interface" ]] && echo " $a"; done; };
+}
+
+__get_members() {
+        local mode=$1
+        local busname=$2
+        local path=$3
+        local interface=$4
+        local type=$5
+        local a b
+        busctl $mode introspect --list --no-legend --no-pager $busname $path $interface | sed -e 's/^\.//' | { while read a b c; do [[ "$b" == "$type" ]] && echo " $a"; done; };
+}
+
+__get_signature() {
+        local mode=$1
+        local busname=$2
+        local path=$3
+        local interface=$4
+        local member=$5
+        local a b
+        busctl $mode introspect --list --no-legend --no-pager $busname $path $interface | sed -e 's/^\.//' | { while read a b c d; do [[ "$a" == "$member" ]] && echo " \"$c\""; done; };
+}
+
 _busctl() {
         local i verb comps mode
         local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
         local -A OPTS=(
                [STANDALONE]='-h --help --version --no-pager --no-legend --system --user
-                             --show-machine --unique --acquired --activatable'
-                      [ARG]='-H --host -M --machine --address --match'
+                             --show-machine --unique --acquired --activatable --list
+                             --quiet --verbose --expect-reply=no --auto-start=no
+                             --allow-interactive-authorization=yes --augment-creds=no'
+                      [ARG]='-H --host -M --machine --address --match --timeout'
         )
 
         if __contains_word "--user" ${COMP_WORDS[*]}; then
-            mode=--user
+                mode=--user
         else
-            mode=--system
+                mode=--system
         fi
 
         if __contains_word "$prev" ${OPTS[ARG]}; then
@@ -70,7 +107,11 @@ _busctl() {
 
         local -A VERBS=(
                 [STANDALONE]='list help'
-                [ENDPOINT]='monitor status'
+                [BUSNAME]='status monitor capture tree'
+                [OBJECT]='introspect'
+                [METHOD]='call'
+                [PROPERTY_GET]='get-property'
+                [PROPERTY_SET]='set-property'
         )
 
         for ((i=0; i < COMP_CWORD; i++)); do
@@ -81,12 +122,64 @@ _busctl() {
                 fi
         done
 
+        n=$(($COMP_CWORD - $i))
+
         if [[ -z $verb ]]; then
                 comps=${VERBS[*]}
         elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
                 comps=''
-        elif __contains_word "$verb" ${VERBS[ENDPOINT]}; then
-                comps=$( __get_endpoints $mode)
+        elif __contains_word "$verb" ${VERBS[BUSNAME]}; then
+                comps=$( __get_busnames $mode)
+        elif __contains_word "$verb" ${VERBS[OBJECT]}; then
+                if [[ $n -eq 1 ]] ; then
+                        comps=$( __get_busnames $mode)
+                elif [[ $n -eq 2 ]] ; then
+                        comps=$( __get_objects $mode ${COMP_WORDS[COMP_CWORD-1]})
+                elif [[ $n -eq 3 ]] ; then
+                        comps=$( __get_interfaces $mode ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+                else
+                        comps=''
+                fi
+        elif __contains_word "$verb" ${VERBS[METHOD]}; then
+                if [[ $n -eq 1 ]] ; then
+                        comps=$( __get_busnames $mode)
+                elif [[ $n -eq 2 ]] ; then
+                        comps=$( __get_objects $mode ${COMP_WORDS[COMP_CWORD-1]})
+                elif [[ $n -eq 3 ]] ; then
+                        comps=$( __get_interfaces $mode ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+                elif [[ $n -eq 4 ]] ; then
+                        comps=$( __get_members $mode ${COMP_WORDS[COMP_CWORD-3]} ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]} method)
+                elif [[ $n -eq 5 ]] ; then
+                        comps=$( __get_signature $mode ${COMP_WORDS[COMP_CWORD-4]} ${COMP_WORDS[COMP_CWORD-3]} ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+                else
+                        comps=''
+                fi
+        elif __contains_word "$verb" ${VERBS[PROPERTY_GET]}; then
+                if [[ $n -eq 1 ]] ; then
+                        comps=$( __get_busnames $mode)
+                elif [[ $n -eq 2 ]] ; then
+                        comps=$( __get_objects $mode ${COMP_WORDS[COMP_CWORD-1]})
+                elif [[ $n -eq 3 ]] ; then
+                        comps=$( __get_interfaces $mode ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+                elif [[ $n -eq 4 ]] ; then
+                        comps=$( __get_members $mode ${COMP_WORDS[COMP_CWORD-3]} ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]} property)
+                else
+                        comps=''
+                fi
+        elif __contains_word "$verb" ${VERBS[PROPERTY_SET]}; then
+                if [[ $n -eq 1 ]] ; then
+                        comps=$( __get_busnames $mode)
+                elif [[ $n -eq 2 ]] ; then
+                        comps=$( __get_objects $mode ${COMP_WORDS[COMP_CWORD-1]})
+                elif [[ $n -eq 3 ]] ; then
+                        comps=$( __get_interfaces $mode ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+                elif [[ $n -eq 4 ]] ; then
+                        comps=$( __get_members $mode ${COMP_WORDS[COMP_CWORD-3]} ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]} property)
+                elif [[ $n -eq 5 ]] ; then
+                        comps=$( __get_signature $mode ${COMP_WORDS[COMP_CWORD-4]} ${COMP_WORDS[COMP_CWORD-3]} ${COMP_WORDS[COMP_CWORD-2]} ${COMP_WORDS[COMP_CWORD-1]})
+                else
+                        comps=''
+                fi
         fi
 
         COMPREPLY=( $(compgen -W '$comps' -- "$cur") )

commit 4f44c03eaa7bc05240ef619d07766f61eda3d5b7
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Dec 23 22:42:55 2014 +0100

    busctl: when introspecting objects, optionally limit output by interface name

diff --git a/man/busctl.xml b/man/busctl.xml
index 285725e..c8a087c 100644
--- a/man/busctl.xml
+++ b/man/busctl.xml
@@ -313,11 +313,13 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
       </varlistentry>
 
       <varlistentry>
-        <term><command>introspect</command> <arg choice="plain"><replaceable>SERVICE</replaceable></arg> <arg choice="plain"><replaceable>OBJECT</replaceable></arg></term>
+        <term><command>introspect</command> <arg choice="plain"><replaceable>SERVICE</replaceable></arg> <arg choice="plain"><replaceable>OBJECT</replaceable></arg> <arg choice="opt"><replaceable>INTERFACE</replaceable></arg></term>
 
         <listitem><para>Show interfaces, methods, properties and
         signals of the specified object (identified by its path) on
-        the specified service.</para></listitem>
+        the specified service. If the interface argument is passed the
+        output is limited to members of the specified
+        interface.</para></listitem>
       </varlistentry>
 
       <varlistentry>
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index 3233c1b..009739f 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -883,13 +883,19 @@ static int introspect(sd_bus *bus, char **argv) {
         int r;
         unsigned name_width,  type_width, signature_width, result_width;
         Member **sorted = NULL;
-        unsigned k = 0, j;
+        unsigned k = 0, j, n_args;
 
-        if (strv_length(argv) != 3) {
+        n_args = strv_length(argv);
+        if (n_args < 3) {
                 log_error("Requires service and object path argument.");
                 return -EINVAL;
         }
 
+        if (n_args > 4) {
+                log_error("Too many arguments.");
+                return -EINVAL;
+        }
+
         members = set_new(&member_hash_ops);
         if (!members)
                 return log_oom();
@@ -918,6 +924,9 @@ static int introspect(sd_bus *bus, char **argv) {
                 if (m->value)
                         continue;
 
+                if (argv[3] && !streq(argv[3], m->interface))
+                        continue;
+
                 r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", m->interface);
                 if (r < 0) {
                         log_error("%s", bus_error_message(&error, r));
@@ -995,6 +1004,10 @@ static int introspect(sd_bus *bus, char **argv) {
         sorted = newa(Member*, set_size(members));
 
         SET_FOREACH(m, members, i) {
+
+                if (argv[3] && !streq(argv[3], m->interface))
+                        continue;
+
                 if (m->interface)
                         name_width = MAX(name_width, strlen(m->interface));
                 if (m->name)
@@ -1014,7 +1027,6 @@ static int introspect(sd_bus *bus, char **argv) {
         if (result_width > 40)
                 result_width = 40;
 
-        assert(k == set_size(members));
         qsort(sorted, k, sizeof(Member*), member_compare_funcp);
 
         if (arg_legend) {
@@ -1033,8 +1045,14 @@ static int introspect(sd_bus *bus, char **argv) {
 
                 m = sorted[j];
 
+                if (argv[3] && !streq(argv[3], m->interface))
+                        continue;
+
                 is_interface = streq(m->type, "interface");
 
+                if (argv[3] && is_interface)
+                        continue;
+
                 if (m->value) {
                         ellipsized = ellipsize(m->value, result_width, 100);
                         if (!ellipsized)
@@ -1686,7 +1704,7 @@ static int help(void) {
                "  monitor [SERVICE...]    Show bus traffic\n"
                "  capture [SERVICE...]    Capture bus traffic as pcap\n"
                "  tree [SERVICE...]       Show object tree of service\n"
-               "  introspect SERVICE OBJECT\n"
+               "  introspect SERVICE OBJECT [INTERFACE]\n"
                "  call SERVICE OBJECT INTERFACE METHOD [SIGNATURE [ARGUMENT...]]\n"
                "                          Call a method\n"
                "  get-property SERVICE OBJECT INTERFACE PROPERTY...\n"



More information about the systemd-commits mailing list