Beispiel #1
0
def snapremove_cmd(jail, name):
    """Removes a snapshot from a user supplied jail."""
    lgr = ioc_logger.Logger('ioc_cli_snapremove').getLogger()

    jails, paths = IOCList("uuid").list_datasets()
    pool = IOCJson().json_get_value("pool")
    _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)

    # Looks like foo/iocage/jails/df0ef69a-57b6-4480-b1f8-88f7b6febbdf@BAR
    conf = IOCJson(path).json_load()

    if conf["template"] == "yes":
        target = "{}/iocage/templates/{}@{}".format(pool, tag, name)
    else:
        target = "{}/iocage/jails/{}@{}".format(pool, uuid, name)

    try:
        check_call(["zfs", "destroy", "-r", "-f", target])
        lgr.info("Snapshot: {} destroyed.".format(target))
    except CalledProcessError as err:
        lgr.error("{}".format(err))
Beispiel #2
0
def export_cmd(jail):
    """Make a recursive snapshot of the jail and export to a file."""
    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.error("  {} ({})".format(u, t))
        raise RuntimeError()
    else:
        lgr.critical("{} not found!".format(jail))
        exit(1)

    status, _ = IOCList().list_get_jid(uuid)
    if status:
        lgr.critical("{} ({}) is runnning, stop the jail before "
                     "exporting!".format(uuid, tag))
        exit(1)

    IOCImage(callback=callback).export_jail(uuid, tag, path)
Beispiel #3
0
def restart_cmd(jail, soft):
    """
    Looks for the jail supplied and passes the uuid, path and configuration
    location to stop_jail and start_jail.
    """
    jails, paths = IOCList("uuid").list_datasets()

    if jail == "ALL":
        for j in jails:
            uuid = jails[j]
            path = paths[j]

            check_type(uuid, j, path, True, soft)
    else:
        _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]

            check_type(uuid, tag, path, False, soft)
        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:
            lgr.critical("{} not found!".format(jail))
            exit(1)
Beispiel #4
0
def destroy_cmd(force, jails):
    """Destroys the jail's 2 datasets and the snapshot from the RELEASE."""
    lgr = logging.getLogger('ioc_cli_destroy')

    if jails:
        get_jid = IOCList().list_get_jid

        try:
            jail_list, paths = IOCList("uuid").list_datasets()
        except RuntimeError as err:
            err = str(err)

            if "Configuration is missing" in err:
                uuid = err.split()[6]
                pool = IOCJson().json_get_value("pool")
                path = f"{pool}/iocage/jails/{uuid}"

                IOCDestroy().__stop_jails__(path.replace(pool, ""))
                IOCDestroy().__destroy_datasets__(path)
                exit()
            else:
                raise RuntimeError(err)

        for jail in jails:
            _jail = {
                tag: uuid
                for (tag, uuid) in jail_list.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.error("  {} ({})".format(u, t))
                raise RuntimeError()
            else:
                raise RuntimeError("{} not found!".format(jail))

            if not force:
                lgr.warning("\nWARNING: This will destroy"
                            " jail {} ({})".format(uuid, tag))

                if not click.confirm("\nAre you sure?"):
                    continue  # no, continue to next jail

            status, _ = get_jid(uuid)

            # If the jail is not running, let's do this thing.
            if status and not force:
                raise RuntimeError(f"{uuid} ({tag}) is running.\nPlease stop "
                                   "it first!")
            elif status and force:
                lgr.info("Stopping {} ({}).".format(uuid, tag))

            IOCDestroy().destroy_jail(path)
    else:
        raise RuntimeError("Please specify one or more jails!")
Beispiel #5
0
def pkg_cmd(command, jail):
    """Runs pkg with the command given inside the specified jail."""
    lgr = logging.getLogger('ioc_cli_pkg')

    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.error("  {} ({})".format(u, t))
        raise RuntimeError()
    else:
        raise RuntimeError("{} not found!".format(jail))

    cmd = ("pkg", ) + command

    IOCExec(cmd, uuid, tag, path).exec_jail()
Beispiel #6
0
def chroot_cmd(jail, command):
    """Will chroot into a jail regardless if it's running."""
    lgr = logging.getLogger('ioc_cli_chroot')
    jails, paths = IOCList("uuid").list_datasets()
    command = list(command)

    # We may be getting ';', '&&' and so forth. Adding the shell for safety.
    if len(command) == 1:
        command = ["/bin/sh", "-c"] + command

    if jail.startswith("-"):
        raise RuntimeError("Please specify a jail first!")

    _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.error("  {} ({})".format(u, t))
        raise RuntimeError()
    else:
        raise RuntimeError("{} not found!".format(jail))

    devfs_stderr = mount(f"{path}/root/dev", "devfs")

    if devfs_stderr:
        raise RuntimeError("ERROR: Mounting devfs failed!")

    fstab_stderr = mount(f"{path}/fstab", "fstab")

    if fstab_stderr:
        raise RuntimeError("ERROR: Mounting devfs failed!")

    chroot = Popen(["chroot", f"{path}/root"] + command)
    chroot.communicate()

    udevfs_stderr = umount(f"{path}/root/dev", "devfs")
    if udevfs_stderr:
        raise RuntimeError("ERROR: Unmounting devfs failed!")

    ufstab_stderr = umount(f"{path}/fstab", "fstab")
    if ufstab_stderr:
        if b"fstab reading failure\n" in ufstab_stderr:
            # By default our fstab is empty and will throw this error.
            pass
        else:
            raise RuntimeError("ERROR: Unmounting fstab failed!")

    if chroot.returncode:
        lgr.warning("WARNING: Chroot had a non-zero exit code!")
Beispiel #7
0
def rollback_cmd(jail, name, force):
    """Get a list of jails and print the property."""
    lgr = ioc_logger.Logger('ioc_cli_rollback').getLogger()

    jails, paths = IOCList("uuid").list_datasets()
    pool = IOCJson().json_get_value("pool")

    _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" f" {jail}:")
        for t, u in sorted(_jail.items()):
            lgr.error(f"  {u} ({t})")
        raise RuntimeError()
    else:
        lgr.critical(f"{jail} not found!")
        exit(1)

    # Looks like foo/iocage/jails/df0ef69a-57b6-4480-b1f8-88f7b6febbdf@BAR
    conf = IOCJson(path).json_load()

    if conf["template"] == "yes":
        target = f"{pool}/iocage/templates/{tag}"
    else:
        target = f"{pool}/iocage/jails/{uuid}"

    try:
        checkoutput(["zfs", "get", "-H", "creation", target], stderr=PIPE)
    except CalledProcessError:
        lgr.critical(f"Snapshot {target} does not exist!")
        exit(1)

    if not force:
        lgr.warning("\nThis will destroy ALL data created since"
                    f" {name} was taken.\nIncluding ALL snapshots taken after"
                    f" {name} for {uuid} ({tag})")
        if not click.confirm("\nAre you sure?"):
            exit()
    try:
        datasets = Popen(["zfs", "list", "-H", "-r", "-o", "name", target],
                         stdout=PIPE,
                         stderr=PIPE).communicate()[0].decode("utf-8").split()

        for dataset in datasets:
            check_call(["zfs", "rollback", "-r", f"{dataset}@{name}"])

        lgr.info(f"Rolled back to: {target}")
    except CalledProcessError as err:
        lgr.error(f"{err}")
        exit(1)
Beispiel #8
0
def console_cmd(jail, force):
    """
    Runs jexec to login into the specified jail. Accepts a force flag that
    will attempt to start the jail if it is not already running.
    """
    lgr = ioc_logger.Logger('ioc_cli_console').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]

        iocjson = IOCJson(path)
        conf = iocjson.json_load()
        login_flags = conf["login_flags"].split()
        exec_fib = conf["exec_fib"]
        status, _ = IOCList().list_get_jid(uuid)
    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)

    if not status and not force:
        lgr.critical("{} ({}) is not running!".format(uuid, tag))
        exit(1)

    if not status and force:
        lgr.info("{} ({}) is not running".format(uuid, tag) +
                 ", starting jail.")
        if conf["type"] == "jail":
            IOCStart(uuid, jail, path, conf, silent=True)
            status = True
        elif conf["type"] == "basejail":
            lgr.critical("Please run \"iocage migrate\" before trying"
                         " to start {} ({})".format(uuid, tag))
            exit(1)
        elif conf["type"] == "template":
            lgr.critical("Please convert back to a jail before trying"
                         " to start {} ({})".format(uuid, tag))
            exit(1)
        else:
            lgr.critical("{} is not a supported jail type.".format(
                conf["type"]
            ))
            exit(1)

    if status:
        Popen(["setfib", exec_fib, "jexec", f"ioc-{uuid}", "login"] +
              login_flags).communicate()
Beispiel #9
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)
Beispiel #10
0
def rollback_cmd(jail, name, force):
    """Get a list of jails and print the property."""
    lgr = ioc_logger.Logger('ioc_cli_rollback').getLogger()

    jails, paths = IOCList("uuid").list_datasets()
    pool = IOCJson().json_get_value("pool")

    _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.error("  {} ({})".format(u, t))
        raise RuntimeError()
    else:
        lgr.critical("{} not found!".format(jail))
        exit(1)

    # Looks like foo/iocage/jails/df0ef69a-57b6-4480-b1f8-88f7b6febbdf@BAR
    target = "{}{}@{}".format(pool, path, name)
    try:
        checkoutput(["zfs", "get", "-H", "creation", target], stderr=PIPE)
    except CalledProcessError:
        lgr.critical("Snapshot {} does not exist!".format(target))
        exit(1)

    if not force:
        lgr.warning("\nThis will destroy ALL data created since"
                    " {} was taken.".format(name) +
                    "\nIncluding ALL snapshots taken after"
                    " {} for {} ({}).".format(name, uuid, tag))
        if not click.confirm("\nAre you sure?"):
            exit()
    try:
        datasets = Popen([
            "zfs", "list", "-H", "-r", "-o", "name", "{}{}".format(pool, path)
        ],
                         stdout=PIPE,
                         stderr=PIPE).communicate()[0].decode("utf-8").split()

        for dataset in datasets:
            check_call(
                ["zfs", "rollback", "-r", "{}@{}".format(dataset, name)])

        lgr.info("Rolled back to: {}.".format(target))
    except CalledProcessError as err:
        lgr.error("{}".format(err))
        exit(1)
Beispiel #11
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)
Beispiel #12
0
    def check_jail_existence(self, jail):
        self.check_dataset_existence()

        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]

            return tag, uuid, path
        elif len(_jail) > 1:
            raise RuntimeError("Multiple jails found for {}:".format(jail))
        else:
            raise RuntimeError("{} not found!".format(jail))
Beispiel #13
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
Beispiel #14
0
    def check_jail_existence(self, jail):
        self.check_dataset_existence()

        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]

            return tag, uuid, path
        elif len(_jail) > 1:
            raise RuntimeError("Multiple jails found for {}:".format(jail))
        else:
            raise RuntimeError("{} not found!".format(jail))
Beispiel #15
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
Beispiel #16
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
Beispiel #17
0
def __soft_restart__(uuid, jail, path, conf):
    """
    Will tear down the jail by running exec_stop and then exec_start, leaving
    the network stack intact, ideal for VIMAGE.
    """
    getjid = IOCList().list_get_jid(uuid)
    status, jid = getjid
    lgr = ioc_logger.Logger('ioc_cli_restart').getLogger()

    # These needs to be a list.
    exec_start = conf["exec_start"].split()
    exec_stop = conf["exec_stop"].split()

    if status:
        lgr.info("Soft restarting {} ({})".format(uuid, jail))
        stop_cmd = ["jexec", "ioc-{}".format(uuid)] + exec_stop
        Popen(stop_cmd, stdout=PIPE, stderr=PIPE).communicate()

        Popen(["pkill", "-j", jid]).communicate()
        start_cmd = ["jexec", "ioc-{}".format(uuid)] + exec_start
        Popen(start_cmd, stdout=PIPE, stderr=PIPE).communicate()
        IOCJson(path, silent=True).json_set_value("last_started={}".format(
            datetime.utcnow().strftime("%F %T")))
    else:
        lgr.critical("{} is not running!".format(jail))
        exit(1)
Beispiel #18
0
def list_cmd(dataset_type, header, _long, remote, http, plugins):
    """This passes the arg and calls the jail_datasets function."""
    lgr = logging.getLogger('ioc_cli_list')
    freebsd_version = checkoutput(["freebsd-version"])

    if dataset_type is None:
        dataset_type = "all"

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

        IOCFetch("", http=http, hardened=hardened).fetch_release(_list=True)
    elif plugins:
        IOCFetch("").fetch_plugin_index("", _list=True)
    else:
        _list = IOCList(dataset_type, header, _long).list_datasets()

        if not header:
            if dataset_type == "base":
                for item in _list:
                    lgr.info(item)
            else:
                for item in _list:
                    lgr.info("\t".join(item))
        else:
            lgr.info(_list)
Beispiel #19
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)
Beispiel #20
0
def set_cmd(prop, jail, plugin):
    """Get a list of jails and print the property."""
    lgr = ioc_logger.Logger('ioc_cli_set').getLogger()

    jails, paths = IOCList("uuid").list_datasets(set=True)
    _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]
        iocjson = IOCJson(path, cli=True)
    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:
        lgr.critical("{} not found!".format(jail))
        exit(1)

    if "template" in prop.split("=")[0]:
        if "template" in path and prop != "template=no":
            lgr.critical("{} ({}) is already a template!".format(uuid, tag))
            exit(1)
        elif "template" not in path and prop != "template=yes":
            lgr.critical("{} ({}) is already a jail!".format(uuid, tag))
            exit(1)
    if plugin:
        _prop = prop.split(".")
        IOCJson(path, cli=True).json_plugin_set_value(_prop)
    else:
        try:
            # We use this to test if it's a valid property at all.
            _prop = prop.partition("=")[0]
            iocjson.json_get_value(_prop)

            # The actual setting of the property.
            iocjson.json_set_value(prop)
        except KeyError:
            _prop = prop.partition("=")[0]
            lgr.critical("{} is not a valid property!".format(_prop))
            exit(1)
Beispiel #21
0
    def json_plugin_set_value(self, prop):
        from iocage.lib.ioc_exec import IOCExec
        from iocage.lib.ioc_list import IOCList

        pool, iocroot = _get_pool_and_iocroot()
        conf = self.json_load()
        uuid = conf["host_hostuuid"]
        tag = conf["tag"]
        _path = checkoutput([
            "zfs", "get", "-H", "-o", "value", "mountpoint",
            "{}/iocage/jails/{}".format(pool, uuid)
        ]).rstrip()
        status, _ = IOCList().list_get_jid(uuid)

        # Plugin variables
        settings = self.json_plugin_load()
        serviceset = settings["serviceset"]
        servicerestart = settings["servicerestart"].split()
        keys, _, value = ".".join(prop).partition("=")
        prop = keys.split(".")
        restart = False

        if "options" in prop:
            prop = keys.split(".")[1:]

        prop_cmd = "{},{},{}".format(serviceset, ",".join(prop),
                                     value).split(",")
        setting = settings["options"]

        try:
            while prop:
                current = prop[0]
                key = current
                prop.remove(current)

                if not prop:
                    if setting[current]:
                        try:
                            restart = setting[current]["requirerestart"]
                        except KeyError:
                            pass
                else:
                    setting = setting[current]

            if status:
                # IOCExec will not show this if it doesn't start the jail.
                self.lgr.info("Command output:")
            IOCExec(prop_cmd, uuid, tag, _path).exec_jail()

            if restart:
                self.lgr.info("\n-- Restarting service --")
                self.lgr.info("Command output:")
                IOCExec(servicerestart, uuid, tag, _path).exec_jail()

            self.lgr.info("\nKey: {} has been updated to {}".format(
                keys, value))
        except KeyError:
            raise RuntimeError("Key: \"{}\" does not exist!".format(key))
Beispiel #22
0
def exec_cmd(command, jail, host_user, jail_user):
    """Runs the command given inside the specified jail as the supplied
    user."""
    lgr = ioc_logger.Logger('ioc_cli_exec').getLogger()

    # We may be getting ';', '&&' and so forth. Adding the shell for safety.
    if len(command) == 1:
        command = ("/bin/sh", "-c") + command

    if jail.startswith("-"):
        lgr.critical("Please specify a jail first!")
        exit(1)

    if host_user and jail_user:
        lgr.critical("Please only specify either host_user or"
                     " jail_user, not both!")
        exit(1)

    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.error("  {} ({})".format(u, t))
        raise RuntimeError()
    else:
        lgr.critical("{} not found!".format(jail))
        exit(1)

    msg, err = IOCExec(command, uuid, tag, path, host_user,
                       jail_user).exec_jail()

    if err:
        err = indent_lines(msg)
        lgr.error("{}".format(err))
    else:
        lgr.info(msg.decode("utf-8"))
Beispiel #23
0
def snapshot_cmd(jail, name):
    """Get a list of jails and print the property."""
    lgr = ioc_logger.Logger('ioc_cli_snapshot').getLogger()

    jails, paths = IOCList("uuid").list_datasets()
    pool = IOCJson().json_get_value("pool")
    date = datetime.utcnow().strftime("%F_%T")

    _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.error("  {} ({})".format(u, t))
        raise RuntimeError()
    else:
        lgr.critical("{} not found!".format(jail))
        exit(1)

    # If they don't supply a snapshot name, we will use the date.
    if not name:
        name = date

    # Looks like foo/iocage/jails/df0ef69a-57b6-4480-b1f8-88f7b6febbdf@BAR
    conf = IOCJson(path).json_load()

    if conf["template"] == "yes":
        target = "{}/iocage/templates/{}@{}".format(pool, tag, name)
    else:
        target = "{}/iocage/jails/{}@{}".format(pool, uuid, name)

    try:
        check_call(["zfs", "snapshot", "-r", target], stderr=PIPE)
        lgr.info("Snapshot: {} created.".format(target))
    except CalledProcessError:
        lgr.critical("Snapshot already exists!")
        exit(1)
Beispiel #24
0
def df_cmd(header, _long, _sort):
    """Allows a user to show resource usage of all jails."""
    lgr = ioc_logger.Logger('ioc_cli_df').getLogger()

    jails, paths = IOCList("uuid").list_datasets()
    pool = IOCJson().json_get_value("pool")
    jail_list = []
    table = Texttable(max_width=0)

    for jail in jails:
        full_uuid = jails[jail]

        if not _long:
            uuid = full_uuid[:8]
        else:
            uuid = full_uuid

        path = paths[jail]
        conf = IOCJson(path).json_load()
        zconf = ["zfs", "get", "-H", "-o", "value"]
        mountpoint = f"{pool}/iocage/jails/{full_uuid}"

        tag = conf["tag"]
        template = conf["type"]

        if template == "template":
            mountpoint = f"{pool}/iocage/templates/{tag}"

        compressratio = Popen(
            zconf + ["compressratio", mountpoint],
            stdout=PIPE).communicate()[0].decode("utf-8").strip()
        reservation = Popen(
            zconf + ["reservation", mountpoint],
            stdout=PIPE).communicate()[0].decode("utf-8").strip()
        quota = Popen(zconf + ["quota", mountpoint],
                      stdout=PIPE).communicate()[0].decode("utf-8").strip()
        used = Popen(zconf + ["used", mountpoint],
                     stdout=PIPE).communicate()[0].decode("utf-8").strip()
        available = Popen(
            zconf + ["available", mountpoint],
            stdout=PIPE).communicate()[0].decode("utf-8").strip()

        jail_list.append(
            [uuid, compressratio, reservation, quota, used, available, tag])

    sort = ioc_common.ioc_sort("df", _sort)
    jail_list.sort(key=sort)
    if header:
        jail_list.insert(0, ["UUID", "CRT", "RES", "QTA", "USE", "AVA", "TAG"])
        # We get an infinite float otherwise.
        table.set_cols_dtype(["t", "t", "t", "t", "t", "t", "t"])
        table.add_rows(jail_list)
        lgr.info(table.draw())
    else:
        for jail in jail_list:
            print("\t".join(jail))
Beispiel #25
0
def test_set():
    _, paths = IOCList("uuid").list_datasets()

    path = paths["test"]
    path_short = paths["test_short"]

    IOCJson(path, silent=True).json_set_value("tag=newtest")
    IOCJson(path_short, silent=True).json_set_value("tag=newtest_short")

    assert True == True
Beispiel #26
0
def test_destroy():
    jails, paths = IOCList("uuid").list_datasets()

    path = paths["newtest"]
    path_short = paths["newtest_short"]

    IOCDestroy().destroy_jail(path)
    IOCDestroy().destroy_jail(path_short)

    assert True == True
Beispiel #27
0
def test_get():
    _, paths = IOCList("uuid").list_datasets()

    path = paths["newtest"]
    path_short = paths["newtest_short"]

    prop = IOCJson(path).json_get_value("tag")
    prop_short = IOCJson(path_short).json_get_value("tag")

    assert prop == "newtest"
    assert prop_short == "newtest_short"
def test_destroy():
    jails, paths = IOCList("uuid").list_datasets()

    uuid = jails["newtest"]
    uuid_short = jails["newtest_short"]

    path = paths["newtest"]
    path_short = paths["newtest_short"]

    IOCDestroy(uuid, "newtest", path).destroy_jail()
    IOCDestroy(uuid_short, "newtest_short", path_short).destroy_jail()

    assert True == True
Beispiel #29
0
    def __fstab_umount__(self, dest):
        """
        Umounts the users mount if the jail is running.

        :param dest: The destination to umount.
        """
        status, _ = IOCList().list_get_jid(self.uuid)

        if status:
            proc = Popen(["umount", "-f", dest], stdout=PIPE, stderr=PIPE)
            stdout_data, stderr_data = proc.communicate()

            if stderr_data:
                raise RuntimeError(f"{stderr_data.decode('utf-8')}")
Beispiel #30
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"
Beispiel #31
0
    def destroy(self, jail):
        """Takes a jail and destroys it."""
        from iocage.lib.ioc_destroy import IOCDestroy

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

        if status:
            from iocage.lib.ioc_stop import IOCStop
            IOCStop(uuid, tag, path, conf, silent=True)

        IOCDestroy(uuid, tag, path).destroy_jail()

        return True
Beispiel #32
0
    def __init__(self, uuid, jail, path, conf, silent=False):
        self.pool = IOCJson(" ").json_get_value("pool")
        self.iocroot = IOCJson(self.pool).json_get_value("iocroot")
        self.uuid = uuid
        self.jail = jail
        self.path = path
        self.conf = conf
        self.status, self.jid = IOCList().list_get_jid(uuid)
        self.nics = conf["interfaces"]
        self.lgr = logging.getLogger('ioc_stop')

        if silent:
            self.lgr.disabled = True

        self.__stop_jail__()
Beispiel #33
0
    def start_network(self, vnet):
        """
        This function is largely a check to see if VNET is true, and then to
        actually run the correct function, otherwise it passes.

        :param vnet: Boolean
        """
        if vnet:
            _, jid = IOCList().list_get_jid(self.uuid)
            net_configs = ((self.get("ip4_addr"), self.get("defaultrouter")),
                           (self.get("ip6_addr"), self.get("defaultrouter6")))
            nics = self.get("interfaces").split(",")

            for nic in nics:
                self.start_network_interface_vnet(nic, net_configs, jid)
Beispiel #34
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
Beispiel #35
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
Beispiel #36
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
Beispiel #37
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