[Howto] Using D-BUS to query status information from NetworkManager (or others)

920839987_135ba34fffMost of the current Linux installations rely on the inter process communication framework D-Bus. D-Bbus can be used to gather quite some information about the system – however the usage can be a bit troublesome. This howto sheds some light on the usage of D-Bus by the example of querying the NetworkManagaer interface.

Background

D-BUS enables tools and programs to talk to each other. For example tools like NetworkManager, systemd or firewalld all provide methods and information via D-Bus to query their information and change their configuration or trigger some specific behavior. And of course all these operations can also be performed on the command line. This can be handy in case you want to include it in some bash scripts or for example in your monitoring setup. It also helps understanding the basic principles behind D-Bus in case you want to use it in more complex scripts and programs.

First steps: qdbus

For this example I use qdbus which is shipped with Qt. There are corresponding tools like gdbus and others available in case you don’t want to install qt on your machine for whatever reason.

When you first launch qdbus it shows you a list of strange names which roughly remind you of the apps currently running on your desktop/user session. The point is that you are asking your own user environment – but in case of NetworkManager or other system tools you need to query the system D-Bus:

$ qdbus --system
...
 org.freedesktop.NetworkManager
...

This outputs show a list of all available services, or better said, interfaces. You can connect to these and can get a list of the objects the have:

$ qdbus --system org.freedesktop.NetworkManager
...
/org
/org/freedesktop
/org/freedesktop/NetworkManager
/org/freedesktop/NetworkManager/AccessPoint
/org/freedesktop/NetworkManager/AccessPoint/0
...

Each object has a path which identifies, well, the path to the object. That’s how you call it and everything which is connected to it.

Querying objects

Now that we have a list of objects, we can check which members belong to an object. Members can be actions which can be triggered, or information about a current state, signals, etc. – when we have access to the members things get interesting. In this case we query the object NetworkManager itself, not one of its sub-objects:

$ qdbus --system org.freedesktop.NetworkManager /org/freedesktop/NetworkManager
...
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface, QString propname)
method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface)
...
property read QList<QDBusObjectPath> org.freedesktop.NetworkManager.ActiveConnections
...

The output shows a list of various members. In the above given code snippet I highlighted the methods to get information – and a property which is called org.freedesktop.NetworkManager.ActiveConnections. Guess what, that property holds the information of the current active connections (there can be more than one!) of the NetworkManager. And we can ask this information (using the --literal because otherwise the output is not possible):

$ qdbus --system --literal org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.DBus.Properties.Get org.freedesktop.NetworkManager ActiveConnections
[Variant: [Argument: ao {[ObjectPath: /org/freedesktop/NetworkManager/ActiveConnection/0]}]]

Please note that as arguments we gave not the entire property as a whole, but we separated at the last dot. Formally we asked for the content of the property ActiveConnections at the interface org.freedesktop.NetworkManager. The interface and the property are merged in the output, but the query always needs to have them separated by a space. I’m not sure why…
But well, now we know that our active connection is actually a NetworkManager object with the path given above. We can again query that object to get a list of all members:

$ qdbus --system --literal org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/ActiveConnection/0
...
method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface, QString propname)
...
property read QDBusObjectPath org.freedesktop.NetworkManager.Connection.Active.Ip4Config
...

There is again a member to get properties – and the interesting property again is an object path:

$ qdbus --system --literal org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/ActiveConnection/0 org.freedesktop.DBus.Properties.Get org.freedesktop.NetworkManager.Connection.Active Ip4Config
[Variant: [ObjectPath: /org/freedesktop/NetworkManager/IP4Config/1]]

We query again that given object path and see rather promising members:

$ qdbus --system --literal org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/IP4Config/1
property read QDBusRawType::aau org.freedesktop.NetworkManager.IP4Config.Addresses
property read QStringList org.freedesktop.NetworkManager.IP4Config.Domains
property read QString org.freedesktop.NetworkManager.IP4Config.Gateway
...

And indeed: if we now query these members, we get for example the current Gateway:

$ qdbus --system --literal org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/IP4Config/1 org.freedesktop.DBus.Properties.Get org.freedesktop.NetworkManager.IP4Config Gateway
[Variant(QString): "192.168.178.1"]

That’s it. Now you know the gateway I have configured right now. If you do not want to query each member individually, you can simply call all given members of an interface:

$ qdbus --system --literal org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/IP4Config/1 org.freedesktop.DBus.Properties.GetAll org.freedesktop.NetworkManager.IP4Config|sed 's/, /\n/g'
[Argument: a{sv} {"Gateway" = [Variant(QString): "192.168.178.1"]
"Addresses" = [Variant: [Argument: aau {[Argument: au {565356736
24
28485824}]}]]
"Routes" = [Variant: [Argument: aau {}]]
"Nameservers" = [Variant: [Argument: au {28485824}]]
"Domains" = [Variant(QStringList): {"example.com"}]
"Searches" = [Variant(QStringList): {}]
"WinsServers" = [Variant: [Argument: au {}]]}]

As you see the ipv4 addresses are encoded in reverse decimal notation. I am sure there is reason for that. A good one. Surely. But well, that’s just a stupid encoding problem, nothing else. In the end, the queries worked: the current gateway was successfully identified via D-Bus.

Methods: calling panic mode in firewalld

As mentioned above there are also methods which influence the behavior of an application. One simple example I came across is to kill all networking by calling the firewalld panic mode. For that you need the interface org.fedoraproject.FirewallD1, the object /org/fedoraproject/FirewallD1 and the method org.fedoraproject.FirewallD1.enablePanicMode:

$ qdbus --system --literal org.fedoraproject.FirewallD1 /org/fedoraproject/FirewallD1 org.fedoraproject.FirewallD1.enablePanicMode
[]

And your internet connection is gone. It comes back by disabling the panic mode again:

$ qdbus --system --literal org.fedoraproject.FirewallD1 /org/fedoraproject/FirewallD1 org.fedoraproject.FirewallD1.disablePanicMode
[]

Rights

You should also be aware that there is a rights management embedded in D-Bus – not every user is allowed to do anything. For example, as a normal user you cannot simply query all configured chains. If you call the following method:

$ qdbus --system --literal org.fedoraproject.FirewallD1 /org/fedoraproject/FirewallD1 org.fedoraproject.FirewallD1.direct.getAllChains
[Argument: a(sss) {}]

you are greeted with a password dialog before the command is executed.

Summary

D-Bus is used for inter process communication and thus can help when various programs are supposed to work together. It can also used on the shell to query information or to call specific methods as long as they are provided via the D-Bus interface. That might come in handy – some applications have rather strange ways to provide data or procedures via their user interfaces, and D-Bus offers a very generic way to interact without the need to respect any user interfaces.

First look at cockpit, a web based server management interface [Update]

TuxOnly recently the Cockpit project was launched, aiming at providing a web based management interface for various servers. It already leaves an interesting impression for simple management tasks – and the design is actually well done.

I just recently came across the only three month old Cockpit project. The mission statement is clear:

Cockpit is a server manager that makes it easy to administer your GNU/Linux servers via a web browser.

The web page also states three aims: beginners friendly interface, multi server management – and that there should be no interference in mixed usage of web interface and shell. Especially the last point caught my attention: many other web based solutions introduce their own magic, thus making it sometimes tricky to co-administrate the system manually via the shell. The listed objectives also make clear that cockpit does not try to replace tools that go much deeper into the configuration of servers, like Webmin, which for example offers modules to configure Apache servers in a quite detailed manner. Cockpit tries to simply administrate the server, not the applications. I must admit that I would always do such a application configuration manually anyway…

The installation of Cockpit is a bit bumpy: besides the requirement of tools like systemd which limits the usage to only very recent distributions (excluding Ubuntu, I guess) there are no packages yet, some manual steps are required. A post at unshut.me highlights the necessary steps for Fedora which I followed: in includes installing dependencies, setting firewall rules, etc. – and in the end it just works. But please note, in case you wanna give it a try: it is not ready for production. Not at all. Use virtual machines!

What I did see after the installation was actually rather appealing: a clean, yet modern web interface offering the most important and simple tasks a sysadmin might need in a daily routine: quickly showing the current health state, providing logs, starting and stopping services, creating new users, switching between servers, etc. And: there is even a working rescue console!

And where ever you click you see quickly what the foundation for Cockpit is: systemd. The logviewer shows systemd journal logs, services are displayed as seen and managed by systemd, and so on. That is the reason why one goal – no interference between shell and web interface – can be rather easily reached: the web interface communicates with systemd, just like a administrator on such a machine would do.  <Update> Speaking about: if you want to get an idea of *how* Cockpit communicates with its components, have a look at their transport graphic. </Update> Systemd by the way also explains why Cockpit currently is developed on Fedora: it ships with fully activated systemd.

But back to Cockpit itself: Some people might note that running a web server on a machine which is not meant to provide web pages is a security issue. And they are right. Each additional service on a server is a potential threat. But also keep in mind that many simple server installations already have an additional web server for example to show Munin statistics. So as always you have to carefully balance the pros of usable system management with the cons of an additional service and a web reachable system console…

To summarize: The interface is slick and easy to use, for simple server setups it could come in handy as a server management tool for example for beginners and accessible from the internal network only. A downside currently is the already mentioned limit to the distributions: as far as I got it, only Fedora 18 and 20 are supported yet. But the project has just begun, and will most certainly pick up more support in the near future, as long as the foundations (systemd) are properly supported in the distribution of your choice. And in the meantime Cockpit might be an extra bonus for people testing the coming Fedora Server. 😉

Last but not least, in case you wonder how server management looks like with systemd, Cockpit can give you a first impression: it uses systemd and almost nothing else for exactly that.

Wall-Skills.com Advent calender launched – one 1-pager each day

Simple Workflow diagramIt happened: we launched the wall-skills.com Advent calendar, featuring one 1-pager every day to hang up on your office walls. Daily learning and improving your skills just got easier.

As announced a couple of weeks ago Wall-Skills.com launched its Advent calendar today. For the ext 24 days we will release one new 1-pager each day featuring information worth reading and learning about agile software development, IT project management and sometimes even self improvement tips for office workers.

Get the 1-pagers, hang them upon your office and toilet walls, and share knowledge which you think should be shared among your colleagues and team members. Subscribe to the RSS feed and make sure you don’t miss any Advent calendar post.

Today’s feature is about the Agile principles:
Agile-Principles_Wall-Skills

I’d like to thanks to Corinna from finding-marbles.com for her awesome dedication to the project, her design and work – and also for coming up with the idea to transform my 1-pagers into an actual project.

If you have interesting Ideas you’d like to share with the Wall-Skills community, let us know. The Advent calendar is almost filled by now, but there we plan to release more 1-pagers in the weeks after.

Wall-Skills – learning with 1-pagers, and an Advent Calender

Simple Workflow diagramA couple of weeks ago I introduced Learning on the Toilet here at this blog as well as at my regular Agile Meetup. It was well received, and fellow agile developer Corinna convinced me to team up and launch a dedicated project, which we called: wall-skills.com!

The idea for wall-skills.com is based upon Learning on the toilet (#LotT), which is again based upon Google’s Testing on the Toilet: it means hanging up 1-pagers on walls in places like toilets, on refrigerators and so on for people to read during their “leisure” time. The idea is to bring up information worth reading which can be summarized on one single page to improve the skills of the members of your company. Even if you read all the books about one topic, sometimes an additional tip or some prodding is just what you need. And if it’s hanging on a wall in a place where when you see it, you can’t ignore it.

The idea of Learning on the Toilet was well received when I presented the idea at my regulars Agile Meetup, I got a lot of constructive feedback. And Corinna (finding-marbles.com) brought up the idea to team up and create a project page dedicated to collect and spread such 1-pagers. Thus we met, found a name – hanging 1-pagers on “walls” to improve “skills”, aren’t we brilliant 😉 – and launched a project page: wall-skills.com was born!

wall-skills_screenshot
So in the future we will collect 1-page PDFs or images on Agile, Lean, development, devOps, system administration, Scrum and Kanban at wall-skills.com – ready for you to print out.

Right now we have published two sample posts to give you an idea what to expect. To kick off the project page and the entire collection we will present more 1-pagers in form of an Advent Calendar, publishing a new 1-pager each day of December until the 24th. So stay tuned – and subscribe to our RSS feed =)

Currently we’ve got ideas for most of the 24 slots, but some slots are still open and a greater diversity is always more interesting. Also, we will need more information for the future. If you got great, suitable content in your blog, tell us! Contact us on Twitter, via email, via this blog, whatever. If you are quick (that means 25th of November) your content might be included with the Advent Calendar, including a short paragraph about you and your blog.

And of course, please feel free to tell us what you think of the project, of the 1-pagers, and so on.