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

[libvirt] [sandbox PATCH v2 2/2] Add support for templated unit in virt-sandbox

This permit to create a templated unit inside the sandbox,
using the sandbox name as a variable and so running the same
unit with a different configuration without too much hassle.

For example, someone could have several different configuration of
website in /etc/nginx/websites.d/ and have each of them started in
a different sandbox, with a sample templated unit using the sandbox
name as a option to read the proper configuration file directly.

One could take the following file in /etc/systemd/system/nginx_lxc  service :

  Description=Test of a specific nginx running in lxc
  After=syslog.target network.target remote-fs.target nss-lookup.target

  ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.%i.conf
  ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.%i.conf
  ExecReload=/bin/kill -s HUP $MAINPID
  ExecStop=/bin/kill -s QUIT $MAINPID


Then create a container like this:

  # virt-sandbox-service  create -u nginx_lxc@  test.example.org --package nginx

And then we will have nginx running in a container, using the specific
config file /etc/nginx/nginx.test.example.org.conf
 bin/virt-sandbox-service            | 14 ++++++++++++++
 bin/virt-sandbox-service-create.pod |  1 +
 2 files changed, 15 insertions(+)

diff --git a/bin/virt-sandbox-service b/bin/virt-sandbox-service
index 3cecff8..942f788 100755
--- a/bin/virt-sandbox-service
+++ b/bin/virt-sandbox-service
@@ -345,6 +345,10 @@ class GenericContainer(Container):
     def set_command(self, 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" ]
@@ -624,7 +628,15 @@ WantedBy=%(TARGET)s
                 source = "%s%s" % ( self.dest, d)
                 self.add_bind_mount(source, d)
+    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):
@@ -681,6 +693,8 @@ PrivateNetwork=false
         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("../" + i, self.dest + tgtdir + "/" + i)
         tgtfile = unitdir + "/multi-user.target"
diff --git a/bin/virt-sandbox-service-create.pod b/bin/virt-sandbox-service-create.pod
index ee8cffc..942c919 100644
--- a/bin/virt-sandbox-service-create.pod
+++ b/bin/virt-sandbox-service-create.pod
@@ -37,6 +37,7 @@ supported currently).
 =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 instancied systemd unit will be created, using the name of the container as a instance identifier.
 =item B<-C>, B<--copy>

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