Exemple #1
0
def cli(**kwargs):
    """CLI command that calls fetch_release()"""
    release = kwargs.get("release", None)
    _file = kwargs.get("_file", False)

    proxy = kwargs.pop('proxy')
    if proxy:
        os.environ.update({'http_proxy': proxy, 'https_proxy': proxy})

    if release is not None:
        if release.lower() == "latest":
            release = ioc_common.parse_latest_release()
            kwargs["release"] = release

        try:
            float(release.rsplit("-", 1)[0].rsplit("-", 1)[0])
        except ValueError:
            ioc_common.logit({
                "level": "EXCEPTION",
                "message": "Please supply a valid entry."
            })

        if not _file:
            ioc_common.check_release_newer(release, major_only=True)

    ioc.IOCage().fetch(**kwargs)
Exemple #2
0
def cli(**kwargs):
    """CLI command that calls fetch_release()"""
    release = kwargs.get("release", None)
    _file = kwargs.get("_file", False)

    proxy = kwargs.pop('proxy')
    if proxy:
        os.environ.update({
            'http_proxy': proxy,
            'https_proxy': proxy
        })

    if kwargs['plugin_file'] and kwargs['name'] is None:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please supply a --name for plugin-file."
        })

    if release is not None:
        if release.lower() == "latest":
            release = ioc_common.parse_latest_release()
            kwargs["release"] = release

        try:
            float(release.rsplit("-", 1)[0].rsplit("-", 1)[0])
        except ValueError:
            ioc_common.logit({
                "level": "EXCEPTION",
                "message": "Please supply a valid entry."
            })

        if not _file:
            ioc_common.check_release_newer(release)

    ioc.IOCage().fetch(**kwargs)
Exemple #3
0
def cli(command, jail, host_user, jail_user, force):
    """Runs the command given inside the specified jail as the supplied
    user."""
    # We may be getting ';', '&&' and so forth. Adding the shell for safety.

    if len(command) == 1:
        command = ("/bin/sh", "-c") + command

    if jail.startswith("-"):
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please specify a jail first!"
        })

    # They haven't set a host_user then, and actually want a jail one,
    # unsetting the convenience default
    host_user = "" if jail_user and host_user == "root" else host_user

    try:
        ioc.IOCage(jail=jail).exec(command,
                                   host_user,
                                   jail_user,
                                   interactive=True,
                                   start_jail=force)
    except KeyboardInterrupt:
        pass
    except Exception as e:
        ioc_common.logit({
            'level':
            'EXCEPTION',
            'message':
            'Command failed!\n'
            f'Exception: "{e.__class__.__name__}:{str(e)}" occured'
        })
Exemple #4
0
def cli(**kwargs):
    """CLI command that calls fetch_release()"""
    release = kwargs.get("release", None)
    _file = kwargs.get("_file", False)

    if kwargs['plugin_file'] and kwargs['name'] is None:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please supply a --name for plugin-file."
        })

    if release is not None:
        if release.lower() == "latest":
            release = ioc_common.parse_latest_release()
            kwargs["release"] = release

        try:
            float(release.rsplit("-", 1)[0].rsplit("-", 1)[0])
        except ValueError:
            ioc_common.logit({
                "level": "EXCEPTION",
                "message": "Please supply a valid entry."
            })

        if not _file:
            ioc_common.check_release_newer(release)

    ioc.IOCage().fetch(**kwargs)
Exemple #5
0
def cli(zpool):
    """Calls ZFS set to change the property org.freebsd.ioc:active to yes."""
    ioc.IOCage(activate=True).activate(zpool)

    ioc_common.logit({
        "level"  : "INFO",
        "message": f"ZFS pool '{zpool}' successfully activated."
    })
Exemple #6
0
def cli(zpool):
    """Calls ZFS set to change the property org.freebsd.ioc:active to yes."""
    ioc.IOCage(activate=True).activate(zpool)

    ioc_common.logit({
        "level": "INFO",
        "message": f"ZFS pool '{zpool}' successfully activated."
    })
Exemple #7
0
def cli(force, release, download, jails, recursive):
    """Destroys the jail's 2 datasets and the snapshot from the RELEASE."""
    # Want these here, otherwise they're reinstanced for each jail.
    zfs = libzfs.ZFS(history=True, history_prefix="<iocage>")
    iocroot = ioc.PoolAndDataset().get_iocroot()

    if download and not release:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "--release (-r) must be specified as well!"
        })

    if jails and not release:
        for jail in jails:
            if not force:
                ioc_common.logit({
                    "level": "WARNING",
                    "message": f"\nThis will destroy jail {jail}"
                })

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

            child_test(zfs, iocroot, jail, "jail", force=force,
                       recursive=recursive)

            ioc.IOCage(jail=jail,
                       skip_jails=True).destroy_jail(force=force)
    elif jails and release:
        for release in jails:
            if not force:
                ioc_common.logit({
                    "level": "WARNING",
                    "message": f"\nThis will destroy RELEASE: {release}"
                })

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

            children = child_test(zfs, iocroot, release, "release",
                                  force=force, recursive=recursive)

            if children:
                for child in children:
                    ioc.IOCage(jail=child).destroy_jail(force)

            ioc.IOCage(jail=release,
                       skip_jails=True).destroy_release(download)
    elif not jails and release:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please specify one or more RELEASEs!"
        })
    else:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please specify one or more jails!"
        })
Exemple #8
0
def cli(force, dataset_type):
    """Calls the correct destroy function."""
    if dataset_type == 'jails':
        msg = {
            'level':
            'WARNING',
            'message':
            '\nThis will destroy ALL jails and any '
            'snapshots on a RELEASE,'
            ' including templates!'
        }
    elif dataset_type == 'all':
        msg = {
            'level': 'WARNING',
            'message': '\nThis will destroy ALL iocage data!'
        }
    elif dataset_type == 'release':
        msg = {
            'level':
            'WARNING',
            'message':
            '\nThis will destroy ALL fetched RELEASES and'
            ' jails/templates created from them!'
        }
    elif dataset_type == 'template':
        msg = {
            'level':
            'WARNING',
            'message':
            'This will destroy ALL templates and jails'
            ' created from them!'
        }
    elif dataset_type == 'images':
        msg = {
            'level': 'WARNING',
            'message': 'This will destroy ALL exports created!'
        }
    elif dataset_type == 'debug':
        msg = {
            'level': 'WARNING',
            'message': 'This will destroy ALL debugs created at iocage/debug!'
        }
    else:
        ioc_common.logit({
            'level': 'EXCEPTION',
            'message': 'Please specify a dataset type to clean!'
        })

    if not force:
        ioc_common.logit(msg)
        if not click.confirm('\nAre you sure?'):
            exit()

    ioc.IOCage(skip_jails=True).clean(dataset_type)
Exemple #9
0
def cli(source, props, count, name, _uuid):
    # At this point we don't care
    _uuid = name if name else _uuid

    err, msg = ioc.IOCage(jail=source).create(source,
                                              props,
                                              count,
                                              _uuid=_uuid,
                                              clone=True)

    if err:
        ioc_common.logit({"level": "EXCEPTION", "message": msg})
Exemple #10
0
def cli(jail, props, plugin):
    """Get a list of jails and print the property."""

    if not props:
        # Click doesn't correctly assign the two variables for some reason
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "You must specify a jail!"
        })

    for prop in props:
        ioc.IOCage(jail=jail, skip_jails=True).set(prop, plugin)
Exemple #11
0
def cli(source, props, count, name, _uuid, thickjail):
    # At this point we don't care
    _uuid = name if name else _uuid

    err, msg = ioc.IOCage(jail=source).create(
        source, props, count, _uuid=_uuid, thickjail=thickjail, clone=True
    )

    if err:
        ioc_common.logit({
            'level': 'EXCEPTION',
            'message': msg
        })
Exemple #12
0
def cli(jail, name, force):
    """Get a list of jails and print the property."""
    if not force:
        ioc_common.logit({
            "level"  : "WARNING",
            "message": "\nThis will destroy ALL data created including "
                       f"ALL snapshots taken after the snapshot {name}"
        })

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

    ioc.IOCage(jail=jail).rollback(name)
Exemple #13
0
def cli(jail, name, force):
    """Get a list of jails and print the property."""
    if not force:
        ioc_common.logit({
            "level"  : "WARNING",
            "message": "\nThis will destroy ALL data created including "
                       f"ALL snapshots taken after the snapshot {name}"
        })

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

    ioc.IOCage(jail=jail).rollback(name)
Exemple #14
0
def cli(header, jail, _long, _sort):
    """Allows a user to show resource usage of all jails."""
    table = texttable.Texttable(max_width=0)
    snap_list = ioc.IOCage(jail=jail).snap_list(_long, _sort)

    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)
        ioc_common.logit({"level": "INFO", "message": table.draw()})
    else:
        for snap in snap_list:
            ioc_common.logit({"level": "INFO", "message": "\t".join(snap)})
Exemple #15
0
def validate_count(ctx, param, value):
    """Takes a string, removes the commas and returns an int."""
    if isinstance(value, str):
        try:
            value = value.replace(",", "")

            return int(value)
        except ValueError:
            ioc_common.logit({
                "level": "EXCEPTION",
                "message": f"({value} is not a valid  integer."
            })
    else:
        return int(value)
Exemple #16
0
def cli(jail, props, plugin):
    """Get a list of jails and print the property."""

    if not props:
        # Click doesn't correctly assign the two variables for some reason
        ioc_common.logit(
            {
                "level": "EXCEPTION",
                "message": "You must specify a jail!"
            })

    for prop in props:
        ioc.IOCage(
            jail=jail, skip_jails=True).set(prop, plugin)
Exemple #17
0
def validate_count(ctx, param, value):
    """Takes a string, removes the commas and returns an int."""
    if isinstance(value, str):
        try:
            value = value.replace(',', '')

            return int(value)
        except ValueError:
            ioc_common.logit({
                'level': 'EXCEPTION',
                'message': f'({value} is not a valid  integer.'
            })
    else:
        return int(value)
Exemple #18
0
def validate_count(ctx, param, value):
    """Takes a string, removes the commas and returns an int."""

    if isinstance(value, str):
        try:
            value = value.replace(",", "")

            return int(value)
        except ValueError:
            ioc_common.logit({
                "level": "EXCEPTION",
                "message": f"{value} is not a valid integer."
            })
    else:
        return int(value)
Exemple #19
0
def cli(force, dataset_type):
    """Calls the correct destroy function."""
    if dataset_type == 'jails':
        msg = {
            'level': 'WARNING',
            'message': '\nThis will destroy ALL jails and any '
                       'snapshots on a RELEASE,'
                       ' including templates!'
        }
    elif dataset_type == 'all':
        msg = {
            'level': 'WARNING',
            'message': '\nThis will destroy ALL iocage data!'
        }
    elif dataset_type == 'release':
        msg = {
            'level': 'WARNING',
            'message': '\nThis will destroy ALL fetched RELEASES and'
                       ' jails/templates created from them!'
        }
    elif dataset_type == 'template':
        msg = {
            'level': 'WARNING',
            'message': 'This will destroy ALL templates and jails'
                       ' created from them!'
        }
    elif dataset_type == 'images':
        msg = {
            'level': 'WARNING',
            'message': 'This will destroy ALL exports created!'
        }
    elif dataset_type == 'debug':
        msg = {
            'level': 'WARNING',
            'message': 'This will destroy ALL debugs created at iocage/debug!'
        }
    else:
        ioc_common.logit({
            'level': 'EXCEPTION',
            'message': 'Please specify a dataset type to clean!'
        })

    if not force:
        ioc_common.logit(msg)
        if not click.confirm('\nAre you sure?'):
            exit()

    ioc.IOCage(skip_jails=True).clean(dataset_type)
Exemple #20
0
def cli(rc, jails, ignore):
    """
    Looks for the jail supplied and passes the uuid, path and configuration
    location to start_jail.
    """
    if not jails and not rc:
        ioc_common.logit({
            'level': 'EXCEPTION',
            'message': 'Usage: iocage start [OPTIONS] JAILS...\n'
                       '\nError: Missing argument "jails".'
        })

    if rc:
        ioc.IOCage(rc=rc, silent=True).start(ignore_exception=ignore)
    else:
        for jail in jails:
            ioc.IOCage(jail=jail, rc=rc).start(ignore_exception=ignore)
Exemple #21
0
def cli(rc, force, jails):
    """
    Looks for the jail supplied and passes the uuid, path and configuration
    location to stop_jail.
    """
    if not jails and not rc:
        ioc_common.logit({
            "level"  : "EXCEPTION",
            "message": 'Usage: iocage stop [OPTIONS] JAILS...\n'
                       '\nError: Missing argument "jails".'
        })

    if rc:
        ioc.IOCage(rc=rc, silent=True).stop(force=force)
    else:
        for jail in jails:
            ioc.IOCage(jail=jail, rc=rc).stop(force=force)
Exemple #22
0
def cli(header, _long, _sort):
    """Allows a user to show resource usage of all jails."""
    table = texttable.Texttable(max_width=0)
    jail_list = ioc.IOCage().df()

    sort = ioc_common.ioc_sort("df", _sort)
    jail_list.sort(key=sort)

    if header:
        jail_list.insert(0, ["NAME", "CRT", "RES", "QTA", "USE", "AVA"])
        # We get an infinite float otherwise.
        table.set_cols_dtype(["t", "t", "t", "t", "t", "t"])
        table.add_rows(jail_list)

        ioc_common.logit({"level": "INFO", "message": table.draw()})
    else:
        for jail in jail_list:
            ioc_common.logit({"level": "INFO", "message": "\t".join(jail)})
Exemple #23
0
def cli(header, _long, _sort):
    """Allows a user to show resource usage of all jails."""
    table = texttable.Texttable(max_width=0)
    jail_list = ioc.IOCage().df()

    sort = ioc_common.ioc_sort("df", _sort)
    jail_list.sort(key=sort)

    if header:
        jail_list.insert(0, ["NAME", "CRT", "RES", "QTA", "USE", "AVA"])
        # We get an infinite float otherwise.
        table.set_cols_dtype(["t", "t", "t", "t", "t", "t"])
        table.add_rows(jail_list)

        ioc_common.logit({"level": "INFO", "message": table.draw()})
    else:
        for jail in jail_list:
            ioc_common.logit({"level": "INFO", "message": "\t".join(jail)})
Exemple #24
0
def cli(force, dataset_type):
    """Calls the correct destroy function."""
    if dataset_type == "jails":
        msg = {
            "level":
            "WARNING",
            "message":
            "\nThis will destroy ALL jails and any "
            "snapshots on a RELEASE,"
            "including templates!"
        }
    elif dataset_type == "all":
        msg = {
            "level": "WARNING",
            "message": "\nThis will destroy ALL iocage data!"
        }
    elif dataset_type == "release":
        msg = {
            "level":
            "WARNING",
            "message":
            "\nThis will destroy ALL fetched RELEASES and"
            " jails/templates created from them!"
        }
    elif dataset_type == "template":
        msg = {
            "level":
            "WARNING",
            "message":
            "This will destroy ALL templates and jails"
            " created from them!"
        }
    else:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please specify a dataset type to clean!"
        })

    if not force:
        ioc_common.logit(msg)
        if not click.confirm("\nAre you sure?"):
            exit()

    ioc.IOCage(skip_jails=True).clean(dataset_type)
Exemple #25
0
def cli(jail, name):
    """Removes a snapshot from a user supplied jail."""
    # TODO: Move to API
    jails = ioc_list.IOCList("uuid").list_datasets()
    pool = ioc_json.IOCJson().json_get_value("pool")
    _jail = {
        uuid: path
        for (uuid, path) in jails.items() if uuid.startswith(jail)
    }

    if len(_jail) == 1:
        uuid, path = next(iter(_jail.items()))
    elif len(_jail) > 1:
        ioc_common.logit({
            "level": "ERROR",
            "message": f"Multiple jails found for {jail}:"
        })
        for u, p in sorted(_jail.items()):
            ioc_common.logit({"level": "ERROR", "message": f"  {u} ({p})"})
        exit(1)
    else:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": f"{jail} not found!"
        })

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

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

    try:
        su.check_call(["zfs", "destroy", "-r", "-f", target])
        ioc_common.logit({
            "level": "INFO",
            "message": f"Snapshot: {target} destroyed."
        })
    except su.CalledProcessError as err:
        ioc_common.logit({"level": "EXCEPTION", "message": f"{err}"})
        exit(1)
Exemple #26
0
def cli(rc, force, jails):
    """
    Looks for the jail supplied and passes the uuid, path and configuration
    location to stop_jail.
    """
    if not jails and not rc:
        ioc_common.logit({
            "level":
            "EXCEPTION",
            "message":
            'Usage: iocage stop [OPTIONS] JAILS...\n'
            '\nError: Missing argument "jails".'
        })

    if rc:
        ioc.IOCage(rc=rc, silent=True).stop(force=force)
    else:
        for jail in jails:
            ioc.IOCage(jail=jail, rc=rc).stop(force=force)
Exemple #27
0
def cli(header, jail, _long, _sort):
    """Allows a user to show resource usage of all jails."""
    table = texttable.Texttable(max_width=0)
    snap_list = ioc.IOCage(jail=jail).snap_list(_long, _sort)

    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)
        ioc_common.logit({
            "level"  : "INFO",
            "message": table.draw()
        })
    else:
        for snap in snap_list:
            ioc_common.logit({
                "level"  : "INFO",
                "message": "\t".join(snap)
            })
Exemple #28
0
def cli(dataset_type, header, _long, remote, http, plugins, _sort, quick,
        official):
    """This passes the arg and calls the jail_datasets function."""
    freebsd_version = ioc_common.checkoutput(["freebsd-version"])
    iocage = ioc.IOCage(skip_jails=True)

    if dataset_type is None:
        dataset_type = "all"

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

        _list = iocage.fetch(list=True,
                             remote=True,
                             http=http,
                             hardened=hardened)
        header = False

    if plugins and remote:
        _list = iocage.fetch(list=True,
                             remote=True,
                             header=header,
                             _long=_long,
                             plugin_file=True,
                             official=official)
    elif not remote:
        _list = iocage.list(dataset_type,
                            header,
                            _long,
                            _sort,
                            plugin=plugins,
                            quick=quick)

    if not header:
        if dataset_type == "base":
            for item in _list:
                ioc_common.logit({"level": "INFO", "message": item})
        else:
            for item in _list:
                if remote and not plugins:
                    ioc_common.logit({"level": "INFO", "message": item})
                else:
                    ioc_common.logit({
                        "level": "INFO",
                        "message": "\t".join(item)
                    })
    else:
        ioc_common.logit({"level": "INFO", "message": _list})
Exemple #29
0
def cli(command, jail, host_user, jail_user):
    """Runs the command given inside the specified jail as the supplied
    user."""
    # We may be getting ';', '&&' and so forth. Adding the shell for safety.

    if len(command) == 1:
        command = ("/bin/sh", "-c") + command

    if jail.startswith("-"):
        ioc_common.logit(
            {
                "level": "EXCEPTION",
                "message": "Please specify a jail first!"
            }
        )

    # They haven't set a host_user then, and actually want a jail one,
    # unsetting the convenience default
    host_user = "" if jail_user and host_user == "root" else host_user

    ioc.IOCage(jail=jail).exec(command, host_user, jail_user)
Exemple #30
0
def cli(force, dataset_type):
    """Calls the correct destroy function."""
    if dataset_type == "jails":
        msg = {
            "level"  : "WARNING",
            "message": "\nThis will destroy ALL jails and any "
                       "snapshots on a RELEASE,"
                       "including templates!"
        }
    elif dataset_type == "all":
        msg = {
            "level"  : "WARNING",
            "message": "\nThis will destroy ALL iocage data!"
        }
    elif dataset_type == "release":
        msg = {
            "level"  : "WARNING",
            "message": "\nThis will destroy ALL fetched RELEASES and"
                       " jails/templates created from them!"
        }
    elif dataset_type == "template":
        msg = {
            "level"  : "WARNING",
            "message": "This will destroy ALL templates and jails"
                       " created from them!"
        }
    else:
        ioc_common.logit({
            "level"  : "EXCEPTION",
            "message": "Please specify a dataset type to clean!"
        })

    if not force:
        ioc_common.logit(msg)
        if not click.confirm("\nAre you sure?"):
            exit()

    ioc.IOCage(skip_jails=True).clean(dataset_type)
Exemple #31
0
def child_test(iocroot, name, _type, force=False, recursive=False):
    """Tests for dependent children"""
    path = None
    children = []
    paths = [
        f"{iocroot}/jails/{name}/root", f"{iocroot}/releases/{name}",
        f"{iocroot}/templates/{name}/root"
    ]

    for p in paths:
        if os.path.isdir(p):
            path = p
            children = Dataset(path).snapshots_recursive()

            break

    if path is None:
        if not force:
            ioc_common.logit({
                "level":
                "WARNING",
                "message":
                "Partial UUID/NAME supplied, cannot check for "
                "dependant jails."
            })

            if not click.confirm("\nProceed?"):
                exit()
        else:
            return

    _children = []

    for child in children:
        _name = child.name
        _children.append(f"  {_name}\n")

    sort = ioc_common.ioc_sort("", "name", data=_children)
    _children.sort(key=sort)

    if len(_children) != 0:
        if not force and not recursive:
            ioc_common.logit({
                "level":
                "WARNING",
                "message":
                f"\n{name} has dependent jails"
                " (who may also have dependents),"
                " use --recursive to destroy: "
            })

            ioc_common.logit({
                "level": "WARNING",
                "message": "".join(_children)
            })
            exit(1)
        else:
            return _children
Exemple #32
0
def cli(command, jail, host_user, jail_user, force):
    """Runs the command given inside the specified jail as the supplied
    user."""
    # We may be getting ';', '&&' and so forth. Adding the shell for safety.

    if len(command) == 1:
        command = ("/bin/sh", "-c") + command

    if jail.startswith("-"):
        ioc_common.logit(
            {
                "level": "EXCEPTION",
                "message": "Please specify a jail first!"
            }
        )

    # They haven't set a host_user then, and actually want a jail one,
    # unsetting the convenience default
    host_user = "" if jail_user and host_user == "root" else host_user

    try:
        ioc.IOCage(jail=jail).exec(
            command,
            host_user,
            jail_user,
            interactive=True,
            start_jail=force
        )
    except KeyboardInterrupt:
        pass
    except Exception as e:
        ioc_common.logit({
            'level': 'EXCEPTION',
            'message': 'Command failed!\n'
                       f'Exception: "{e.__class__.__name__}:{str(e)}" occured'
        })
Exemple #33
0
def cli(dataset_type, header, _long, remote, http, plugins, _sort, quick,
        official):
    """This passes the arg and calls the jail_datasets function."""
    freebsd_version = ioc_common.checkoutput(["freebsd-version"])
    iocage = ioc.IOCage(skip_jails=True)

    if dataset_type is None:
        dataset_type = "all"

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

        _list = iocage.fetch(
            list=True, remote=True, http=http, hardened=hardened)
        header = False

    if plugins and remote:
        _list = iocage.fetch(
            list=True,
            remote=True,
            header=header,
            _long=_long,
            plugin_file=True,
            official=official)
    elif not remote:
        _list = iocage.list(
            dataset_type, header, _long, _sort, plugin=plugins, quick=quick)

    if not header:
        if dataset_type == "base":
            for item in _list:
                ioc_common.logit({"level": "INFO", "message": item})
        else:
            for item in _list:
                if remote and not plugins:
                    ioc_common.logit({"level": "INFO", "message": item})
                else:
                    ioc_common.logit({
                        "level": "INFO",
                        "message": "\t".join(item)
                    })
    else:
        ioc_common.logit({"level": "INFO", "message": _list})
Exemple #34
0
def child_test(zfs, iocroot, name, _type, force=False, recursive=False):
    """Tests for dependent children"""
    path = None
    children = []
    paths = [f"{iocroot}/jails/{name}/root",
             f"{iocroot}/releases/{name}",
             f"{iocroot}/templates/{name}/root"]

    for p in paths:
        if os.path.isdir(p):
            path = p
            children = zfs.get_dataset_by_path(path).snapshots_recursive

            break

    if path is None:
        if not force:
            ioc_common.logit({
                "level": "WARNING",
                "message": "Partial UUID/NAME supplied, cannot check for "
                           "dependant jails."
            })

            if not click.confirm("\nProceed?"):
                exit()
        else:
            return

    _children = []

    for child in children:
        _name = child.name.rsplit("@", 1)[-1]
        _children.append(f"  {_name}\n")

    sort = ioc_common.ioc_sort("", "name", data=_children)
    _children.sort(key=sort)

    if len(_children) != 0:
        if not force and not recursive:
            ioc_common.logit({
                "level": "WARNING",
                "message": f"\n{name} has dependent jails"
                           " (who may also have dependents),"
                           " use --recursive to destroy: "
            })

            ioc_common.logit({
                "level": "WARNING",
                "message": "".join(_children)
            })
            exit(1)
        else:
            return
Exemple #35
0
def cli(prop, _type, _pool, jail, recursive, header, plugin, force):
    """Get a list of jails and print the property."""
    table = texttable.Texttable(max_width=0)

    if _type:
        # Confusing I know.
        jail = prop
        prop = _type
    elif _pool:
        pool = ioc.IOCage(skip_jails=True).get('', pool=True)
        ioc_common.logit({
            'level': 'INFO',
            'message': pool
        })
        exit()
    else:
        if not jail and not recursive:
            ioc_common.logit({
                'level': 'EXCEPTION',
                'message': 'You must specify a jail!'
            })

    if _type == 'all' and recursive:
        # TODO: Port this back
        ioc_common.logit({
            'level': 'EXCEPTION',
            'message': 'You cannot use --all (-a) and --recursive (-r) '
                       'together. '
        })

    if not recursive:
        if prop == 'state' or _type == 'state':
            state = ioc.IOCage(jail=jail).get(prop)

            ioc_common.logit({
                'level': 'INFO',
                'message': state
            })
        elif prop == 'jid' or _type == 'jid':
            jid = ioc.IOCage(jail=jail).list('jid', uuid=jail)[1]

            ioc_common.logit({
                'level': 'INFO',
                'message': jid
            })
        elif plugin:
            _plugin = ioc.IOCage(jail=jail, skip_jails=True).get(
                prop, plugin=True, start_jail=force
            )

            ioc_common.logit({
                'level': 'INFO',
                'message': _plugin
            })
        elif prop == 'all':
            props = ioc.IOCage(jail=jail, skip_jails=True).get(prop)

            for p, v in props.items():
                ioc_common.logit({
                    'level': 'INFO',
                    'message': f'{p}:{v}'
                })
        else:
            p = ioc.IOCage(jail=jail, skip_jails=True).get(prop)

            ioc_common.logit({
                'level': 'INFO',
                'message': p
            })
    else:
        jails = ioc.IOCage().get(prop, recursive=True)
        table.header(['NAME', f'PROP - {prop}'])

        for jail_dict in jails:
            for jail, prop in jail_dict.items():
                if header:
                    table.add_row([jail, prop])
                else:
                    ioc_common.logit({
                        'level': 'INFO',
                        'message': f'{jail}\t{prop}'
                    })

        if header:
            # Prints the table
            ioc_common.logit({
                'level': 'INFO',
                'message': table.draw()
            })
Exemple #36
0
def cli(force, release, download, jails, recursive):
    """Destroys the jail's 2 datasets and the snapshot from the RELEASE."""
    # Want these here, otherwise they're reinstanced for each jail.
    zfs = libzfs.ZFS(history=True, history_prefix="<iocage>")
    iocroot = ioc.PoolAndDataset().get_iocroot()

    if download and not release:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "--release (-r) must be specified as well!"
        })

    if jails and not release:
        for jail in jails:
            if not force:
                ioc_common.logit({
                    "level": "WARNING",
                    "message": f"\nThis will destroy jail {jail}"
                })

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

            child_test(zfs,
                       iocroot,
                       jail,
                       "jail",
                       force=force,
                       recursive=recursive)

            ioc.IOCage(jail=jail, skip_jails=True).destroy_jail()
    elif jails and release:
        for release in jails:
            if not force:
                ioc_common.logit({
                    "level":
                    "WARNING",
                    "message":
                    f"\nThis will destroy RELEASE: {release}"
                })

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

            child_test(zfs,
                       iocroot,
                       release,
                       "release",
                       force=force,
                       recursive=recursive)

            ioc.IOCage(jail=release, skip_jails=True).destroy_release(download)
    elif not jails and release:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please specify one or more RELEASEs!"
        })
    else:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please specify one or more jails!"
        })
Exemple #37
0
def cli(prop, _type, _pool, jail, recursive, header, plugin):
    """Get a list of jails and print the property."""
    table = texttable.Texttable(max_width=0)

    if _type:
        # Confusing I know.
        jail = prop
        prop = _type
    elif _pool:
        pool = ioc.IOCage(skip_jails=True).get("", pool=True)
        ioc_common.logit({
            "level"  : "INFO",
            "message": pool
        })
        exit()
    else:
        if not jail and not recursive:
            ioc_common.logit({
                "level"  : "EXCEPTION",
                "message": "You must specify a jail!"
            })

    if _type == "all" and recursive:
        # TODO: Port this back
        ioc_common.logit({
            "level"  : "EXCEPTION",
            "message": "You cannot use --all (-a) and --recursive (-r) "
                       "together. "
        })

    if not recursive:
        if prop == "state" or _type == "state":
            state = ioc.IOCage(jail=jail).get(prop)

            ioc_common.logit({
                "level"  : "INFO",
                "message": state
            })
        elif prop == "jid" or _type == "jid":
            jid = ioc.IOCage(jail=jail).list("jid", uuid=jail)[1]

            ioc_common.logit({
                "level"  : "INFO",
                "message": jid
            })
        elif plugin:
            _plugin = ioc.IOCage(jail=jail, skip_jails=True).get(prop,
                                                                 plugin=True)

            ioc_common.logit({
                "level"  : "INFO",
                "message": _plugin
            })
        elif prop == "all":
            props = ioc.IOCage(jail=jail, skip_jails=True).get(prop)

            for p, v in props.items():
                ioc_common.logit({
                    "level"  : "INFO",
                    "message": f"{p}:{v}"
                })
        else:
            p = ioc.IOCage(jail=jail, skip_jails=True).get(prop)

            ioc_common.logit({
                "level"  : "INFO",
                "message": p
            })
    else:
        jails = ioc.IOCage().get(prop, recursive=True)
        table.header(["NAME", f"PROP - {prop}"])

        for jail_dict in jails:
            for jail, prop in jail_dict.items():
                if header:
                    table.add_row([jail, prop])
                else:
                    ioc_common.logit({
                        "level"  : "INFO",
                        "message": f"{jail}\t{prop}"
                    })

        if header:
            # Prints the table
            ioc_common.logit({
                "level"  : "INFO",
                "message": table.draw()
            })
Exemple #38
0
def cli(action, fstab_string, jail, header, replace):
    """
    Looks for the jail supplied and passes the uuid, path and configuration
    location to manipulate the fstab.
    """
    index = None if not replace else replace
    _index = False
    add_path = False
    fstab_string = list(fstab_string)
    action = action if not replace else "replace"

    if not fstab_string and action != "edit" and action != "list":
        ioc_common.logit({
            'level': 'EXCEPTION',
            'message': 'Please supply an fstab entry or jail!'
        })

    # 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])

                _index = True
                source, destination, fstype, options, dump, _pass = "", "", \
                                                                    "", "", \
                                                                    "", ""
            except TypeError:
                ioc_common.logit({
                    "level": "EXCEPTION",
                    "message": "Please specify either a valid fstab "
                               "entry or an index number."
                })
            except ValueError:
                # We will assume this is just a source, and will do a readonly
                # nullfs mount
                source = fstab_string[0]
                destination = source
                fstype = "nullfs"
                options = "ro"
                dump = "0"
                _pass = "******"
    elif action == "list":
        # We don't need these
        source, destination, fstype, options, dump, _pass = "", "", \
                                                            "", "", \
                                                            "", ""
    else:
        if action != "edit":
            try:
                source, destination, fstype, options, dump, _pass = \
                    fstab_string
            except ValueError:
                ioc_common.logit({
                    "level": "EXCEPTION",
                    "message": "Please specify a valid fstab entry!\n\n"
                               "Example:\n  /the/source /dest FSTYPE "
                               "FSOPTIONS FSDUMP FSPASS"
                })
        else:
            source, destination, fstype, options, dump, _pass = "", "", \
                                                                "", "", \
                                                                "", ""

    if not _index:
        add_path = True

    fstab = ioc.IOCage(jail=jail).fstab(
        action, source, destination, fstype, options, dump, _pass, index=index,
        add_path=add_path, header=header)

    if action == "list":
        if header:
            ioc_common.logit({
                "level": "INFO",
                "message": fstab
            })
        else:
            for f in fstab:
                ioc_common.logit({
                    "level": "INFO",
                    "message": f"{f[0]}\t{f[1]}"
                })
Exemple #39
0
def cli(release, template, count, props, pkglist, basejail, thickjail, empty,
        short, name, _uuid, thickconfig):

    if _uuid:
        try:
            uuid.UUID(_uuid, version=4)
        except ValueError:
            ioc_common.logit({
                "level": "EXCEPTION",
                "message": "Please provide a valid UUID"
            })
        else:
            if count > 1:
                ioc_common.logit({
                    "level": "EXCEPTION",
                    "message": "Flag --count cannot be used with --uuid"
                })

    if name:
        # noinspection Annotator
        valid = True if re.match(r"^[a-zA-Z0-9\._-]+$", name) else False

        if not valid:
            ioc_common.logit({
                "level": "EXCEPTION",
                "message": f"Invalid character in {name}, please remove it."
            })

        # At this point we don't care
        _uuid = name

    if release and "=" in release:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please supply a valid RELEASE!"
        })
    elif release and release.lower() == "latest":
        release = ioc_common.parse_latest_release()

    if release:
        try:
            ioc_common.check_release_newer(release)
        except ValueError:
            # We're assuming they understand the implications of a custom
            # scheme
            iocroot = ioc.PoolAndDataset().get_iocroot()
            path = f'{iocroot}/releases/{release}/root'
            _release = ioc_common.get_jail_freebsd_version(path, release)

            try:
                ioc_common.check_release_newer(_release)
            except ValueError:
                # We tried
                pass

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

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

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

    if empty:
        release = "EMPTY"

    iocage = ioc.IOCage(skip_jails=True)

    try:
        iocage.create(release, props, count, pkglist=pkglist,
                      template=template, short=short, _uuid=_uuid,
                      basejail=basejail, thickjail=thickjail, empty=empty,
                      thickconfig=thickconfig)
    except RuntimeError as err:
        if template and "Dataset" in str(err):
            # We want to list the available templates first
            ioc_common.logit({
                "level": "ERROR",
                "message": f"Template: {release} not found!"
            })
            templates = ioc.IOCage().list("template")

            for temp in templates:
                ioc_common.logit({
                    "level": "EXCEPTION",
                    "message": f"Created Templates:\n  {temp[1]}"
                })
            exit(1)
        else:
            # Standard errors
            ioc_common.logit({
                "level": "EXCEPTION",
                "message": err
            })
Exemple #40
0
def cli(prop, _type, _pool, jail, recursive, header, plugin):
    """Get a list of jails and print the property."""
    table = texttable.Texttable(max_width=0)

    if _type:
        # Confusing I know.
        jail = prop
        prop = _type
    elif _pool:
        pool = ioc.IOCage(skip_jails=True).get("", pool=True)
        ioc_common.logit({"level": "INFO", "message": pool})
        exit()
    else:
        if not jail and not recursive:
            ioc_common.logit({
                "level": "EXCEPTION",
                "message": "You must specify a jail!"
            })

    if _type == "all" and recursive:
        # TODO: Port this back
        ioc_common.logit({
            "level":
            "EXCEPTION",
            "message":
            "You cannot use --all (-a) and --recursive (-r) "
            "together. "
        })

    if not recursive:
        if prop == "state" or _type == "state":
            state = ioc.IOCage(jail=jail).get(prop)

            ioc_common.logit({"level": "INFO", "message": state})
        elif prop == "jid" or _type == "jid":
            jid = ioc.IOCage(jail=jail).list("jid", uuid=jail)[1]

            ioc_common.logit({"level": "INFO", "message": jid})
        elif plugin:
            _plugin = ioc.IOCage(jail=jail, skip_jails=True).get(prop,
                                                                 plugin=True)

            ioc_common.logit({"level": "INFO", "message": _plugin})
        elif prop == "all":
            props = ioc.IOCage(jail=jail, skip_jails=True).get(prop)

            for p, v in props.items():
                ioc_common.logit({"level": "INFO", "message": f"{p}:{v}"})
        else:
            p = ioc.IOCage(jail=jail, skip_jails=True).get(prop)

            ioc_common.logit({"level": "INFO", "message": p})
    else:
        jails = ioc.IOCage().get(prop, recursive=True)
        table.header(["NAME", f"PROP - {prop}"])

        for jail_dict in jails:
            for jail, prop in jail_dict.items():
                if header:
                    table.add_row([jail, prop])
                else:
                    ioc_common.logit({
                        "level": "INFO",
                        "message": f"{jail}\t{prop}"
                    })

        if header:
            # Prints the table
            ioc_common.logit({"level": "INFO", "message": table.draw()})
Exemple #41
0
def cli(prop, _type, _pool, jail, recursive, header, plugin, force):
    """Get a list of jails and print the property."""
    table = texttable.Texttable(max_width=0)

    if _type:
        # Confusing I know.
        jail = prop
        prop = _type
    elif _pool:
        pool = ioc.IOCage(skip_jails=True).get('', pool=True)
        ioc_common.logit({'level': 'INFO', 'message': pool})
        exit()
    else:
        if not jail and not recursive:
            ioc_common.logit({
                'level': 'EXCEPTION',
                'message': 'You must specify a jail!'
            })

    if _type == 'all' and recursive:
        # TODO: Port this back
        ioc_common.logit({
            'level':
            'EXCEPTION',
            'message':
            'You cannot use --all (-a) and --recursive (-r) '
            'together. '
        })

    if _type == 'all' and not jail:
        ioc_common.logit({
            'level':
            'EXCEPTION',
            'message':
            'Please specify a jail name when using -a flag.'
        })

    if not recursive:
        if prop == 'state' or _type == 'state':
            state = ioc.IOCage(jail=jail).get(prop)

            ioc_common.logit({'level': 'INFO', 'message': state})
        elif prop == 'jid' or _type == 'jid':
            jid = ioc.IOCage(jail=jail).list('jid', uuid=jail)[1]

            ioc_common.logit({'level': 'INFO', 'message': jid})
        elif plugin:
            _plugin = ioc.IOCage(jail=jail,
                                 skip_jails=True).get(prop,
                                                      plugin=True,
                                                      start_jail=force)

            ioc_common.logit({'level': 'INFO', 'message': _plugin})
        elif prop == 'all':
            props = ioc.IOCage(jail=jail, skip_jails=True).get(prop)

            for p, v in props.items():
                ioc_common.logit({'level': 'INFO', 'message': f'{p}:{v}'})
        else:
            p = ioc.IOCage(jail=jail, skip_jails=True).get(prop)

            ioc_common.logit({'level': 'INFO', 'message': p})
    else:
        jails = ioc.IOCage().get(prop, recursive=True)
        table.header(['NAME', f'PROP - {prop}'])

        for jail_dict in jails:
            for jail, prop in jail_dict.items():
                if header:
                    table.add_row([jail, prop])
                else:
                    ioc_common.logit({
                        'level': 'INFO',
                        'message': f'{jail}\t{prop}'
                    })

        if header:
            # Prints the table
            ioc_common.logit({'level': 'INFO', 'message': table.draw()})
Exemple #42
0
def cli(force, release, download, jails, recursive):
    """Destroys the jail's 2 datasets and the snapshot from the RELEASE."""
    # Want these here, otherwise they're reinstanced for each jail.
    iocroot = ioc.PoolAndDataset().get_iocroot()

    if download and not release:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "--release (-r) must be specified as well!"
        })

    if jails and not release:
        for jail in jails:
            iocage = ioc.IOCage(jail=jail, skip_jails=True)
            # If supplied a partial, we want the real match we got.
            jail, _ = iocage.__check_jail_existence__()

            if not force:
                ioc_common.logit({
                    "level": "WARNING",
                    "message": f"\nThis will destroy jail {jail}"
                })

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

            child_test(iocroot, jail, "jail", force=force, recursive=recursive)

            iocage.destroy_jail(force=force)
    elif jails and release:
        for release in jails:
            if not force:
                ioc_common.logit({
                    "level":
                    "WARNING",
                    "message":
                    f"\nThis will destroy RELEASE: {release}"
                })

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

            children = child_test(iocroot,
                                  release,
                                  "release",
                                  force=force,
                                  recursive=recursive)

            if children:
                for child in children:
                    ioc.IOCage(jail=child).destroy_jail(force)

            ioc.IOCage(jail=release, skip_jails=True).destroy_release(download)
    elif not jails and release:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please specify one or more RELEASEs!"
        })
    else:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please specify one or more jails!"
        })
Exemple #43
0
def cli(release, template, count, props, pkglist, basejail, thickjail, empty,
        short, name, _uuid, force):

    if name:
        # noinspection Annotator
        valid = True if re.match("^[a-zA-Z0-9\._-]+$", name) else False

        if not valid:
            ioc_common.logit({
                "level":
                "EXCEPTION",
                "message":
                f"Invalid character in {name}, please remove it."
            })

        # At this point we don't care
        _uuid = name

    if release and "=" in release:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please supply a valid RELEASE!"
        })
    elif release and release.lower() == "latest":
        release = ioc_common.parse_latest_release()

    if release:
        release = release.upper()
        ioc_common.check_release_newer(release)

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

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

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

    if empty:
        release = "EMPTY"

    iocage = ioc.IOCage(skip_jails=True)

    try:
        iocage.create(release,
                      props,
                      count,
                      pkglist=pkglist,
                      template=template,
                      short=short,
                      _uuid=_uuid,
                      basejail=basejail,
                      thickjail=thickjail,
                      empty=empty)
    except RuntimeError as err:
        if template and "Dataset" in str(err):
            # We want to list the available templates first
            ioc_common.logit({
                "level": "ERROR",
                "message": f"Template: {release} not found!"
            })
            templates = ioc.IOCage().list("template")

            for temp in templates:
                ioc_common.logit({
                    "level": "EXCEPTION",
                    "message": f"Created Templates:\n  {temp[1]}"
                })
            exit(1)
        else:
            # Standard errors
            ioc_common.logit({"level": "EXCEPTION", "message": err})
Exemple #44
0
def cli(release, template, count, props, pkglist, basejail, clone_basejail,
        thickjail, empty, short, name, _uuid, thickconfig):

    if _uuid:
        try:
            uuid.UUID(_uuid, version=4)
        except ValueError:
            ioc_common.logit({
                "level": "EXCEPTION",
                "message": "Please provide a valid UUID"
            })
        else:
            if count > 1:
                ioc_common.logit({
                    "level":
                    "EXCEPTION",
                    "message":
                    "Flag --count cannot be used with --uuid"
                })

    if name:
        # noinspection Annotator
        valid = True if re.match(r"^[a-zA-Z0-9\._-]+$", name) else False

        if not valid:
            ioc_common.logit({
                "level":
                "EXCEPTION",
                "message":
                f"Invalid character in {name}, please remove it."
            })

        # At this point we don't care
        _uuid = name

    if release and "=" in release:
        ioc_common.logit({
            "level": "EXCEPTION",
            "message": "Please supply a valid RELEASE!"
        })
    elif release and release.lower() == "latest":
        release = ioc_common.parse_latest_release()

    if release:
        try:
            ioc_common.check_release_newer(release)
        except ValueError:
            # We're assuming they understand the implications of a custom
            # scheme
            iocroot = ioc.PoolAndDataset().get_iocroot()
            path = f'{iocroot}/releases/{release}/root'
            _release = ioc_common.get_jail_freebsd_version(path, release)

            try:
                ioc_common.check_release_newer(_release)
            except ValueError:
                # We tried
                pass

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

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

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

    if empty:
        release = "EMPTY"

    if clone_basejail:
        # We want to still create a basejail
        basejail = True

    iocage = ioc.IOCage(skip_jails=True)

    try:
        iocage.create(release,
                      props,
                      count,
                      pkglist=pkglist,
                      template=template,
                      short=short,
                      _uuid=_uuid,
                      basejail=basejail,
                      thickjail=thickjail,
                      empty=empty,
                      thickconfig=thickconfig,
                      clone_basejail=clone_basejail)
    except (RuntimeError, ioc_exceptions.JailMissingConfiguration) as err:
        if template and "Dataset" in str(err) or str(err).startswith(
                'Template'):
            # We want to list the available templates first
            ioc_common.logit({
                "level": "ERROR",
                "message": f"Template: {release} not found!"
            })
            templates = ioc.IOCage(silent=True).list('template')
            template_names = ''
            for temp in templates:
                template_names += '\n  ' + temp[1]

            ioc_common.logit({
                'level': 'EXCEPTION',
                'message': f'Created Templates:{template_names}'
            })
            exit(1)
        else:
            # Standard errors
            ioc_common.logit({"level": "EXCEPTION", "message": err})
Exemple #45
0
def cli(force, delete):
    """Migrates all the iocage_legacy develop basejails to clone jails."""
    # TODO: Move to API
    jails = ioc_list.IOCList("uuid").list_datasets()

    if not force:
        ioc_common.logit({
            "level":
            "WARNING",
            "message":
            "\nThis will migrate ALL iocage-legacy develop"
            " basejails to clonejails, it can take a long"
            " time!\nPlease make sure you are not running"
            " this on iocage-legacy 1.7.6 basejails."
        })

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

    for uuid, path in jails.items():
        pool = ioc_json.IOCJson().json_get_value("pool")
        iocroot = ioc_json.IOCJson(pool).json_get_value("iocroot")
        jail = f"{pool}/iocage/jails/{uuid}"
        jail_old = f"{pool}/iocage/jails_old/{uuid}"
        conf = ioc_json.IOCJson(path).json_load()

        try:
            tag = conf["tag"]
        except KeyError:
            # These are actually NEW jails.

            continue

        release = conf["cloned_release"]

        if conf["type"] == "basejail":
            try:
                ioc_common.checkoutput(["zfs", "rename", "-p", jail, jail_old],
                                       stderr=su.STDOUT)
            except su.CalledProcessError as err:
                ioc_common.logit({
                    "level":
                    "EXCEPTION",
                    "message":
                    f"{err.output.decode('utf-8').strip()}"
                })

            try:
                os.remove(f"{iocroot}/tags/{tag}")
            except OSError:
                pass

            date_fmt_legacy = "%Y-%m-%d@%H:%M:%S"

            # We don't want to rename datasets to a bunch of dates.
            try:
                datetime.datetime.strptime(tag, date_fmt_legacy)
                _name = str(uuid.uuid4())
            except ValueError:
                # They already named this jail, making it like our new ones.
                _name = tag

            new_uuid = ioc_create.IOCCreate(
                release,
                "",
                0,
                None,
                migrate=True,
                config=conf,
                silent=True,
                uuid=_name,
            ).create_jail()
            new_prop = ioc_json.IOCJson(f"{iocroot}/jails/{new_uuid}",
                                        silent=True).json_set_value
            new_prop(f"host_hostname={new_uuid}")
            new_prop(f"host_hostuuid={new_uuid}")
            new_prop("type=jail")
            new_prop(f"jail_zfs_dataset={iocroot}/jails/{new_uuid}/data")

            ioc_common.logit({
                "level":
                "INFO",
                "message":
                f"Copying files for {new_uuid}, please wait..."
            })

            ioc_common.copytree(f"{iocroot}/jails_old/{uuid}/root",
                                f"{iocroot}/jails/{new_uuid}/root",
                                symlinks=True)

            shutil.copy(f"{iocroot}/jails_old/{uuid}/fstab",
                        f"{iocroot}/jails/{new_uuid}/fstab")

            for line in fileinput.input(
                    f"{iocroot}/jails/{new_uuid}/root/etc/"
                    "rc.conf", inplace=1):
                print(
                    line.replace(f'hostname="{uuid}"',
                                 f'hostname="{new_uuid}"').rstrip())

            if delete:
                try:
                    ioc_common.checkoutput(
                        ["zfs", "destroy", "-r", "-f", jail_old],
                        stderr=su.STDOUT)
                except su.CalledProcessError as err:
                    raise RuntimeError(
                        f"{err.output.decode('utf-8').rstrip()}")

                try:
                    su.check_call([
                        "zfs", "destroy", "-r", "-f",
                        f"{pool}/iocage/jails_old"
                    ])
                except su.CalledProcessError:
                    # We just want the top level dataset gone, no big deal.
                    pass

            ioc_common.logit({
                "level":
                "INFO",
                "message":
                f"{uuid} ({tag}) migrated to {new_uuid}!\n"
            })
Exemple #46
0
def cli(force, delete):
    """Migrates all the iocage_legacy develop basejails to clone jails."""
    # TODO: Move to API
    jails = ioc_list.IOCList("uuid").list_datasets()

    if not force:
        ioc_common.logit({
            "level":
            "WARNING",
            "message":
            "\nThis will migrate ALL iocage-legacy develop"
            " basejails to clonejails, it can take a long"
            " time!\nPlease make sure you are not running"
            " this on iocage-legacy 1.7.6 basejails."
        })

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

    for uuid, path in jails.items():
        pool = ioc_json.IOCJson().json_get_value("pool")
        iocroot = ioc_json.IOCJson(pool).json_get_value("iocroot")
        jail = f"{pool}/iocage/jails/{uuid}"
        jail_old = f"{pool}/iocage/jails_old/{uuid}"
        conf = ioc_json.IOCJson(path).json_get_value('all')

        try:
            tag = conf["tag"]
        except KeyError:
            # These are actually NEW jails.

            continue

        release = conf["cloned_release"]

        if conf["type"] == "basejail":
            try:
                ioc_common.checkoutput(
                    ["zfs", "rename", "-p", jail, jail_old], stderr=su.STDOUT)
            except su.CalledProcessError as err:
                ioc_common.logit(
                    {
                        "level": "EXCEPTION",
                        "message": f"{err.output.decode('utf-8').strip()}"
                    })

            try:
                os.remove(f"{iocroot}/tags/{tag}")
            except OSError:
                pass

            date_fmt_legacy = "%Y-%m-%d@%H:%M:%S"

            # We don't want to rename datasets to a bunch of dates.
            try:
                datetime.datetime.strptime(tag, date_fmt_legacy)
                _name = str(uuid.uuid4())
            except ValueError:
                # They already named this jail, making it like our new ones.
                _name = tag

            new_uuid = ioc_create.IOCCreate(
                release,
                "",
                0,
                None,
                migrate=True,
                config=conf,
                silent=True,
                uuid=_name,
            ).create_jail()
            new_prop = ioc_json.IOCJson(
                f"{iocroot}/jails/{new_uuid}", silent=True).json_set_value
            new_prop(f"host_hostname={new_uuid}")
            new_prop(f"host_hostuuid={new_uuid}")
            new_prop("type=jail")
            new_prop(f"jail_zfs_dataset={iocroot}/jails/{new_uuid}/data")

            ioc_common.logit({
                "level":
                "INFO",
                "message":
                f"Copying files for {new_uuid}, please wait..."
            })

            ioc_common.copytree(
                f"{iocroot}/jails_old/{uuid}/root",
                f"{iocroot}/jails/{new_uuid}/root",
                symlinks=True)

            shutil.copy(f"{iocroot}/jails_old/{uuid}/fstab",
                        f"{iocroot}/jails/{new_uuid}/fstab")

            for line in fileinput.input(
                    f"{iocroot}/jails/{new_uuid}/root/etc/"
                    "rc.conf", inplace=1):
                print(
                    line.replace(f'hostname="{uuid}"',
                                 f'hostname="{new_uuid}"').rstrip())

            if delete:
                try:
                    ioc_common.checkoutput(
                        ["zfs", "destroy", "-r", "-f", jail_old],
                        stderr=su.STDOUT)
                except su.CalledProcessError as err:
                    raise RuntimeError(
                        f"{err.output.decode('utf-8').rstrip()}")

                try:
                    su.check_call([
                        "zfs", "destroy", "-r", "-f",
                        f"{pool}/iocage/jails_old"
                    ])
                except su.CalledProcessError:
                    # We just want the top level dataset gone, no big deal.
                    pass

            ioc_common.logit({
                "level":
                "INFO",
                "message":
                f"{uuid} ({tag}) migrated to {new_uuid}!\n"
            })
Exemple #47
0
def cli(action, fstab_string, jail, header, replace):
    """
    Looks for the jail supplied and passes the uuid, path and configuration
    location to manipulate the fstab.
    """
    index = None if not replace else replace
    _index = False
    add_path = False
    fstab_string = list(fstab_string)
    action = action if not replace else "replace"

    if not fstab_string and action != "edit" and action != "list":
        ioc_common.logit({
            'level': 'EXCEPTION',
            'message': 'Please supply an fstab entry or jail!'
        })

    # 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])

                _index = True
                source, destination, fstype, options, dump, _pass = "", "", \
                                                                    "", "", \
                                                                    "", ""
            except TypeError:
                ioc_common.logit({
                    "level":
                    "EXCEPTION",
                    "message":
                    "Please specify either a valid fstab "
                    "entry or an index number."
                })
            except ValueError:
                # We will assume this is just a source, and will do a readonly
                # nullfs mount
                source = fstab_string[0]
                destination = source
                fstype = "nullfs"
                options = "ro"
                dump = "0"
                _pass = "******"
    elif action == "list":
        # We don't need these
        source, destination, fstype, options, dump, _pass = "", "", \
                                                            "", "", \
                                                            "", ""
    else:
        if action != "edit":
            try:
                source, destination, fstype, options, dump, _pass = \
                    fstab_string
            except ValueError:
                ioc_common.logit({
                    "level":
                    "EXCEPTION",
                    "message":
                    "Please specify a valid fstab entry!\n\n"
                    "Example:\n  /the/source /dest FSTYPE "
                    "FSOPTIONS FSDUMP FSPASS"
                })
        else:
            source, destination, fstype, options, dump, _pass = "", "", \
                                                                "", "", \
                                                                "", ""

    if not _index:
        add_path = True

    fstab = ioc.IOCage(jail=jail).fstab(action,
                                        source,
                                        destination,
                                        fstype,
                                        options,
                                        dump,
                                        _pass,
                                        index=index,
                                        add_path=add_path,
                                        header=header)

    if action == "list":
        if header:
            ioc_common.logit({"level": "INFO", "message": fstab})
        else:
            for f in fstab:
                ioc_common.logit({
                    "level": "INFO",
                    "message": f'{f[0]}\t{f[1]}'
                })