Connections¶
In libvirt, a connection is the underpinning of every action and object in the system. Every entity that wants to interact with libvirt, be it virsh, virt-manager, or a program using the libvirt library, needs to first obtain a connection to the libvirt daemon on the host it is interested in interacting with. A connection describes not only the type of virtualization technology that the agent wants to interact with (qemu, xen, uml, etc), but also describes any authentication methods necessary to connect to that resource.
Overview¶
The very first thing a libvirt agent must do is call the virInitialize
function, or one of the Python libvirt connection functions to obtain an instance of the virConnect
class. This instance will be used in subsequent operations. The Python libvirt module provides 3 different functions for connecting to a resource:
import libvirt
conn = libvirt.open(name)
conn = libvirt.openAuth(uri, auth, flags)
conn = libvirt.openReadOnly(name)
In all three cases there is a name parameter which in fact refers to the URI of the hypervisor to connect to.
libvirt.open(name=None)¶
The open function will attempt to open a connection for full read-write access. It does not have any scope for authentication callbacks to be provided, so it will only succeed for connections where authentication can be done based on the credentials of the application.
import libvirt
conn = libvirt.open("qemu:///system")
if not conn:
raise SystemExit("Failed to open connection to qemu:///system")
conn.close()
The above example opens up a read-write connection to the system qemu
hypervisor driver, checks to make sure it was successful, and if so closes the connection.
libvirt.openReadOnly(name=None)¶
The openReadOnly function will attempt to open a connection for read-only access. Such a connection has a restricted set of method calls that are allowed, and is typically useful for monitoring applications that should not be allowed to make changes. As with open, this method has no scope for authentication callbacks, so it relies on credentials.
import libvirt
conn = libvirt.openReadOnly("qemu:///system")
if not conn:
raise SystemExit("Failed to open connection to qemu:///system")
conn.close()
The above example opens up a read-only connection to the system qemu hypervisor driver, checks to make sure it was successful, and if so closes the connection.
libvirt.openAuth(uri, auth, flags=0)¶
The openAuth function is the most flexible, and effectively obsoletes the previous two functions. It takes an extra parameter providing a list which contains the authentication credentials from the client app. The flags parameter allows the application to request a read-only connection with the VIR_CONNECT_RO
flag if desired. A simple example that uses openAuth with username and password credentials follows. As with open, this method has no scope for authentication callbacks, so it relies on credentials.
import libvirt
SASL_USER = "my-super-user"
SASL_PASS = "my-super-pass"
def request_cred(credentials, user_data):
for credential in credentials:
if credential[0] == libvirt.VIR_CRED_AUTHNAME:
credential[4] = SASL_USER
elif credential[0] == libvirt.VIR_CRED_PASSPHRASE:
credential[4] = SASL_PASS
return 0
auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE], request_cred, None]
conn = libvirt.openAuth("qemu+tcp://localhost/system", auth, 0)
if not conn:
raise SystemExit("Failed to open connection to qemu+tcp://localhost/system")
conn.close()
To test the above program, the following configuration must be present:
- /etc/libvirt/libvirtd.conf
listen_tls = 0
listen_tcp = 1
auth_tcp = "sasl"
- /etc/sasl2/libvirt.conf
mech_list: digest-md5
-
A virt user has been added to the SASL database.
-
libvirtd has been started with
--listen
.
Once the above is configured, openAuth
can utilize the configured username and password and allow read-write access to libvirtd.
virConnect.close(self)¶
A connection must be released by calling the close
method of the virConnection class when no longer required. Connections are reference counted objects, so there should be a corresponding call to the close method for each open function call.
Connections are reference counted; the count is explicitly increased by the initial (open, openAuth, and the like); it is also temporarily increased by other methods that depend on the connection remaining alive. The open function call should have a matching close, and all other references will be released after the corresponding operation completes.
import libvirt
conn1 = libvirt.open("qemu:///system")
if not conn1:
raise SystemExit("Failed to open connection to qemu:///system")
conn2 = libvirt.open("qemu:///system")
if not conn2:
raise SystemExit("Failed to open connection to qemu:///system")
conn1.close()
conn2.close()
In Python reference counts can be automatically decreased when an class instance goes out of scope or when the program ends. Also note that every other class instance associated with a connection (virDomain, virNetwork, etc.) will also hold a reference on the connection.