Accessing libvirt's virtual machines from a script

written on Sat 19 January 2013

Everyone who has ever used the libvirt library probably knows that it's impossible to use it from scripts without previous authorization in the polkit daemon.

This complicates things when the user would like to create a script to control some virtual machines. The script that is probably configured to be invoked periodically is running from the context of normal user. Popping up the polkit messagebox which requires to enter authorization credentials at every execution of this script is probably not what most people would like to have.

screenshot from 'pkexec ls'

This problem can be fixed by creating two polkit rules. There is however some confusion about the format of the files which hold the rules.

Until polkit version 106 it was possible to create the pkla descriptor (polkit local authority file), which was a simple .ini file. It was possible to put the rules in there, by using the simple INI file format. However, since version 106, it's not possible anymore, because this version forces the use of JavaScript language to create new polkit rules. All of your existing rules you have written until now are expired, and need to be rewritten to the new JavaScript syntax.

To allow authorization of the libvirt library in polkit, taking as an example the virt-manager frontend application, you need to find the proper action of libvirt 's polkit rule provider. You can find it by using the pkaction command:

(2:504)$ for i in `pkaction | grep libvirt`; do pkaction --action-id $i --verbose; done
org.libvirt.unix.manage:
  description:       Manage local virtualized systems
  message:           System policy prevents management of local virtualized systems
  vendor:
  vendor_url:
  icon:
  implicit any:      auth_admin_keep
  implicit inactive: auth_admin_keep
  implicit active:   auth_admin_keep

org.libvirt.unix.monitor:
  description:       Monitor local virtualized systems
  message:           System policy prevents monitoring of local virtualized systems
  vendor:
  vendor_url:
  icon:
  implicit any:      yes
  implicit inactive: yes
  implicit active:   yes

It seems that the org.libvirt.unix.manage action is responsible for allowing or declining the access to libvirt. This action needs to be used in the declaration of our directive which defines the authorization permission.

The rules themselves are placed inside the /etc/polkit-1/rules.d directory (or /usr/share/polkit-1/rules.d). The default action (on ArchLinux), in the time of writing this post, is located inside the 50-default.rules file, but we should create a new file, named i.e. 50-virtmgr.rules, and put this content inside the file:

polkit.addRule(function(action, subject) {
        if(action.id == "org.libvirt.unix.manage" && subject.isInGroup("wheel")) {
                return polkit.Result.YES;
        }
});

Which means, more or less: if currently evaluating action is named org.libvirt.unix.manage and the user, who asks for authorization, belongs to the wheel system group (see the /etc/group file), then allow the authorization. Just remember to add yourself to the wheel group before using this rule.

This entry was tagged on #linux and #virt