Example #1
0
    def export(self):
        """Exports storage pool.

        pool = Pool('dpool')
        pool.export()

        """
        sh.zpool('export', self.name)
        return True
Example #2
0
    def import_(self):
        """Imports storage pool.

        pool = Pool('dpool')
        pool.import_()

        """
        sh.zpool('import', self.name)
        return True
Example #3
0
    def upgrade(self):
        """Upgrades storage pool version.

        pool = Pool('dpool')
        pool.upgrade()

        """
        sh.zpool('upgrade', self.name)
        return True
Example #4
0
    def clear(self):
        """Clears any errors on storage pool.

        pool = Pool('dpool')
        pool.clear()

        """
        sh.zpool('clear', self.name)
        return True
Example #5
0
    def destroy(self, confirm=False):
        """Destroys storage pool.

        pool = Pool('dpool')
        pool.destroy()

        """
        if confirm is not True:
            raise ZfsError('Destroy of storage pool requires confirm=True')
        sh.zpool('destroy', self.name)
        return True
Example #6
0
    def destroy(self, confirm=False):
        """Destroys storage pool.

        pool = Pool('dpool')
        pool.destroy()

        """
        if not confirm:
            raise LoggedException('Destroy of storage pool requires confirm=True')
        sh.zpool('destroy', self.name)
        return True
Example #7
0
def recover(chroot):
    """ Import pool and mount filesystem in prep for recovery efforts """
    sh.zpool.export('-a', _fg=True)
    sh.zpool('import', '-Nf', '-R', paths.zroot, config.pool_name, _fg=True)
    sh.zfs('load-key', '-a', _fg=True)
    sh.zfs.mount(config.os_root_ds, _fg=True)
    sh.zfs.mount('-a', _fg=True)

    other_mounts()

    if chroot:
        sh.chroot(paths.zroot, '/bin/bash', '--login', _fg=True)
Example #8
0
    def exists(self):
        """Checks if pool exists.

        pool = Pool('dpool')
        pool.exists()

        """
        try:
            sh.zpool('list', self.name)
        except sh.ErrorReturnCode_1:
            return False
        return True
Example #9
0
    def _get(self, *props):
        """Gets pool property.

        pool = Pool('dpool')
        pool.properties._get('alloc', 'free')
        pool.properties._get('all')

        """
        assert props

        ret = []
        skip = 1
        try:
            out = sh.zpool('get', ','.join(props), self._parent.name)
        except sh.ErrorReturnCode_2:
            raise KeyError
        for line in out:
            if skip > 0:
                skip -= 1
                continue
            line = line.rstrip("\n")
            (obj_name, name, value, source) = line.split(None, 3)
            ret.append(PoolProperty(self, name, value, source))

        # If we only requested a single property from a single object that
        # isn't the magic word 'all', just return the value.
        if len(props) == 1 and len(ret) == len(props) and 'all' not in props:
            ret = ret[0]
        return ret
Example #10
0
def status():
    print(f'$ config values --------------------\n')
    print(config)

    print(f'\n$ sgdisk --print {config.disk_dev} --------------------\n')
    sh.sgdisk('--print', config.disk_dev, _out=sys.stdout, _ok_code=[0,2])

    print(f'\n$ blkid --------------------------\n')
    sh.blkid(_out=sys.stdout,)

    print('\n$ zpool list ---------------------------\n')
    sh.zpool('list', _out=sys.stdout)

    print('\n$ zfs list ---------------------------\n')
    sh.zfs('list', _out=sys.stdout)

    print('\n$ zfs mount ---------------------------\n')
    sh.zfs('mount', _out=sys.stdout)
Example #11
0
def zpool_status_parse(from_string=None):
    if not from_string:
        from_string = sh.zpool("status", "-v").stdout

    ret = {}

    pools_m = from_string.split("pool:")
    for pool_m in pools_m:
        if not pool_m.strip():
            continue

        for m in re.finditer(
            " (?P<pool>[^\n]+)\n *"
            "state: (?P<state>[^ ]+)\n *"
            "(status: (?P<status>(.|\n)+)\n *)??"
            "scan: (?P<scan>(.|\n)*)\n *"
            "config: ?(?P<config>(.|\n)*)\n *"
            "errors: (?P<errors>[^\n]*)",
            pool_m,
        ):
            m = m.groupdict()
            pool_name = m.pop("pool")
            pool = ret[pool_name] = m

            devices = pool["devices"] = {}

            parent = None
            for device in re.finditer(
                "(?P<indent>[ \t]+)(?P<name>[^ \t\n]+)( +(?P<state>[^ \t\n]+) +)?("
                "(?P<read>[^ \t\n]+) +(?P<write>[^ \t\n]+) +"
                "(?P<cksum>[^\n]+))?(?P<notes>[^\n]+)?\n",
                pool.pop("config"),
            ):
                device = device.groupdict()
                if not device["name"] or device["name"] in ("NAME", pool_name):
                    continue
                device_name = device.pop("name").strip()
                device.pop("indent")

                is_parent = False
                for device_type in ("mirror", "log", "raid", "spare", "cache"):
                    if device_name.startswith(device_type):
                        parent = device_name
                        devices[device_name] = device
                        devices[parent]["children"] = {}
                        is_parent = True
                        break
                if is_parent:
                    continue

                if parent:
                    devices[parent]["children"][device_name] = device
                else:
                    devices[device_name] = device

    return ret
Example #12
0
 def __call__(self, arg=None):
     if not arg:
         arg = sh.zpool('status', '-v').stdout
     ret = OrderedDict()
     for v in self.p_status.parseString(str(arg)).asList():
         v = dict(v)
         v['config'] = self._config_parser(v)
         pool_name = v.pop('pool')
         ret[pool_name] = v
     return ret
Example #13
0
    def status(self):
        """Returns status of storage pool.

        pool = Pool('dpool')
        pool.status()

        """
        p = ZpoolStatusParser()
        out = sh.zpool('status', '-v', self.name).stdout
        ret = p(out)
        return ret[self.name]
Example #14
0
    def status(self, devices=False):
        """Returns status of storage pool.

        pool = Pool('dpool')
        pool.status()

        """
        out = sh.zpool('status', '-v', self.name).stdout
        ret = zpool_status_parse2(from_string=out)
        ret = ret[self.name]
        if not devices:
            ret.pop('devices', None)
        return ret
Example #15
0
    def _set(self, k, v, ignore=False):
        """Sets pool property.

        pool = Pool('dpool')
        pool.properties._set('readonly', 'on')

        """
        if ignore:
            return

        prop = None
        if isinstance(v, PoolProperty):
            prop = v
            v = prop.value

        try:
            sh.zpool('set', '%s=%s' % (k, v), self._parent.name)
        except sh.ErrorReturnCode_2:
            raise ValueError

        if prop:
            prop.value = v
Example #16
0
    def iostat(self, capture_length=30):
        """Returns iostat of storage pool.

        pool = Pool('dpool')
        pool.iostat()

        """
        timestamp = None
        skip_past_dashline = False
        for line in sh.zpool('iostat', '-T', 'u', self.name, capture_length, 2):
            line = line.rstrip("\n")

            # Got a timestamp
            if line.isdigit():
                # If this is our first record, skip till we get the header seperator
                if not timestamp:
                    skip_past_dashline = True
                # TZify the timestamp
                timestamp = timezone.make_aware(
                    datetime.fromtimestamp(int(line)),
                    timezone.get_current_timezone())
                continue

            # If we haven't gotten the dashline yet, wait till the line after it
            if skip_past_dashline:
                if line.startswith('-----'):
                    skip_past_dashline = False
                continue
            # Either way, let's not worry about them
            if line.startswith('-----'):
                continue

            # If somehow we got here without a timestamp, something is probably wrong.
            if not timestamp:
                raise LoggedException("Got unexpected input from zpool iostat: %s", line)

            # Parse iostats output
            j = {}
            (j['name'],
             j['alloc'], j['free'],
             j['iops_read'], j['iops_write'],
             j['bandwidth_read'], j['bandwidth_write']) = line.strip().split()
            j['timestamp'] = timestamp
            j.pop('name')
            return j
Example #17
0
 def ui_command_zpool_iostat(self):
     return sh.zpool('iostat', '-v', '5', '2')
Example #18
0
def zpool_status_parse2(from_string=None):
    if not from_string:
        from_string = sh.zpool("status", "-v").stdout

    ret = {}

    pools_m = from_string.split("pool:")
    for pool_m in pools_m:
        if not pool_m.strip():
            continue

        for m in re.finditer(
            " (?P<pool>[^\n]+)\n *" "state: (?P<state>[^ ]+)\n *"
            # Some versions of zpool use tabs, some do not.
            "(status: (?P<status>(.|\n {8}|\n\t)+)\n *)??"
            "(action: (?P<action>(.|\n {8}|\n\t)+)\n *)??"
            "(see: (?P<see>(.|\n {8}|\n\t)+)\n *)??"
            "scan: (?P<scan>(.|\n)*)\n *"
            "config: ?(?P<config>(.|\n)*)\n *"
            "errors: (?P<errors>[^\n]*)",
            pool_m,
        ):
            m = m.groupdict()

            # Remove nasty newlines and prefixing whitespace
            for k, v in m.items():
                if k == "config" or not v:
                    continue
                # Some versions of zpool use tabs, some do not.
                m[k] = v.replace("\n\t", " ")
                m[k] = m[k].replace("\n        ", " ")

            pool_name = m.pop("pool")
            pool = ret[pool_name] = m

            devices = pool["devices"] = {}

            _devices = [
                d.groupdict()
                for d in re.finditer(
                    "(?P<indent>[ \t]+)(?P<name>[^ \t\n]+)( +(?P<state>[^ \t\n]+) +)?("
                    "(?P<read>[^ \t\n]+) +(?P<write>[^ \t\n]+) +"
                    "(?P<cksum>[^\n]+))?(?P<notes>[^\n]+)?\n",
                    pool.pop("config"),
                )
            ]
            _devices = filter(lambda d: d["name"] and not d["name"] == "NAME", _devices)

            ancestry = []
            # ancestry_level = 0
            dev_types = {"devices": Device, "logs": Log, "cache": Cache, "spare": Spare}
            dev_type_cls = None

            for device in _devices:
                device_name = device.pop("name").strip()
                # Some versions of zpool use tabs, some do not.
                cur_level = (len(device["indent"].replace("\t", "        ")) - 8) / 2
                # level_diff = cur_level - ancestry_level
                ancestry = ancestry[:cur_level]
                ancestry.append(device_name)
                # ancestry_level = cur_level
                # pp(dict(name=device_name, cur_level=cur_level, level_diff=level_diff, ancestry=ancestry))

                if cur_level == 0 and device_name in dev_types.keys() or device_name == pool_name:
                    if device_name == pool_name:
                        device_name = "devices"
                    dev_type_cls = dev_types.pop(device_name)
                    ancestry.append(device_name)
                    continue

                cur = None
                for level in ancestry[:cur_level]:
                    # print level
                    if not cur:
                        cur = devices
                        continue
                    if not level in cur:
                        cur[level] = {}
                    cur = cur[level]

                if device_name.startswith("mirror-"):
                    cur[device_name] = Mirror()
                    continue

                dev = dev_type_cls(device_name)

                if isinstance(cur, Mirror):
                    cur.append(dev, _device_check=False)
                else:
                    cur[device_name] = dev

    return ret