Ejemplo n.º 1
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)
Ejemplo n.º 2
0
def pkg_cmd(command, jail):
    """Runs pkg with the command given inside the specified jail."""
    lgr = ioc_logger.Logger('ioc_cli_pkg').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.error("  {} ({})".format(u, t))
        raise RuntimeError()
    else:
        lgr.critical("{} not found!".format(jail))
        exit(1)

    cmd = ("pkg", ) + command

    IOCExec(cmd, uuid, tag, path).exec_jail()
Ejemplo n.º 3
0
def list_cmd(dataset_type, header, _long, remote, http, plugins):
    """This passes the arg and calls the jail_datasets function."""
    lgr = ioc_logger.Logger('ioc_cli_list').getLogger()
    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:
                    print("\t".join(item))
        else:
            lgr.info(_list)
Ejemplo n.º 4
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))
Ejemplo n.º 5
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()
Ejemplo n.º 6
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)
Ejemplo n.º 7
0
Archivo: df.py Proyecto: lbivens/iocage
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))
Ejemplo n.º 8
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)
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
    def __callback__(self, log):
        """Helper to call the appropriate logging level"""
        lgr = ioc_logger.Logger('mng_jail').getLogger()

        if log['level'] == 'CRITICAL':
            lgr.critical(log['message'])
        elif log['level'] == 'ERROR':
            lgr.error(log['message'])
        elif log['level'] == 'WARNING':
            lgr.warning(log['message'])
        elif log['level'] == 'INFO':
            lgr.info(log['message'])
        elif log['level'] == 'DEBUG':
            lgr.debug(log['message'])
Ejemplo n.º 11
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)
Ejemplo n.º 12
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"))
Ejemplo n.º 13
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)
Ejemplo n.º 14
0
def activate_cmd(zpool):
    """Calls ZFS set to change the property org.freebsd.ioc:active to yes."""
    lgr = ioc_logger.Logger('ioc_cli_activate').getLogger()
    zfs = libzfs.ZFS(history=True, history_prefix="<iocage>")
    pools = zfs.pools
    prop = "org.freebsd.ioc:active"

    for _pool in pools:
        if _pool.name == zpool:
            ds = zfs.get_dataset(_pool.name)
            ds.properties[prop] = libzfs.ZFSUserProperty("yes")
        else:
            ds = zfs.get_dataset(_pool.name)
            ds.properties[prop] = libzfs.ZFSUserProperty("no")

        # Check and clean if necessary iocage_legacy way
        # to mark a ZFS pool as usable (now replaced by ZFS property)
        comment = zfs.get(_pool.name).properties["comment"]

        if comment.value == "iocage":
            comment.value = "-"

    lgr.info(f"ZFS pool '{zpool}' successfully activated.")
Ejemplo n.º 15
0
def clean_cmd(force, dataset_type):
    """Calls the correct destroy function."""
    lgr = ioc_logger.Logger('ioc_cli_clean').getLogger()

    if dataset_type == "jails":
        if not force:
            lgr.warning("\nThis will destroy ALL jails"
                        " and any snapshots on a RELEASE, including "
                        "templates!")
            if not click.confirm("\nAre you sure?"):
                exit()

        IOCClean().clean_jails()
        lgr.info("All iocage jail datasets have been destroyed.")
    elif dataset_type == "all":
        if not force:
            lgr.warning("\nThis will destroy ALL iocage data!")
            if not click.confirm("\nAre you sure?"):
                exit()

        IOCClean().clean_all()
        lgr.info("All iocage datasets have been destroyed.")
    elif dataset_type == "release":
        pass
    elif dataset_type == "template":
        if not force:
            lgr.warning("This will destroy ALL templates"
                        " and jails created from them!")
            if not click.confirm("\nAre you sure?"):
                exit()

        IOCClean().clean_templates()
        lgr.info("All iocage template datasets have been destroyed.")
    else:
        lgr.critical("Please specify a dataset type to clean!")
        exit(1)
Ejemplo n.º 16
0
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))
Ejemplo n.º 17
0
def fetch_cmd(http, _file, server, user, password, auth, verify, release,
              plugins, plugin_file, root_dir, props, count, update, eol,
              files):
    """CLI command that calls fetch_release()"""
    freebsd_version = checkoutput(["freebsd-version"])
    arch = os.uname()[4]

    lgr = ioc_logger.Logger("ioc_cli_fetch").getLogger()

    if not files:
        if arch == "arm64":
            files = ("MANIFEST", "base.txz", "doc.txz")
        else:
            files = ("MANIFEST", "base.txz", "lib32.txz", "doc.txz")

    if "HBSD" in freebsd_version:
        if server == "ftp.freebsd.org":
            hardened = True
        else:
            hardened = False
    else:
        hardened = False

    if plugins or plugin_file:
        if plugin_file:
            try:
                with open(plugin_file) as f:
                    return json.load(f)
            except FileNotFoundError:
                lgr.critical("Please supply a file before any properties.")
                exit(1)
            except json.decoder.JSONDecodeError:
                lgr.critical("Invalid JSON file supplied, please supply a "
                             "correctly formatted JSON file.")
                exit(1)

        ip = [
            x for x in props
            if x.startswith("ip4_addr") or x.startswith("ip6_addr")
        ]
        if not ip:
            lgr.critical("An IP address is needed to fetch a "
                         "plugin!\nPlease specify "
                         "ip(4|6)_addr=\"INTERFACE|IPADDRESS\"!")
            exit(1)
        if plugins:
            IOCFetch(release=None).fetch_plugin_index(props)
            exit()

        if count == 1:
            IOCFetch("",
                     server,
                     user,
                     password,
                     auth,
                     root_dir,
                     http=http,
                     _file=_file,
                     verify=verify,
                     hardened=hardened,
                     update=update,
                     eol=eol,
                     files=files).fetch_plugin(plugin_file, props, 0)
        else:
            for j in range(1, count + 1):
                IOCFetch("",
                         server,
                         user,
                         password,
                         auth,
                         root_dir,
                         http=http,
                         _file=_file,
                         verify=verify,
                         hardened=hardened,
                         update=update,
                         eol=eol,
                         files=files).fetch_plugin(plugin_file, props, j)
    else:
        IOCFetch(release,
                 server,
                 user,
                 password,
                 auth,
                 root_dir,
                 http=http,
                 _file=_file,
                 verify=verify,
                 hardened=hardened,
                 update=update,
                 eol=eol,
                 files=files).fetch_release()
Ejemplo n.º 18
0
def create_cmd(release, template, count, props, pkglist, basejail, empty,
               short, uuid):
    lgr = ioc_logger.Logger('ioc_cli_create').getLogger()

    if short and uuid:
        lgr.critical(
            "Can't use --short (-s) and --uuid (-u) at the same time!")
        exit(1)

    if not template and not release and not empty:
        lgr.critical("Must supply either --template (-t) or --release (-r)!")
        exit(1)

    if release and "=" in release:
        lgr.critical("Please supply a valid RELEASE!")
        exit(1)

    if template:
        # We don't really care it's not a RELEASE at this point.
        release = template

    if pkglist:
        _pkgformat = """
{
    "pkgs": [
    "foo",
    "bar"
    ]
}"""

        if not os.path.isfile(pkglist):
            lgr.critical("{} does not exist!\nPlease supply a JSON file "
                         "with the format:{}".format(pkglist, _pkgformat))
            exit(1)
        else:
            try:
                # Just try to open the JSON with the right key.
                with open(pkglist, "r") as p:
                    json.load(p)["pkgs"]  # noqa
            except JSONDecodeError:
                lgr.critical("Please supply a valid JSON file with the"
                             f" format:\n{_pkgformat}")
                exit(1)

    pool = IOCJson().json_get_value("pool")
    iocroot = IOCJson(pool).json_get_value("iocroot")

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

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

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

    if empty:
        release = "EMPTY"

    if count == 1:
        try:
            IOCCreate(release,
                      props,
                      0,
                      pkglist,
                      template=template,
                      short=short,
                      uuid=uuid,
                      basejail=basejail,
                      empty=empty).create_jail()
        except RuntimeError as err:
            lgr.error(err)
            if template:
                lgr.info("Created Templates:")
                templates = IOCList("template", hdr=False).list_datasets()
                for temp in templates:
                    lgr.info("  {}".format(temp[3]))
    else:
        for j in range(1, count + 1):
            try:
                IOCCreate(release,
                          props,
                          j,
                          pkglist,
                          template=template,
                          short=short,
                          basejail=basejail,
                          empty=empty).create_jail()
            except RuntimeError as err:
                lgr.error(err)
                if template:
                    lgr.info("Created Templates:")
                    templates = IOCList("template", hdr=False).list_datasets()
                    for temp in templates:
                        lgr.info("  {}".format(temp[3]))
                exit(1)
Ejemplo n.º 19
0
def destroy_cmd(force, release, download, jails):
    """Destroys the jail's 2 datasets and the snapshot from the RELEASE."""
    lgr = ioc_logger.Logger('ioc_cli_destroy').getLogger()

    if download and not release:
        exit("--release (-r) must be specified as well!")

    if jails and not release:
        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()[5]
                pool = IOCJson().json_get_value("pool")
                path = f"{pool}/iocage/jails/{uuid}"

                IOCDestroy().__stop_jails__(path.replace(pool, ""))
                IOCDestroy().__destroy_parse_datasets__(path)
                exit()
            else:
                lgr.critical(err)
                exit(1)

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

            if not force:
                lgr.warning("\nThis 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:
                lgr.critical(f"{uuid} ({tag}) is running.\nPlease stop "
                             "it first!")
                exit(1)
            elif status and force:
                lgr.info("Stopping {} ({}).".format(uuid, tag))

            IOCDestroy().destroy_jail(path)
    elif jails and release:
        pool = IOCJson().json_get_value("pool")

        for release in jails:
            path = f"{pool}/iocage/releases/{release}"

            if not force:
                lgr.warning(f"\nThis will destroy RELEASE: {release}")
                lgr.warning("       and any jail that was created with it.")

                if not click.confirm("\nAre you sure?"):
                    continue

            IOCDestroy().__destroy_parse_datasets__(path)

            if download:
                path = f"{pool}/iocage/download/{release}"
                IOCDestroy().__destroy_parse_datasets__(path)

    elif not jails and release:
        lgr.critical("Please specify one or more RELEASEs!")
        exit(1)
    else:
        lgr.critical("Please specify one or more jails!")
        exit(1)
Ejemplo n.º 20
0
def callback(message):
    lgr = ioc_logger.Logger('ioc_cli_import').getLogger()

    lgr.info(message)
Ejemplo n.º 21
0
"""export module for the cli."""
import click

import iocage.lib.ioc_logger as ioc_logger
from iocage.lib.ioc_image import IOCImage
from iocage.lib.ioc_list import IOCList

__cmdname__ = "export_cmd"
__rootcmd__ = True

lgr = ioc_logger.Logger("ioc_cli_export").getLogger()


def callback(message):
    lgr.info(message)


@click.command(name="export", help="Exports a specified jail.")
@click.argument("jail", required=True)
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]
Ejemplo n.º 22
0
def fstab_cmd(action, fstab_string, jail):
    """
    Looks for the jail supplied and passes the uuid, path and configuration
    location to manipulate the fstab.
    """
    lgr = ioc_logger.Logger('ioc_cli_fstab').getLogger()
    pool = IOCJson().json_get_value("pool")
    iocroot = IOCJson(pool).json_get_value("iocroot")
    index = None
    _index = False
    fstab_string = list(fstab_string)

    _jails, paths = IOCList("uuid").list_datasets()

    if not fstab_string and action != "edit":
        lgr.critical("Please supply a fstab entry!")
        exit(1)

    _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()))
    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)

    # The user will expect to supply a string, the API would prefer these
    # separate. If the user supplies a quoted string, we will split it,
    # otherwise the format is acceptable to be imported directly.
    if len(fstab_string) == 1:
        try:
            source, destination, fstype, options, dump, _pass = fstab_string[
                0].split()
        except ValueError:
            # We're going to assume this is an index number.
            try:
                index = int(fstab_string[0])
            except TypeError:
                lgr.critical("Please specify either a valid fstab "
                             "entry or an index number.")
                exit(1)
            _index = True
            source, destination, fstype, options, dump, _pass = "", "", "", \
                                                                "", "", ""
    else:
        if action != "edit":
            try:
                source, destination, fstype, options, dump, _pass = \
                    fstab_string
            except ValueError:
                lgr.critical("Please specify a valid fstab entry!\n\n"
                             "Example:\n  /the/source /dest FSTYPE "
                             "FSOPTIONS FSDUMP FSPASS")
                exit(1)
        else:
            source, destination, fstype, options, dump, _pass = "", "", \
                                                                "", "", \
                                                                "", ""

    if not _index and action == "add":
        destination = "{}/jails/{}/root".format(iocroot, uuid) + destination

    IOCFstab(uuid,
             tag,
             action,
             source,
             destination,
             fstype,
             options,
             dump,
             _pass,
             index=index)
Ejemplo n.º 23
0
"""restart module for the cli."""
from datetime import datetime
from subprocess import PIPE, Popen

import click

import iocage.lib.ioc_logger as ioc_logger
from iocage.lib.ioc_json import IOCJson
from iocage.lib.ioc_list import IOCList
from iocage.lib.ioc_start import IOCStart
from iocage.lib.ioc_stop import IOCStop

__cmdname__ = "restart_cmd"
__rootcmd__ = True

lgr = ioc_logger.Logger('ioc_cli_restart').getLogger()


def check_type(uuid, tag, path, _all, soft):
    """
    Checks the jail type and spits out an error or does the specified 
    restart method.
    """
    conf = IOCJson(path).json_load()

    if conf["type"] in ("jail", "plugin"):
        if not soft:
            __hard_restart__(uuid, tag, path, conf)
        else:
            __soft_restart__(uuid, tag, path, conf)
    elif conf["type"] == "basejail":
Ejemplo n.º 24
0
def snaplist_cmd(header, jail):
    """Allows a user to show resource usage of all jails."""
    lgr = ioc_logger.Logger('ioc_cli_snaplist').getLogger()

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

    _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)

    conf = IOCJson(path).json_load()

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

    zconf = ["zfs", "get", "-H", "-o", "value"]
    snapshots = Popen(["zfs", "list", "-r", "-H", "-t", "snapshot", full_path],
                      stdout=PIPE,
                      stderr=PIPE).communicate()[0].decode("utf-8").split("\n")

    for snap in snapshots:
        # We get an empty list at the end.
        if snap:
            snap = snap.split()
            snapname = snap[0].rsplit("@")[1]
            root_snapname = snap[0].rsplit("@")[0].split("/")[-1]

            if root_snapname == "root":
                snapname += "/root"
            elif root_snapname != uuid and root_snapname != tag:
                # basejail datasets.
                continue

            creation = Popen(
                zconf + ["creation", snap[0]],
                stdout=PIPE).communicate()[0].decode("utf-8").strip()
            used = snap[1]
            referenced = Popen(
                zconf + ["referenced", snap[0]],
                stdout=PIPE).communicate()[0].decode("utf-8").strip()

            snap_list.append([snapname, creation, referenced, used])

    if header:
        snap_list.insert(0, ["NAME", "CREATED", "RSIZE", "USED"])
        # We get an infinite float otherwise.
        table.set_cols_dtype(["t", "t", "t", "t"])
        table.add_rows(snap_list)
        lgr.info(table.draw())
    else:
        for snap in snap_list:
            lgr.info("\t".join(snap))
Ejemplo n.º 25
0
def chroot_cmd(jail, command):
    """Will chroot into a jail regardless if it's running."""
    lgr = ioc_logger.Logger('ioc_cli_chroot').getLogger()
    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.critical("  {} ({})".format(u, t))
        exit(1)
    else:
        lgr.critical("{} not found!".format(jail))
        exit(1)

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

    if devfs_stderr:
        lgr.critical("Mounting devfs failed!")
        exit(1)

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

    if fstab_stderr:
        lgr.critical("Mounting devfs failed!")
        exit(1)

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

    udevfs_stderr = umount(f"{path}/root/dev", "devfs")
    if udevfs_stderr:
        lgr.critical("Unmounting devfs failed!")
        exit(1)

    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:
            lgr.critical("Unmounting fstab failed!")
            exit(1)

    if chroot.returncode:
        lgr.warning("Chroot had a non-zero exit code!")
Ejemplo n.º 26
0
def get_cmd(prop, _all, _pool, jail, recursive, header, plugin):
    """Get a list of jails and print the property."""
    lgr = ioc_logger.Logger('ioc_cli_get').getLogger()

    get_jid = IOCList.list_get_jid
    jails, paths = IOCList("uuid").list_datasets()
    jail_list = []
    table = Texttable(max_width=0)

    if _all:
        # Confusing I know.
        jail = prop
        prop = "all"

    if _pool:
        pool = IOCJson().json_get_value("pool")

        lgr.info(pool)
        exit()

    if recursive is None:
        if jail == "":
            lgr.info("Usage: iocage get [OPTIONS] PROP JAIL\n")
            lgr.critical("Missing argument \"jail\".")
            exit(1)

        _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 prop == "state":
            status, _ = get_jid(path.split("/")[3])

            if status:
                state = "up"
            else:
                state = "down"

            lgr.info(state)
        elif plugin:
            _prop = prop.split(".")
            props = IOCJson(path).json_plugin_get_value(_prop)

            if isinstance(props, dict):
                lgr.info(json.dumps(props, indent=4))
            else:
                pass
        elif prop == "all":
            props = IOCJson(path).json_get_value(prop)

            for p, v in props.items():
                lgr.info("{}:{}".format(p, v))
        elif prop == "fstab":
            pool = IOCJson().json_get_value("pool")
            iocroot = IOCJson(pool).json_get_value("iocroot")
            index = 0

            with open("{}/jails/{}/fstab".format(iocroot, uuid), "r") as \
                    fstab:
                for line in fstab.readlines():
                    line = line.rsplit("#")[0].rstrip()
                    jail_list.append([index, line.replace("\t", " ")])
                    index += 1

            if header:
                jail_list.insert(0, ["INDEX", "FSTAB ENTRY"])
                # We get an infinite float otherwise.
                table.set_cols_dtype(["t", "t"])
                table.add_rows(jail_list)
                lgr.info(table.draw())
            else:
                for fstab in jail_list:
                    lgr.info("{}\t{}".format(fstab[0], fstab[1]))
        else:
            try:
                lgr.info(IOCJson(path).json_get_value(prop))
            except:
                lgr.critical("{} is not a valid property!".format(prop))
                exit(1)
    else:
        for j in jails:
            uuid = jails[j]
            path = paths[j]
            try:
                if prop == "state":
                    status, _ = get_jid(path.split("/")[3])

                    if status:
                        state = "up"
                    else:
                        state = "down"

                    jail_list.append([uuid, j, state])
                elif prop == "all":
                    props = IOCJson(path).json_get_value(prop)

                    for p, v in props.items():
                        jail_list.append([uuid, j, "{}:{}".format(p, v)])
                else:
                    jail_list.append(
                        [uuid, j, IOCJson(path).json_get_value(prop)])
            except:
                lgr.critical("{} is not a valid property!".format(prop))
                exit(1)

        # Prints the table
        if header:
            jail_list.insert(0, ["UUID", "TAG", "PROP - {}".format(prop)])
            # We get an infinite float otherwise.
            table.set_cols_dtype(["t", "t", "t"])
            table.add_rows(jail_list)
            lgr.info(table.draw())
        else:
            for jail in jail_list:
                lgr.info("\t".join(jail))