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

Radostin Stoyanov rstoyanov1 at gmail.com
Sun Aug 27 16:18:18 UTC 2017

Hi everyone!

I am Radostin, a student involved with Libvirt in the Ease creation of
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:


   Adding new features to virt-bootstrap

   Integration of virt-bootstrap with virt-manager
   <https://github.com/virt-manager/virt-manager> for smooth user

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


   Extract root file system from a tar archive.

$ virt-bootstrap /home/user/rootfs.tar

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

--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


   Extract root file system from Docker image

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 <http://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


   Extract root file system from VM image build with virt-builder

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.


   Apply UID/GID mapping

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

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

Kind Regards,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/virt-tools-list/attachments/20170827/9076c3e8/attachment.htm>

More information about the virt-tools-list mailing list