LXC Python bindings
The latest lxc version (0.9.0) has Python bindings included. You can download the latest version from github or install it from standard repositories on Ubuntu 13.04. If you have chosen to install it from source then dont forget to run configure with --enable-python flag. The library has been written for Python 3.
Good example of usage is in the api_test.py file, and following code snippets will show how to create, start, stop and destroy container named test_container. This library requires root permissions, so dont forget to run Python as root.
In the following code we instantiate lxc container.
import lxc
container = lxc.Container(test_container)
First we have to import lxc library. Next line instantiates new container with container name test_container. It doesnt have to exist yet, but it can. The constructor can take one more argument called config_path, which is a path to the configuration file for the container. If it is not specified, the default configuration will be used, usually located in /etc/lxc/default.conf.
Here we show how to create a container from template.
container.create(busybox)
If it doesnt exist yet, you can create it using create method and specify which template will be used to create it. Creating a container is just creating a rootfs folder for the container, and creating a configuration file. They will be located in /var/lib/lxc/test_container/. There are several templates such as, ubuntu, fedora, debian, sshd. I chose busybox because it is light weight, only few megabytes, while ubuntu would start downloading ubuntu minimal package which is over 300 megabytes. Container templates are just scripts that create rootfs folder for container. If custom behavior is needed, then a new script can be created or existing modified.
This code shows how to start a container.
container.start()
container.wait("RUNNING", 5)
print ("Container state", container.state)
The start method starts the container in daemonized mode and doesnt block the execution, that is why the wait method is used to wait at most 5 seconds for the container to reach the running state. Output of this script should just be a line saying that the container state is running, if not then something is wrong with the container or the lxc installation.
There are two optional arguments that the start command expects:
- cmd argument which expects a tuple. If specified then the default init process is replaced with that command. Note that this resembles to lxc-start command, because it can also replace standard init process with the command specified after the -- flag. The first element of the tuple should be a path to executable, relative to containers rootfs, and the rest is passed as command line arguments to it. When using it with ubuntu template the start method sometimes prints an error message, even do it successfully runs the application and returns true.
- useinit argument uses the lxc-init executable as init process, this is used to run a command in a similar way the lxc-execute runs it. I have not been able to successfully run a container with useinit set to true.
container.stop()
container.wait("STOPPED", 5)
print ("State should be stopped", container.state)
Stop method takes no arguments and stops the container without blocking the execution, and this is why wait method has to be used to reach the stopped state. This is very similar behavior to the start method.
This line shows how to destroy a container.
container.destroy()
Destroy method removes the container and its rootfs from the disk. To use it again one would have to create it with create method. This method is implemented just by calling lxc-destroy command.
These were the basic functions to operate the container, but there are still few more interesting functions to look at.
The following code shows how to access container console.
container.console()
Once the container had started and reached the running state its console can be accessed with console method. This will bring the console and will prompt for username and password.
This code snippet shows to attach a single process to an already running container.
container.attach(ALL, /bin/ls, -l)
This runs the command inside an already running container. First argument regulates which namespaces to attach to, ALL is the default and safest choice, but if you want to specify particular namespaces just enter it as OR-ed list of arguments such as NETWORK|IPC. The second argument is path to the command that should be attached to the container, and the rest of the parameters are passed to it as command line arguments. This command is useful for running just one command, and it doesnt close its file descriptors. This means that the stdin, stdout and stderr are still open and available to use.
All of these methods resemble the lxc-* commands in the command line. To find more information about them use man pages, and to find some info on how to use them inside Python just call help(lxc).
download file now
alternative link download