예제 #1
0
파일: migrate.py 프로젝트: worr/iocage
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"
            })
예제 #2
0
    def create(self,
               release,
               props,
               count=0,
               pkglist=None,
               template=False,
               short=False,
               _uuid=None,
               basejail=False,
               empty=False,
               clone=None,
               skip_batch=False):
        """Creates the jail dataset"""
        count = 0 if count == 1 and not skip_batch else count

        if short and _uuid:
            _uuid = _uuid[:8]

            if len(_uuid) != 8:
                ioc_common.logit(
                    {
                        "level":
                        "EXCEPTION",
                        "message":
                        "Need a minimum of 8 characters to use --short"
                        " (-s) and --uuid (-u) together!"
                    },
                    _callback=self.callback,
                    silent=self.silent)

        if not template and not release and not empty and not clone:
            ioc_common.logit(
                {
                    "level":
                    "EXCEPTION",
                    "message":
                    "Must supply either --template (-t) or"
                    " --release (-r)!"
                },
                _callback=self.callback,
                silent=self.silent)

        if not os.path.isdir(
                f"{self.iocroot}/releases/{release}") and not template and \
                not empty and not clone:
            freebsd_version = ioc_common.checkoutput(["freebsd-version"])

            if "HBSD" in freebsd_version:
                hardened = True
            else:
                hardened = False

            ioc_fetch.IOCFetch(release, hardened=hardened,
                               silent=self.silent).fetch_release()

        if clone:
            clone_uuid, _ = self.__check_jail_existence__()
            status, _ = self.list("jid", uuid=clone_uuid)
            if status:
                ioc_common.logit(
                    {
                        "level":
                        "EXCEPTION",
                        "message":
                        f"Jail: {self.jail} must not be running to be"
                        " cloned!"
                    },
                    _callback=self.callback,
                    silent=self.silent)

            release = clone_uuid
            clone = self.jail

        try:
            if count > 1 and not skip_batch:
                for j in range(1, count + 1):
                    try:
                        if _uuid is not None:
                            uuid.UUID(_uuid, version=4)

                        count_uuid = _uuid  # Is a UUID
                    except ValueError:
                        # This will allow named jails to use count
                        # This can probably be smarter
                        count_uuid = f"{_uuid}_{j}"

                    self.create(release,
                                props,
                                j,
                                pkglist=pkglist,
                                template=template,
                                short=short,
                                _uuid=count_uuid,
                                basejail=basejail,
                                empty=empty,
                                clone=clone,
                                skip_batch=True)
            else:
                ioc_create.IOCCreate(release,
                                     props,
                                     count,
                                     pkglist,
                                     template=template,
                                     short=short,
                                     uuid=_uuid,
                                     basejail=basejail,
                                     empty=empty,
                                     clone=clone,
                                     silent=self.silent).create_jail()
        except RuntimeError:
            raise

        return False, None
예제 #3
0
파일: iocage.py 프로젝트: gronke/iocage
    def create(self,
               release,
               props,
               count=0,
               pkglist=None,
               template=False,
               short=False,
               uuid=None,
               basejail=False,
               empty=False,
               clone=None):
        if short and uuid:
            uuid = uuid[:8]

            if len(uuid) != 8:
                ioc_common.logit(
                    {
                        "level":
                        "EXCEPTION",
                        "message":
                        "Need a minimum of 8 characters to use --short"
                        " (-s) and --uuid (-u) together!"
                    },
                    _callback=self.callback,
                    silent=self.silent)

        if not template and not release and not empty and not clone:
            ioc_common.logit(
                {
                    "level":
                    "EXCEPTION",
                    "message":
                    "Must supply either --template (-t) or"
                    " --release (-r)!"
                },
                _callback=self.callback,
                silent=self.silent)

        if not os.path.isdir(
                f"{self.iocroot}/releases/{release}") and not template and \
                not empty and not clone:
            freebsd_version = ioc_common.checkoutput(["freebsd-version"])

            if "HBSD" in freebsd_version:
                hardened = True
            else:
                hardened = False

            ioc_fetch.IOCFetch(release, hardened=hardened).fetch_release()

        if clone:
            _, clone_uuid, _ = self.__check_jail_existence__()
            status, _ = self.list("jid", uuid=clone_uuid)
            if status:
                ioc_common.logit(
                    {
                        "level":
                        "EXCEPTION",
                        "message":
                        f"Jail: {self.jail} must not be running to be"
                        " cloned!"
                    },
                    _callback=self.callback,
                    silent=self.silent)

            release = clone_uuid
            clone = self.jail

        try:
            ioc_create.IOCCreate(release,
                                 props,
                                 count,
                                 pkglist,
                                 template=template,
                                 short=short,
                                 uuid=uuid,
                                 basejail=basejail,
                                 empty=empty,
                                 clone=clone).create_jail()
        except RuntimeError as err:
            return True, err

        return False, None
예제 #4
0
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"
                    })