File no-libexec.patch of Package virt-sandbox

Index: libvirt-sandbox-0.5.1/bin/virt-sandbox-service
===================================================================
--- libvirt-sandbox-0.5.1.orig/bin/virt-sandbox-service
+++ /dev/null
@@ -1,1279 +0,0 @@
-#!/usr/bin/python -Es
-#
-# Authors: Dan Walsh <dwalsh@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.
-#
-
-from gi.repository import LibvirtGObject
-from gi.repository import LibvirtSandbox
-from gi.repository import GLib
-import gi
-import re
-import os, sys, shutil, errno, stat
-import exceptions
-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",
-                    unicode=False,
-                    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)
-            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, 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, 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, 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 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):
-        # XXX selinux is the default for the while, needs to be configurable someday
-        model = "selinux"
-        supported = False
-
-        # Make sure we have a connection
-        self.connect()
-
-        # Loop over the security models from the host capabilities
-        configCaps = self.conn.get_capabilities()
-        hostCaps = configCaps.get_host()
-        secmodels = hostCaps.get_secmodels()
-        for secmodel in secmodels:
-            if secmodel.get_model() == model:
-                supported = True
-                break
-
-        if not supported:
-            model = None
-        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, e:
-            try:
-                self.delete()
-            except Exception, 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 = mi.next();
-        except exceptions.StopIteration:
-            return None
-        return h['name']
-
-
-    def extract_rpm(self, rpm_name):
-        mi = self.ts.dbMatch('name', rpm_name)
-        try:
-            h = mi.next();
-        except exceptions.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 = h[rpm.RPMTAG_SOURCERPM]
-        srcrpmbits = self.split_filename(srcrpm)
-
-        if srcrpmbits[0] == h[rpm.RPMTAG_NAME]:
-            return
-
-        mi = self.ts.dbMatch(rpm.RPMTAG_NAME, srcrpmbits[0])
-        try:
-            h = mi.next();
-        except exceptions.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 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)
-        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, 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, 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, e:
-            try:
-                self.delete()
-            except Exception, 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, 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(args):
-    configfile = get_legacy_config_path(args.name)
-    if os.path.exists(configfile):
-        upgrade_config_legacy(configfile)
-
-
-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)
-        args.func(args)
-        sys.exit(0)
-    except KeyboardInterrupt, e:
-        sys.exit(0)
-    except ValueError, e:
-        for line in e:
-            for l in line:
-                sys.stderr.write("%s: %s\n" % (sys.argv[0], l))
-        sys.stderr.flush()
-        sys.exit(1)
-    except IOError, e:
-        sys.stderr.write("%s: %s: %s\n" % (sys.argv[0], e.filename, e.strerror))
-        sys.stderr.flush()
-        sys.exit(1)
-    except OSError, e:
-        sys.stderr.write("%s: %s\n" % (sys.argv[0], e))
-        sys.stderr.flush()
-        sys.exit(1)
-    except GLib.GError, e:
-        sys.stderr.write("%s: %s\n" % (sys.argv[0], e))
-        sys.stderr.flush()
-        sys.exit(1)
Index: libvirt-sandbox-0.5.1/bin/Makefile.am
===================================================================
--- libvirt-sandbox-0.5.1.orig/bin/Makefile.am
+++ libvirt-sandbox-0.5.1/bin/Makefile.am
@@ -66,6 +66,11 @@ virt-sandbox-service-upgrade.1: virt-san
 
 CLEANFILES = $(man1_MANS)
 
+virt-sandbox-service: virt-sandbox-service.in
+	sed							           \
+		-e 's!/usr/libexec/!$(libexecdir)/!g'   \
+		< $< > $@
+
 virt_sandbox_SOURCES = virt-sandbox.c
 virt_sandbox_CFLAGS = \
 		$(GIO_UNIX_CFLAGS) \
Index: libvirt-sandbox-0.5.1/bin/virt-sandbox-service.in
===================================================================
--- /dev/null
+++ libvirt-sandbox-0.5.1/bin/virt-sandbox-service.in
@@ -0,0 +1,1279 @@
+#!/usr/bin/python -Es
+#
+# Authors: Dan Walsh <dwalsh@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.
+#
+
+from gi.repository import LibvirtGObject
+from gi.repository import LibvirtSandbox
+from gi.repository import GLib
+import gi
+import re
+import os, sys, shutil, errno, stat
+import exceptions
+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",
+                    unicode=False,
+                    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)
+            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, 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, 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, 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 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):
+        # XXX selinux is the default for the while, needs to be configurable someday
+        model = "selinux"
+        supported = False
+
+        # Make sure we have a connection
+        self.connect()
+
+        # Loop over the security models from the host capabilities
+        configCaps = self.conn.get_capabilities()
+        hostCaps = configCaps.get_host()
+        secmodels = hostCaps.get_secmodels()
+        for secmodel in secmodels:
+            if secmodel.get_model() == model:
+                supported = True
+                break
+
+        if not supported:
+            model = None
+        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, e:
+            try:
+                self.delete()
+            except Exception, 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 = mi.next();
+        except exceptions.StopIteration:
+            return None
+        return h['name']
+
+
+    def extract_rpm(self, rpm_name):
+        mi = self.ts.dbMatch('name', rpm_name)
+        try:
+            h = mi.next();
+        except exceptions.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 = h[rpm.RPMTAG_SOURCERPM]
+        srcrpmbits = self.split_filename(srcrpm)
+
+        if srcrpmbits[0] == h[rpm.RPMTAG_NAME]:
+            return
+
+        mi = self.ts.dbMatch(rpm.RPMTAG_NAME, srcrpmbits[0])
+        try:
+            h = mi.next();
+        except exceptions.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 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)
+        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, 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, 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, e:
+            try:
+                self.delete()
+            except Exception, 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, 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(args):
+    configfile = get_legacy_config_path(args.name)
+    if os.path.exists(configfile):
+        upgrade_config_legacy(configfile)
+
+
+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)
+        args.func(args)
+        sys.exit(0)
+    except KeyboardInterrupt, e:
+        sys.exit(0)
+    except ValueError, e:
+        for line in e:
+            for l in line:
+                sys.stderr.write("%s: %s\n" % (sys.argv[0], l))
+        sys.stderr.flush()
+        sys.exit(1)
+    except IOError, e:
+        sys.stderr.write("%s: %s: %s\n" % (sys.argv[0], e.filename, e.strerror))
+        sys.stderr.flush()
+        sys.exit(1)
+    except OSError, e:
+        sys.stderr.write("%s: %s\n" % (sys.argv[0], e))
+        sys.stderr.flush()
+        sys.exit(1)
+    except GLib.GError, e:
+        sys.stderr.write("%s: %s\n" % (sys.argv[0], e))
+        sys.stderr.flush()
+        sys.exit(1)