Exemplo n.º 1
0
    def query(self, filters=None, options=None):
        """
        Query all jails with `query-filters` and `query-options`.
        """
        options = options or {}
        jail_identifier = None
        jails = []

        if filters and len(filters) == 1 and list(
                filters[0][:2]) == ['host_hostuuid', '=']:
            jail_identifier = filters[0][2]

        recursive = False if jail_identifier == 'default' else True

        try:
            jail_dicts = ioc.IOCage(
                jail=jail_identifier).get('all', recursive=recursive)

            if jail_identifier == 'default':
                jail_dicts['host_hostuuid'] = 'default'
                jails.append(jail_dicts)
            else:
                for jail in jail_dicts:
                    jail = list(jail.values())[0]
                    jail['id'] = jail['host_hostuuid']
                    if jail['dhcp'] == 'on':
                        uuid = jail['host_hostuuid']

                        if jail['state'] == 'up':
                            interface = jail['interfaces'].split(',')[0].split(
                                ':')[0]
                            if interface == 'vnet0':
                                # Inside jails they are epair0b
                                interface = 'epair0b'
                            ip4_cmd = ['jexec', f'ioc-{uuid}', 'ifconfig',
                                       interface, 'inet']
                            try:
                                out = su.check_output(ip4_cmd)
                                out = out.splitlines()[2].split()[1].decode()
                                jail['ip4_addr'] = f'{interface}|{out}'
                            except (su.CalledProcessError, IndexError):
                                jail['ip4_addr'] = f'{interface}|ERROR'
                        else:
                            jail['ip4_addr'] = 'DHCP (not running)'

                    if jail['state'] == 'up':
                        try:
                            jail['jid'] = su.check_output(
                                [
                                    'jls', '-j',
                                    f'ioc-{jail["host_hostuuid"]}',
                                    'jid'
                                ]
                            ).decode().strip()
                        except su.CalledProcessError:
                            jail['jid'] = 'ERROR'
                    else:
                        jail['jid'] = None

                    jails.append(jail)
        except ioc_exceptions.JailMisconfigured as e:
            self.logger.error(e, exc_info=True)
        except BaseException:
            # Brandon is working on fixing this generic except, till then I
            # am not going to make the perfect the enemy of the good enough!
            self.logger.debug('Failed to get list of jails', exc_info=True)

        return filter_list(jails, filters, options)
Exemplo n.º 2
0
    def list_resource(self, job, resource, remote, want_cache, branch):
        """Returns a JSON list of the supplied resource on the host"""
        self.check_dataset_existence()  # Make sure our datasets exist.
        iocage = ioc.IOCage(skip_jails=True)
        resource = "base" if resource == "RELEASE" else resource.lower()

        if resource == "plugin":
            if remote:
                if want_cache:
                    try:
                        resource_list = self.middleware.call_sync(
                            'cache.get', 'iocage_remote_plugins')

                        return resource_list
                    except KeyError:
                        pass

                resource_list = iocage.fetch(list=True, plugins=True, header=False, branch=branch)
                try:
                    plugins_versions_data = self.middleware.call_sync('cache.get', 'iocage_plugin_versions')
                except KeyError:
                    plugins_versions_data_job = self.middleware.call_sync(
                        'core.get_jobs',
                        [['method', '=', 'jail.retrieve_plugin_versions'], ['state', '=', 'RUNNING']]
                    )
                    error = None
                    plugins_versions_data = {}
                    if plugins_versions_data_job:
                        try:
                            plugins_versions_data = self.middleware.call_sync(
                                'core.job_wait', plugins_versions_data_job[0]['id'], job=True
                            )
                        except CallError as e:
                            error = str(e)
                    else:
                        try:
                            plugins_versions_data = self.middleware.call_sync(
                                'jail.retrieve_plugin_versions', job=True
                            )
                        except Exception as e:
                            error = e

                    if error:
                        # Let's not make the failure fatal
                        self.middleware.logger.error(f'Retrieving plugins version failed: {error}')
            else:
                resource_list = iocage.list("all", plugin=True)
                pool = IOCJson().json_get_value("pool")
                iocroot = IOCJson(pool).json_get_value("iocroot")
                index_path = f'{iocroot}/.plugin_index/INDEX'
                plugin_jails = {
                    j['host_hostuuid']: j for j in self.middleware.call_sync(
                        'jail.query', [['type', 'in', ['plugin', 'pluginv2']]]
                    )
                }

                if not pathlib.Path(index_path).is_file():
                    index_json = None
                else:
                    index_fd = open(index_path, 'r')
                    index_json = json.load(index_fd)

            for index, plugin in enumerate(resource_list):

                if remote:
                    # In case of remote, "plugin" is going to be a dictionary
                    plugin.update({
                        k: plugins_versions_data.get(plugin['plugin'], {}).get(k, 'N/A')
                        for k in ('version', 'revision', 'epoch')
                    })
                else:
                    # "plugin" is a list which we will convert to a dictionary for readability
                    plugin_dict = {
                        k: v if v != '-' else None
                        for k, v in zip((
                            'jid', 'name', 'boot', 'state', 'type', 'release', 'ip4', 'ip6', 'template', 'admin_portal'
                        ), plugin)
                    }
                    plugin_output = pathlib.Path(
                        f'{iocroot}/jails/{plugin[1]}/root/root/PLUGIN_INFO'
                    )

                    if plugin_output.is_file():
                        plugin_info = [[
                            x for x in plugin_output.read_text().split(
                                '\n') if x
                        ]]
                    else:
                        plugin_info = None

                    plugin_name = plugin_jails[plugin_dict['name']]['plugin_name']
                    plugin_dict.update({
                        'plugin_info': plugin_info,
                        'plugin': plugin_name if plugin_name != 'none' else plugin_dict['name'],
                        **self.get_local_plugin_version(
                            plugin_name if plugin_name != 'none' else plugin_dict['name'],
                            index_json, iocroot, plugin_dict['name']
                        )
                    })

                    resource_list[index] = plugin_dict

            if remote:
                self.middleware.call_sync(
                    'cache.put', 'iocage_remote_plugins', resource_list,
                    86400
                )
            else:
                index_fd.close()
        elif resource == "base":
            try:
                if remote:
                    resource_list = self.middleware.call_sync(
                        'cache.get', 'iocage_remote_releases')

                    return resource_list
            except KeyError:
                pass

            resource_list = iocage.fetch(list=True, remote=remote, http=True)

            if remote:
                self.middleware.call_sync(
                    'cache.put', 'iocage_remote_releases', resource_list,
                    86400
                )
        elif resource == 'branches':
            official_branches = requests.get(
                'https://api.github.com/repos/freenas/iocage-ix-plugins/'
                'branches'
            )
            official_branches.raise_for_status()
            resource_list = [
                {'name': b['name'], 'repo': 'official'}
                for b in official_branches.json()
            ]
        else:
            resource_list = [
                {k: v if v != '-' else None for k, v in zip(('jid', 'name', 'state', 'release', 'ip4'), jail_data)}
                for jail_data in iocage.list(resource)
            ]

        return resource_list
Exemplo n.º 3
0
    def create_job(self, job, options):
        verrors = ValidationErrors()
        uuid = options["uuid"]

        job.set_progress(0, f'Creating: {uuid}')

        try:
            self.check_jail_existence(uuid, skip=False)

            verrors.add(
                'uuid',
                f'A jail with name {uuid} already exists'
            )
            raise verrors
        except CallError:
            # A jail does not exist with the provided name, we can create one
            # now

            verrors = self.common_validation(verrors, options)

            if verrors:
                raise verrors

            job.set_progress(20, 'Initial validation complete')

        iocage = ioc.IOCage(skip_jails=True)

        release = options["release"]
        template = options.get("template", False)
        pkglist = options.get("pkglist", None)
        basejail = options["basejail"]
        empty = options["empty"]
        short = options["short"]
        props = options["props"]
        pool = IOCJson().json_get_value("pool")
        iocroot = IOCJson(pool).json_get_value("iocroot")
        https = options.get('https', True)

        if template:
            release = template

        if (
                not os.path.isdir(f'{iocroot}/releases/{release}') and
                not template and
                not empty
        ):
            job.set_progress(50, f'{release} missing, calling fetch')
            self.middleware.call_sync(
                'jail.fetch', {"release": release, "https": https}, job=True
            )

        err, msg = iocage.create(
            release,
            props,
            0,
            pkglist,
            template=template,
            short=short,
            _uuid=uuid,
            basejail=basejail,
            empty=empty
        )

        if err:
            raise CallError(msg)

        job.set_progress(100, f'Created: {uuid}')

        return True
Exemplo n.º 4
0
    def fetch(self, job, options):
        """Fetches a release or plugin."""
        fetch_output = {'install_notes': []}
        release = options.get('release', None)
        https = options.pop('https', False)
        name = options.pop('name')
        jail_name = options.pop('jail_name')

        post_install = False

        verrors = ValidationErrors()

        self.validate_ips(verrors, options)

        if verrors:
            raise verrors

        def progress_callback(content, exception):
            msg = content['message'].strip('\r\n')
            rel_up = f'* Updating {release} to the latest patch level... '
            nonlocal post_install

            if name is None:
                if 'Downloading : base.txz' in msg and '100%' in msg:
                    job.set_progress(5, msg)
                elif 'Downloading : lib32.txz' in msg and '100%' in msg:
                    job.set_progress(10, msg)
                elif 'Downloading : doc.txz' in msg and '100%' in msg:
                    job.set_progress(15, msg)
                elif 'Downloading : src.txz' in msg and '100%' in msg:
                    job.set_progress(20, msg)
                if 'Extracting: base.txz' in msg:
                    job.set_progress(25, msg)
                elif 'Extracting: lib32.txz' in msg:
                    job.set_progress(50, msg)
                elif 'Extracting: doc.txz' in msg:
                    job.set_progress(75, msg)
                elif 'Extracting: src.txz' in msg:
                    job.set_progress(90, msg)
                elif rel_up in msg:
                    job.set_progress(95, msg)
                else:
                    job.set_progress(None, msg)
            else:
                if post_install:
                    for split_msg in msg.split('\n'):
                        fetch_output['install_notes'].append(split_msg)

                if '  These pkgs will be installed:' in msg:
                    job.set_progress(50, msg)
                elif 'Installing plugin packages:' in msg:
                    job.set_progress(75, msg)
                elif 'Running post_install.sh' in msg:
                    job.set_progress(90, msg)
                    # Sets each message going forward as important to the user
                    post_install = True
                else:
                    job.set_progress(None, msg)

        self.check_dataset_existence()  # Make sure our datasets exist.
        start_msg = f'{release} being fetched'
        final_msg = f'{release} fetched'

        iocage = ioc.IOCage(callback=progress_callback, silent=False)

        if name is not None:
            pool = IOCJson().json_get_value('pool')
            iocroot = IOCJson(pool).json_get_value('iocroot')

            options["plugin_name"] = name
            start_msg = 'Starting plugin install'
            final_msg = f"Plugin: {name} installed"
        elif name is None and https:
            if 'https' not in options['server']:
                options['server'] = f'https://{options["server"]}'

        options["accept"] = True
        options['name'] = jail_name

        job.set_progress(0, start_msg)
        iocage.fetch(**options)

        if post_install and name is not None:
            plugin_manifest = pathlib.Path(
                f'{iocroot}/.plugin_index/{name}.json'
            )
            plugin_json = json.loads(plugin_manifest.read_text())
            schema_version = plugin_json.get('plugin_schema', '1')

            if schema_version.isdigit() and int(schema_version) >= 2:
                plugin_output = pathlib.Path(
                    f'{iocroot}/jails/{name}/root/root/PLUGIN_INFO'
                )

                if plugin_output.is_file():
                    # Otherwise it will be the verbose output from the
                    # post_install script
                    fetch_output['install_notes'] = [
                        x for x in plugin_output.read_text().split('\n') if x
                    ]

                    # This is to get the admin URL and such
                    fetch_output['install_notes'] += job.progress[
                        'description'].split('\n')

        job.set_progress(100, final_msg)

        return fetch_output
Exemplo n.º 5
0
 def __rollback_jail__(self):
     import iocage_lib.iocage as ioc  # Avoids dep issues
     name = f"ioc_upgrade_{self.date}"
     iocage = ioc.IOCage(jail=self.uuid, skip_jails=True, silent=True)
     iocage.stop()
     iocage.rollback(name)
Exemplo n.º 6
0
    def create_job(self, job, options):
        verrors = ValidationErrors()
        uuid = options["uuid"]

        job.set_progress(0, f'Creating: {uuid}')

        try:
            self.check_jail_existence(uuid, skip=False)

            verrors.add(
                'uuid',
                f'A jail with name {uuid} already exists'
            )
            raise verrors
        except CallError:
            # A jail does not exist with the provided name, we can create one
            # now

            verrors = self.common_validation(verrors, options)

            if verrors:
                raise verrors

            job.set_progress(20, 'Initial validation complete')

        if not any('resolver' in p for p in options['props']):
            dc = self.middleware.call_sync(
                'service.query', [('service', '=', 'domaincontroller')]
            )[0]
            dc_config = self.middleware.call_sync('domaincontroller.config')

            if dc['enable'] and (
                dc_config['dns_forwarder'] and
                dc_config['dns_backend'] == 'SAMBA_INTERNAL'
            ):
                options['props'].append(
                    f'resolver=nameserver {dc_config["dns_forwarder"]}'
                )

        iocage = ioc.IOCage(skip_jails=True)

        release = options["release"]
        template = options.get("template", False)
        pkglist = options.get("pkglist", None)
        basejail = options["basejail"]
        empty = options["empty"]
        short = options["short"]
        props = options["props"]
        pool = IOCJson().json_get_value("pool")
        iocroot = IOCJson(pool).json_get_value("iocroot")

        if template:
            release = template

        if (
                not os.path.isdir(f'{iocroot}/releases/{release}') and
                not template and
                not empty
        ):
            job.set_progress(50, f'{release} missing, calling fetch')
            self.middleware.call_sync(
                'jail.fetch', {"release": release}, job=True
            )

        err, msg = iocage.create(
            release,
            props,
            0,
            pkglist,
            template=template,
            short=short,
            _uuid=uuid,
            basejail=basejail,
            empty=empty
        )

        if err:
            raise CallError(msg)

        job.set_progress(100, f'Created: {uuid}')

        return True
Exemplo n.º 7
0
def cli(jail):
    """Update the supplied jail to the latest patchset"""
    skip_jails = bool(jail != 'ALL')
    ioc.IOCage(jail=jail, skip_jails=skip_jails).update()
Exemplo n.º 8
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()})
Exemplo n.º 9
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!"
        })
Exemplo n.º 10
0
def cli(jail, name):
    """Snapshot a jail."""
    ioc.IOCage(jail=jail, skip_jails=True).snapshot(name)
Exemplo n.º 11
0
    def list_resource(self, resource, remote):
        """Returns a JSON list of the supplied resource on the host"""
        self.check_dataset_existence()  # Make sure our datasets exist.
        iocage = ioc.IOCage(skip_jails=True)
        resource = "base" if resource == "RELEASE" else resource.lower()

        if resource == "plugin":
            if remote:
                try:
                    resource_list = self.middleware.call_sync(
                        'cache.get', 'iocage_remote_plugins')

                    return resource_list
                except KeyError:
                    pass

                resource_list = iocage.fetch(list=True,
                                             plugins=True,
                                             header=False)
            else:
                resource_list = iocage.list("all", plugin=True)
                pool = IOCJson().json_get_value("pool")
                iocroot = IOCJson(pool).json_get_value("iocroot")
                index_path = f'{iocroot}/.plugin_index/INDEX'

                if not pathlib.Path(index_path).is_file():
                    index_json = None

                    for plugin in resource_list:
                        plugin += ['N/A', 'N/A']

                    return resource_list
                else:
                    index_fd = open(index_path, 'r')
                    index_json = json.load(index_fd)

            for plugin in resource_list:
                for i, elem in enumerate(plugin):
                    # iocage returns - for None
                    plugin[i] = elem if elem != "-" else None

                if remote:
                    pv = self.get_plugin_version(plugin[2])
                else:
                    pv = self.get_local_plugin_version(plugin[1], index_json,
                                                       iocroot)

                resource_list[resource_list.index(plugin)] = plugin + pv

            if remote:
                self.middleware.call_sync('cache.put', 'iocage_remote_plugins',
                                          resource_list, 86400)
            else:
                index_fd.close()
        elif resource == "base":
            try:
                if remote:
                    resource_list = self.middleware.call_sync(
                        'cache.get', 'iocage_remote_releases')

                    return resource_list
            except KeyError:
                pass

            resource_list = iocage.fetch(list=True, remote=remote, http=True)

            if remote:
                self.middleware.call_sync('cache.put',
                                          'iocage_remote_releases',
                                          resource_list, 86400)
        else:
            resource_list = iocage.list(resource)

        return resource_list
Exemplo n.º 12
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()})
Exemplo n.º 13
0
def cli(jail, name):
    """Removes a snapshot from a user supplied jail."""
    ioc.IOCage(jail=jail).snap_remove(name)
Exemplo n.º 14
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]}"
                })
Exemplo n.º 15
0
def cli(release, template, count, props, pkglist, basejail, thickjail, empty,
        short, name, _uuid, force, thickconfig):

    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,
                      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})
Exemplo n.º 16
0
def cli(jail):
    """Make a recursive snapshot of the jail and export to a file."""
    ioc.IOCage(jail=jail).export()
Exemplo n.º 17
0
    def start_on_boot(self):
        self.logger.debug('Starting jails on boot: PENDING')
        ioc.IOCage(rc=True).start()
        self.logger.debug('Starting jails on boot: SUCCESS')

        return True
Exemplo n.º 18
0
 def __snapshot_jail__(self):
     import iocage_lib.iocage as ioc  # Avoids dep issues
     name = f"ioc_upgrade_{self.date}"
     ioc.IOCage(jail=self.uuid, skip_jails=True, silent=True).snapshot(name)
Exemplo n.º 19
0
    def stop_on_shutdown(self):
        self.logger.debug('Stopping jails on shutdown: PENDING')
        ioc.IOCage(rc=True).stop()
        self.logger.debug('Stopping jails on shutdown: SUCCESS')

        return True
Exemplo n.º 20
0
def cli(release, template, count, props, pkglist, basejail, clone_basejail,
        thickjail, empty, short, name, _uuid, thickconfig, proxy):

    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 proxy:
        os.environ.update({'http_proxy': proxy, 'https_proxy': proxy})

    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, major_only=True)
        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, major_only=True)
            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})
Exemplo n.º 21
0
def cli(jail):
    """Update the supplied jail to the latest patchset"""
    iocage = ioc.IOCage(jail=jail)

    iocage.update()