def cli(force, release, download, jails, recursive): """Destroys the jail's 2 datasets and the snapshot from the RELEASE.""" # Want these here, otherwise they're reinstanced for each jail. zfs = libzfs.ZFS(history=True, history_prefix="<iocage>") iocroot = ioc.PoolAndDataset().get_iocroot() if download and not release: ioc_common.logit({ "level" : "EXCEPTION", "message": "--release (-r) must be specified as well!" }, exit_on_error=True) if jails and not release: for jail in jails: if not force: ioc_common.logit({ "level" : "WARNING", "message": f"\nThis will destroy jail {jail}" }) if not click.confirm("\nAre you sure?"): continue # no, continue to next jail child_test(zfs, iocroot, jail, "jail", force=force, recursive=recursive) ioc.IOCage(exit_on_error=True, jail=jail, skip_jails=True).destroy_jail() elif jails and release: for release in jails: if not force: ioc_common.logit({ "level" : "WARNING", "message": f"\nThis will destroy RELEASE: {release}" }) if not click.confirm("\nAre you sure?"): continue child_test(zfs, iocroot, release, "release", force=force, recursive=recursive) ioc.IOCage(exit_on_error=True, jail=release, skip_jails=True).destroy_release(download) elif not jails and release: ioc_common.logit({ "level" : "EXCEPTION", "message": "Please specify one or more RELEASEs!" }, exit_on_error=True) else: ioc_common.logit({ "level" : "EXCEPTION", "message": "Please specify one or more jails!" }, exit_on_error=True)
def cli(**kwargs): """CLI command that calls fetch_release()""" release = kwargs.get("release", None) _file = kwargs.get("_file", False) if release is not None: if release.lower() == "latest": release = ioc_common.parse_latest_release() kwargs["release"] = release try: release = float(release.rsplit("-", 1)[0].rsplit("-", 1)[0]) except ValueError: ioc_common.logit({ "level": "EXCEPTION", "message": "Please supply a valid entry." }) host_release = float(os.uname()[2].rsplit("-", 1)[0].rsplit("-", 1)[0]) if host_release < release and not _file: ioc_common.logit({ "level": "EXCEPTION", "message": f"\nHost: {host_release} is not greater than" f" target: {release}\nThis is unsupported." }) ioc.IOCage(exit_on_error=True).fetch(**kwargs)
def cli(dataset_type, header, _long, remote, http, plugins, _sort): """This passes the arg and calls the jail_datasets function.""" freebsd_version = ioc_common.checkoutput(["freebsd-version"]) if dataset_type is None: dataset_type = "all" if remote: if "HBSD" in freebsd_version: hardened = True else: hardened = False ioc_fetch.IOCFetch("", http=http, hardened=hardened).fetch_release(_list=True) elif plugins: ioc_fetch.IOCFetch("").fetch_plugin_index("", _list=True) else: _list = ioc.IOCage().list(dataset_type, header, _long, _sort) if not header: if dataset_type == "base": for item in _list: ioc_common.logit({"level": "INFO", "message": item}) else: for item in _list: ioc_common.logit({ "level": "INFO", "message": "\t".join(item) }) else: ioc_common.logit({"level": "INFO", "message": _list})
def cli(jail): """ Runs jexec to login into the specified jail. """ # Command is empty since this command is hardcoded later on. ioc.IOCage(exit_on_error=True, jail=jail, silent=True).exec("", console=True)
def __rollback_jail__(self): import iocage.lib.iocage as ioc # Avoids dep issues name = f"ioc_upgrade_{self.date}" iocage = ioc.IOCage(jail=self.uuid, exit_on_error=self.exit_on_error, skip_jails=True, silent=True) iocage.stop() iocage.rollback(name)
def __snapshot_jail__(self): import iocage.lib.iocage as ioc # Avoids dep issues name = f"ioc_upgrade_{self.date}" ioc.IOCage(jail=self.uuid, exit_on_error=self.exit_on_error, skip_jails=True, silent=True).snapshot(name)
def fetch(self, job, options): """Fetches a release or plugin.""" self.check_dataset_existence() # Make sure our datasets exist. iocage = ioc.IOCage() iocage.fetch(**options) return True
def get_activated_pool(self): """Returns the activated pool if there is one, or None""" try: pool = ioc.IOCage(skip_jails=True).get("", pool=True) except Exception: pool = None return pool
def cli(rc, force, jails): """ Looks for the jail supplied and passes the uuid, path and configuration location to stop_jail. """ if not jails and not rc: ioc_common.logit({ "level" : "EXCEPTION", "message": 'Usage: iocage stop [OPTIONS] JAILS...\n' '\nError: Missing argument "jails".' }, exit_on_error=True) if rc: ioc.IOCage(exit_on_error=True, rc=rc, silent=True).stop(force=force) else: for jail in jails: ioc.IOCage(exit_on_error=True, jail=jail, rc=rc).stop(force=force)
def cli(zpool): """Calls ZFS set to change the property org.freebsd.ioc:active to yes.""" ioc.IOCage(activate=True).activate(zpool) ioc_common.logit({ "level": "INFO", "message": f"ZFS pool '{zpool}' successfully activated." })
def cli(rc, jails): """ Looks for the jail supplied and passes the uuid, path and configuration location to start_jail. """ if not jails and not rc: ioc_common.logit({ "level" : "ERROR", "message": 'Usage: iocage start [OPTIONS] JAILS...\n' '\nError: Missing argument "jails".' }) exit(1) if rc: ioc.IOCage(rc=rc, silent=True).start() else: for jail in jails: ioc.IOCage(jail, rc=rc).start()
def check_jail_existence(self, jail, skip=True): """Wrapper for iocage's API, as a few commands aren't ported to it""" try: iocage = ioc.IOCage(skip_jails=skip, jail=jail) jail, path = iocage.__check_jail_existence__() except SystemExit: raise CallError(f"jail '{jail}' not found!") return jail, path, iocage
def __snapshot_jail__(self, name): """Snapshot the plugin""" # Utilize the nicer API interface for this import iocage.lib.iocage as ioc # Avoids dep issues name = f"ioc_plugin_{name}_{self.date}" ioc.IOCage(jail=self.plugin, exit_on_error=self.exit_on_error, skip_jails=True, silent=True).snapshot(name)
def cli(source, props, count, name, _uuid): # At this point we don't care _uuid = name if name else _uuid err, msg = ioc.IOCage(jail=source).create(source, props, count, _uuid=_uuid, clone=True) if err: ioc_common.logit({ "level" : "EXCEPTION", "message": msg })
def get_activated_pool(self): """Returns the activated pool if there is one, or None""" pool = None try: pool = ioc.IOCage(skip_jails=True).get("", pool=True) except KeyError: pass else: raise return pool
def fetch(self, job, options): """Fetches a release or plugin.""" self.check_dataset_existence() # Make sure our datasets exist. if options["name"] is not None: options["plugins"] = True iocage = ioc.IOCage() iocage.fetch(**options) return True
def __rollback_jail__(self, name): """Rollback the plugins snapshot""" # Utilize the nicer API interface for this import iocage.lib.iocage as ioc # Avoids dep issues name = f"ioc_plugin_{name}_{self.date}" iocage = ioc.IOCage(jail=self.plugin, exit_on_error=self.exit_on_error, skip_jails=True, silent=True) iocage.stop() iocage.rollback(name)
def cli(jail, name, force): """Get a list of jails and print the property.""" if not force: ioc_common.logit({ "level" : "WARNING", "message": "\nThis will destroy ALL data created including " f"ALL snapshots taken after the snapshot {name}" }) if not click.confirm("\nAre you sure?"): exit() ioc.IOCage(exit_on_error=True, jail=jail).rollback(name)
def cli(dataset_type, header, _long, remote, http, plugins, _sort, quick, official): """This passes the arg and calls the jail_datasets function.""" freebsd_version = ioc_common.checkoutput(["freebsd-version"]) iocage = ioc.IOCage(exit_on_error=True, skip_jails=True) if dataset_type is None: dataset_type = "all" if remote and not plugins: if "HBSD" in freebsd_version: hardened = True else: hardened = False _list = iocage.fetch(list=True, remote=True, http=http, hardened=hardened) header = False if plugins and remote: _list = iocage.fetch(list=True, remote=True, header=header, _long=_long, plugin_file=True, official=official) elif not remote: _list = iocage.list(dataset_type, header, _long, _sort, plugin=plugins, quick=quick) if not header: if dataset_type == "base": for item in _list: ioc_common.logit({"level": "INFO", "message": item}) else: for item in _list: if remote and not plugins: ioc_common.logit({"level": "INFO", "message": item}) else: ioc_common.logit({ "level": "INFO", "message": "\t".join(item) }) else: ioc_common.logit({"level": "INFO", "message": _list})
def cli(header, jail, _long): """Allows a user to show resource usage of all jails.""" table = texttable.Texttable(max_width=0) snap_list = ioc.IOCage(jail).snap_list(_long) if header: snap_list.insert(0, ["NAME", "CREATED", "RSIZE", "USED"]) # We get an infinite float otherwise. table.set_cols_dtype(["t", "t", "t", "t"]) table.add_rows(snap_list) ioc_common.logit({"level": "INFO", "message": table.draw()}) else: for snap in snap_list: ioc_common.logit({"level": "INFO", "message": "\t".join(snap)})
def cli(command, jail, host_user, jail_user): """Runs the command given inside the specified jail as the supplied user.""" # We may be getting ';', '&&' and so forth. Adding the shell for safety. if len(command) == 1: command = ("/bin/sh", "-c") + command if jail.startswith("-"): ioc_common.logit({ "level": "EXCEPTION", "message": "Please specify a jail first!" }) ioc.IOCage(jail).exec(command, host_user, jail_user)
def rc_action(self, action): """Does specified action on rc enabled (boot=on) jails""" iocage = ioc.IOCage(rc=True) if action == "START": iocage.start() elif action == "STOP": iocage.stop() else: iocage.stop() time.sleep(0.5) iocage.start() return True
async def query(self, filters=None, options=None): options = options or {} jails = [] try: jails = [ list(jail.values())[0] for jail in ioc.IOCage().get("all", recursive=True) ] except BaseException: # Brandon is working on fixing this generic except, till then I # am not going to make the perfect the enemy of the good enough! self.logger.debug("iocage failed to fetch jails", exc_info=True) pass return filter_list(jails, filters, options)
def cli(jail, props, plugin): """Get a list of jails and print the property.""" if not props: # Click doesn't correctly assign the two variables for some reason ioc_common.logit( { "level": "EXCEPTION", "message": "You must specify a jail!" }, exit_on_error=True) for prop in props: ioc.IOCage( exit_on_error=True, jail=jail, skip_jails=True).set(prop, plugin)
def query(self, filters=None, options=None): options = options or {} jail_identifier = None jails = [] if filters and len(filters) == 1 and list( filters[0][:2]) == ['host_hostuuid', '=']: jail_identifier = filters[0][2] recursive = False if jail_identifier == 'default' else True try: jail_dicts = ioc.IOCage(jail=jail_identifier).get( 'all', recursive=recursive) if jail_identifier == 'default': jail_dicts['host_hostuuid'] = 'default' jails.append(jail_dicts) else: for jail in jail_dicts: jail = list(jail.values())[0] if jail['dhcp'] == 'on': uuid = jail['host_hostuuid'] if jail['state'] == 'up': interface = jail['interfaces'].split(',')[0].split( ':')[0] if interface == 'vnet0': # Inside jails they are epair0b interface = 'epair0b' ip4_cmd = [ 'jexec', f'ioc-{uuid}', 'ifconfig', interface, 'inet' ] out = su.check_output(ip4_cmd) jail['ip4_addr'] = f'{interface}|' \ f'{out.splitlines()[2].split()[1].decode()}' else: jail['ip4_address'] = 'DHCP (not running)' jails.append(jail) except BaseException: # Brandon is working on fixing this generic except, till then I # am not going to make the perfect the enemy of the good enough! self.logger.debug('iocage failed to fetch jails', exc_info=True) pass return filter_list(jails, filters, options)
def cli(**kwargs): """CLI command that calls fetch_release()""" release = kwargs.get("release", None) host_release = os.uname()[2].rsplit("-", 1)[0] if release is not None: if host_release < release: ioc_common.logit({ "level": "EXCEPTION", "message": f"\nHost: {host_release} is not greater than" f" target: {release}\nThis is unsupported." }) ioc.IOCage(exit_on_error=True).fetch(**kwargs)
def cli(force, dataset_type): """Calls the correct destroy function.""" if dataset_type == "jails": msg = { "level": "WARNING", "message": "\nThis will destroy ALL jails and any " "snapshots on a RELEASE," "including templates!" } elif dataset_type == "all": msg = { "level": "WARNING", "message": "\nThis will destroy ALL iocage data!" } elif dataset_type == "release": msg = { "level": "WARNING", "message": "\nThis will destroy ALL fetched RELEASES and" " jails/templates created from them!" } elif dataset_type == "template": msg = { "level": "WARNING", "message": "This will destroy ALL templates and jails" " created from them!" } else: ioc_common.logit( { "level": "EXCEPTION", "message": "Please specify a dataset type to clean!" }, exit_on_error=True) if not force: ioc_common.logit(msg) if not click.confirm("\nAre you sure?"): exit() ioc.IOCage(exit_on_error=True, skip_jails=True).clean(dataset_type)
def cli(header, _long, _sort): """Allows a user to show resource usage of all jails.""" table = texttable.Texttable(max_width=0) jail_list = ioc.IOCage().df(long=_long) sort = ioc_common.ioc_sort("df", _sort) jail_list.sort(key=sort) if header: jail_list.insert(0, ["NAME", "CRT", "RES", "QTA", "USE", "AVA"]) # We get an infinite float otherwise. table.set_cols_dtype(["t", "t", "t", "t", "t", "t"]) table.add_rows(jail_list) ioc_common.logit({"level": "INFO", "message": table.draw()}) else: for jail in jail_list: ioc_common.logit({"level": "INFO", "message": "\t".join(jail)})
def list_resource(self, resource, remote): """Returns a JSON list of the supplied resource on the host""" self.check_dataset_existence() # Make sure our datasets exist. iocage = ioc.IOCage(skip_jails=True) remote = True if resource == "PLUGIN" else remote resource = "base" if resource == "RELEASE" else resource.lower() if resource == "plugin": resource_list = iocage.fetch(list=True, remote=True, plugin_file=True) elif resource == "base": resource_list = iocage.fetch(list=True, remote=remote, http=True) else: resource_list = iocage.list(resource) return resource_list
def cli(command, jail, host_user, jail_user): """Runs the command given inside the specified jail as the supplied user.""" # We may be getting ';', '&&' and so forth. Adding the shell for safety. if len(command) == 1: command = ("/bin/sh", "-c") + command if jail.startswith("-"): ioc_common.logit({ "level" : "EXCEPTION", "message": "Please specify a jail first!" }, exit_on_error=True) # They haven't set a host_user then, and actually want a jail one, # unsetting the convenience default host_user = "" if jail_user and host_user == "root" else host_user ioc.IOCage(exit_on_error=True, jail=jail).exec(command, host_user, jail_user)