[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