def __get_jail_props__(self, name, path): """Avoids a circular dep with iocage_lib.ioc""" _props = {} status, jid = ioc_list.IOCList().list_get_jid(name) state = 'up' if status else 'down' props = ioc_json.IOCJson(path).json_get_value('all') # We want this sorted below, so we add it to the old dict props['state'] = state for key in sorted(props.keys()): _props[key] = props[key] return _props
def cli(jail, name): """Removes a snapshot from a user supplied jail.""" # TODO: Move to API jails = ioc_list.IOCList("uuid").list_datasets() pool = ioc_json.IOCJson().json_get_value("pool") _jail = { uuid: path for (uuid, path) in jails.items() if uuid.startswith(jail) } if len(_jail) == 1: uuid, path = next(iter(_jail.items())) elif len(_jail) > 1: ioc_common.logit({ "level": "ERROR", "message": f"Multiple jails found for {jail}:" }) for u, p in sorted(_jail.items()): ioc_common.logit({"level": "ERROR", "message": f" {u} ({p})"}) exit(1) else: ioc_common.logit({ "level": "EXCEPTION", "message": f"{jail} not found!" }) # Looks like foo/iocage/jails/df0ef69a-57b6-4480-b1f8-88f7b6febbdf@BAR conf = ioc_json.IOCJson(path).json_load() if conf["template"] == "yes": target = f"{pool}/iocage/templates/{uuid}@{name}" else: target = f"{pool}/iocage/jails/{uuid}@{name}" try: su.check_call(["zfs", "destroy", "-r", "-f", target]) ioc_common.logit({ "level": "INFO", "message": f"Snapshot: {target} destroyed." }) except su.CalledProcessError as err: ioc_common.logit({"level": "EXCEPTION", "message": f"{err}"}) exit(1)
def __get_jail_props__(self, name, path): """Avoids a circular dep with iocage_lib.ioc""" _props = {} status, jid = ioc_list.IOCList().list_get_jid(name) state = 'up' if status else 'down' try: props = ioc_json.IOCJson(path).json_get_value('all') except (Exception, SystemExit): # Jail is corrupt, we want all the keys to exist. _props['state'] = 'CORRUPT' return _props # We want this sorted below, so we add it to the old dict props['state'] = state for key in sorted(props.keys()): _props[key] = props[key] return _props
def cli(force, delete): """Migrates all the iocage_legacy develop basejails to clone jails.""" # TODO: Move to API jails = ioc_list.IOCList("uuid").list_datasets() if not force: ioc_common.logit({ "level": "WARNING", "message": "\nThis will migrate ALL iocage-legacy develop" " basejails to clonejails, it can take a long" " time!\nPlease make sure you are not running" " this on iocage-legacy 1.7.6 basejails." }) if not click.confirm("\nAre you sure?"): exit() for uuid, path in jails.items(): pool = ioc_json.IOCJson().json_get_value("pool") iocroot = ioc_json.IOCJson(pool).json_get_value("iocroot") jail = f"{pool}/iocage/jails/{uuid}" jail_old = f"{pool}/iocage/jails_old/{uuid}" conf = ioc_json.IOCJson(path).json_load() try: tag = conf["tag"] except KeyError: # These are actually NEW jails. continue release = conf["cloned_release"] if conf["type"] == "basejail": try: ioc_common.checkoutput(["zfs", "rename", "-p", jail, jail_old], stderr=su.STDOUT) except su.CalledProcessError as err: ioc_common.logit({ "level": "EXCEPTION", "message": f"{err.output.decode('utf-8').strip()}" }) try: os.remove(f"{iocroot}/tags/{tag}") except OSError: pass date_fmt_legacy = "%Y-%m-%d@%H:%M:%S" # We don't want to rename datasets to a bunch of dates. try: datetime.datetime.strptime(tag, date_fmt_legacy) _name = str(uuid.uuid4()) except ValueError: # They already named this jail, making it like our new ones. _name = tag new_uuid = ioc_create.IOCCreate( release, "", 0, None, migrate=True, config=conf, silent=True, uuid=_name, ).create_jail() new_prop = ioc_json.IOCJson(f"{iocroot}/jails/{new_uuid}", silent=True).json_set_value new_prop(f"host_hostname={new_uuid}") new_prop(f"host_hostuuid={new_uuid}") new_prop("type=jail") new_prop(f"jail_zfs_dataset={iocroot}/jails/{new_uuid}/data") ioc_common.logit({ "level": "INFO", "message": f"Copying files for {new_uuid}, please wait..." }) ioc_common.copytree(f"{iocroot}/jails_old/{uuid}/root", f"{iocroot}/jails/{new_uuid}/root", symlinks=True) shutil.copy(f"{iocroot}/jails_old/{uuid}/fstab", f"{iocroot}/jails/{new_uuid}/fstab") for line in fileinput.input( f"{iocroot}/jails/{new_uuid}/root/etc/" "rc.conf", inplace=1): print( line.replace(f'hostname="{uuid}"', f'hostname="{new_uuid}"').rstrip()) if delete: try: ioc_common.checkoutput( ["zfs", "destroy", "-r", "-f", jail_old], stderr=su.STDOUT) except su.CalledProcessError as err: raise RuntimeError( f"{err.output.decode('utf-8').rstrip()}") try: su.check_call([ "zfs", "destroy", "-r", "-f", f"{pool}/iocage/jails_old" ]) except su.CalledProcessError: # We just want the top level dataset gone, no big deal. pass ioc_common.logit({ "level": "INFO", "message": f"{uuid} ({tag}) migrated to {new_uuid}!\n" })