def delete(self, snapshot: str=None, **kwargs: dict): if snapshot: utils.pend("delete snapshot %s" % kwargs['name[:snapshot]']) if snapshot not in self.snapshots: utils.fail("%s: snapshot does not exist" % kwargs['name[:snapshot]']) exit(1) try: os.unlink('%s.%s' % (self.path_raw, snapshot)) utils.ok() except PermissionError: utils.fail("Permission denied") exit(1) else: if not os.path.isdir(self.path): utils.fail("%s: VM does not exist" % self.name) exit(1) if not utils.ask("Delete VM %s?" % self.name, default=False): exit(1) utils.pend("delete %s" % self.name) try: shutil.rmtree(self.path) utils.ok() except PermissionError: utils.fail("Permission denied") exit(1)
def async_send_command(command, host, port, timeout): pid = os.getpid() if os.fork() != 0: return # Avoid the pesky KeyboardInterrupts in the child signal.signal(signal.SIGINT, signal.SIG_IGN) command_deadline = datetime.now() + timedelta(seconds=timeout) utils.pend("sending command %s to %s:%d" % (command.args, host, port)) while True: try: os.kill(pid, 0) # check if parent is still here except OSError: break now = datetime.now() if now < command_deadline: try: send_command(command, host, port, TIMEOUT_CMD_SEND) except CommandError as e: utils.pend(None, msg="%s, retrying for %d more seconds" % (e, (command_deadline - now).seconds)) else: utils.ok("command %s successfully sent" % command.args) exit(0) else: utils.abort("command timeout") break time.sleep(1) exit(1)
def vm_init(path: str): utils.pend("initialise VM directory: %s" % path) try: os.mkdir(path) except OSError as e: utils.fail(e.strip()) exit(1) utils.ok()
def create(self, size: str, force: bool, **kwargs: dict): self.initialise(force) utils.pend("create %s%sB image" % (size, ('i', '')[size[-1] in '0123456789'])) utils.execute(['%s/qemu-img' % self.path_executable, 'create', '-f', 'raw', self.path_raw, size], msg="execute qemu-img") self.size = size utils.ok()
def import_raw(self, raw: str, force: bool): if not os.path.exists(raw): utils.fail("%s: file not found" % raw) exit(1) self.initialise(force) utils.pend("copy disk image") utils.execute(['cp', raw, self.path_raw]) utils.ok()
def execute(args, cmd_line): # Informative: ip = utils.get_default_ip() if args['headless']: utils.info("VNC: port %d (connect with `$vncclient %s:%d`)" % (args['vnc_port'], ip, args['vnc_display'])) utils.info("Qemu monitor: port %d (connect with `{nc,telnet} %s %d)" % (args['monitor_port'], ip, args['monitor_port'])) if args['mode'] == 'sym': utils.info("Experiment name: %s" % args['expname']) if args['script'] or args['command']: utils.info("Watchdog: port %d" % args['command_port']) utils.debug("Command line:\n%s" % ' '.join(cmd_line)) if args['dry_run']: exit(1) environ = dict(os.environ) if args['mode'] == 'sym': environ['LUA_PATH'] = ';'.join(['%s/?.lua' % args['config_root'], environ.get('LUA_PATH', '')]) utils.debug("LUA_PATH=%s" % environ['LUA_PATH']) # each experiment gets its own directory: try: utils.pend("Creating experiment directory %s" % args['exppath']) os.makedirs(args['exppath']) utils.ok() except FileExistsError: utils.fail("Experiment %s already exists. Please choose another name." % args['expname']) exit(1) if args['timeout']: kill_me_later(args['timeout']) obj = None if args['script']: module_file, test = args['script'] with open(module_file, 'r') as f: code = f.read() obj = Script(code=code, test=test) if args['command']: obj = Command.from_cmd_args(args['command'], args['env_var'] or []) if obj: async_send_command(obj, 'localhost', args['command_port'], TIMEOUT_CMD) # drop `s2e-last` symlink somewhere where it does not get in the way: os.chdir(utils.CHEFROOT_EXPDATA) os.execvpe(cmd_line[0], cmd_line, environ)
def export(self, targz: str, **kwargs: dict): if not os.path.isdir(self.path): utils.fail("%s: VM does not exist" % self.name) exit(1) if not targz: targz = '%s.tar.gz' % self.name targz = os.path.abspath(targz) utils.info("exporting to %s" % targz) tar = '%s/%s' % (self.path, os.path.basename(os.path.splitext(targz)[0])) if os.path.exists(targz): utils.fail("%s: package already exists" % targz) exit(1) os.chdir(self.path) # create intermediate files in VM's path utils.pend("package disk image") utils.execute(['tar', '-cSf', tar, os.path.basename(self.path_raw)]) utils.ok() for s in self.snapshots: utils.pend("package snapshot: %s" % s) local_snapshot = '%s.%s' % (os.path.basename(self.path_raw), s) utils.execute(['tar', '-rf', tar, local_snapshot]) utils.ok() utils.pend("compress package", msg="may take some time") utils.execute(['gzip', '-c', tar], outfile=targz) utils.ok() utils.pend("clean up") os.unlink(tar) utils.ok() self.scan_snapshots()
def _import(self, targz: str, raw: bool, force: bool, **kwargs: dict): if raw: self.import_raw(targz, force) return if not os.path.exists(targz): utils.fail("%s: file not found" % targz) exit(1) targz = os.path.abspath(targz) tar = '%s/%s' % (self.path, os.path.basename(os.path.splitext(targz)[0])) self.initialise(force) os.chdir(self.path) # create intermediate files in VM's path utils.pend("decompress package", msg="may take some time") utils.execute(['gzip', '-cd', targz], outfile=tar) utils.ok() utils.pend("scan package") _, file_list, _ = utils.execute(['tar', '-tf', tar], iowrap=True) utils.ok() file_list = file_list.split() for f in file_list: if f == os.path.basename(self.path_raw): utils.pend("extract disk image") else: result = re.search( '(?<=%s\.).+' % os.path.basename(self.path_raw), f ) if not result: utils.warn("misformatted file: %s (skipping)" % f) continue snapshotname = result.group(0) utils.pend("extract snapshot: %s" % snapshotname) utils.execute(['tar', '-x', f, '-f', tar]) utils.ok() utils.pend("clean up") os.unlink(tar) utils.ok()
def clone(self, clone: str, force: bool, **kwargs: dict): if not os.path.isdir(self.path): utils.fail("%s: VM does not exist" % self.name) exit(1) if self.name == clone: utils.fail("%s: please specify a different name" % clone) exit(2) new = VM(clone) new.initialise(force) # http://bugs.python.org/issue10016 utils.pend("copy disk image", msg="may take some time") utils.execute(['cp', self.path_raw, new.path_raw]) utils.ok() for s in self.snapshots: utils.pend("copy snapshot: %s" % s) utils.execute(['cp', '%s.%s' % (self.path_raw, s), new.path]) utils.ok() new.scan_snapshots()
def initialise(self, force: bool): utils.pend("initialise VM") try: os.mkdir(self.path) utils.ok() except PermissionError as pe: utils.fail(pe) exit(1) except OSError as ose: msg = "%s already exists" % self.name if force: utils.info("%s, overwriting" % msg) try: shutil.rmtree(self.path) # FIXME what if PWD == self.path ? os.mkdir(self.path) except PermissionError as pe: utils.fail(pe) exit(1) except OSError as ose2: utils.fail(ose) exit(1) else: utils.info(msg) exit(1)