[libvirt] [PATCH v3 0/9] x86: Secure Encrypted Virtualization (AMD)
by Brijesh Singh
The patch series is test with QEMU recent pull which includes SEV support:
https://lists.gnu.org/archive/html/qemu-devel/2018-03/msg03826.html
This patch series provides support for launching an encrypted guest using
AMD's new Secure Encrypted Virtualization (SEV) feature.
SEV is an extension to the AMD-V architecture which supports running
multiple VMs under the control of a hypervisor. When enabled, SEV feature
allows the memory contents of a virtual machine (VM) to be transparently
encrypted with a key unique to the guest VM.
At very high level the flow looks this:
1. mgmt tool calls virConnectGetDomainCapabilities. This returns an XML document
that includes the following
<feature>
...
<sev supported='yes'>
<cbitpos> </cbitpos>
<reduced-phys-bits> </reduced-phys-bits>
<pdh> </pdh>
<cert-chain> </cert-chain>
</feature>
If <sev> is provided then we indicate that hypervisor is capable of launching
SEV guest.
2. (optional) mgmt tool can provide the PDH and Cert-chain to guest owner in case
if guest owner wish to establish a secure connection with SEV firmware to
negotiate a key used for validating the measurement.
3. mgmt tool requests to start a guest calling virCreateXML(), passing VIR_DOMAIN_START_PAUSED.
The xml would include
<launch-security type='sev'>
<cbitpos> </cbitpos> /* the value is same as what is obtained via virConnectGetDomainCapabilities()
<reduced-phys-bits> </reduced-phys-bits> /* the value is same as what is obtained via virConnectGetDomainCapabilities()
<dh-cert> .. </dh> /* guest owners diffie-hellman key */ (optional)
<session> ..</session> /* guest owners session blob */ (optional)
<policy> ..</policy> /* guest policy */ (optional)
4. Libvirt generate the QEMU cli arg to enable the SEV feature, a typical
args looks like this:
# $QEMU ..
-machine memory-encryption=sev0 \
-object sev-guest,id=sev0,dh-cert-file=<file>....
5. Libvirt generates lifecycle VIR_DOMAIN_EVENT_SUSPENDED_PAUSED event
6. mgmt tool gets the VIR_DOMAIN_EVENT_SUSPENDED_PAUSED and calls virDomainGetLaunchSecretInfo()
to retrieve the measurement of encrypted memory.
7. (optional) mgmt tool can provide the measurement value to guest owner, which can
validate the measurement and gives GO/NO-GO answer. If mgmt tool gets GO then
it resumes the guest otherwise it calls destroy() to kill the guest.
8. mgmt tool resumes the guest
TODO:
* SEV guest require to use DMA apis for the virtio devices. In order to use the DMA
apis the virtio devices must have this tag
<driver iommu=on ats=on>
It is a bit unclear to me where these changes need to go. Do we need to
modify the libvirt to automatically add these when SEV is enabled or
we ask mgmt tool to make sure that it creates XML with right tag to enable
the DMA APIs for virtio devices. I am looking for some suggestions.
Using these patches we have succesfully booted and tested a guest both with and
without SEV enabled.
SEV Firmware API spec is available at:
https://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf
Changes since v2:
* make cbitpos, policy and reduced-phys-bits as unsigned int
* update virDomainGetLaunchSecurityInfo to accept virTypedParameterPtr *params
instead of virTypedParameterPtr params.
Changes since v1:
* rename <sev> -> <launch-security> for domain
* add more information about policy and other fields in domaincaps.html
* split the domain_conf support in two patches
* add virDomainGetLaunchInfo() to retrieve the SEV measurement
* extend virsh command to show the domain's launch security information
* add test cases to validate newly added <launch-security> element
* fix issues reported with 'make check' and 'make syntax-check'
The complete git tree is available at:
https://github.com/codomania/libvirt/tree/v3
Brijesh Singh (8):
qemu: provide support to query the SEV capability
qemu: introduce SEV feature in hypervisor capabilities
conf: introduce launch-security element in domain
qemu: add support to launch SEV guest
libvirt: add new public API to get launch security info
remote: implement the remote protocol for launch security
qemu_driver: add support to launch security info
virsh: implement new command for launch security
Xiaogang Chen (1):
tests: extend tests to include sev specific tag parsing
docs/formatdomain.html.in | 120 ++++++++++++++++++++++++++++++++++++
docs/formatdomaincaps.html.in | 40 ++++++++++++
docs/schemas/domaincaps.rng | 20 ++++++
docs/schemas/domaincommon.rng | 39 ++++++++++++
include/libvirt/libvirt-domain.h | 17 +++++
src/conf/domain_capabilities.c | 20 ++++++
src/conf/domain_capabilities.h | 14 +++++
src/conf/domain_conf.c | 110 +++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 26 ++++++++
src/driver-hypervisor.h | 7 +++
src/libvirt-domain.c | 48 +++++++++++++++
src/libvirt_public.syms | 5 ++
src/qemu/qemu_capabilities.c | 40 ++++++++++++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_capspriv.h | 4 ++
src/qemu/qemu_command.c | 35 +++++++++++
src/qemu/qemu_driver.c | 66 ++++++++++++++++++++
src/qemu/qemu_monitor.c | 17 +++++
src/qemu/qemu_monitor.h | 6 ++
src/qemu/qemu_monitor_json.c | 105 +++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 5 ++
src/qemu/qemu_process.c | 58 +++++++++++++++++
src/remote/remote_daemon_dispatch.c | 47 ++++++++++++++
src/remote/remote_driver.c | 42 ++++++++++++-
src/remote/remote_protocol.x | 20 +++++-
src/remote_protocol-structs | 11 ++++
tests/genericxml2xmlindata/sev.xml | 20 ++++++
tests/genericxml2xmloutdata/sev.xml | 22 +++++++
tests/genericxml2xmltest.c | 2 +
tests/qemuxml2argvdata/sev.args | 24 ++++++++
tests/qemuxml2argvdata/sev.xml | 35 +++++++++++
tests/qemuxml2argvtest.c | 2 +
tests/qemuxml2xmloutdata/sev.xml | 39 ++++++++++++
tests/qemuxml2xmltest.c | 2 +
tools/virsh-domain.c | 84 +++++++++++++++++++++++++
35 files changed, 1151 insertions(+), 2 deletions(-)
create mode 100644 tests/genericxml2xmlindata/sev.xml
create mode 100644 tests/genericxml2xmloutdata/sev.xml
create mode 100644 tests/qemuxml2argvdata/sev.args
create mode 100644 tests/qemuxml2argvdata/sev.xml
create mode 100644 tests/qemuxml2xmloutdata/sev.xml
--
2.14.3
6 years, 9 months
[libvirt] Compiling Libvirt 3.0.0 failed: cannot stat t-kw@kkcor.gmo
by Mathieu Tarral
Hi,
I tried to compile libvirt 3.0.0, from git, on a Debian Stretch.
It failed with these weird errors that i'm not able to fix by myself:
rm -f ky.gmo && : -c --statistics -o ky.gmo ky.po
rm -f lt.gmo && : -c --statistics -o lt.gmo lt.po
mv: cannot stat 't-kw(a)kkcor.gmo': No such file or directory
mv: cannot stat 't-kw(a)uccor.gmo': No such file or directory
Makefile:448: recipe for target 'kw(a)kkcor.gmo' failed
make[3]: *** [kw(a)kkcor.gmo] Error 1
make[3]: *** Waiting for unfinished jobs....
rm -f lv.gmo && : -c --statistics -o lv.gmo lv.po
Makefile:448: recipe for target 'kw(a)uccor.gmo' failed
make[3]: *** [kw(a)uccor.gmo] Error 1
mv: cannot stat 't-kw_GB.gmo': No such file or directory
I have no idea what this "t-kw(a)kkcor.gmo" is about ??
Could you guys help ?
Note: the build failed erlier because uuid-dev was missing.
You might want to add a check for that lib in the configure.ac
Best regards.
--
Mathieu Tarral
6 years, 9 months
[libvirt] [dbus PATCH 0/3] Implement LookupBy* methods for libvirt
by Katerina Koukiou
Katerina Koukiou (3):
Implement LookupByID method for Connect Interface.
Implement LookupByName method for Connect Interface
Implement LookupByUUID method for Connect Interface
data/org.libvirt.Connect.xml | 18 +++++++++
src/connect.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
src/domain.c | 1 +
test/libvirttest.py | 5 +++
test/test_connect.py | 15 +++++++-
test/test_domain.py | 5 ---
6 files changed, 125 insertions(+), 6 deletions(-)
--
2.15.0
6 years, 9 months
[libvirt] [jenkins-ci PATCH] guests: Enable ccache
by Andrea Bolognani
We install ccache on all guests where it's available, but
Fedora is the only one actually using it at the moment,
because it enables it automatically.
Tweak the user's profile so that compilation will use ccache
if it's installed.
Signed-off-by: Andrea Bolognani <abologna(a)redhat.com>
---
guests/tasks/users.yml | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/guests/tasks/users.yml b/guests/tasks/users.yml
index 87693e0..1ecacee 100644
--- a/guests/tasks/users.yml
+++ b/guests/tasks/users.yml
@@ -64,3 +64,21 @@
dest: /home/{{ flavor }}/.ccache/ccache.conf
owner: '{{ flavor }}'
group: '{{ flavor }}'
+
+- name: '{{ flavor }}: Enable ccache'
+ lineinfile:
+ path: /home/{{ flavor }}/.profile
+ line: 'which ccache >/dev/null 2>&1 && export CC="ccache cc"'
+ state: present
+ owner: '{{ flavor }}'
+ group: '{{ flavor }}'
+ create: yes
+
+- name: '{{ flavor }}: Enable ccache'
+ lineinfile:
+ path: /home/{{ flavor }}/.bashrc
+ line: 'which ccache >/dev/null 2>&1 && export CC="ccache cc"'
+ state: present
+ owner: '{{ flavor }}'
+ group: '{{ flavor }}'
+ create: yes
--
2.14.3
6 years, 9 months
Re: [libvirt] [PATCH 01/12] conf: introduce domain XML element <polling> for iothread
by Sergio Lopez
Hi,
I'd like to resurrect this thread:
https://www.redhat.com/archives/libvir-list/2017-February/msg01084.html
Recent benchmarks have demonstrated that using large values for
poll-max-ns significantly decreases the perceived latency in the Guest,
at the expense of the iothread using more CPU:
- virtio-blk+iothread, 16 vCPUs, null_blk=200us and default poll-max-ns
randread: (groupid=0, jobs=4): err= 0: pid=1314: Thu Feb 15 06:24:06 2018
read: IOPS=15.0k, BW=58.7MiB/s (61.6MB/s)(587MiB/10001msec)
clat (usec): min=98, max=2016, avg=257.98, stdev=22.91
lat (usec): min=100, max=2017, avg=259.37, stdev=22.99
randread: (groupid=0, jobs=8): err= 0: pid=1359: Thu Feb 15 06:25:03 2018
read: IOPS=29.8k, BW=117MiB/s (122MB/s)(1166MiB/10002msec)
clat (usec): min=33, max=3818, avg=260.92, stdev=32.02
lat (usec): min=34, max=3819, avg=262.14, stdev=32.02
randread: (groupid=0, jobs=16): err= 0: pid=1339: Thu Feb 15 06:24:41 2018
read: IOPS=55.9k, BW=218MiB/s (229MB/s)(2182MiB/10002msec)
clat (usec): min=37, max=3390, avg=279.19, stdev=34.53
lat (usec): min=38, max=3391, avg=280.41, stdev=34.54
- virtio-blk+iothread, 16 vCPUs, null_blk=200us and poll-max-ns=1000000
randread: (groupid=0, jobs=4): err= 0: pid=1361: Thu Feb 15 06:31:47 2018
read: IOPS=16.2k, BW=63.3MiB/s (66.3MB/s)(633MiB/10001msec)
clat (usec): min=72, max=2790, avg=240.12, stdev=22.28
lat (usec): min=73, max=2791, avg=241.30, stdev=22.28
randread: (groupid=0, jobs=8): err= 0: pid=1342: Thu Feb 15 06:30:51 2018
read: IOPS=32.1k, BW=125MiB/s (132MB/s)(1255MiB/10001msec)
clat (usec): min=30, max=5474, avg=242.14, stdev=46.24
lat (usec): min=31, max=5475, avg=243.33, stdev=46.25
randread: (groupid=0, jobs=16): err= 0: pid=1324: Thu Feb 15 06:30:11 2018
read: IOPS=61.8k, BW=241MiB/s (253MB/s)(2413MiB/10002msec)
clat (usec): min=26, max=2931, avg=251.89, stdev=38.37
lat (usec): min=27, max=2932, avg=253.11, stdev=38.38
I think this trade-off should be user's decision. Layered products may
consider abstracting this configuration under simplified VM tuning
attributes.
Sergio.
6 years, 9 months
[libvirt] [dbus PATCH v2] Add 'Version' property for virConnectGetVersion
by Katerina Koukiou
---
data/org.libvirt.Connect.xml | 4 ++++
src/connect.c | 25 ++++++++++++++++++++++++-
test/test_connect.py | 9 +++++++++
3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/data/org.libvirt.Connect.xml b/data/org.libvirt.Connect.xml
index e47c2f5..56a1126 100644
--- a/data/org.libvirt.Connect.xml
+++ b/data/org.libvirt.Connect.xml
@@ -3,6 +3,10 @@
<node name="/org/libvirt/connect">
<interface name="org.libvirt.Connect">
+ <property name="Version" type="t" access="read">
+ <annotation name="org.gtk.GDBus.DocString"
+ value="See https://libvirt.org/html/libvirt-libvirt-domain.html#virConnectGetVersion"/>
+ </property>
<method name="ListDomains">
<annotation name="org.gtk.GDBus.DocString"
value="See https://libvirt.org/html/libvirt-libvirt-domain.html#virConnectListAllDom..."/>
diff --git a/src/connect.c b/src/connect.c
index bf97cd5..8898e6d 100644
--- a/src/connect.c
+++ b/src/connect.c
@@ -80,6 +80,24 @@ virtDBusConnectOpen(virtDBusConnect *connect,
return TRUE;
}
+static void
+virtDBusConnectGetVersion(const gchar *objectPath G_GNUC_UNUSED,
+ gpointer userData,
+ GVariant **value,
+ GError **error)
+{
+ virtDBusConnect *connect = userData;
+ gulong hvVer;
+
+ if (!virtDBusConnectOpen(connect, error))
+ return;
+
+ if (virConnectGetVersion(connect->connection, &hvVer) < 0)
+ return virtDBusUtilSetLastVirtError(error);
+
+ *value = g_variant_new("t", hvVer);
+}
+
static void
virtDBusConnectListDomains(GVariant *inArgs,
GUnixFDList *inFDs G_GNUC_UNUSED,
@@ -177,6 +195,11 @@ virtDBusConnectDefineXML(GVariant *inArgs,
*outArgs = g_variant_new("(o)", path);
}
+static virtDBusGDBusPropertyTable virtDBusConnectPropertyTable[] = {
+ { "Version", virtDBusConnectGetVersion, NULL },
+ { NULL, NULL, NULL }
+};
+
static virtDBusGDBusMethodTable virtDBusConnectMethodTable[] = {
{ "ListDomains", virtDBusConnectListDomains },
{ "CreateXML", virtDBusConnectCreateXML },
@@ -228,7 +251,7 @@ virtDBusConnectNew(virtDBusConnect **connectp,
connect->connectPath,
interfaceInfo,
virtDBusConnectMethodTable,
- NULL,
+ virtDBusConnectPropertyTable,
connect);
virtDBusDomainRegister(connect, error);
diff --git a/test/test_connect.py b/test/test_connect.py
index a52140c..01d4d41 100755
--- a/test/test_connect.py
+++ b/test/test_connect.py
@@ -2,6 +2,7 @@
import dbus
import libvirttest
+import pytest
class TestConnect(libvirttest.BaseTestClass):
@@ -53,6 +54,14 @@ class TestConnect(libvirttest.BaseTestClass):
self.main_loop()
+ @pytest.mark.parametrize("property_name,expected_type", [
+ ("Version", dbus.UInt64),
+ ])
+ def test_connect_properties_return_type(self, property_name, expected_type):
+ obj = self.bus.get_object('org.libvirt', '/org/libvirt/Test')
+ props = obj.GetAll('org.libvirt.Connect', dbus_interface=dbus.PROPERTIES_IFACE)
+ assert isinstance(props[property_name], expected_type)
+
if __name__ == '__main__':
libvirttest.run()
--
2.15.0
6 years, 9 months
[libvirt] [dbus PATCH 0/4] remove AUTHORS file and cleanup spec file
by Pavel Hrdina
Pavel Hrdina (4):
maint: remove AUTHORS from repository
spec: cleanup spec file based on fedora package review
spec: Require dbus and polkit
spec: fix D-Bus spelling and improve description
AUTHORS.in | 13 -------------
Makefile.am | 14 --------------
libvirt-dbus.spec.in | 34 +++++++++++++++-------------------
3 files changed, 15 insertions(+), 46 deletions(-)
delete mode 100644 AUTHORS.in
--
2.14.3
6 years, 9 months
[libvirt] [PATCH sandbox] Delete the virt-sandbox-service command
by Daniel P. Berrangé
This command attempted to create sandboxed containers for running
systemd services that exist on the host. This code has proved very
fragile, however, since it needs heuristics to figure out which dirs
need to be made private in the container vs shared with the host. Even
a relatively simple "httpd.service" sandbox no longer works with
current Fedora.
Users wanting to sandbox services are better served by using systemd's
native container functionality, or using Docker container images. The
virt-sandbox-image tool can even run Docker/virt-builder images directly.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
TODO | 24 -
bin/Makefile.am | 80 +-
bin/virt-sandbox-service | 1314 ---------------------------
bin/virt-sandbox-service-bash-completion.sh | 141 ---
bin/virt-sandbox-service-clone.pod | 100 --
bin/virt-sandbox-service-connect.pod | 59 --
bin/virt-sandbox-service-create.pod | 264 ------
bin/virt-sandbox-service-delete.pod | 65 --
bin/virt-sandbox-service-execute.pod | 71 --
bin/virt-sandbox-service-reload.pod | 63 --
bin/virt-sandbox-service-upgrade.pod | 74 --
bin/virt-sandbox-service-util.c | 305 -------
bin/virt-sandbox-service.logrotate | 9 -
bin/virt-sandbox-service.pod | 85 --
cfg.mk | 2 +-
libvirt-sandbox.spec.in | 7 -
libvirt-sandbox/tests/containers_test.sh | 37 -
po/POTFILES.in | 1 -
18 files changed, 3 insertions(+), 2698 deletions(-)
delete mode 100644 TODO
delete mode 100755 bin/virt-sandbox-service
delete mode 100755 bin/virt-sandbox-service-bash-completion.sh
delete mode 100644 bin/virt-sandbox-service-clone.pod
delete mode 100644 bin/virt-sandbox-service-connect.pod
delete mode 100644 bin/virt-sandbox-service-create.pod
delete mode 100644 bin/virt-sandbox-service-delete.pod
delete mode 100644 bin/virt-sandbox-service-execute.pod
delete mode 100644 bin/virt-sandbox-service-reload.pod
delete mode 100644 bin/virt-sandbox-service-upgrade.pod
delete mode 100644 bin/virt-sandbox-service-util.c
delete mode 100644 bin/virt-sandbox-service.logrotate
delete mode 100644 bin/virt-sandbox-service.pod
delete mode 100755 libvirt-sandbox/tests/containers_test.sh
diff --git a/TODO b/TODO
deleted file mode 100644
index fc63361..0000000
--- a/TODO
+++ /dev/null
@@ -1,24 +0,0 @@
- libvirt-sandbox TODO list
- =================
-
-systemd-tmpfiles --create needs to be run within the container, before any
-apps are started, since it will populate /run (Completed)
-
-CGROUPFS: integration so libvirt does it rather then systemd within the container
- We need kernel labeling support for cgroupfs so we can allow systemd to write to its section of the cgroupfs.
-
-SYSLOG: Currently syslog messages are going no where within the container.
-If we run a syslog within the container will it get messages from the outside? Should we just use systemd-journal. I think sysadmins will want to be able to look in /var/log/messages within the container. (systemd-journal is now running within a container)
-
-EXECUTE:
- virt-sandbox-service execute --command "BLAH" does not work. We need to have the ability to execute any random command within the container, and get stdin, stdout, stderror outside the container. (Partially Completed)
-Still needs kernel to implement missing container namespace files under /proc/PID/ns, Also need a mechanism to get the PID of systemd from libvirt.
-
-HOSTNAME:
- Currently if I execute hostname within the container it sees the name of the host not the name based on the container name or the IP Address associated with dhclient. (Completed)
-
-virt-sandbox-service connect NAME hangs when you attempt to end the connection.
-^d should bring you back to the host terminal.
-
-Need a mechanism to allow admins to specify additional services to run within
-the container. For example you may want to run mysql and apache within the same container. (Completed) You can do this using systemctl enabel BLAH
diff --git a/bin/Makefile.am b/bin/Makefile.am
index deedcf6..db0a1d1 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -1,39 +1,12 @@
bin_PROGRAMS = virt-sandbox
-libexec_PROGRAMS = virt-sandbox-service-util
+bin_SCRIPTS = virt-sandbox-image
-bin_SCRIPTS = virt-sandbox-service \
- virt-sandbox-image
-
-virtsandboxcompdir = $(datarootdir)/bash-completion/completions/
-
-crondailydir = $(sysconfdir)/cron.daily
-crondaily_SCRIPTS = virt-sandbox-service.logrotate
-
-POD_FILES = \
- virt-sandbox-service.pod \
- virt-sandbox-service-execute.pod \
- virt-sandbox-service-create.pod \
- virt-sandbox-service-clone.pod \
- virt-sandbox-service-connect.pod \
- virt-sandbox-service-delete.pod \
- virt-sandbox-service-reload.pod \
- virt-sandbox-service-upgrade.pod \
- $(NULL)
-EXTRA_DIST = $(bin_SCRIPTS) $(POD_FILES) virt-sandbox-service-bash-completion.sh virt-sandbox-service.logrotate
-EXTRA_DIST += virt-sandbox-service-bash-completion.sh
+EXTRA_DIST = $(bin_SCRIPTS)
man1_MANS = \
virt-sandbox.1 \
- virt-sandbox-service.1 \
- virt-sandbox-service-execute.1 \
- virt-sandbox-service-create.1 \
- virt-sandbox-service-clone.1 \
- virt-sandbox-service-connect.1 \
- virt-sandbox-service-delete.1 \
- virt-sandbox-service-reload.1 \
- virt-sandbox-service-upgrade.1 \
$(NULL)
POD2MAN = pod2man -c "Virtualization Support" -r "$(PACKAGE)-$(VERSION)"
@@ -41,30 +14,6 @@ POD2MAN = pod2man -c "Virtualization Support" -r "$(PACKAGE)-$(VERSION)"
virt-sandbox.1: virt-sandbox.c Makefile
$(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@
-virt-sandbox-service.1: virt-sandbox-service.pod Makefile
- $(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@
-
-virt-sandbox-service-execute.1: virt-sandbox-service-execute.pod Makefile
- $(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@
-
-virt-sandbox-service-clone.1: virt-sandbox-service-clone.pod Makefile
- $(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@
-
-virt-sandbox-service-create.1: virt-sandbox-service-create.pod Makefile
- $(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@
-
-virt-sandbox-service-connect.1: virt-sandbox-service-connect.pod Makefile
- $(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@
-
-virt-sandbox-service-delete.1: virt-sandbox-service-delete.pod Makefile
- $(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@
-
-virt-sandbox-service-reload.1: virt-sandbox-service-reload.pod Makefile
- $(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@
-
-virt-sandbox-service-upgrade.1: virt-sandbox-service-upgrade.pod Makefile
- $(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@
-
CLEANFILES = $(man1_MANS)
virt_sandbox_SOURCES = virt-sandbox.c
@@ -81,28 +30,3 @@ virt_sandbox_LDFLAGS = \
../libvirt-sandbox/libvirt-sandbox-1.0.la \
$(WARN_CFLAGS) \
$(NULL)
-
-virt_sandbox_service_util_SOURCES = virt-sandbox-service-util.c
-virt_sandbox_service_util_CFLAGS = \
- $(GIO_UNIX_CFLAGS) \
- $(LIBVIRT_GOBJECT_CFLAGS) \
- -I$(top_srcdir) \
- -DLOCALEDIR="\"$(datadir)/locale"\" \
- $(WARN_CFLAGS) \
- $(NULL)
-virt_sandbox_service_util_LDFLAGS = \
- $(GIO_UNIX_LIBS) \
- $(LIBVIRT_GOBJECT_LIBS) \
- ../libvirt-sandbox/libvirt-sandbox-1.0.la \
- $(WARN_CFLAGS) \
- $(NULL)
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(sysconfdir)/libvirt-sandbox/services
- $(MKDIR_P) $(DESTDIR)$(virtsandboxcompdir)
- cp $(srcdir)/virt-sandbox-service-bash-completion.sh $(DESTDIR)$(virtsandboxcompdir)/virt-sandbox-service
-
-uninstall-local:
- $(rmdir) $(DESTDIR)$(sysconfdir)/libvirt-sandbox/services ||:
- $(rmdir) $(DESTDIR)$(sysconfdir)/libvirt-sandbox ||:
- rm -f $(DESTDIR)$(virtsandboxcompdir)/virt-sandbox-service
diff --git a/bin/virt-sandbox-service b/bin/virt-sandbox-service
deleted file mode 100755
index c458716..0000000
--- a/bin/virt-sandbox-service
+++ /dev/null
@@ -1,1314 +0,0 @@
-#!/usr/bin/env python3
-#
-# Authors: Dan Walsh <dwalsh(a)redhat.com>
-#
-# Copyright (C) 2012-2013 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-
-import gi
-gi.require_version('LibvirtGConfig', '1.0')
-from gi.repository import LibvirtGConfig
-gi.require_version('LibvirtGObject', '1.0')
-from gi.repository import LibvirtGObject
-gi.require_version('LibvirtSandbox', '1.0')
-from gi.repository import LibvirtSandbox
-from gi.repository import GLib
-import gi
-import re
-import os, sys, shutil, errno, stat
-import rpm
-from subprocess import Popen, PIPE, STDOUT
-import gettext
-import pwd
-
-if os.path.exists("/sys/fs/selinux"):
- import selinux
-else:
- selinux = None
-
-LibvirtGObject.init_object_check(None)
-LibvirtSandbox.init_check(None)
-
-gettext.bindtextdomain("libvirt-sandbox", "/usr/share/locale")
-gettext.textdomain("libvirt-sandbox")
-try:
- gettext.install("libvirt-sandbox",
- localedir="/usr/share/locale",
- codeset = 'utf-8')
-except IOError:
- import __builtin__
- __builtin__.__dict__['_'] = unicode
-
-CONFIG_PATH = "/etc/libvirt-sandbox/services/"
-def get_config_path(name):
- return CONFIG_PATH + name + "/config/sandbox.cfg"
-
-def get_legacy_config_path(name):
- return CONFIG_PATH + name + ".sandbox"
-
-def read_config(name):
- path = get_config_path(name)
- if not os.path.exists(path):
- return None
- return LibvirtSandbox.Config.load_from_path(path)
-
-# shutil.copytree throws a fit if it finds sockets
-# or fifos, and has really bad behaviour on block
-# and character devices too.
-def copydirtree(src, dst):
- filenames = os.listdir(src)
- os.makedirs(dst)
-
- for filename in filenames:
- srcfilepath = os.path.join(src, filename)
- dstfilepath = os.path.join(dst, filename)
-
- st = os.lstat(srcfilepath)
- if stat.S_ISDIR(st.st_mode):
- copydirtree(srcfilepath, dstfilepath)
-
- os.utime(dstfilepath, (st.st_atime, st.st_mtime))
- os.chmod(dstfilepath, stat.S_IMODE(st.st_mode))
- elif stat.S_ISREG(st.st_mode):
- with open(srcfilepath, 'rb') as fsrc:
- with open(dstfilepath, 'wb') as fdst:
- while 1:
- buf = fsrc.read(1024*32)
- if not buf:
- break
- fdst.write(buf)
-
- os.utime(dstfilepath, (st.st_atime, st.st_mtime))
- os.chmod(dstfilepath, stat.S_IMODE(st.st_mode))
- elif stat.S_ISLNK(st.st_mode):
- linkdst = os.readlink(srcfilepath)
- os.symlink(linkdst, dstfilepath)
- else:
- # Ignore all other special files (block/char/sock/fifo)
- pass
-
-class Container:
- DEFAULT_PATH = "/var/lib/libvirt/filesystems"
- DEFAULT_IMAGE = "/var/lib/libvirt/images/%s.raw"
- SELINUX_FILE_TYPE = "svirt_lxc_file_t"
-
- def __init__(self, name=None, uri = "lxc:///", path = DEFAULT_PATH, config=None, create=False):
- self.uri = uri
- self.use_image = False
- self.size = 10 * MB
- self.path = path
- self.config = config
- if self.config:
- self.name = self.config.get_name()
- else:
- self.name = name
- self.dest = "%s/%s" % (self.path, self.name)
- self.file_type = self.SELINUX_FILE_TYPE
- self.conn = None
- self.image = None
- self.uid = 0
- self.mounts = []
-
- def get_file_type(self):
- return self.file_type
-
- def set_file_type(self, file_type):
- self.file_type = file_type
-
- def set_uid(self, uid):
- self.config.set_userid(uid)
-
- def get_uid(self):
- return self.config.get_userid(uid)
-
- def set_gid(self, gid):
- self.config.set_groupid(gid)
-
- def get_gid(self):
- return self.config.get_groupid(gid)
-
- def set_username(self, username):
- self.config.set_username(username)
-
- def get_username(self):
- return self.config.get_username()
-
- def set_homedir(self, homedir):
- self.config.set_homedir(homedir)
-
- def get_homedir(self):
- return self.config.get_homedir()
-
- def set_mounts(self, mounts):
- self.mounts = mounts
-
- def get_mounts(self):
- return self.mounts
-
- def add_mounts(self):
- self.config.add_mount_strv(self.mounts)
-
- def get_config_path(self, name = None):
- if not name:
- name = self.name
- return get_config_path(name)
-
- def get_filesystem_path(self, name = None):
- if not name:
- name = self.get_name()
- return "%s/%s" % (self.path, name)
-
- def get_image_path(self, name = None):
- if not name:
- name = self.get_name()
- return self.DEFAULT_IMAGE % name
-
- def set_image(self, size):
- self.use_image = True
- self.size = size * MB
-
- def set_path(self, path):
- self.path = path
- self.dest = "%s/%s" % (self.path, self.name)
-
- def get_name(self):
- return self.name
-
- def set_name(self, name):
- if self.config:
- raise ValueError([_("Cannot modify Name")])
- self.name = name
- self.dest = "%s/%s" % (self.path, self.name)
-
- def set_security(self, val):
- self.config.set_security_opts(val)
-
- def add_network(self, val):
- self.config.add_network_opts(val)
-
- def get_security_dynamic(self):
- return self.config.get_security_dynamic()
-
- def get_security_label(self):
- return self.config.get_security_label()
-
- def set_security_label(self):
- if selinux is None:
- return
-
- if self.image or self.get_security_dynamic():
- return
-
- selabel = self.get_security_label()
- if selabel is None:
- raise ValueError([_("Missing security label configuration")])
- parts = selabel.split(":")
- selinux.chcon(self.dest, "system_u:object_r:%s:%s" % (
- self.get_file_type(), ":".join(parts[3:])), True)
-
- def gen_filesystems(self):
- if self.use_image:
- self.image = self.DEFAULT_IMAGE % self.get_name()
- mount = LibvirtSandbox.ConfigMountHostImage.new(self.image, self.dest,
- LibvirtGConfig.DomainDiskFormat.RAW)
- self.config.add_mount(mount)
-
- def fix_stat(self, f):
- try:
- s = os.stat(f)
- path = "%s%s" % (self.dest, f)
- os.chown(path, s.st_uid, s.st_gid)
- os.chmod(path, s.st_mode)
- except OSError as e:
- if not e.errno == errno.ENOENT:
- raise
-
- def fix_protection(self):
- l = len(self.dest)
- for root, dirs, files in os.walk(self.dest):
- for f in files:
- dest = root + "/" + f
- self.fix_stat(dest[l:])
- for d in dirs:
- dest = root + "/" + d
- self.fix_stat(dest[l:])
-
- def makedirs(self, d):
- try:
- path = "%s%s" % (self.dest, d)
- os.makedirs(path)
- except OSError as e:
- if not e.errno == errno.EEXIST:
- raise
-
- def makefile(self, f):
- self.makedirs(os.path.dirname(f))
- try:
- path = "%s%s" % (self.dest, f)
- fd=open(path, "w")
- fd.close()
- except OSError as e:
- if not e.errno == errno.EEXIST:
- raise
-
- def umount(self):
- p = Popen(["/bin/umount", self.dest])
- p.communicate()
- if p.returncode and p.returncode != 0:
- raise OSError(_("Failed to unmount image %s from %s") % (self.image, self.dest))
-
- def create_image(self):
- fd = open(self.image, "w")
- fd.truncate(self.size)
- fd.close()
- p = Popen(["/sbin/mkfs","-F", "-t", "ext4", self.image],stdout=PIPE, stderr=PIPE)
- p.communicate()
- if p.returncode and p.returncode != 0:
- raise OSError(_("Failed to build image %s") % self.image )
-
- p = Popen(["/bin/mount", self.image, self.dest])
- p.communicate()
- if p.returncode and p.returncode != 0:
- raise OSError(_("Failed to mount image %s on %s") % (self.image, self.dest))
-
- def save_config(self):
- self.connect()
- context = self.context()
- context.define()
- sys.stdout.write(_("Created sandbox config %s\n") % get_config_path(self.name))
-
- def update_config(self):
- self.connect()
- context = self.context()
- context.undefine()
- context.define()
- sys.stdout.write(_("Re-created sandbox config %s\n") % get_config_path(self.name))
-
- def delete(self):
- self.connect()
- self.conn.fetch_domains(None)
- dom = self.conn.find_domain_by_name(self.name)
- if dom is not None:
- info = dom.get_info()
- if info.state == LibvirtGObject.DomainState.RUNNING:
- raise ValueError([_("Cannot delete running container")])
-
- # Not sure we should remove content
- if os.path.exists(self.dest):
- shutil.rmtree(self.dest)
-
- image = self.get_image_path()
- if os.path.exists(image):
- os.remove(image)
-
- context = self.context()
- context.undefine()
-
- def get_security_model(self):
- model = None
-
- # Make sure we have a connection
- self.connect()
-
- # Loop over the security models from the host capabilities
- # The first in "selinux" and "apparmor" will be the returned model
- # Those two models can't coexist on a machine
- configCaps = self.conn.get_capabilities()
- hostCaps = configCaps.get_host()
- secmodels = hostCaps.get_secmodels()
- for secmodel in secmodels:
- if secmodel.get_model() == "selinux":
- model = "selinux"
- break
- elif secmodel.get_model() == "apparmor":
- model = "apparmor"
- break
-
- return model
-
-
- def create(self):
- self.connect()
- if self.get_security_model() is not None and \
- self.config.get_security_dynamic() and not self.use_image:
- raise ValueError([_("Dynamic security label only supported for image based containers")])
- if self.uri != "lxc:///":
- self.config.set_shell(True)
- if not os.path.exists(self.dest):
- os.mkdir(self.dest)
-
- def connect(self):
- if not self.conn:
- self.conn=LibvirtGObject.Connection.new(self.uri)
- self.conn.open(None)
-
- def disconnect(self):
- if self.conn:
- self.conn.close()
- self.conn = None
-
- def context(self):
- return LibvirtSandbox.ContextService.new(self.conn, self.config)
-
- def add_bind_mount(self, source, dest):
- if self.image is None:
- mount = LibvirtSandbox.ConfigMountHostBind.new(source, dest)
- else:
- mount = LibvirtSandbox.ConfigMountGuestBind.new(source, dest)
- self.config.add_mount(mount)
-
- def add_ram_mount(self, dest, size):
- mount = LibvirtSandbox.ConfigMountRam.new(dest, size);
- self.config.add_mount(mount)
-
-class GenericContainer(Container):
- def __init__(self, name=None, uri = "lxc:///", path = Container.DEFAULT_PATH, config=None, create=False):
- Container.__init__(self, name, uri, path, config, create)
-
- if create:
- self.config = LibvirtSandbox.ConfigServiceGeneric.new(name)
-
- def gen_filesystems(self):
- Container.gen_filesystems(self)
- self.add_bind_mount(self.dest, self.path)
- self.add_mounts()
-
- def create_generic(self):
- Container.create(self)
- self.gen_filesystems()
-
- if self.image:
- self.create_image()
- self.umount()
- sys.stdout.write(_("Created sandbox container image %s\n") % self.image)
- else:
- sys.stdout.write(_("Created sandbox container dir %s\n") % self.dest)
- self.save_config()
-
- def create(self):
- try:
- self.create_generic()
- except Exception as e:
- try:
- self.delete()
- except Exception as e2:
- pass
- raise e
-
- def set_command(self, command):
- self.config.set_command(command)
-
-
-def is_template_unit(unit):
- return '@' in unit
-
-class SystemdContainer(Container):
- IGNORE_DIRS = [ "/var/run/", "/etc/logrotate.d/", "/etc/pam.d" ]
- DEFAULT_DIRS = [ "/etc", "/var" ]
- PROFILE_FILES = [ ".bashrc", ".bash_profile", ".profile" ]
- MACHINE_ID = "/etc/machine-id"
- HOSTNAME = "/etc/hostname"
- SYSVINIT_PATH = "/etc/rc.d"
- ANACONDA_WANTS_PATH = "/usr/lib/systemd/system/anaconda.target.wants"
- MULTI_USER_WANTS_PATH = "/usr/lib/systemd/system/multi-user.target.wants"
- SYSINIT_WANTS_PATH = "/usr/lib/systemd/system/sysinit.target.wants"
- SOCKET_WANTS_PATH = "/usr/lib/systemd/system/sockets.target.wants"
- MAKE_SYSTEM_DIRS = [ "/var/lib/dhclient", "/var/lib/dbus", "/var/log", "/var/spool", "/var/cache", "/var/tmp", "/var/lib/nfs/rpc_pipefs", SYSVINIT_PATH, "/lib/lsb" ]
- BIND_SYSTEM_DIRS = [ "/var", "/home", "/root", "/etc/systemd/system", "/etc/rc.d", "/usr/lib/systemd/system/basic.target.wants", "/usr/lib/systemd/system/local-fs.target.wants", ANACONDA_WANTS_PATH, MULTI_USER_WANTS_PATH, SYSINIT_WANTS_PATH, SOCKET_WANTS_PATH ]
- BIND_SYSTEM_FILES = [ MACHINE_ID, "/etc/fstab", HOSTNAME ]
- LOCAL_LINK_FILES = { SYSINIT_WANTS_PATH : [ "systemd-tmpfiles-setup.service" ] , SOCKET_WANTS_PATH : [ "dbus.socket", "systemd-journald.socket", "systemd-shutdownd.socket", "systemd-initctl.socket" ] }
-
- DEFAULT_UNIT = "/etc/systemd/system/%s_sandbox.service"
-
- def __init__(self, name=None, uri = "lxc:///", path = Container.DEFAULT_PATH, config=None, create=False, packages=[]):
- Container.__init__(self, name, uri, path, config, create)
- self.copy = False
- self.unit_file_list = []
- self.packages = packages
- if create:
- self.config = LibvirtSandbox.ConfigServiceSystemd.new(name)
- self.unitfile = None
- else:
- self.unitfile = self.get_unit_path()
-
- def follow_units(self):
- unitst=""
- for i, src in self.unit_file_list:
- unitst += "ReloadPropagatedFrom=%s\n" % i
-
- return unitst
-
- def get_unit_path(self, name = None):
- if not name:
- name = self.get_name()
- return self.DEFAULT_UNIT % name
-
- def set_unit_file_list(self, unit_file_list):
- self.unit_file_list = unit_file_list
-
- def get_sandboxed_service(self):
- return self.unit_file_list[0][0].split(".")[0]
-
- def create_system_unit(self):
- self.unitfile = self.get_unit_path()
- unit = r"""
-[Unit]
-Description=Secure Sandbox Container %(NAME)s
-Requires=libvirtd.service
-After=libvirtd.service
-%(FOLLOW)s
-[Service]
-Type=simple
-ExecStart=/usr/libexec/virt-sandbox-service-util -c %(URI)s -s %(NAME)s
-ExecReload=/usr/bin/virt-sandbox-service -c %(URI)s reload -u %(RELOAD)s %(NAME)s
-ExecStop=/usr/bin/virsh -c %(URI)s destroy %(NAME)s
-
-[Install]
-WantedBy=multi-user.target
-""" % { 'NAME':self.name,
- 'FOLLOW':self.follow_units(),
- 'RELOAD': " -u ".join(map(lambda x: x[0], self.unit_file_list)),
- 'URI': self.uri,
- }
-
- fd = open(self.unitfile, "w")
- fd.write(unit)
- fd.close()
- if selinux is not None:
- selinux.restorecon(self.unitfile)
- sys.stdout.write(_("Created unit file %s\n") % self.unitfile)
-
- def add_dir(self, newd):
- if newd in self.all_dirs:
- return
- for ignd in self.IGNORE_DIRS:
- if newd.startswith(ignd):
- return
- for defd in self.DEFAULT_DIRS:
- if newd.startswith(defd):
- self.all_dirs.append(newd)
- tmp_dirs = []
- for d in self.dirs:
- if newd.startswith(d):
- return
- if not d.startswith(newd):
- tmp_dirs.append(d)
- self.dirs = tmp_dirs
- self.dirs.append(newd)
- break;
-
- def add_file(self, newf):
- if newf in self.files:
- return
- for d in self.IGNORE_DIRS:
- if newf.startswith(d):
- return
- for d in self.DEFAULT_DIRS:
- if newf.startswith(d):
- self.files.append(newf)
- break;
-
- def get_name(self):
- if self.config:
- return self.config.get_name()
- raise ValueError([_("Name not configured")])
-
- def set_copy(self, copy):
- self.copy = copy
-
- def get_security_dynamic(self):
- return self.config.get_security_dynamic()
-
- def extract_rpms(self):
- self.all_dirs = []
- self.dirs = []
- self.files = []
-
- self.ts = rpm.ts()
-
- nb_packages = 0
- for u, src in self.unit_file_list:
- rpm_name = self.get_rpm_for_unit(src)
- if rpm_name:
- self.extract_rpm(rpm_name)
- nb_packages += 1
-
- for package in self.packages:
- self.extract_rpm(package)
- nb_packages += 1
-
- if nb_packages == 0:
- raise ValueError([_("Cannot autodetect the package for unit files, please use --package")])
-
- def split_filename(self, filename):
- if filename[-4:] == '.rpm':
- filename = filename[:-4]
-
- archIndex = filename.rfind('.')
- arch = filename[archIndex+1:]
-
- relIndex = filename[:archIndex].rfind('-')
- rel = filename[relIndex+1:archIndex]
-
- verIndex = filename[:relIndex].rfind('-')
- ver = filename[verIndex+1:relIndex]
-
- epochIndex = filename.find(':')
- if epochIndex == -1:
- epoch = ''
- else:
- epoch = filename[:epochIndex]
-
- name = filename[epochIndex + 1:verIndex]
- return name, ver, rel, epoch, arch
-
- def get_rpm_for_unit(self, unitfile):
- mi = self.ts.dbMatch(rpm.RPMTAG_BASENAMES, unitfile)
- try:
- h = next(mi);
- except StopIteration:
- return None
- return h['name']
-
-
- def extract_rpm(self, rpm_name):
- mi = self.ts.dbMatch('name', rpm_name)
- try:
- h = next(mi);
- except StopIteration:
- raise ValueError([_("Cannot find package named %s") % rpm_name])
-
- for fentry in h.fiFromHeader():
- fname = fentry[0]
-
- if os.path.isdir(fname):
- self.add_dir(fname)
- if os.path.isfile(fname):
- self.add_file(fname)
-
- srcrpm = str(h[rpm.RPMTAG_SOURCERPM], encoding='utf-8')
- srcrpmbits = self.split_filename(srcrpm)
-
- if srcrpmbits[0] == str(h[rpm.RPMTAG_NAME], encoding='utf-8'):
- return
-
- mi = self.ts.dbMatch(rpm.RPMTAG_NAME, srcrpmbits[0])
- try:
- h = next(mi);
- except StopIteration:
- raise ValueError([_("Cannot find base package %s") % srcrpmbits[0]])
-
- for fentry in h.fiFromHeader():
- fname = fentry[0]
-
- if os.path.isdir(fname):
- self.add_dir(fname)
- if os.path.isfile(fname):
- self.add_file(fname)
-
- def gen_hostname(self):
- fd=open(self.dest + self.HOSTNAME, "w")
- fd.write("%s\n" % self.name )
- fd.close()
-
- def gen_machine_id(self):
- uuid_fd = open("/proc/sys/kernel/random/uuid")
- uuid = uuid_fd.read().replace("-","").rstrip()
- uuid_fd.close()
- self.config.set_uuid(uuid)
- fd=open(self.dest + self.MACHINE_ID, "w")
- fd.write("%s\n" % uuid)
- fd.close()
-
- if not self.use_image:
- # Link /var/log/journal within the container to /var/log/journal/UUID
- # on host. This will allow the hosts journalctl to easily read
- # containers journal information.
- jdir = "/var/log/journal/"
- jpath = jdir + uuid
- if not os.path.exists(self.dest + jpath):
- os.makedirs(self.dest + jpath)
- if not os.path.exists(jdir):
- os.makedirs(jdir)
-
- os.symlink(self.dest + jpath, jpath)
-
- def gen_filesystems(self):
- Container.gen_filesystems(self)
- # 10 MB /run
- mount = LibvirtSandbox.ConfigMountRam.new("/run", 10 * 1024 * 1024);
- self.config.add_mount(mount)
-
- # 100 MB /tmp
- mount = LibvirtSandbox.ConfigMountRam.new("/tmp", 100 * 1024 * 1024);
- self.config.add_mount(mount)
-
- # 100 MB /tmp
- mount = LibvirtSandbox.ConfigMountRam.new("/dev/shm", 100 * 1024 * 1024);
- self.config.add_mount(mount)
-
- for d in self.BIND_SYSTEM_DIRS:
- if d != "/var" and os.path.exists(d):
- source = "%s%s" % ( self.dest, d)
- self.add_bind_mount(source, d)
-
- for f in self.BIND_SYSTEM_FILES:
- if os.path.exists(f):
- source = "%s%s" % ( self.dest, f)
- self.add_bind_mount(source, f)
-
- for d in self.dirs:
- found = False
- # Dont add dirs whos parents are in SYSTEM_DIRS
- for s in self.BIND_SYSTEM_DIRS:
- if d.startswith(s):
- found = True
- break
- if not found:
- source = "%s%s" % ( self.dest, d)
- self.add_bind_mount(source, d)
-
- # /var contains the mounted image if there is an image: should be the
- # last thing to mount
- self.add_bind_mount("%s/var" % self.dest, "/var")
- self.add_mounts()
-
- def get_expanded_unit_template(self, unit):
- return unit.replace('@', '@' + self.name)
-
- def create_container_unit(self, src, dest, unit):
- if is_template_unit(unit):
- shutil.copy(src, dest + "/" + unit)
- unit = self.get_expanded_unit_template(unit)
- os.symlink(src, dest + "/" + unit)
-
- dropin_dir = "%s/%s.d" % (dest, unit)
- if not os.path.exists(dropin_dir):
- os.mkdir(dropin_dir)
-
- fd = open(dropin_dir + "/virt-sandbox.conf", "w")
- fd.write("""; file placed here by virt-sandbox-service
-[Service]
-PrivateTmp=false
-PrivateNetwork=false
-""" )
- fd.close()
-
- def gen_content(self):
- if self.copy:
- for d in self.dirs:
- copydirtree(d, "%s%s" % (self.dest, d))
- for f in self.files:
- self.makedirs(os.path.dirname(f))
- shutil.copy(f, "%s%s" % (self.dest, f))
- else:
- for d in self.all_dirs:
- self.makedirs(d)
- for f in self.files:
- self.makedirs(os.path.dirname(f))
- self.makefile(f)
-
- for d in self.BIND_SYSTEM_DIRS + self.MAKE_SYSTEM_DIRS:
- self.makedirs(d)
-
- for f in self.BIND_SYSTEM_FILES:
- self.makefile(f)
-
- destpath = self.dest + self.SYSVINIT_PATH
- for i in range(7):
- os.mkdir(destpath+("/rc%s.d" % i))
-
- # Copy both /etc/rc.d/init.d/functions and /lib/lsb/init-functions, even
- # though the latter is the one recommended
- if os.path.exists(self.SYSVINIT_PATH + "/init.d/functions"):
- os.mkdir(destpath+"/init.d")
- shutil.copy(self.SYSVINIT_PATH + "/init.d/functions" , destpath + "/init.d")
-
- if os.path.exists("/lib/lsb/init-functions"):
- shutil.copy("/lib/lsb/init-functions" , self.dest + "/lib/lsb/")
-
- self.gen_machine_id()
- self.gen_hostname()
-
- for k in self.LOCAL_LINK_FILES:
- for d in self.LOCAL_LINK_FILES[k]:
- src = "../%s" % ( d)
- dest = "%s%s/%s" % ( self.dest, k, d)
- os.symlink(src,dest)
-
- unitdir = "/etc/systemd/system"
- tgtdir = unitdir + "/multi-user.target.wants"
-
- self.makedirs(unitdir)
- self.makedirs(tgtdir)
- os.symlink("/run", self.dest + "/var/run")
-
- for i, src in self.unit_file_list:
- self.create_container_unit(src, self.dest + unitdir, i)
- if is_template_unit(i):
- i = self.get_expanded_unit_template(i)
- os.symlink(src, self.dest + tgtdir + "/" + i)
-
- tgtfile = unitdir + "/multi-user.target"
- try:
- fd = open(self.dest + tgtfile, "w")
- fd.write("[Unit]\n")
- fd.write("Description=Sandbox multi-user target\n")
- fd.close()
- except OSError as e:
- if not e.errno == errno.EEXIST:
- raise
-
- for p in self.PROFILE_FILES:
- profile = "/etc/skel/" + p
- if os.path.exists(profile):
- shutil.copy(profile, self.dest + "/root/")
-
- self.fix_protection()
-
- def delete(self):
- try:
- uuid = self.config.get_uuid()
- if uuid is not None:
- jpath = "/var/log/journal/" + uuid
- if os.path.lexists(jpath):
- os.remove(jpath)
- except Exception as e:
- sys.stderr.write("%s: %s\n" % (sys.argv[0], e))
- sys.stderr.flush()
-
- Container.delete(self)
-
- if self.unitfile and os.path.exists(self.unitfile):
- p = Popen(["/usr/bin/systemctl","disable", self.unitfile],stdout=PIPE, stderr=PIPE)
- p.communicate()
- if p.returncode and p.returncode != 0:
- raise OSError(_("Failed to disable %s unit file") % self.unitfile)
- os.remove(self.unitfile)
-
- def create_systemd(self):
- self.extract_rpms()
- Container.create(self)
- self.gen_filesystems()
- if self.image:
- self.create_image()
- self.gen_content()
- self.umount()
- sys.stdout.write(_("Created sandbox container image %s\n") % self.image)
- else:
- self.gen_content()
- sys.stdout.write(_("Created sandbox container dir %s\n") % self.dest)
- self.set_security_label()
- self.create_system_unit()
- self.config.set_boot_target("multi-user.target")
- self.save_config()
-
- def create(self):
- if os.path.exists(self.dest):
- raise OSError(_("%s already exists") % self.dest)
-
- try:
- self.create_systemd()
- except Exception as e:
- try:
- self.delete()
- except Exception as e2:
- sys.stderr.write("Cleanup failed: %s\n" % str(e2))
- raise
-
- def reload(self, unitfiles):
- class Args:
- command = []
- noseclabel = None
- name = self.name
- uri = self.uri
- args = Args()
- args.command = [ "systemctl", "reload" ] + map(lambda x: x[0], unitfiles)
- execute(args)
-
-MB = int(1000000)
-
-def delete(args):
- config = read_config(args.name)
- if config is None:
- sys.stderr.write("Sandbox '%s' does not exist\n" % args.name)
- sys.exit(1)
-
- if isinstance(config, gi.repository.LibvirtSandbox.ConfigServiceGeneric):
- container = GenericContainer(uri=args.uri, config = config)
- else:
- container = SystemdContainer(uri=args.uri, config = config)
- container.set_path(args.path)
- container.delete()
-
-def create(args):
- if len(args.command) > 0 and len(args.unitfiles) > 0:
- raise ValueError([_("Commands cannot be specified with unit files")])
-
- if len(args.command) == 0 and len(args.unitfiles) == 0:
- raise ValueError([_("You must specify a command or a unit file")])
-
- if args.packages and len(args.unitfiles) != 1:
- raise ValueError([_("Option --package cannot be used without a unit file")])
-
- if len(args.command) > 0:
- container = GenericContainer(name = args.name, uri=args.uri, create = True)
- container.set_command(args.command)
- else:
- container = SystemdContainer(name = args.name, uri=args.uri, create = True, packages = args.packages)
- container.set_copy(args.copy)
- container.set_unit_file_list(args.unitfiles)
- for net in args.network:
- container.add_network(net)
- if args.security:
- container.set_security(args.security)
- container.set_uid(args.uid)
- if not args.homedir:
- args.homedir = pwd.getpwuid(args.uid).pw_dir
- container.set_homedir(args.homedir)
- if not args.username:
- args.username = pwd.getpwuid(args.uid).pw_name
- container.set_username(args.username)
- if not args.gid:
- args.gid = pwd.getpwuid(args.uid).pw_gid
- container.set_gid(args.gid)
- container.set_path(args.path)
- container.set_file_type(args.file_type)
- container.set_mounts(args.mounts)
- if args.imagesize:
- container.set_image(args.imagesize)
-
- container.create()
-
-def usage(parser, msg):
- parser.print_help()
-
- sys.stderr.write("\n%s\n" % msg)
- sys.stderr.flush()
- sys.exit(1)
-
-def sandbox_reload(args):
- config = read_config(args.name)
- if isinstance(config, gi.repository.LibvirtSandbox.ConfigServiceGeneric):
- raise ValueError([_("Generic Containers do not support reload")])
- container = SystemdContainer(uri = args.uri, config = config)
- container.reload(args.unitfiles)
-
-def connect(args):
- if args.uri == "lxc:///":
- class Args:
- command = []
- noseclabel = None
- name = args.name
- uri = args.uri
-
- args = Args()
- args.command = [ "/bin/sh" ]
- execute(args)
- return
-
- print ("""\
-Connected to %s.
-Type 'Ctrl + ]' to detach from the console.
-""" % ( args.name ))
- os.execl("/usr/libexec/virt-sandbox-service-util",
- "virt-sandbox-service-util",
- "-c", args.uri,
- "-a", args.name)
-
-#
-# Search Path for command to execute within the container.
-#
-def fullpath(cmd):
- for i in [ "/", "./", "../" ]:
- if cmd.startswith(i):
- return cmd
- for i in os.environ["PATH"].split(':'):
- f = "%s/%s" % (i, cmd)
- if os.access(f, os.X_OK):
- return f
- return cmd
-
-def execute(args):
- if args.uri != "lxc:///":
- raise ValueError([_("Can only execute commands inside of linux containers.")])
-
- myexec = [ "virsh", "-c", args.uri, "lxc-enter-namespace" ]
- if args.noseclabel:
- myexec.append("--noseclabel")
- myexec.extend([ args.name, "--", fullpath(args.command[0])] + args.command[1:])
- os.execv("/usr/bin/virsh", myexec)
-
-def clone(args):
- config = read_config(args.source)
- if isinstance(config, gi.repository.LibvirtSandbox.ConfigServiceGeneric):
- container = GenericContainer(uri=args.uri, config=config)
- else:
- container = SystemdContainer(uri=args.uri, config=config)
- newcontainer = None
-
- container.set_path(args.path)
-
- old_path = container.get_filesystem_path()
- new_path = container.get_filesystem_path(args.dest)
-
- if os.path.exists(new_path):
- raise OSError(_("%s already exists") % new_path)
-
- try:
- fd = open(container.get_config_path(),"r")
- recs = fd.read()
- fd.close()
-
- newrec = recs.replace(old_path + "/", new_path + "/")
- newrec = newrec.replace("name=" + args.source, "name=" + args.dest)
- old_image_path = container.get_image_path()
- if os.path.exists(old_image_path):
- new_image_path = container.get_image_path(args.dest)
- newrec = newrec.replace(old_image_path, new_image_path)
- shutil.copy(old_image_path, new_image_path)
- sys.stdout.write(_("Created sandbox container image %s\n") % new_image_path)
- os.mkdir(new_path)
- else:
- copydirtree(old_path, new_path)
- sys.stdout.write(_("Created sandbox container dir %s\n") % new_path)
-
- if isinstance(config, gi.repository.LibvirtSandbox.ConfigServiceGeneric):
- newcontainer = GenericContainer(name=args.dest, uri=args.uri, create=True)
- newcontainer.set_path(args.path)
- else:
- fd = open(container.get_unit_path())
- recs = fd.read()
- fd.close()
-
- new_unit = container.get_unit_path(args.dest)
- fd = open(new_unit, "wx")
- fd.write(recs.replace(args.source, args.dest))
- fd.close()
-
- sys.stdout.write(_("Created unit file %s\n") % new_unit)
-
- config = LibvirtSandbox.Config.load_from_data(newrec)
- newcontainer = SystemdContainer(config=config, uri=args.uri)
- newcontainer.set_path(args.path)
- newcontainer.gen_machine_id()
- newcontainer.gen_hostname()
-
- if args.security:
- newcontainer.set_security(args.security)
- newcontainer.set_security_label()
- newcontainer.save_config()
- except Exception as e:
- if newcontainer is not None:
- newcontainer.delete()
- raise
-
-
-def upgrade_config_legacy(path):
- config = LibvirtSandbox.Config.load_from_path(path)
-
- if isinstance(config, gi.repository.LibvirtSandbox.ConfigServiceGeneric):
- container = GenericContainer(uri=args.uri, config=config)
- else:
- container = SystemdContainer(uri=args.uri, config=config)
-
- fd = open(container.get_unit_path())
- unitfile = fd.read()
- fd.close()
-
- unitfile = unitfile.replace("/usr/bin/virt-sandbox-service start",
- "/usr/libexec/virt-sandbox-service-util -c lxc:/// -s")
- unitfile = unitfile.replace("/usr/bin/virt-sandbox-service reload",
- "/usr/bin/virt-sandbox-service -c lxc:/// reload")
- unitfile = unitfile.replace("/usr/bin/virt-sandbox-service stop",
- "/usr/bin/virsh -c lxc:/// destroy")
-
- unitfile = re.sub("WantedBy=.*\.target",
- "WantedBy=multi-user.target",
- unitfile)
-
- os.remove(container.get_unit_path())
- fd = open(container.get_unit_path(), "wx")
- fd.write(unitfile)
- fd.close()
-
- sys.stdout.write(_("Created unit file %s\n") %
- container.get_unit_path())
-
- # Create new config file + libvirt persistent XML config
- container.save_config()
- # Kill legacy config file
- os.remove(path)
-
-
-def upgrade_config_current(path):
- config = LibvirtSandbox.Config.load_from_path(path)
-
- if isinstance(config, gi.repository.LibvirtSandbox.ConfigServiceGeneric):
- container = GenericContainer(uri=args.uri, config=config)
- else:
- container = SystemdContainer(uri=args.uri, config=config)
-
- # Create new config file + libvirt persistent XML config
- container.update_config()
-
-
-def upgrade_config(args):
- newconfigfile = get_config_path(args.name)
- oldconfigfile = get_legacy_config_path(args.name)
- if os.path.exists(oldconfigfile):
- upgrade_config_legacy(oldconfigfile)
- elif os.path.exists(newconfigfile):
- upgrade_config_current(newconfigfile)
- else:
- sys.stderr.write("Sandbox '%s' does not exist\n" % args.name)
- sys.exit(1)
-
-
-def upgrade_filesystem(args):
- # This is where we'd look at RPM DB and upgrade the
- # filesystem with new info for the unit files
- pass
-
-# This function must be capable of reading configs created by
-# old releases and "fixing" them to work with the new release
-def upgrade(args):
- upgrade_config(args)
- upgrade_filesystem(args)
-
-import argparse
-class AddMount(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- newval = getattr(namespace, self.dest)
- if not newval:
- newval = []
- for v in values:
- newval.append(v)
- setattr(namespace, self.dest, newval)
-
-class SizeAction(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- setattr(namespace, self.dest, int(values))
-
-class CheckUnit(argparse.Action):
- def __call__(self, parser, namespace, value, option_string=None):
- def check_unit(unit):
- src = "/etc/systemd/system/" + unit
- if os.path.exists(src):
- return src
- src = "/usr/lib/systemd/system/" + unit
- if os.path.exists(src):
- return src
- return None
- src = check_unit(value)
- if not src:
- src = check_unit(value + ".service")
- if src:
- value = value + ".service"
- else:
- raise OSError(_("Requested unit %s does not exist") % value)
-
- unitfiles = getattr(namespace, self.dest)
- if unitfiles:
- unitfiles.append((value, src))
- else:
- unitfiles = [ (value, src) ]
- setattr(namespace, self.dest, unitfiles)
-
-class SetNet(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- nets = getattr(namespace, self.dest)
- if nets:
- nets.append(values)
- else:
- nets = [values]
- setattr(namespace, self.dest, nets)
-
-class CheckPackage(argparse.Action):
- def __call__(self, parser, namespace, value, option_string=None):
- nb_rpm = len(rpm.TransactionSet().dbMatch('name', value))
- if nb_rpm == 0:
- raise OSError(_("Cannot find %s rpm") % value)
- elif nb_rpm > 1:
- raise OSError(_("%s rpm is installed more than once") % value)
- packages = getattr(namespace, self.dest)
- if packages:
- packages.append(value)
- else:
- packages = [ value ]
- setattr(namespace, self.dest, packages)
-
-def requires_name(parser):
- parser.add_argument("name",
- help=_("name of the sandbox container"))
-
-def default_security_opts():
- if selinux is None:
- return None
-
- # XXX vary per URI for kvm/qemu/lxc.
- # XXX generate a random category
- return "static,label=system_u:system_r:svirt_lxc_net_t:s0"
-
-def gen_create_args(subparser):
- parser = subparser.add_parser("create",
- help=_("Create a sandbox container."))
-
- parser.add_argument("-C", "--copy", default=False,
- action="store_true",
- help=_("copy content from the hosts /etc and /var directories that will be mounted within the sandbox"))
-
- parser.add_argument("-f", "--filetype", dest="file_type",
- default=c.get_file_type(),
- help=_("SELinux file type to assign to content within the sandbox. Default: %s") % c.get_file_type())
- parser.add_argument("--homedir", dest="homedir",
- help=_("Specify the homedir for the container. Default: UID homedir."))
- parser.add_argument("-G", "--gid", dest="gid",
- default=None, type=int,
- help=_("Specify the login gid for the container. Default: login GID of the UID."))
- parser.add_argument("-i", "--imagesize", dest="imagesize", default = None,
- action=SizeAction,
- help=_("create image of this many megabytes."))
- parser.add_argument("-m", "--mount", dest="mounts",default=[], nargs="*", action=AddMount,
- help=_("Mount a filesytem in the sandbox"))
- parser.add_argument("-N", "--network", dest="network",
- action=SetNet, default=[],
- help=_("Specify the network configuration"))
- parser.add_argument("-p", "--path", dest="path", default=c.DEFAULT_PATH,
- help=_("select path to store sandbox content. Default: %s") % c.DEFAULT_PATH)
- parser.add_argument("-s", "--security", dest="security",
- default=default_security_opts(),
- help=_("Specify the security model configuration for the sandbox: Defaults to dynamic"))
- parser.add_argument("-u", "--unitfile",
- action=CheckUnit,
- dest="unitfiles", default=[],
- help=_("Systemd Unit file to run within the systemd sandbox container. Commands cannot be specified with unit files."))
- parser.add_argument("-P", "--package",
- action=CheckPackage,
- dest="packages", default=[],
- help=_("RPM package to be used in the container. Default: autodetected from unit files."))
- parser.add_argument("--username", dest="username",
- help=_("Specify the username for the container. Default: UID username."))
- parser.add_argument("-U", "--uid", dest="uid",
- default=os.getuid(),type=int,
- help=_("Specify the uid for the container: Default to current UID."))
-
- requires_name(parser)
- parser.add_argument("command", default=[], nargs="*",
- help=_("Command to run within the generic sandbox container. Commands cannot be specified with unit files."))
-
- parser.set_defaults(func=create)
-
-def gen_connect_args(subparser):
- parser = subparser.add_parser("connect",
- help=_("Connect to a sandbox container"))
- requires_name(parser)
- parser.set_defaults(func=connect)
-
-def gen_execute_args(subparser):
- parser = subparser.add_parser("execute",
- help=_("Execute a command within a sandbox container. Only available for lxc:///"))
- parser.add_argument("-N", "--noseclabel", dest="noseclabel",
- default=False, action="store_true",
- help=_("do not modify the label of the executable process. By default all commands execute with the label of the sandbox"))
- requires_name(parser)
- parser.add_argument("command", nargs="+",
- help=_("command to execute within the container"))
- parser.set_defaults(func=execute)
-
-def gen_reload_args(subparser):
- parser = subparser.add_parser("reload",
- help=_("Reload a running sandbox container"))
- parser.add_argument("-u", "--unitfile", required=True,
- action=CheckUnit, dest="unitfiles",
- help=_("Systemd Unit file to reload within the sandbox container"))
- requires_name(parser)
- parser.set_defaults(func=sandbox_reload)
-
-def gen_clone_args(subparser):
- parser = subparser.add_parser("clone",
- help=_("Clone an existing sandbox container"))
- parser.set_defaults(func=clone)
- parser.add_argument("-p", "--path", dest="path", default=c.DEFAULT_PATH,
- help=_("select path to copy sandbox content from/to. Default: %s") % c.DEFAULT_PATH)
- parser.add_argument("-s", "--security", dest="security",
- default=default_security_opts(),
- help=_("Specify the security model configuration for the sandbox: Defaults to dynamic"))
-
- parser.add_argument("source",
- help=_("source sandbox container name"))
- parser.add_argument("dest",
- help=_("dest name of the new sandbox container"))
-
-def gen_delete_args(subparser):
- parser = subparser.add_parser("delete",
- help=_("Delete a sandbox container"))
- parser.add_argument("-p", "--path", dest="path", default=c.DEFAULT_PATH,
- help=_("select path to delete sandbox content from. Default: %s") % c.DEFAULT_PATH)
- requires_name(parser)
- parser.set_defaults(func=delete)
-
-def gen_upgrade_args(subparser):
- parser = subparser.add_parser("upgrade",
- help=_("Upgrade the sandbox container"))
- requires_name(parser)
- parser.set_defaults(func=upgrade)
-
-if __name__ == '__main__':
- c = Container()
-
- parser = argparse.ArgumentParser(description='Sandbox Container Tool')
- parser.add_argument("-c", "--connect", required=False, dest="uri", default="lxc:///",
- help=_("libvirt connection URI to use (lxc:/// [default] or qemu:///session)"))
-
- subparser = parser.add_subparsers(help=_("commands"))
- gen_create_args(subparser)
- gen_clone_args(subparser)
- gen_connect_args(subparser)
- gen_delete_args(subparser)
- gen_execute_args(subparser)
- gen_reload_args(subparser)
- gen_upgrade_args(subparser)
-
- try:
- args = parser.parse_args()
- if args.uri[0:3] != "lxc":
- sys.stderr.write("%s: only lxc:/// URIs are currently supported\n" % sys.argv[0])
- sys.exit(1)
- if os.geteuid() != 0:
- sys.stderr.write("%s: lxc:/// URIs are only supported when run as root\n" % sys.argv[0])
- sys.exit(1)
- args.func(args)
- sys.exit(0)
- except KeyboardInterrupt as e:
- sys.exit(0)
- except ValueError as e:
- sys.stderr.write("%s: %s\n" % (sys.argv[0], e))
- sys.stderr.flush()
- sys.exit(1)
- except IOError as e:
- sys.stderr.write("%s: %s: %s\n" % (sys.argv[0], e.filename, e.strerror))
- sys.stderr.flush()
- sys.exit(1)
- except OSError as e:
- sys.stderr.write("%s: %s\n" % (sys.argv[0], e))
- sys.stderr.flush()
- sys.exit(1)
- except GLib.GError as e:
- sys.stderr.write("%s: %s\n" % (sys.argv[0], e))
- sys.stderr.flush()
- sys.exit(1)
diff --git a/bin/virt-sandbox-service-bash-completion.sh b/bin/virt-sandbox-service-bash-completion.sh
deleted file mode 100755
index a101f4a..0000000
--- a/bin/virt-sandbox-service-bash-completion.sh
+++ /dev/null
@@ -1,141 +0,0 @@
-# This file is part of libvirt-sandbox.
-#
-# Copyright (C) 2012-2013 Red Hat, Inc.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# systemd is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with systemd; If not, see <http://www.gnu.org/licenses/>.
-#
-# Authors: Dan Walsh <dwalsh(a)redhat.com>
-#
-__contains_word () {
- local word=$1; shift
- for w in $*; do [[ $w = $word ]] && return 0; done
- return 1
-}
-
-ALL_OPTS='-h --help'
-
-__get_all_unit_files () {
- systemctl list-unit-files --no-legend | cut -d' ' -f 1 | grep -v '@'
-}
-
-__get_all_containers () {
- virt-sandbox-service list
-}
-
-__get_all_running_containers () {
- virt-sandbox-service list --running
-}
-
-__get_all_file_types () {
- seinfo -afile_type -x 2>/dev/null | tail -n +2
-}
-
-_virt_sandbox_service () {
- local command=${COMP_WORDS[1]}
- local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
- local verb comps
- local -A VERBS=(
- [CONNECT]='connect'
- [CREATE]='create'
- [DELETE]='delete'
- [RELOAD]='reload'
- [START]='start'
- [EXECUTE]='execute'
- [STOP]='stop'
- [LIST]='list'
- )
- local -A OPTS=(
- [ALL]='-h --help'
- [CREATE]='-C --copy -f --filetype -G --gid -i --imagesize --homedir -m --mount -N --network -p --path -s --security -u --unitfile --username -U -uid'
- [LIST]='-r --running'
- [RELOAD]='-u --unitfile'
- [EXECUTE]='-N --noseclabel'
- )
-
- for ((i=0; $i <= $COMP_CWORD; i++)); do
- if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
- ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then
- verb=${COMP_WORDS[i]}
- break
- fi
- done
-
- if test "$verb" = "" && test "$prev" = "virt-sandbox-service" ; then
- comps="${VERBS[*]}"
- COMPREPLY=( $(compgen -W "$comps" -- "$cur") )
- return 0
- elif test "$verb" == "list" ; then
- if test "$prev" = "-r" || test "$prev" = "--running" ; then
- return 0
- fi
- COMPREPLY=( $(compgen -W "${OPTS[ALL]} ${OPTS[LIST]} " -- "$cur") )
- return 0
- elif test "$verb" == "delete" ; then
- COMPREPLY=( $(compgen -W "${OPTS[ALL]} $( __get_all_containers ) " -- "$cur") )
- return 0
- elif test "$verb" == "start" ; then
- COMPREPLY=( $(compgen -W "${OPTS[ALL]} $( __get_all_containers ) " -- "$cur") )
- return 0
- elif test "$verb" == "stop" ; then
- COMPREPLY=( $(compgen -W "${OPTS[ALL]} $( __get_all_running_containers ) " -- "$cur") )
- return 0
- elif test "$verb" == "reload" ; then
- COMPREPLY=( $(compgen -W "${OPTS[ALL]} ${OPTS[RELOAD]} $( __get_all_running_containers ) " -- "$cur") )
- return 0
- elif test "$verb" == "connect" ; then
- COMPREPLY=( $(compgen -W "${OPTS[ALL]} $( __get_all_running_containers ) " -- "$cur") )
- return 0
- elif test "$verb" == "execute" ; then
- if test "$prev" = "execute"; then
- COMPREPLY=( $(compgen -W "${OPTS[ALL]} ${OPTS[EXECUTE]} $( __get_all_running_containers ) " -- "$cur") )
- else
- COMPREPLY=( $( compgen -c -- "$cur") )
- fi
- return 0
- elif test "$verb" == "create" ; then
- if test "$prev" = "-p" || test "$prev" = "--path" ; then
- COMPREPLY=( $( compgen -d -- "$cur") )
- compopt -o filenames
- return 0
- elif test "$prev" = "-u" || test "$prev" = "--unitfile" ; then
- COMPREPLY=( $(compgen -W "$( __get_all_unit_files ) " -- "$cur") )
- return 0
- elif test "$prev" = "-f" || test "$prev" = "--filetype" ; then
- COMPREPLY=( $(compgen -W "$( __get_all_file_types ) " -- "$cur") )
- return 0
- elif test "$prev" = "-s" || test "$prev" = "--security" ; then
- return 0
- elif test "$prev" = "-m" || test "$prev" = "--mount" ; then
- return 0
- elif test "$prev" = "-n" || test "$prev" = "--network" ; then
- return 0
- elif test "$prev" = "-i" || test "$prev" = "--imagesize" ; then
- return 0
- elif __contains_word "$command" ${VERBS[CREATE]} ; then
- COMPREPLY=( $(compgen -W "${OPTS[ALL]} ${OPTS[CREATE]}" -- "$cur") )
- return 0
- elif __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} ; then
- COMPREPLY=( $(compgen -W "${OPTS[ALL]}" -- "$cur") )
- return 0
- fi
- else
- if ! __contains_word "${prev}" ${VERBS[*]} &&
- ! __contains_word "${prev}" ${OPTS[*]}; then
- return 0
- fi
- fi
- COMPREPLY=( $(compgen -W "${OPTS[ALL]} $( __get_all_containers ) " -- "$cur") )
- return 0
-}
-complete -F _virt_sandbox_service virt-sandbox-service
diff --git a/bin/virt-sandbox-service-clone.pod b/bin/virt-sandbox-service-clone.pod
deleted file mode 100644
index e9d997b..0000000
--- a/bin/virt-sandbox-service-clone.pod
+++ /dev/null
@@ -1,100 +0,0 @@
-=head1 NAME
-
-virt-sandbox-service clone - clone an existing Secure container
-
-=head1 SYNOPSIS
-
-Clone a Security container
-
- virt-sandbox-service [-c URI] clone [-h] [-p PATH] [-s SECURITY-OPTS] SOURCE DEST
-
-=head1 DESCRIPTION
-
-virt-sandbox-service is used to manage secure sandboxed system services.
-These applications will be launched via libvirt and run within a virtualization
-technology such as LinuX Containers (LXC), or optionally QEMU/KVM. The
-container / virtual machines will be secured by SELinux and resource
-separated using cgroups.
-
-The clone command will clone the SOURCE security sandbox container into the DEST security sandbox container.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Display help message
-
-=item B<-c> URI, B<--connect URI>
-
-The connection URI for the hypervisor (currently only LXC URIs are
-supported).
-
-=item B<-p PATH>, B<--path PATH>
-
-Set path to copy container content from/to. This argument must match the value of
-the C<-p> arg given when creating the original source container.
-
-Default: C</var/lib/libvirt/filesystems>.
-
-=item B<-s SECURITY-OPTIONS>, B<--security=SECURITY-OPTIONS>
-
-Use alternative security options. SECURITY-OPTIONS is a set of key=val pairs,
-separated by commas. The following options are valid for SELinux
-
-=over 4
-
-=item dynamic
-
-Dynamically allocate an SELinux label, using the default base context.
-The default base context is system_u:system_r:svirt_lxc_net_t:s0 for LXC,
-system_u:system_r:svirt_t:s0 for KVM, system_u:system_r:svirt_tcg_t:s0
-for QEMU.
-
-=item dynamic,label=USER:ROLE:TYPE:LEVEL
-
-Dynamically allocate an SELinux label, using the base context
-USER:ROLE:TYPE:LEVEL, instead of the default base context.
-
-=item static,label=USER:ROLE:TYPE:LEVEL
-
-To set a completely static label. For example,
-static,label=system_u:system_r:svirt_t:s0:c412,c355
-
-=back
-
-=back
-
-=head1 EXAMPLE
-
-Execute /bin/sh in httpd1 container
-
- # virt-sandbox-service clone -s static,label=system_u:system_r:svirt_lxc_net_t:s0:c1,c2 httpd1 httpd2
-
-=head1 SEE ALSO
-
-C<libvirt(8)>, C<selinux(8)>, C<systemd(8)>, C<virt-sandbox-service(1)>
-
-=head1 FILES
-
-Container content will be stored in subdirectories of
-/var/lib/libvirt/filesystems, by default. You can manage the
-content in these directories outside of the container and
-processes within the container will see the content.
-
-=head1 AUTHORS
-
-Daniel Walsh <dwalsh(a)redhat.com>
-Daniel P. Berrange <dan(a)berrange.com>
-
-=head1 COPYRIGHT
-
-Copyright (C) 2011-2013 Red Hat, Inc.
-
-=head1 LICENSE
-
-virt-sandbox is distributed under the terms of the GNU LGPL v2+.
-This is free software; see the source for copying conditions.
-There is NO warranty; not even for MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE
diff --git a/bin/virt-sandbox-service-connect.pod b/bin/virt-sandbox-service-connect.pod
deleted file mode 100644
index cefa37a..0000000
--- a/bin/virt-sandbox-service-connect.pod
+++ /dev/null
@@ -1,59 +0,0 @@
-=head1 NAME
-
-virt-sandbox-service connect - Connect to a security container console
-
-=head1 SYNOPSIS
-
- virt-sandbox-service [-c URI] connect [-h] NAME
-
-=head1 DESCRIPTION
-
-virt-sandbox-service is used to manage secure sandboxed system services.
-These applications will be launched via libvirt and run within a virtualization
-technology such as LinuX Containers (LXC), or optionally QEMU/KVM. The
-container / virtual machines will be secured by SELinux and resource
-separated using cgroups.
-
-The connect command will connect to the security sandbox container console NAME.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Display help message
-
-=item B<-c URI>, B<--connect URI>
-
-The connection URI for the hypervisor (currently only LXC URIs are
-supported).
-
-=back
-
-=head1 EXAMPLE
-
-Connect to the in httpd1 container console
-
- # virt-sandbox-service connect httpd1
- #
-
-=head1 SEE ALSO
-
-C<libvirt(8)>, C<selinux(8)>, C<systemd(8)>, C<virt-sandbox-service(1)>
-
-=head1 AUTHORS
-
-Daniel Walsh <dwalsh(a)redhat.com>
-Daniel P. Berrange <dan(a)berrange.com>
-
-=head1 COPYRIGHT
-
-Copyright (C) 2011-2013 Red Hat, Inc.
-
-=head1 LICENSE
-
-virt-sandbox is distributed under the terms of the GNU LGPL v2+.
-This is free software; see the source for copying conditions.
-There is NO warranty; not even for MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE
diff --git a/bin/virt-sandbox-service-create.pod b/bin/virt-sandbox-service-create.pod
deleted file mode 100644
index d2f5fdb..0000000
--- a/bin/virt-sandbox-service-create.pod
+++ /dev/null
@@ -1,264 +0,0 @@
-=head1 NAME
-
-virt-sandbox-service create - Create a Security container
-
-=head1 SYNOPSIS
-
- virt-sandbox-service [-c URI] create [-h] [-C] [-f FILE_TYPE]
- [--homedir HOMEDIR] [-G GID] [-i IMAGESIZE]
- [[-m TYPE:DST=SRC ] ...]
- [-N NETWORK] [-p PATH] [-s SECURITY]
- [[-u UNITFILES] ...] [--username USERNAME]
- [-U UID] [[-P package] ... ]
- NAME -- COMMAND [ARG1 [ARG2...]]
-
-=head1 DESCRIPTION
-
-virt-sandbox-service is used to manage secure sandboxed system services.
-These applications will be launched via libvirt and run within a virtualization
-technology such as LinuX Containers (LXC), or optionally QEMU/KVM. The
-container / virtual machines will be secured by SELinux and resource
-separated using cgroups.
-
-The create command can setup a sandbox for running one or more systemd unit files.
-It can also setup a sandbox for running a command in an GenericContainer.
-Specify a unit file to create the SystemdContainer and the command to create an
-GenericContainer.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Display help message
-
-=item B<-c URI>, B<--connect URI>
-
-The connection URI for the hypervisor (currently only LXC URIs are
-supported).
-
-=item B<-u UNIT_FILE>, B<--unitfile UNIT_FILE>
-
-Name of the systemd unit file to be to run within the Systemd Container.
-Can be repeated if multiple unit files are required within the sandbox.
-Cannot be specified if you are using a COMMAND. If the unit file end
-with @, this will be considered as a template, and a instantiated
-systemd unit will be created, using the name of the container as a
-instance identifier.
-
-=item B<-C>, B<--copy>
-
-Copy content from /etc and /var directories that will be mounted within the container.
-
-=item B<-G GID>, B<--gid GID>
-
-Set login gid to use within the container.
-
-Default: C<Login GID of UID>.
-
-=item B<-f FILETYPE>, B<--filetype FILETYPE>
-
-Set SELinux file type to use within container.
-
-Default: C<svirt_lxc_file_t>.
-
-=item B<-p PATH>, B<--path PATH>
-
-Set path to store container content. NB if this argument is used when creating
-a container, the exact same argument must also be used when later cloning or
-deleting the container.
-
-Default: C</var/lib/libvirt/filesystems>.
-
-=item B<--homedir HOMEDIR>
-
-Set homedir path to use within container.
-
-Default: C<UID's Homedir>.
-
-=item B<-m TYPE:DST=SRC>, B<--mount TYPE:DST=SRC>
-
-Sets up a mount inside the sandbox at B<DST> backed by B<SRC>. The
-meaning of B<SRC> depends on the value of C<TYPE> specified:
-
-=over 4
-
-=item B<host-bind>
-
-If B<TYPE> is B<host-bind>, then B<SRC> is interpreted as the path
-to a directory on the host filesystem. If C<SRC> is the empty string,
-then a temporary (empty) directory is created on the host before
-starting the sandbox and deleted afterwards. The C<--include> option
-is useful for populating these temporary directories with copies of host
-files.
-
-=item B<host-image>
-
-If B<TYPE> is B<host-image>, then B<SRC> is interpreted as the path
-to a disk image file on the host filesystem. The image should be
-formatted with a filesystem that can be auto-detected by the sandbox,
-such as B<ext3>, B<ext4>, etc. The disk image itself should be a raw
-file, not qcow2 or any other special format
-
-=item B<guest-bind>
-
-If B<TYPE> is B<guest-bind>, then B<SRC> is interpreted as the path
-to another directory in the container filesystem.
-
-=item B<ram>
-
-If B<TYPE> is B<ram>, then B<SRC> is interpreted as specifying the
-size of the RAM disk in bytes. The suffix B<K>, B<KiB>, B<M>,
-B<MiB>, B<G>, B<GiB> can used to alter the units from bytes to a
-coarser level.
-
-=back
-
-Some examples
-
- -m host-bind:/tmp=/var/lib/sandbox/demo/tmp
- -m host-image:/=/var/lib/sandbox/demo.img
- -m guest-bind:/home=/tmp/home
- -m ram:/tmp=500M
-
-=item B<-N NETWORK-OPTIONS>, B<--network NETWORK-OPTIONS>
-
-Add a network interface to the sandbox. By default the sandbox will
-only have a loopback interface. This option allows for connectivity
-to the LAN in some manner. NETWORK-OPTIONS is a set of
-key=val pairs, separated by commas. The following options are valid
-
-=over 4
-
-=item dhcp
-
-Configure the network interface using dhcp. This key takes no value.
-No other keys may be specified. eg
-
- -N dhcp,source=default
- --network dhcp,source=lan
-
-where 'source' is the name of any libvirt virtual network.
-
-=item source=NETWORK
-
-Set the name of the network to connect the interface to. C<NETWORK>
-is the name of any libvirt virtual network. See also B<virsh net-list>
-
-=item mac=NN:NN:NN:NN:NN:NN
-
-Set the MAC address of the network interface, where each NN is a pair
-of hex digits.
-
-=item address=IP-ADDRESS/PREFIX%BROADCAST
-
-Configure the network interface with the static IPv4 or IPv6 address
-B<IP-ADDRESS>. The B<PREFIX> value is the length of the network
-prefix in B<IP-ADDRESS>. The optional B<BROADCAST> parameter
-specifies the broadcast address. Some examples
-
- address=192.168.122.1/24
- address=192.168.122.1/24%192.168.122.255
- address=2001:212::204:2/64
-
-=item route=IP-NETWORK/PREFIX%GATEWAY
-
-Configure the network interface with the static IPv4 or IPv6 route
-B<IP-NETWORK>. The B<PREFIX> value is the length of the network
-prefix in B<IP-NETWORK>. The B<GATEWAY> parameter specifies the
-address of the gateway for the route. Some examples
-
- route=192.168.122.255/24%192.168.1.1
-
-=back
-
-=item B<-s SECURITY-OPTIONS>, B<--security=SECURITY-OPTIONS>
-
-Use alternative security options. SECURITY-OPTIONS is a set of key=val pairs,
-separated by commas. The following options are valid for SELinux
-
-=over 4
-
-=item dynamic
-
-Dynamically allocate an SELinux label, using the default base context.
-The default base context is system_u:system_r:svirt_lxc_net_t:s0 for LXC,
-system_u:system_r:svirt_t:s0 for KVM, system_u:system_r:svirt_tcg_t:s0
-for QEMU.
-
-=item dynamic,label=USER:ROLE:TYPE:LEVEL
-
-Dynamically allocate an SELinux label, using the base context
-USER:ROLE:TYPE:LEVEL, instead of the default base context.
-
-=item static,label=USER:ROLE:TYPE:LEVEL
-
-To set a completely static label. For example,
-static,label=system_u:system_r:svirt_t:s0:c412,c355
-
-=back
-
-=item B<-i SIZE>, B<--image SIZE>
-
-Create file system image file of this size to store container content.
-
-=item B<-P PACKAGE>, B<--package PACKAGE>
-
-Package(s) to be used within the container.
-
-=item B<-U UID>, B<--uid UID>
-
-Set uid to use within container.
-
-Default: C<CURRENT UID>.
-
-=item B<--username USERNAME>
-
-Set username to use within container.
-
-Default: C<UID's Username>.
-
-=back
-
-=head1 EXAMPLE
-
-Create httpd1 Systemd container
-
- # virt-sandbox-service create -C -u httpd.service httpd1
- Created container dir /var/lib/libvirt/filesystems/httpd1
- Created sandbox config /etc/libvirt-sandbox/services/httpd1/config/sandbox.cfg
- Created unit file /etc/systemd/system/httpd(a)httpd1.service
-
-Create foobar1 Generic container
-
- # virt-sandbox-service create -U 1234 foobar1 -- /usr/bin/foobar -a -b
- Created container dir /var/lib/libvirt/filesystems/foobar1
- Created sandbox config /etc/libvirt-sandbox/services/foobar1/config/sandbox.cfg
-
-=head1 SEE ALSO
-
-C<libvirt(8)>, C<selinux(8)>, C<systemd(8)>, C<virt-sandbox-service(1)>
-
-=head1 FILES
-
-Container content will be stored in subdirectories of
-C</var/lib/libvirt/filesystems>, by default. You can manage the
-content in these directories outside of the container and
-processes within the container will see the content.
-
-=head1 AUTHORS
-
-Daniel Walsh <dwalsh(a)redhat.com>
-Daniel P. Berrange <dan(a)berrange.com>
-
-=head1 COPYRIGHT
-
-Copyright (C) 2011-2013 Red Hat, Inc.
-
-=head1 LICENSE
-
-virt-sandbox is distributed under the terms of the GNU LGPL v2+.
-This is free software; see the source for copying conditions.
-There is NO warranty; not even for MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE
diff --git a/bin/virt-sandbox-service-delete.pod b/bin/virt-sandbox-service-delete.pod
deleted file mode 100644
index 3b17b97..0000000
--- a/bin/virt-sandbox-service-delete.pod
+++ /dev/null
@@ -1,65 +0,0 @@
-=head1 NAME
-
-virt-sandbox-service delete - Delete a security container
-
-=head1 SYNOPSIS
-
- virt-sandbox-service [-c URI] delete [-h] [-p PATH] NAME
-
-=head1 DESCRIPTION
-
-virt-sandbox-service is used to manage secure sandboxed system services.
-These applications will be launched via libvirt and run within a virtualization
-technology such as LinuX Containers (LXC), or optionally QEMU/KVM. The
-container / virtual machines will be secured by SELinux and resource
-separated using cgroups.
-
-The delete command will delete a sandbox container.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Display help message
-
-=item B<-c URI>, B<--connect URI>
-
-The connection URI for the hypervisor (currently only LXC URIs are
-supported).
-
-=item B<-p PATH>, B<--path PATH>
-
-Set path to delete container content from. This argument must match the value of
-the C<-p> arg given when creating the original source container.
-
-Default: C</var/lib/libvirt/filesystems>.
-
-=back
-
-=head1 EXAMPLE
-
-Delete the httpd1 container
-
- # virt-sandbox-service delete httpd1
-
-=head1 SEE ALSO
-
-C<libvirt(8)>, C<selinux(8)>, C<systemd(8)>, C<virt-sandbox-service(1)>
-
-=head1 AUTHORS
-
-Daniel Walsh <dwalsh(a)redhat.com>
-Daniel P. Berrange <dan(a)berrange.com>
-
-=head1 COPYRIGHT
-
-Copyright (C) 2011-2013 Red Hat, Inc.
-
-=head1 LICENSE
-
-virt-sandbox is distributed under the terms of the GNU LGPL v2+.
-This is free software; see the source for copying conditions.
-There is NO warranty; not even for MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE
diff --git a/bin/virt-sandbox-service-execute.pod b/bin/virt-sandbox-service-execute.pod
deleted file mode 100644
index 62771eb..0000000
--- a/bin/virt-sandbox-service-execute.pod
+++ /dev/null
@@ -1,71 +0,0 @@
-=head1 NAME
-
-virt-sandbox-service execute - execute commands inside Secure container
-
-=head1 SYNOPSIS
-
-Execute a command within a security container
-
- virt-sandbox-service [-c URI] execute [-h] [-N] NAME -- COMMAND [ARG1 [ARG2...]]
-
-=head1 DESCRIPTION
-
-virt-sandbox-service is used to manage secure sandboxed system services.
-These applications will be launched via libvirt and run within a virtualization
-technology such as LinuX Containers (LXC), or optionally QEMU/KVM. The
-container / virtual machines will be secured by SELinux and resource
-separated using cgroups.
-
-The execute subcommand is used to execute commands within an already running container.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Display help message
-
-=item B<-c> URI, B<--connect URI>
-
-The connection URI for the hypervisor (currently only LXC URIs are
-supported).
-
-=item B<-N>, B<--noseclabel>
-
-Execute command within the container.
-
-=back
-
-=head1 EXAMPLE
-
-Execute /bin/sh in httpd1 container
-
- # virt-sandbox-service execute httpd1 -- /bin/sh
-
-=head1 SEE ALSO
-
-C<libvirt(8)>, C<selinux(8)>, C<systemd(8)>, C<virt-sandbox-service(1)>
-
-=head1 FILES
-
-Container content will be stored in subdirectories of
-/var/lib/libvirt/filesystems, by default. You can manage the
-content in these directories outside of the container and
-processes within the container will see the content.
-
-=head1 AUTHORS
-
-Daniel Walsh <dwalsh(a)redhat.com>
-Daniel P. Berrange <dan(a)berrange.com>
-
-=head1 COPYRIGHT
-
-Copyright (C) 2011-2013 Red Hat, Inc.
-
-=head1 LICENSE
-
-virt-sandbox is distributed under the terms of the GNU LGPL v2+.
-This is free software; see the source for copying conditions.
-There is NO warranty; not even for MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE
diff --git a/bin/virt-sandbox-service-reload.pod b/bin/virt-sandbox-service-reload.pod
deleted file mode 100644
index fe6fbcc..0000000
--- a/bin/virt-sandbox-service-reload.pod
+++ /dev/null
@@ -1,63 +0,0 @@
-=head1 NAME
-
-virt-sandbox-service reload - Reload a security container
-
-=head1 SYNOPSIS
-
- virt-sandbox-service [-c URI] reload [-h] -u UNIT_FILE NAME
-
-=head1 DESCRIPTION
-
-virt-sandbox-service is used to manage secure sandboxed system services.
-These applications will be launched via libvirt and run within a virtualization
-technology such as LinuX Containers (LXC), or optionally QEMU/KVM. The
-container / virtual machines will be secured by SELinux and resource
-separated using cgroups.
-
-The reload command will reload a sandbox container. This is used when software is updated outside of a container and processes within the container need to reload or restart. For example, if you update your httpd software, and you had a running container that was using the httpd service, systemd would send the reload to the container.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Display help message
-
-=item B<-c URI>, B<--connect URI>
-
-The connection URI for the hypervisor (currently only LXC URIs are
-supported).
-
-=item B<-u UNIT_FILE>, B<--unitfile UNIT_FILE>
-
-Name of the systemd unit file to reload within the container. Can be repeated
-if multiple unit files need to be reloaded within the sandbox.
-
-=back
-
-=head1 EXAMPLE
-
-Reload the httpd1 container
-
- # virt-sandbox-service reload -u httpd.service httpd1
-
-=head1 SEE ALSO
-
-C<libvirt(8)>, C<selinux(8)>, C<systemd(8)>, C<virt-sandbox-service(1)>
-
-=head1 AUTHORS
-
-Daniel Walsh <dwalsh(a)redhat.com>
-Daniel P. Berrange <dan(a)berrange.com>
-
-=head1 COPYRIGHT
-
-Copyright (C) 2011-2013 Red Hat, Inc.
-
-=head1 LICENSE
-
-virt-sandbox is distributed under the terms of the GNU LGPL v2+.
-This is free software; see the source for copying conditions.
-There is NO warranty; not even for MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE
diff --git a/bin/virt-sandbox-service-upgrade.pod b/bin/virt-sandbox-service-upgrade.pod
deleted file mode 100644
index 76eb428..0000000
--- a/bin/virt-sandbox-service-upgrade.pod
+++ /dev/null
@@ -1,74 +0,0 @@
-=head1 NAME
-
-virt-sandbox-service upgrade - upgrade an existing Secure container
-
-=head1 SYNOPSIS
-
-Upgrade a Security container
-
- virt-sandbox-service [-c URI] upgrade NAME
-
-=head1 DESCRIPTION
-
-virt-sandbox-service is used to manage secure sandboxed system services.
-These applications will be launched via libvirt and run within a virtualization
-technology such as LinuX Containers (LXC), or optionally QEMU/KVM. The
-container / virtual machines will be secured by SELinux and resource
-separated using cgroups.
-
-The upgrade command will update the config files for NAME to be compatible
-with the currently installed software version. NB this works in an upgrade
-direction only, it is not possible to install older versions of the software
-and use this command to downgrade the configs.
-
-If you have editted the main sandbox configuration file manually, this
-command can also be used to update the libvirt guest configuration to
-match it.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Display help message
-
-=item B<-c URI>, B<--connect URI>
-
-The connection URI for the hypervisor (currently only LXC URIs are
-supported).
-
-=back
-
-=head1 EXAMPLE
-
-Execute /bin/sh in httpd1 container
-
- # virt-sandbox-service upgrade httpd
-
-=head1 SEE ALSO
-
-C<libvirt(8)>, C<selinux(8)>, C<systemd(8)>, C<virt-sandbox-service(1)>
-
-=head1 FILES
-
-Container content will be stored in subdirectories of
-/var/lib/libvirt/filesystems, by default. You can manage the
-content in these directories outside of the container and
-processes within the container will see the content.
-
-=head1 AUTHORS
-
-Daniel Walsh <dwalsh(a)redhat.com>
-Daniel P. Berrange <dan(a)berrange.com>
-
-=head1 COPYRIGHT
-
-Copyright (C) 2011-2013 Red Hat, Inc.
-
-=head1 LICENSE
-
-virt-sandbox is distributed under the terms of the GNU LGPL v2+.
-This is free software; see the source for copying conditions.
-There is NO warranty; not even for MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE
diff --git a/bin/virt-sandbox-service-util.c b/bin/virt-sandbox-service-util.c
deleted file mode 100644
index a0e090d..0000000
--- a/bin/virt-sandbox-service-util.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * virt-sandbox-service-util.c: libvirt sandbox service util command
- *
- * Copyright (C) 2012-2013 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Author: Daniel J Walsh <dwalsh(a)redhat.com>
- * Author: Daniel P. Berrange <berrange(a)redhat.com>
- */
-
-#include <config.h>
-
-#include <libvirt-sandbox/libvirt-sandbox.h>
-#include <glib/gi18n.h>
-
-#define STREQ(x,y) (strcmp(x,y) == 0)
-
-static gboolean do_close(GVirSandboxConsole *con G_GNUC_UNUSED,
- gboolean error G_GNUC_UNUSED,
- gpointer opaque)
-{
- GMainLoop *loop = opaque;
- g_main_loop_quit(loop);
- return FALSE;
-}
-
-
-static void libvirt_sandbox_version(void)
-{
- g_print(_("%s version %s\n"), PACKAGE, VERSION);
- exit(EXIT_SUCCESS);
-}
-
-
-static GVirSandboxContext *libvirt_sandbox_get_context(const char *uri,
- const char *name)
-{
- GVirSandboxConfig *config = NULL;
- GVirSandboxContextService *ctx = NULL;
- GError *err = NULL;
- GVirConnection *conn = NULL;
- gchar *configfile = NULL;
-
- configfile = g_strdup_printf("/etc/libvirt-sandbox/services/%s/config/sandbox.cfg", name);
-
- if (uri)
- conn = gvir_connection_new(uri);
- else
- conn = gvir_connection_new("lxc:///");
-
- if (!gvir_connection_open(conn, NULL, &err)) {
- g_printerr(_("Unable to open connection: %s\n"),
- err && err->message ? err->message : _("unknown"));
- goto cleanup;
- }
-
- if (!(config = gvir_sandbox_config_load_from_path(configfile, &err))) {
- g_printerr(_("Unable to read config file %s: %s\n"), configfile,
- err && err->message ? err->message : _("unknown"));
- goto cleanup;
- }
-
- if (!(ctx = gvir_sandbox_context_service_new(conn, GVIR_SANDBOX_CONFIG_SERVICE(config)))) {
- g_printerr(_("Unable to create new context service: %s\n"),
- err && err->message ? err->message : _("unknown"));
- goto cleanup;
- }
-
-cleanup:
- g_free(configfile);
- if (conn)
- g_object_unref(conn);
- if (config)
- g_object_unref(config);
-
- return ctx ? GVIR_SANDBOX_CONTEXT(ctx) : NULL;
-}
-
-static int container_start(const char *uri, const char *name, GMainLoop *loop)
-{
- int ret = EXIT_FAILURE;
- GError *err = NULL;
- GVirSandboxConsole *con = NULL;
- GVirSandboxContext *ctx = NULL;
-
- if (!(ctx = libvirt_sandbox_get_context(uri, name)))
- goto cleanup;
-
- if (!(gvir_sandbox_context_start(ctx, &err))) {
- g_printerr(_("Unable to start container: %s\n"),
- err && err->message ? err->message : _("unknown"));
- goto cleanup;
- }
-
- if (!(con = gvir_sandbox_context_get_log_console(ctx, &err))) {
- g_printerr(_("Unable to get log console for container: %s\n"),
- err && err->message ? err->message : _("unknown"));
- goto cleanup;
- }
-
- gvir_sandbox_console_set_direct(con, TRUE);
-
- g_signal_connect(con, "closed", (GCallback)do_close, loop);
-
- if (gvir_sandbox_console_attach_stderr(con, &err) < 0) {
- g_printerr(_("Unable to attach console to stderr in the container: %s\n"),
- err && err->message ? err->message : _("unknown"));
- goto cleanup;
- }
-
- /* Stop holding open libvirt connection */
- if (gvir_sandbox_console_isolate(con, &err) < 0) {
- g_printerr(_("Unable to disconnect console from libvirt: %s\n"),
- err && err->message ? err->message : _("unknown"));
- goto cleanup;
- }
-
- gvir_sandbox_context_detach(ctx, NULL);
- g_object_unref(ctx);
- ctx = NULL;
-
- g_main_loop_run(loop);
-
- ret = EXIT_SUCCESS;
-
-cleanup:
- if (ctx)
- g_object_unref(ctx);
- if (con)
- g_object_unref(con);
- return ret;
-}
-
-static int container_attach(const char *uri, const char *name, GMainLoop *loop)
-{
- int ret = EXIT_FAILURE;
- GError *err = NULL;
- GVirSandboxConsole *con = NULL;
- GVirSandboxContext *ctx = NULL;
-
- if (!(ctx = libvirt_sandbox_get_context(uri, name)))
- goto cleanup;
-
- if (!(gvir_sandbox_context_attach(ctx, &err))) {
- g_printerr(_("Unable to attach to container: %s\n"),
- err && err->message ? err->message : _("unknown"));
- goto cleanup;
- }
-
- if (!(con = gvir_sandbox_context_get_shell_console(ctx, &err))) {
- g_printerr(_("Unable to get shell console for container: %s\n"),
- err && err->message ? err->message : _("unknown"));
- goto cleanup;
- }
-
- gvir_sandbox_console_set_direct(con, TRUE);
-
- g_signal_connect(con, "closed", (GCallback)do_close, loop);
-
- if (!(gvir_sandbox_console_attach_stdio(con, &err))) {
- g_printerr(_("Unable to attach to container: %s\n"),
- err && err->message ? err->message : _("unknown"));
- goto cleanup;
- }
-
- /* Stop holding open libvirt connection */
- if (gvir_sandbox_console_isolate(con, &err) < 0) {
- g_printerr(_("Unable to disconnect console from libvirt: %s\n"),
- err && err->message ? err->message : _("unknown"));
- goto cleanup;
- }
-
- gvir_sandbox_context_detach(ctx, NULL);
-
- g_object_unref(ctx);
- ctx = NULL;
-
- g_main_loop_run(loop);
-
- ret = EXIT_SUCCESS;
-
-cleanup:
- if (ctx)
- g_object_unref(ctx);
- if (con)
- g_object_unref(con);
- return ret;
-}
-
-
-static int (*container_func)(const char *uri, const char *name, GMainLoop *loop) = NULL;
-
-static gboolean libvirt_lxc_start(const gchar *option_name,
- const gchar *value,
- const gpointer *data,
- const GError **error)
-
-{
- if (container_func) return FALSE;
- container_func = container_start;
- return TRUE;
-}
-
-static gboolean libvirt_lxc_attach(const gchar *option_name,
- const gchar *value,
- const gpointer *data,
- const GError **error)
-
-{
- if (container_func) return FALSE;
- container_func = container_attach;
- return TRUE;
-}
-
-int main(int argc, char **argv)
-{
- GError *err = NULL;
- GMainLoop *loop = NULL;
- int ret = EXIT_FAILURE;
- pid_t pid = 0;
- gchar *uri = NULL;
-
- gchar **cmdargs = NULL;
- GOptionContext *context;
- GOptionEntry options[] = {
- { "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
- libvirt_sandbox_version, N_("Display version information"), NULL },
- { "start", 's', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
- libvirt_lxc_start, N_("Start a container"), NULL },
- { "attach", 'a', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
- libvirt_lxc_attach, N_("Attach to a container"), NULL },
- { "pid", 'p', 0, G_OPTION_ARG_INT, &pid,
- N_("Pid of process in container to which the command will run"), "PID"},
- { "connect", 'c', 0, G_OPTION_ARG_STRING, &uri,
- N_("Connect to hypervisor Default:'lxc:///'"), "URI"},
- { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &cmdargs,
- NULL, "CONTAINER_NAME" },
- { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
- };
- const char *help_msg = N_("Run 'virt-sandbox-service-util --help' to see a full list of available command line options\n");
-
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- bind_textdomain_codeset(PACKAGE, "UTF-8");
- textdomain(PACKAGE);
-
- if (!gvir_sandbox_init_check(&argc, &argv, &err))
- exit(EXIT_FAILURE);
-
- context = g_option_context_new (_("- Libvirt Sandbox Service"));
- g_option_context_add_main_entries (context, options, NULL);
- g_option_context_parse (context, &argc, &argv, &err);
-
- if (err) {
- g_printerr("%s\n%s\n",
- err->message,
- gettext(help_msg));
- goto cleanup;
- }
-
- if ( container_func == NULL ) {
- g_printerr(_("Invalid command: You must specify --start or --attach\n%s"),
- gettext(help_msg));
- goto cleanup;
- }
-
- if (!cmdargs || !cmdargs[0] ) {
- g_printerr(_("Invalid command CONTAINER_NAME required: %s"),
- gettext(help_msg));
- goto cleanup;
- }
-
- g_option_context_free(context);
-
- g_set_application_name(_("Libvirt Sandbox Service"));
-
- loop = g_main_loop_new(g_main_context_default(), 1);
- ret = container_func(uri, cmdargs[0], loop);
- g_main_loop_unref(loop);
-
-cleanup:
- exit(ret);
-}
-
-/*
- * Local variables:
- * c-indent-level: 4
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/bin/virt-sandbox-service.logrotate b/bin/virt-sandbox-service.logrotate
deleted file mode 100644
index 6bb7d68..0000000
--- a/bin/virt-sandbox-service.logrotate
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-for name in `/usr/bin/virsh -c lxc:/// -q list | awk '{print $2}'`
-do
- if test -d "/etc/libvirt-sandbox/services/$name"
- then
- /usr/bin/virt-sandbox-service -c lxc:/// execute $name -- /etc/cron.daily/logrotate
- fi
-done
-exit 0
diff --git a/bin/virt-sandbox-service.pod b/bin/virt-sandbox-service.pod
deleted file mode 100644
index e6f0739..0000000
--- a/bin/virt-sandbox-service.pod
+++ /dev/null
@@ -1,85 +0,0 @@
-=head1 NAME
-
-virt-sandbox-service - Secure container tool
-
-=head1 SYNOPSIS
-
- {create,clone,connect,delete,execute,reload,upgrade}
-
- commands:
-
- create create a sandbox container
-
- clone Clone an existing sandbox container
-
- connect Connect to a sandbox container
-
- delete Delete a sandbox container
-
- execute Execute a command within a sandbox container
-
- reload Reload a running sandbox container
-
- upgrade Upgrade an existing sandbox container
-
-=head1 DESCRIPTION
-
-virt-sandbox-service is used to provision secure sandboxed system services.
-These applications will be launched via libvirt and run within a virtualization
-technology such as LinuX Containers (LXC), or optionally QEMU/KVM. The
-container / virtual machines will be secured by SELinux and resource
-separated using cgroups.
-
-By default, it will use the libvirt LXC driver, with the C<lxc:///> URI.
-This is different from libvirt's normal behaviour, which is to probe
-for the best URI to use. Thus if using C<virsh> to get a list of containers,
-one must specify an explicit URI for it, C<virsh -c lxc:///>. Alternatively
-the C<LIBVIRT_DEFAULT_URI> environment variable can be set, or the config
-file C</etc/libvirt/libvirt.conf> can have a default URI set.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-h>, B<--help>
-
-Display help message
-
-=item B<-c URI>, B<--connect URI>
-
-The connection URI for the hypervisor (currently only LXC URIs are
-supported).
-
-=back
-
-=head1 SEE ALSO
-
-C<libvirt(8)>, C<selinux(8)>, C<systemd(8)>, C<virt-sandbox(1)>,
-C<virt-sandbox-service-create(1)>, C<virt-sandbox-service-clone(1)>,
-C<virt-sandbox-service-connect(1)>, C<virt-sandbox-service-delete(1)>,
-C<virt-sandbox-service-execute(1)>, C<virt-sandbox-service-reload(1)>,
-C<virt-sandbox-service-upgrade(1)>
-
-=head1 FILES
-
-Container content will be stored in subdirectories of
-/var/lib/libvirt/filesystems, by default. You can manage the
-content in these directories outside of the container and
-processes within the container will see the content.
-
-=head1 AUTHORS
-
-Daniel Walsh <dwalsh(a)redhat.com>
-
-Daniel P. Berrange <dan(a)berrange.com>
-
-=head1 COPYRIGHT
-
-Copyright (C) 2011-2013 Red Hat, Inc.
-
-=head1 LICENSE
-
-virt-sandbox is distributed under the terms of the GNU LGPL v2+.
-This is free software; see the source for copying conditions.
-There is NO warranty; not even for MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE
diff --git a/cfg.mk b/cfg.mk
index 37e5050..39b54f6 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -129,6 +129,6 @@ prev_version_file = /dev/null
exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics = ^libvirt-sandbox/tests
-exclude_file_name_regexp--sc_bindtextdomain = ^(libvirt-sandbox/tests)|(libvirt-sandbox/libvirt-sandbox-init-*)|(bin/virt-sandbox.c)|(bin/virt-sandbox-service-util.c)
+exclude_file_name_regexp--sc_bindtextdomain = ^(libvirt-sandbox/tests)|(libvirt-sandbox/libvirt-sandbox-init-*)|(bin/virt-sandbox.c)
exclude_file_name_regexp--sc_preprocessor_indentation = ^*/*.[ch]
diff --git a/libvirt-sandbox.spec.in b/libvirt-sandbox.spec.in
index f5868c1..125a361 100644
--- a/libvirt-sandbox.spec.in
+++ b/libvirt-sandbox.spec.in
@@ -101,17 +101,10 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
-%{_datadir}/bash-completion/completions/virt-sandbox-service
-%config(noreplace) %{_sysconfdir}/cron.daily/virt-sandbox-service.logrotate
-%dir %{_sysconfdir}/libvirt-sandbox/services
%{_bindir}/virt-sandbox
-%{_bindir}/virt-sandbox-service
%{_bindir}/virt-sandbox-image
-%{_libexecdir}/virt-sandbox-service-util
%{python3_sitelib}/libvirt_sandbox
%{_mandir}/man1/virt-sandbox.1*
-%{_mandir}/man1/virt-sandbox-service.1*
-%{_mandir}/man1/virt-sandbox-service-*.1*
%files libs -f %{name}.lang
%defattr(-,root,root,-)
diff --git a/libvirt-sandbox/tests/containers_test.sh b/libvirt-sandbox/tests/containers_test.sh
deleted file mode 100755
index 9b2a716..0000000
--- a/libvirt-sandbox/tests/containers_test.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-#
-# Simple script to setup hundreds of containers at the same time
-#
-# In order to create 100 containers execute
-# containers_test.sh create apache 100
-# Start
-# containers_test.sh start apache 100
-# Stop
-# containers_test.sh stop apache 100
-# Delete
-# containers_test.sh delete apache 100
-#
-
-create() {
- virt-sandbox-service create -C -l s0:c$2 -u httpd.service $1
-}
-
-delete() {
- virt-sandbox-service delete $1
-}
-
-start() {
- systemctl start httpd(a)$1.service
-}
-
-stop() {
- systemctl stop httpd(a)$1.service
-}
-
-command=$1
-name=$2
-repeat=$3
-for i in $(seq 1 $repeat)
-do
- eval $command $name$i $i
-done
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 724c49c..6c500b2 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,5 +1,4 @@
bin/virt-sandbox.c
-bin/virt-sandbox-service-util.c
libvirt-sandbox/libvirt-sandbox-builder-initrd.c
libvirt-sandbox/libvirt-sandbox-builder-machine.c
libvirt-sandbox/libvirt-sandbox-config.c
--
2.14.3
6 years, 9 months