def migrate_cmd(force, delete): """Migrates all the iocage_legacy develop basejails to clone jails.""" lgr = ioc_logger.Logger('ioc_cli_migrate').getLogger() jails, paths = IOCList("uuid").list_datasets() if not force: lgr.warning("\nThis will migrate ALL basejails to " "clonejails, it can take a long time!") if not click.confirm("\nAre you sure?"): exit() for tag, uuid in jails.items(): pool = IOCJson().json_get_value("pool") iocroot = IOCJson(pool).json_get_value("iocroot") jail = "{}/iocage/jails/{}".format(pool, uuid) jail_old = "{}/iocage/jails_old/{}".format(pool, uuid) path = paths[tag] conf = IOCJson(path).json_load() release = conf["release"] if conf["type"] == "basejail": try: checkoutput(["zfs", "rename", "-p", jail, jail_old], stderr=STDOUT) except CalledProcessError as err: lgr.critical("{}".format(err.output.decode("utf-8").strip())) exit(1) try: os.remove("{}/tags/{}".format(iocroot, tag)) except OSError: pass new_uuid = IOCCreate(release, "", 0, None, migrate=True, config=conf, silent=True).create_jail() new_prop = IOCJson("{}/jails/{}".format(iocroot, new_uuid), silent=True).json_set_value new_prop("host_hostname={}".format(new_uuid)) new_prop("host_hostuuid={}".format(new_uuid)) new_prop("type=jail") new_prop( "jail_zfs_dataset={}/jails/{}/data".format(iocroot, new_uuid)) lgr.info("Copying files for {} ({}), please wait...".format( uuid, tag )) copytree("{}/jails_old/{}/root".format(iocroot, uuid), "{}/jails/{}/root".format(iocroot, new_uuid), symlinks=True) copy("{}/jails_old/{}/fstab".format(iocroot, uuid), "{}/jails/{}/fstab".format(iocroot, new_uuid)) for line in fileinput.input("{}/jails/{}/root/etc/rc.conf".format( iocroot, new_uuid), inplace=1): lgr.info(line.replace(f'hostname="{uuid}"', f'hostname="{new_uuid}"').rstrip()) if delete: try: checkoutput(["zfs", "destroy", "-r", "-f", jail_old], stderr=STDOUT) except CalledProcessError as err: raise RuntimeError("{}".format( err.output.decode("utf-8").rstrip())) try: check_call(["zfs", "destroy", "-r", "-f", "{}/iocage/jails_old".format(pool)]) except CalledProcessError: # We just want the top level dataset gone, no big deal. pass lgr.info("{} ({}) migrated to {} ({})!\n".format(uuid, tag, new_uuid, tag))
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()}" }, exit_on_error=True) 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, exit_on_error=True).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" })
def cli(force, delete): """Migrates all the iocage_legacy develop basejails to clone jails.""" jails, paths = ioc_list.IOCList("uuid").list_datasets() if not force: ioc_common.logit({ "level": "WARNING", "message": "\nThis will migrate ALL basejails to clonejails," " it can take a long time!" }) if not click.confirm("\nAre you sure?"): exit() for tag, uuid 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}" path = paths[tag] conf = ioc_json.IOCJson(path).json_load() release = conf["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": "ERROR", "message": f"{err.output.decode('utf-8').strip()}" }) exit(1) try: os.remove(f"{iocroot}/tags/{tag}") except OSError: pass new_uuid = ioc_create.IOCCreate(release, "", 0, None, migrate=True, config=conf, silent=True).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": "Copying files for {uuid} ({tag}), 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): ioc_common.logit({ "level": "INFO", "message": 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}" f" ({tag})!\n" })