[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[virt-tools-list] [GSoC] Easy creation of containers

Hi everyone!

I am Radostin, a student involved with Libvirt in the Ease creation of containers Google Summer of Code (GSoC) Project. The idea of this project was to provide a simple way to setup root file system for the Libvirt LXC driver. Here I present the complete work I did during the GSoC term and also explanations for the same.

This summer I mostly worked on 2 things:

What has been done?

At the beginning of the project I shared my idea for extending the user interface of virt-manager on the virt-tools mailing list. The received feedback gave me ideas for adjustments to work towards but mainly this was to show the progress of virt-bootstrap in virt-manager.

Before the integration with virt-manager some improvements for virt-bootstrap were required to ensure that the installation process is simple and the progress information is tracked in accessible for virt-manager way.

In addition to that, conversion of Docker image layers to qemu copy-on-write images using backing chains was enabled.

[virt-bootstrap] Cache downloaded container images

[virt-bootstrap] Extract tar archives safely using virt-sandbox

[virt-bootstrap] Add support for layer extraction in qcow2 images

[virt-bootstrap] Move source files in src/virtBootstrap

[virt-bootstrap] Use setuptools (setup.py) for installation

[virt-bootstrap] Log executed process calls

[virt-bootstrap] Add "debug" and "quiet" flags

[virt-bootstrap] Show error if destination path is not folder

[virt-bootstrap] Improve logging of executed processes

[virt-bootstrap] Raise exception if file source is invalid

[virt-bootstrap] Improve logging of virt-sandbox

[virt-bootstrap] Refactor info messages

[virt-bootstrap] Auto-correct docker source URI 

[virt-bootstrap] Check for write permissions on destination path

[virt-bootstrap] Set logger name/format/level

[virt-bootstrap] Expose bootstrap method from virtBootstrap module

[virt-bootstrap] bootstrap: Use explicit arguments

[virt-bootstrap] Improve URI parse of DockerSource

[virt-bootstrap] DockerSource: Use getter for image directory

[virt-bootstrap] DockerSource: Retrieve manifest before download

[virt-bootstrap] Log the size of layers when extracting

[virt-bootstrap] Compact layers' details passed to extract methods 

[virt-bootstrap] DockerSource: Encapsulate skopeo copy in a method

[virt-bootstrap] DockerSource: Use downloaded layers

[virt-bootstrap] Remove redundant checksum verification

[virt-bootstrap] checksum: Log failures

[virt-bootstrap] Add new module to store the progress 

[virt-bootstrap] Add --status-only flag 

[virt-bootstrap] Detect and log download progress of layers 

[virt-bootstrap] get_image_details: Use connection options

[virt-bootstrap] Gather common utility functions in "utils" module

[virt-bootstrap] DockerSource: Ignore short lines from skopeo 

[virt-bootstrap] utils: size_to_bytes convert from int

[virt-bootstrap] utils: bytes_to_size remove trailing space

[virt-bootstrap] DockerSource: Encapsulate layers' info retrieval

The integration of virt-bootstrap with virt-manager was achieved by extending the UI and importing the virtBootstrap python module. Creation of the root file system tree is done using the bootstrap() method which is called asynchronously in a thread. [Demo video]

[virt-manager] create: Add support for OS tree creation 

[virt-manager] create: Validate input on container bootstrap 

[virt-manager] gschema: Populate/Store previous container URLs 

[virt-manager] create: Show progress of container bootstrap 

[virt-manager] create: Call virt-bootstrap asynchronously 

[virt-manager] create: Show details of container bootstrap 

[virt-manager] asyncjob: Add enable/update details methods 

Another feature added to virt-bootstrap was the UID/GID mapping which can be used to create Libvirt LXC container with enabled user namespace. In such container the owner/group of files must be mapped to UID/GID of users inside the container.

[virt-bootstrap] Add remapping ownership of files in rootfs 

What code was merged?

Merged commits for virt-bootstrap

Merged commits for virt-manager

How to use virt-bootstrap?

The command line tool virt-bootstrap provides an easy way to setup root file system from various sources such as a tar archive containing the file system, container image from Docker registry or VM disk image created with virt-builder.

$ virt-bootstrap /home/user/rootfs.tar /var/lib/Libvirt/filesystems/container1

This will extract securely the root file system from rootfs.tar to /var/lib/Libvirt/filesystems/container1 using LXC container if the user is with effective UID 0 or kvm instance (qemu:///session) otherwise.

Optionally to apply adjustments can be the flags:

--fmt         Specify the output format. Possible values are “dir” and “qcow2”

--idmap    Apply map for owner and group of entries

--uidmap Apply map for owner of entries

--gidmap    Apply map for group of entries

--root-password         Set password for root

Container images might have multiple layers where each layer store only the changes made. To extract root file system from them we have to extract the layers in order starting from base layer. This is what you can do with virt-bootstrap in the following example:

$ virt-bootstrap docker://ubuntu /var/lib/Libvirt/filesystems/ct1

The root file system extracted in /var/lib/Libvirt/filesystems/ct1 can be used by Libvirt to start LXC container.

Alternatively the layers of container image can be preserved using qcow2 image with backing chains:

$ virt-bootstrap docker://ubuntu /var/lib/Libvirt/filesystems/ct1 \

–-format qcow2

This example will create qcow2 image with single partition and ext3 file system which contains the base layer of the latest Ubuntu container image available on docker.io. Then it will create qcow2 image with backing file for each layer of the container image and store only the changes applied within this layer. This is implemented using libguestfs and does not require root privileges.

Optionally the flags for UID/GID mapping or root password can be used as well.

The tool virt-builder can be used to build disk image for virtual machine from template. To create container from such VM image we have to extract the root file system. The example below demonstrates how this can be achieved with virt-bootstrap:

$ virt-bootstrap virt-builder://fedora-25 /var/lib/Libvirt/filesystems/ct1

This command will build VM image from fedora-25 in temporary file and extract the root file system to /var/lib/Libvirt/filesystems/ct1 which can be used with Libvirt to create LXC container. Optionally the flags for UID/GID mapping or setting root password can be used as well.

The flags --idmap, --uidmap and --gidmap can be used to map the owner and group of members in the created root file system. Each of these flags can be used multiple times and take input with format: <start>:<target>:<count>

Where <start> is the UID/GID on the host, <target> is the UID/GID inside the container and <count> is the number of UID/GIDs to be mapped (range).


$ virt-bootstrap docker://fedora /var/lib/Libvirt/filesystems/ct1 \

--idmap 0:1000:10 \

-–idmap 500:1500:10

This will apply the UID/GID map:

0, 1, 2 … 9 to 1000, 1001, … 1009

500, 501 … 509 to 1500, 1501 … 1509

Limitations and known bugs

You do not necessarily need to be root to use virt-bootstrap, however there are some limitations for unprivileged users when used with output format “dir”. In such case all members of the extracted root file system will be owned by the same unprivileged and UID/GID mapping cannot be applied.

When the output format is qcow2 all functionalities are available for unprivileged users, however at the time of writing this post Libvirt has a bug which does not allow to start LXC container from qcow2 image with enabled user namespace . This bug has been reported here https://bugzilla.redhat.com/show_bug.cgi?id=1328946 and the work around is to mount the qcow2 image and start LXC container from the mounted directory with enabled user namespaces.


I would like to thanks all members of Libvirt and virt-tools communities and particularly Cédric Bosdonnat, Cole Robinson and Pavel Hrdina for all commit reviews and suggestions.

I would also like to thanks Daniel P. Berrange for the help in resolving issues.

And of course, many thanks to the staff of GSoC for running the programme.

Kind Regards,

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]