This way we can share common methods between the ServiceContainer and the InteractiveContainer --- bin/virt-sandbox-service | 823 ++++++++++++++++++++++++++--------------------- 1 file changed, 450 insertions(+), 373 deletions(-) diff --git a/bin/virt-sandbox-service b/bin/virt-sandbox-service index 9f4941b..f4d0eff 100755 --- a/bin/virt-sandbox-service +++ b/bin/virt-sandbox-service @@ -58,56 +58,387 @@ def read_config(name): return LibvirtSandbox.Config.load_from_path(get_config_path(name)) 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 = None + 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 + + 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.uid = uid + + def get_uid(self): + return self.uid + + 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 self.DEFAULT_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): + return self.config.set_security_opts(val) + + def add_network(self, val): + return self.config.add_network_opts(val) + + def get_security_dynamic(self): + return self.config.get_security_dynamic() + + def get_security_type(self): + try: + if self.config: + con = self.config.get_security_label().split(':') + return con[2] + except: + pass + return "svirt_lxc_net_t" + + def get_security_level(self): + try: + if self.config: + con = self.config.get_security_label().split(':') + return ":".join(con[3:]) + except: + pass + return "s0" + + 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 set_security_type(self, security_type): + label = "system_u:system_r:%s:%s" % (security_type, self.get_security_level()) + try: + selinux.security_check_context(label) + self.config.set_security_label(label) + except OSError, e: + raise OSError(_("Invalid Security Type %s: %s ") % (security_type, e)) + + def set_security_level(self, security_level): + label = "system_u:system_r:%s:%s" % (self.get_security_type(), security_level) + try: + selinux.security_check_context(label) + self.config.set_security_label(label) + except OSError, e: + raise OSError(_("Invalid Security Level %s: %s ") % (security_level, e)) + + 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) + + # 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) + + 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 e + + 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 e + + 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 e + + 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): + config_path = self.get_config_path() + if os.path.exists(config_path): + os.remove(config_path) + self.config.save_to_path(config_path) + if selinux is not None: + selinux.restorecon(config_path) + sys.stdout.write(_("Created sandbox config %s\n") % config_path) + + def _get_image_path(self): + mounts = self.config.get_mounts() + for m in mounts: + if type(m) != LibvirtSandbox.ConfigMountHostImage: + continue + + if m.get_target() == self.dest: + return m.get_source() + return None + + def delete(self): + # Stop service if it is running + try: + self.stop() + except: + pass + + config = self.get_config_path() + if os.path.exists(config): + os.remove(config) + + print (_("You need to manually remove the '%s' content") % self.name) + return + + # Not sure we should remove content + if os.path.exists(self.dest): + shutil.rmtree(self.dest) + mount_path = self._get_image_path() + if mount_path: + os.remove(mount_path) + + image = self.get_image_path() + if os.path.exists(image): + os.remove(image) + + def create(self): + self._connect() + self.config.set_shell(True) + 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 running(self): + def closed(obj, error): + self.loop.quit() + try: + self._connect() + context = LibvirtSandbox.ContextService.new(self.conn, self.config) + context.attach() + self._disconnect() + return 1 + except GLib.GError, e: + return 0 + + def start(self): + def closed(obj, error): + self.loop.quit() + + try: + self._connect() + context = LibvirtSandbox.ContextService.new(self.conn, self.config) + context.start() + console = context.get_log_console() + console.connect("closed", closed) + console.attach_stderr() + self.loop = GLib.MainLoop() + self.loop.run() + try: + console.detach() + except: + pass + try: + context.stop() + except: + pass + except GLib.GError, e: + raise OSError(str(e)) + + def stop(self): + try: + self._connect() + context = LibvirtSandbox.ContextService.new(self.conn, self.config) + context.attach() + context.stop() + except GLib.GError, e: + raise OSError(str(e)) + + def connect(self): + def closed(obj, error): + self.loop.quit() + + try: + self._connect() + context = LibvirtSandbox.ContextService.new(self.conn, self.config) + context.attach() + console = context.get_shell_console() + console.connect("closed", closed) + console.attach_stdio() + self.loop = GLib.MainLoop() + self.loop.run() + try: + console.detach() + except: + pass + except GLib.GError, e: + raise OSError(str(e)) + + def execute(self, command): + def closed(obj, error): + self.loop.quit() + + try: + self._connect() + context = LibvirtSandbox.ContextService.new(self.conn, self.config) + context.attach() + console = context.get_shell_console() + console.connect("closed", closed) + console.attach_stdio() + print "not currently implemented" + console.detach() + return + self.loop = GLib.MainLoop() + self.loop.run() + try: + console.detach() + except: + pass + except GLib.GError, e: + raise OSError(str(e)) + + def add_bind_mount(self, source, dest): + mount = LibvirtSandbox.ConfigMountHostBind.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 ServiceContainer(Container): IGNORE_DIRS = [ "/var/run/", "/etc/logrotate.d/", "/etc/pam.d" ] DEFAULT_DIRS = [ "/etc", "/var" ] PROFILE_FILES = [ ".bashrc", ".bash_profile" ] MACHINE_ID = "/etc/machine-id" HOSTNAME = "/etc/hostname" - FUNCTIONS = "/etc/rc.d/init.d/functions" + 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", "/etc/rc.d/init.d"] + MAKE_SYSTEM_DIRS = [ "/var/lib/dhclient", "/var/lib/dbus", "/var/log", "/var/spool", "/var/cache", "/var/tmp", "/var/lib/nfs/rpc_pipefs", SYSVINIT_PATH ] 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" ] } - SELINUX_FILE_TYPE = "svirt_lxc_file_t" - DEFAULT_PATH = "/var/lib/libvirt/filesystems" - DEFAULT_IMAGE = "/var/lib/libvirt/images/%s.raw" DEFAULT_UNIT = "/etc/systemd/system/%s_sandbox.service" - def __init__(self, name=None, uri = "lxc:///", path = DEFAULT_PATH, config=None, create=False): - self.uri = uri + def __init__(self, name=None, uri = "lxc:///", path = Container.DEFAULT_PATH, config=None, create=False): + Container.__init__(self, name, uri, path, config, create) self.copy = False - self.use_image = False - self.path = path - self.conn = None - self.image = None - self.size = 10 * MB - self.config = None - self.unitfile = None self.unit_file_list = [] - self.name = name - - if name: - config = self.get_config_path(name) - self.dest = "%s/%s" % (self.path, name) - if create: - if config and os.path.exists(config): - raise ValueError([_("Container already exists")]) - self.config = LibvirtSandbox.ConfigService.new(name) - return - - if config: - try: - self.config = LibvirtSandbox.Config.load_from_path(config) - self.unitfile = self.get_unit_path() - except GLib.GError, e: - raise OSError(config + ": " + str(e)) + else: + self.unitfile = self.get_unit_path() def _follow_units(self): unitst="" @@ -128,14 +459,11 @@ class Container: return self.unit_file_list[0][0].split(".")[0] def _get_sandbox_target(self): - if len(self.unit_file_list) > 1: - raise ValueError([_("Only Valid for single units")]) return "%s_sandbox.target" % self._get_sandboxed_service() - def _target(self): + def _create_target(self, name): try: - name = self._get_sandbox_target() - path = "/etc/systemd/system/" + name + path = "/etc/systemd/system/%s_sandbox.target" % name if not os.path.exists(path): fd = open(path, "w") fd.write(""" @@ -151,16 +479,18 @@ class Container: Description=%(NAME)s Sandbox Container Target Documentation=man:virt-sandbox-service(1) -[Install] -WantedBy=multi-user.target """ % { "NAME" : self._get_sandboxed_service() }) - return "%s" % name + except ValueError: + return "" except OSError: return "" + path += ".wants" + if not os.path.exists(path): + os.makedirs(path) + os.symlink(self.get_unit_path(), path + "/" + os.path.basename(self.get_unit_path())) def _create_system_unit(self): self.unitfile = self.get_unit_path() - name = self.config.get_name() unit = r""" [Unit] Description=Secure Sandbox Container %(NAME)s @@ -175,17 +505,16 @@ ExecStop=/usr/bin/virt-sandbox-service stop %(NAME)s [Install] WantedBy=%(TARGET)s -""" % { 'NAME':name, 'FOLLOW':self._follow_units(), 'TARGET':self._target(), 'RELOAD': " -u ".join(map(lambda x: x[0], self.unit_file_list)) } +""" % { 'NAME':self.name, 'FOLLOW':self._follow_units(), 'TARGET':self._get_sandbox_target(), 'RELOAD': " -u ".join(map(lambda x: x[0], self.unit_file_list)) } + fd = open(self.unitfile, "w") fd.write(unit) fd.close() if selinux is not None: selinux.restorecon(self.unitfile) - p = Popen(["/usr/bin/systemctl","enable", self.unitfile],stdout=PIPE, stderr=PIPE) - p.communicate() - if p.returncode and p.returncode != 0: - raise OSError(_("Failed to enable %s unit file") % self.unitfile) sys.stdout.write(_("Created unit file %s\n") % self.unitfile) + for i, src in self.unit_file_list: + self._create_target(i.split(".service")[0]) def _add_dir(self, newd): if newd in self.all_dirs: @@ -204,87 +533,29 @@ WantedBy=%(TARGET)s 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_config_path(self, name = None): - if not name: - name = self.get_name() - return get_config_path() - - def get_filesystem_path(self, name = None): - if not name: - name = self.get_name() - return self.DEFAULT_PATH + "/" + name - - def get_image_path(self, name = None): - if not name: - name = self.get_name() - return self.DEFAULT_IMAGE % name - - 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 set_security(self, val): - return self.config.set_security_opts(val) - - def add_network(self, val): - return 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(":") - if len(parts) != 5 and len(parts) != 4: - raise ValueError([_("Expected 5 parts in SELinux security label %s") % parts]) - - if len(parts) == 5: - selinux.chcon(self.dest, "system_u:object_r:%s:%s:%s" % ( - self.SELINUX_FILE_TYPE, parts[3], parts[4]), True) - else: - selinux.chcon(self.dest, "system_u:object_r:%s:%s" % ( - self.SELINUX_FILE_TYPE, parts[3]), True) - - def set_image(self, size): - self.use_image = True - self.size = size * MB + break; - def set_path(self, path): - self.path = path + 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 set_name(self, name): + def get_name(self): if self.config: - raise ValueError([_("Cannot modify Name")]) - self.dest = "%s/%s" % (self.path, self.name) - self.config = LibvirtSandbox.ConfigService.new(name) + 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 = [] @@ -323,7 +594,7 @@ WantedBy=%(TARGET)s try: h = mi.next(); except exceptions.StopIteration: - raise ValueError([_("Cannot find package containing %s") % unitfile]) + raise ValueError(["Cannot find package containing %s" % unitfile]) for fentry in h.fiFromHeader(): fname = fentry[0] @@ -343,7 +614,7 @@ WantedBy=%(TARGET)s try: h = mi.next(); except exceptions.StopIteration: - raise ValueError([_("Cannot find base package %s") % srcrpmbits[0]]) + raise ValueError(["Cannot find base package %s" % srcrpmbits[0]]) for fentry in h.fiFromHeader(): fname = fentry[0] @@ -353,10 +624,6 @@ WantedBy=%(TARGET)s if os.path.isfile(fname): self._add_file(fname) - def _add_mount(self, source, dest): - mount = LibvirtSandbox.ConfigMountHostBind.new(source, dest) - self.config.add_mount(mount) - def gen_hostname(self): fd=open(self.dest + self.HOSTNAME, "w") fd.write("%s\n" % self.name ) @@ -383,32 +650,16 @@ WantedBy=%(TARGET)s os.symlink(self.dest + jpath, jpath) 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) - - # 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) - + Container._gen_filesystems(self) for d in self.BIND_SYSTEM_DIRS: if os.path.exists(d): source = "%s%s" % ( self.dest, d) - self._add_mount(source, 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_mount(source, f) + self.add_bind_mount(source, f) for d in self.dirs: found = False @@ -419,10 +670,7 @@ WantedBy=%(TARGET)s break if not found: source = "%s%s" % ( self.dest, d) - self._add_mount(source, d) - - def _get_init_path(self): - return "%s/%s/init" % (self.path, self.get_name()) + self.add_bind_mount(source, d) def _create_container_unit(self, src, dest, unit): fd = open(dest + "/" + unit, "w") @@ -433,44 +681,6 @@ PrivateNetwork=false """ % src ) fd.close() - 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 e - - 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 e - - 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 e - def _gen_content(self): if self.copy: for d in self.dirs: @@ -491,10 +701,13 @@ PrivateNetwork=false for f in self.BIND_SYSTEM_FILES: self._makefile(f) - shutil.copy(self.FUNCTIONS, "%s%s" % (self.dest, self.FUNCTIONS)) + destpath = self.dest + self.SYSVINIT_PATH + for i in range(7): + os.mkdir(destpath+("/rc%s.d" % i)) + os.mkdir(destpath+"/init.d") + shutil.copy(self.SYSVINIT_PATH + "/init.d/functions" , destpath + "/init.d") self.gen_machine_id() - self.gen_hostname() for k in self.LOCAL_LINK_FILES: @@ -530,70 +743,20 @@ PrivateNetwork=false self._fix_protection() - 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): - config_path = self.get_config_path() - if os.path.exists(config_path): - os.remove(config_path) - self.config.save_to_path(config_path) - if selinux is not None: - selinux.restorecon(config_path) - sys.stdout.write(_("Created sandbox config %s\n") % config_path) - - def _get_image_path(self): - mounts = self.config.get_mounts() - for m in mounts: - if type(m) != LibvirtSandbox.ConfigMountHostImage: - continue - - if m.get_target() == self.dest: - return m.get_source() - return None - def _delete(self): - # Should be stored in config + # + # Delete A ServiceContainer + # try: fd=open(self.dest + self.MACHINE_ID, "r") uuid = fd.read().rstrip() fd.close() - jpath = "/var/log/journal/" + uuid - if os.path.exists(jpath): - os.remove(jpath) - except Exception, e: - pass - - if os.path.exists(self.dest): - shutil.rmtree(self.dest) - mount_path = self._get_image_path() - if mount_path: - os.remove(mount_path) - - config = self.get_config_path() - if os.path.exists(config): - os.remove(config) + os.remove("/var/log/journal/" + uuid) + except OSError, e: + sys.stderr.write("%s: %s\n" % (sys.argv[0], e)) + sys.stderr.flush() - image = self.get_image_path() - if os.path.exists(image): - os.remove(image) + Container.delete(self) if self.unitfile is not None and os.path.exists(self.unitfile): p = Popen(["/usr/bin/systemctl","disable", self.unitfile],stdout=PIPE, stderr=PIPE) @@ -624,12 +787,13 @@ PrivateNetwork=false self._delete() def _create(self): - self._connect() - self.config.set_shell(True) - self.config.set_boot_target("multi-user.target") + # + # Create A ServiceContainer + # self._extract_rpms() + Container.create(self) self._gen_filesystems() - os.mkdir(self.dest) + if self.image: self._create_image() self._gen_content() @@ -639,8 +803,9 @@ PrivateNetwork=false self._gen_content() sys.stdout.write(_("Created sandbox container dir %s\n") % self.dest) self.set_security_label() - self.save_config() self._create_system_unit() + self.config.set_boot_target("multi-user.target") + self.save_config() def create(self): if os.path.exists(self.dest): @@ -667,119 +832,22 @@ PrivateNetwork=false args.command = [ "systemctl", "reload" ] + map(lambda x: x[0], unitfiles) execute(args) - 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 running(self): - def closed(obj, error): - self.loop.quit() - try: - self._connect() - context = LibvirtSandbox.ContextService.new(self.conn, self.config) - context.attach() - self._disconnect() - return 1 - except GLib.GError, e: - return 0 - - def start(self): - def closed(obj, error): - self.loop.quit() - - try: - self._connect() - context = LibvirtSandbox.ContextService.new(self.conn, self.config) - context.start() - console = context.get_log_console() - console.connect("closed", closed) - console.attach_stderr() - self.loop = GLib.MainLoop() - self.loop.run() - try: - console.detach() - except: - pass - try: - context.stop() - except: - pass - except GLib.GError, e: - raise OSError(str(e)) - - def stop(self): - try: - self._connect() - context = LibvirtSandbox.ContextService.new(self.conn, self.config) - context.attach() - context.stop() - except GLib.GError, e: - raise OSError(str(e)) - - def connect(self): - def closed(obj, error): - self.loop.quit() - - try: - self._connect() - context = LibvirtSandbox.ContextService.new(self.conn, self.config) - context.attach() - console = context.get_shell_console() - console.connect("closed", closed) - console.attach_stdio() - self.loop = GLib.MainLoop() - self.loop.run() - try: - console.detach() - except: - pass - except GLib.GError, e: - raise OSError(str(e)) - - def execute(self, command): - def closed(obj, error): - self.loop.quit() - - try: - self._connect() - context = LibvirtSandbox.ContextService.new(self.conn, self.config) - context.attach() - console = context.get_shell_console() - console.connect("closed", closed) - console.attach_stdio() - print "not currently implemented" - console.detach() - return - self.loop = GLib.MainLoop() - self.loop.run() - try: - console.detach() - except: - pass - except GLib.GError, e: - raise OSError(str(e)) - MB = int(1000000) def delete(args): - container = Container(args.name) + config = read_config(args.name) + container = ServiceContainer(uri=args.uri, config = config) container.delete() def create(args): - container = Container(name = args.name, create = True) + container = ServiceContainer(name = args.name, uri=args.uri, create = True) container.set_copy(args.copy) - if args.network: - for net in args.network: - container.add_network(net) + for net in args.network: + container.add_network(net) if args.security: container.set_security(args.security) container.set_unit_file_list(args.unitfiles) + container.set_path(args.path) if args.imagesize: container.set_image(args.imagesize) @@ -788,7 +856,6 @@ def create(args): def usage(parser, msg): parser.print_help() - sys.stderr.write("\n%s\n" % msg) sys.stderr.flush() sys.exit(1) @@ -799,7 +866,7 @@ def sandbox_list(args): g.sort() for gc in g: try: - c = Container(config = gc) + c = LibvirtSandbox.Config.load_from_path(gc) if args.running: if c.running(): print c.get_name() @@ -812,8 +879,6 @@ def sandbox_list(args): def sandbox_reload(args): config = read_config(args.name) - if isinstance(config, gi.repository.LibvirtSandbox.ConfigInteractive): - raise ValueError(_("Interactive Containers do not support reload")) container = ServiceContainer(uri = args.uri, config = config) container.reload(args.unitfiles) @@ -860,7 +925,8 @@ def execute(args): # os.execv("/usr/libexec/virt-sandbox-service-util", myexec) def clone(args): - container = Container(args.source, args.uri) + config = read_config(args.source) + container = Container(uri = args.uri, config=config) fd = open(container.get_config_path(),"r") recs = fd.read() fd.close() @@ -893,7 +959,7 @@ def clone(args): fd.close() sys.stdout.write(_("Created unit file %s\n") % new_unit) - container = Container(args.dest, args.uri) + container = ServiceContainer(name=args.dest, uri=args.uri, create=True) if args.security: container.set_security(args.security) container.gen_machine_id() @@ -907,17 +973,28 @@ class SizeAction(argparse.Action): setattr(namespace, self.dest, int(values)) class CheckUnit(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - src = "/etc/systemd/system/" + values - if not os.path.exists(src): - src = "/lib/systemd/system/" + values - if not os.path.exists(src): - raise OSError(_("Requested unit %s does not exist") % values) + 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 = "/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((values, src)) + unitfiles.append((value, src)) else: - unitfiles = [ (values, src) ] + unitfiles = [ (value, src) ] setattr(namespace, self.dest, unitfiles) class SetNet(argparse.Action): @@ -1011,7 +1088,7 @@ def gen_reload_args(subparser): def gen_clone_args(subparser): parser = subparser.add_parser("clone", - help=_("Clone an existing sandbox container")) + help=_("Clone an existing sandbox container")) parser.set_defaults(func=clone) parser.add_argument("-s", "--security", dest="security", default=default_security_opts(), -- 1.8.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list