Esempio n. 1
0
def update_cmd(jail):
    """Runs update with the command given inside the specified jail."""
    lgr = ioc_logger.Logger('ioc_cli_update').getLogger()

    jails, paths = IOCList("uuid").list_datasets()
    _jail = {
        tag: uuid
        for (tag, uuid) in jails.items()
        if uuid.startswith(jail) or tag == jail
    }

    if len(_jail) == 1:
        tag, uuid = next(iter(_jail.items()))
        path = paths[tag]
    elif len(_jail) > 1:
        lgr.error("Multiple jails found for" " {}:".format(jail))
        for t, u in sorted(_jail.items()):
            lgr.critical("  {} ({})".format(u, t))
        exit(1)
    else:
        lgr.critical("{} not found!".format(jail))
        exit(1)

    freebsd_version = checkoutput(["freebsd-version"])
    status, jid = IOCList.list_get_jid(uuid)
    conf = IOCJson(path).json_load()
    started = False

    if conf["type"] == "jail":
        if not status:
            IOCStart(uuid, tag, path, conf, silent=True)
            status, jid = IOCList.list_get_jid(uuid)
            started = True
    elif conf["type"] == "basejail":
        lgr.critical("Please run \"iocage migrate\" before trying"
                     " to update {} ({})".format(uuid, tag))
        exit(1)
    elif conf["type"] == "template":
        lgr.critical("Please convert back to a jail before trying"
                     " to update {} ({})".format(uuid, tag))
        exit(1)
    else:
        lgr.critical("{} is not a supported jail type.".format(conf["type"]))
        exit(1)

    if "HBSD" in freebsd_version:
        Popen(["hbsd-update", "-j", jid]).communicate()

        if started:
            IOCStop(uuid, tag, path, conf, silent=True)
    else:
        IOCFetch(conf["cloned_release"]).fetch_update(True, uuid, tag)

        if started:
            IOCStop(uuid, tag, path, conf, silent=True)
Esempio n. 2
0
    def update_to_latest_patch(self, job, jail):
        """Updates specified jail to latest patch level."""

        uuid, path, _ = self.check_jail_existence(jail)
        status, jid = IOCList.list_get_jid(uuid)
        conf = IOCJson(path).json_load()

        # Sometimes if they don't have an existing patch level, this
        # becomes 11.1 instead of 11.1-RELEASE
        _release = conf["release"].rsplit("-", 1)[0]
        release = _release if "-RELEASE" in _release else conf["release"]

        started = False

        if conf["type"] == "jail":
            if not status:
                self.start(jail)
                started = True
        else:
            return False

        if conf["basejail"] != "yes":
            IOCFetch(release).fetch_update(True, uuid)
        else:
            # Basejails only need their base RELEASE updated
            IOCFetch(release).fetch_update()

        if started:
            self.stop(jail)

        return True
Esempio n. 3
0
    def update(self, job, jail):
        # FIXME: No-op until I change iocage behavior with freebsd-update
        # not existing.
        # TODO: upgrade needs to be broken out of cli.
        """Updates specified jail to latest patch level."""
        from iocage.lib.ioc_fetch import IOCFetch

        tag, uuid, path = self.check_jail_existence(jail)
        status, jid = IOCList.list_get_jid(uuid)
        conf = IOCJson(path).json_load()
        started = False

        if conf["type"] == "jail":
            if not status:
                self.start(jail)
                started = True
        else:
            return False

        IOCFetch(conf["cloned_release"]).fetch_update(True, uuid, tag)

        if started:
            self.stop(jail)

        return True
Esempio n. 4
0
    def get(self, jail, options):
        """Gets a jail property."""
        prop = options["prop"]
        plugin = options["plugin"]

        tag, uuid, path = self.check_jail_existence(jail)

        if "template" in prop.split("=")[0]:
            if "template" in path and prop != "template=no":
                raise RuntimeError(f"{uuid} ({tag}) is already a template!")
            elif "template" not in path and prop != "template=yes":
                raise RuntimeError(f"{uuid} ({tag}) is already a jail!")

        if plugin:
            _prop = prop.split(".")
            return IOCJson(path).json_plugin_set_value(_prop)

        if prop == "all":
            return IOCJson(path).json_get_value(prop)
        elif prop == "state":
            status, _ = IOCList.list_get_jid(path.split("/")[3])

            if status:
                return "UP"
            else:
                return "DOWN"

        return IOCJson(path).json_get_value(prop)
Esempio n. 5
0
    def update_to_latest_patch(self, job, jail):
        """Updates specified jail to latest patch level."""

        uuid, path, _ = self.check_jail_existence(jail)
        status, jid = IOCList.list_get_jid(uuid)
        conf = IOCJson(path).json_load()

        # Sometimes if they don't have an existing patch level, this
        # becomes 11.1 instead of 11.1-RELEASE
        _release = conf["release"].rsplit("-", 1)[0]
        release = _release if "-RELEASE" in _release else conf["release"]

        started = False

        if conf["type"] == "jail":
            if not status:
                self.start(jail)
                started = True
        else:
            return False

        if conf["basejail"] != "yes":
            IOCFetch(release).fetch_update(True, uuid)
        else:
            # Basejails only need their base RELEASE updated
            IOCFetch(release).fetch_update()

        if started:
            self.stop(jail)

        return True
Esempio n. 6
0
    def get(self, jail, options):
        """Gets a jail property."""
        prop = options["prop"]
        plugin = options["plugin"]

        tag, uuid, path = self.check_jail_existence(jail)

        if "template" in prop.split("=")[0]:
            if "template" in path and prop != "template=no":
                raise RuntimeError(f"{uuid} ({tag}) is already a template!")
            elif "template" not in path and prop != "template=yes":
                raise RuntimeError(f"{uuid} ({tag}) is already a jail!")

        if plugin:
            _prop = prop.split(".")
            return IOCJson(path).json_plugin_set_value(_prop)

        if prop == "all":
            return IOCJson(path).json_get_value(prop)
        elif prop == "state":
            status, _ = IOCList.list_get_jid(path.split("/")[3])

            if status:
                return "UP"
            else:
                return "DOWN"

        return IOCJson(path).json_get_value(prop)
Esempio n. 7
0
 def __init__(self, conf, new_release, path):
     self.lgr = logging.getLogger("ioc_upgrade")
     self.pool = IOCJson().json_get_value("pool")
     self.iocroot = IOCJson(self.pool).json_get_value("iocroot")
     self.freebsd_version = checkoutput(["freebsd-version"])
     self.conf = conf
     self.uuid = conf["host_hostuuid"]
     self.host_release = os.uname()[2]
     self.jail_release = conf["cloned_release"]
     self.new_release = new_release
     self.path = path
     self.status, self.jid = IOCList.list_get_jid(self.uuid)
     self._freebsd_version = f"{self.iocroot}/releases/" \
                             f"{new_release}/root/bin/freebsd-version"
Esempio n. 8
0
    def export(self, job, jail):
        """Exports jail to zip file"""
        uuid, path, _ = self.check_jail_existence(jail)
        status, jid = IOCList.list_get_jid(uuid)
        started = False

        if status:
            self.stop(jail)
            started = True

        IOCImage().export_jail(uuid, path)

        if started:
            self.start(jail)

        return True
Esempio n. 9
0
    def export(self, job, jail):
        """Exports jail to zip file"""
        uuid, path, _ = self.check_jail_existence(jail)
        status, jid = IOCList.list_get_jid(uuid)
        started = False

        if status:
            self.stop(jail)
            started = True

        IOCImage().export_jail(uuid, path)

        if started:
            self.start(jail)

        return True
Esempio n. 10
0
    def export(self, job, jail):
        """Exports jail to zip file"""
        from iocage.lib.ioc_image import IOCImage
        tag, uuid, path = self.check_jail_existence(jail)
        status, jid = IOCList.list_get_jid(uuid)
        started = False

        if status:
            self.stop(jail)
            started = True

        IOCImage().export_jail(uuid, tag, path)

        if started:
            self.start(jail)

        return True
Esempio n. 11
0
    def export(self, job, jail):
        """Exports jail to zip file"""
        from iocage.lib.ioc_image import IOCImage
        tag, uuid, path = self.check_jail_existence(jail)
        status, jid = IOCList.list_get_jid(uuid)
        started = False

        if status:
            self.stop(jail)
            started = True

        IOCImage().export_jail(uuid, tag, path)

        if started:
            self.start(jail)

        return True
Esempio n. 12
0
    def upgrade(self, job, jail, release):
        """Upgrades specified jail to specified RELEASE."""

        uuid, path, _ = self.check_jail_existence(jail)
        status, jid = IOCList.list_get_jid(uuid)
        conf = IOCJson(path).json_load()
        root_path = f"{path}/root"
        started = False

        if conf["type"] == "jail":
            if not status:
                self.start(jail)
                started = True
        else:
            return False

        IOCUpgrade(conf, release, root_path).upgrade_jail()

        if started:
            self.stop(jail)

        return True
Esempio n. 13
0
    def upgrade(self, job, jail, release):
        """Upgrades specified jail to specified RELEASE."""

        uuid, path, _ = self.check_jail_existence(jail)
        status, jid = IOCList.list_get_jid(uuid)
        conf = IOCJson(path).json_load()
        root_path = f"{path}/root"
        started = False

        if conf["type"] == "jail":
            if not status:
                self.start(jail)
                started = True
        else:
            return False

        IOCUpgrade(conf, release, root_path).upgrade_jail()

        if started:
            self.stop(jail)

        return True
Esempio n. 14
0
    def update(self, job, jail):
        """Updates specified jail to latest patch level."""
        from iocage.lib.ioc_fetch import IOCFetch

        tag, uuid, path = self.check_jail_existence(jail)
        status, jid = IOCList.list_get_jid(uuid)
        conf = IOCJson(path).json_load()
        started = False

        if conf["type"] == "jail":
            if not status:
                self.start(jail)
                started = True
        else:
            return False

        IOCFetch(conf["cloned_release"]).fetch_update(True, uuid, tag)

        if started:
            self.stop(jail)

        return True
Esempio n. 15
0
    def update(self, job, jail):
        """Updates specified jail to latest patch level."""
        from iocage.lib.ioc_fetch import IOCFetch

        tag, uuid, path = self.check_jail_existence(jail)
        status, jid = IOCList.list_get_jid(uuid)
        conf = IOCJson(path).json_load()
        started = False

        if conf["type"] == "jail":
            if not status:
                self.start(jail)
                started = True
        else:
            return False

        IOCFetch(conf["cloned_release"]).fetch_update(True, uuid, tag)

        if started:
            self.stop(jail)

        return True
Esempio n. 16
0
def upgrade_cmd(jail, release):
    """Runs upgrade with the command given inside the specified jail."""
    lgr = logging.getLogger('ioc_cli_upgrade')

    jails, paths = IOCList("uuid").list_datasets()
    _jail = {
        tag: uuid
        for (tag, uuid) in jails.items()
        if uuid.startswith(jail) or tag == jail
    }

    if len(_jail) == 1:
        tag, uuid = next(iter(_jail.items()))
        path = paths[tag]
        root_path = "{}/root".format(path)
    elif len(_jail) > 1:
        lgr.error("Multiple jails found for" " {}:".format(jail))
        for t, u in sorted(_jail.items()):
            lgr.error("  {} ({})".format(u, t))
        raise RuntimeError()
    else:
        raise RuntimeError("{} not found!".format(jail))

    pool = IOCJson().json_get_value("pool")
    iocroot = IOCJson(pool).json_get_value("iocroot")
    freebsd_version = checkoutput(["freebsd-version"])
    status, jid = IOCList.list_get_jid(uuid)
    conf = IOCJson(path).json_load()
    host_release = os.uname()[2]
    jail_release = conf["release"]
    started = False

    if conf["release"] == "EMPTY":
        raise RuntimeError("Upgrading is not supported for empty jails.")

    if conf["type"] == "jail":
        if not status:
            IOCStart(uuid, tag, path, conf, silent=True)
            status, jid = IOCList.list_get_jid(uuid)
            started = True
    elif conf["type"] == "basejail":
        raise RuntimeError("Please run \"iocage migrate\" before trying"
                           " to upgrade {} ({})".format(uuid, tag))
    elif conf["type"] == "template":
        raise RuntimeError("Please convert back to a jail before trying"
                           " to upgrade {} ({})".format(uuid, tag))
    else:
        raise RuntimeError("{} is not a supported jail type.".format(
            conf["type"]))

    _freebsd_version = "{}/releases/{}/root/bin/freebsd-version".format(
        iocroot, release)

    if "HBSD" in freebsd_version:
        Popen(["hbsd-upgrade", "-j", jid]).communicate()
    else:
        if os.path.isfile("{}/etc/freebsd-update.conf".format(root_path)):
            # 10.3-RELEASE and under lack this flag
            if float(host_release.partition("-")[0][:5]) <= 10.3:
                raise RuntimeError(
                    "Host: {} is too old, please upgrade to "
                    "10.3-RELEASE or above".format(host_release))

            os.environ["PAGER"] = "/bin/cat"
            fetch = Popen([
                "freebsd-update", "-b", root_path, "-d",
                "{}/var/db/freebsd-update/".format(root_path), "-f",
                "{}/etc/freebsd-update.conf".format(root_path),
                "--currently-running {}".format(jail_release), "-r", release,
                "upgrade"
            ],
                          stdin=PIPE)
            fetch.communicate(b"y")

            while not __upgrade_install__(root_path, release):
                pass

            if release[:4].endswith("-"):
                # 9.3-RELEASE and under don't actually have this binary.
                new_release = release
            else:
                with open(_freebsd_version, "r") as r:
                    for line in r:
                        if line.startswith("USERLAND_VERSION"):
                            new_release = line.rstrip().partition(
                                "=")[2].strip('"')

            IOCJson(path, silent=True).json_set_value(
                "release={}".format(new_release))

            if started:
                IOCStop(uuid, tag, path, conf, silent=True)

            lgr.info("\n{} ({}) successfully upgraded from {} to {}!".format(
                uuid, tag, jail_release, new_release))
Esempio n. 17
0
    def json_set_value(self, prop, create_func=False):
        """Set a property for the specified jail."""
        # Circular dep! Meh.
        from iocage.lib.ioc_list import IOCList
        from iocage.lib.ioc_create import IOCCreate
        key, _, value = prop.partition("=")

        conf = self.json_load()
        old_tag = conf["tag"]
        uuid = conf["host_hostuuid"]
        status, jid = IOCList.list_get_jid(uuid)
        conf[key] = value
        sysctls_cmd = ["sysctl", "-d", "security.jail.param"]
        jail_param_regex = re.compile("security.jail.param.")
        sysctls_list = Popen(
            sysctls_cmd, stdout=PIPE).communicate()[0].decode("utf-8").split()
        jail_params = [
            p.replace("security.jail.param.", "").replace(":", "")
            for p in sysctls_list if re.match(jail_param_regex, p)
        ]
        single_period = [
            "allow_raw_sockets", "allow_socket_af", "allow_set_hostname"
        ]

        if not create_func:
            if key == "tag":
                conf["tag"] = IOCCreate("", prop,
                                        0).create_link(conf["host_hostuuid"],
                                                       value,
                                                       old_tag=old_tag)
                tag = conf["tag"]

        if key == "template":
            pool, iocroot = _get_pool_and_iocroot()
            old_location = "{}/iocage/jails/{}".format(pool, uuid)
            new_location = "{}/iocage/templates/{}".format(pool, old_tag)

            if status:
                raise RuntimeError(f"{uuid} ({old_tag}) is running.\nPlease"
                                   "stop it first!")

            jails, paths = IOCList("uuid").list_datasets()
            for j in jails:
                _uuid = jails[j]
                _path = f"{paths[j]}/root"
                t_old_path = f"{old_location}/root@{_uuid}"
                t_path = f"{new_location}/root@{_uuid}"

                if _uuid == uuid:
                    continue

                origin = checkoutput(
                    ["zfs", "get", "-H", "-o", "value", "origin",
                     _path]).rstrip()

                if origin == t_old_path or origin == t_path:
                    _status, _ = IOCList.list_get_jid(_uuid)

                    if _status:
                        raise RuntimeError(f"CHILD: {_uuid} ({j}) is"
                                           f" running.\nPlease stop it first!")
            if value == "yes":
                try:
                    checkoutput(
                        ["zfs", "rename", "-p", old_location, new_location],
                        stderr=STDOUT)
                    conf["type"] = "template"

                    self.location = new_location.lstrip(pool).replace(
                        "/iocage", iocroot)
                except CalledProcessError as err:
                    raise RuntimeError("{}".format(
                        err.output.decode("utf-8").rstrip()))

                self.lgr.info("{} ({}) converted to a template.".format(
                    uuid, old_tag))
                self.lgr.disabled = True
            elif value == "no":
                try:
                    checkoutput(
                        ["zfs", "rename", "-p", new_location, old_location],
                        stderr=STDOUT)
                    conf["type"] = "jail"

                    self.location = old_location.lstrip(pool).replace(
                        "/iocage", iocroot)
                except CalledProcessError as err:
                    raise RuntimeError("{}".format(
                        err.output.decode("utf-8").rstrip()))

                self.lgr.info("{} ({}) converted to a jail.".format(
                    uuid, old_tag))
                self.lgr.disabled = True

        self.json_check_prop(key, value, conf)
        self.json_write(conf)
        self.lgr.info("Property: {} has been updated to {}".format(key, value))

        # Used for import
        if not create_func:
            if key == "tag":
                return tag

        # We can attempt to set a property in realtime to jail.
        if status:
            if key in single_period:
                key = key.replace("_", ".", 1)
            else:
                key = key.replace("_", ".")

            if key in jail_params:
                try:
                    checkoutput([
                        "jail", "-m", "jid={}".format(jid), "{}={}".format(
                            key, value)
                    ],
                                stderr=STDOUT)
                except CalledProcessError as err:
                    raise RuntimeError("{}".format(
                        err.output.decode("utf-8").rstrip()))