def release_parent(path):
    ppath = os.path.dirname(path)
    info = examine_path(ppath)
    parent = get_volume_entry(info['vid'])
    if 'ro' in parent:
       vos('release', parent['name'], '-verbose')
       fs("checkvolumes")
def examine_path(path):
    info = {}
    out = fs('examine', '-path', path)
    for line in out.splitlines():
        m = re.match(r'File (\S+) \(([\d\.]+)\) contained in volume (\d+)', line)
        if m:
            info['path'] = m.group(1)
            info['fid'] = m.group(2)
            info['vid'] = int(m.group(3))
        m = re.match(r'Volume status for vid = (\d+) named (\S+)', line)
        if m:
            info['name'] = m.group(2)
        m = re.match(r'Current disk quota is unlimited', line)
        if m:
            info['quota'] = 0
        m = re.match(r'Current disk quota is (\d+)', line)
        if m:
            info['quota'] = int(m.group(1))
        m = re.match(r'Current blocks used are (\d+)', line)
        if m:
            info['blocks'] = int(m.group(1))
        m = re.match(r'The partition has (\d+) blocks available out of (\d+)', line)
        if m:
            free = int(m.group(1))
            total = int(m.group(2))
            used = total - free
            info['part'] = {'free':free, 'used':used, 'total':total}
    return info
    def get_cache_size(self):
        """Get the cache size.

        Outputs AFS cache size as the number of 1K blocks."""
        s = fs("getcacheparms")  # get output string
        size = re.findall('\d+', s)  # find the decimal values in the string
        return int(size[1])  # output integer for number of 1K blocks
Пример #4
0
 def from_path(cls, path):
     """Read an ACL from AFS directory to create an ACL test object."""
     if not os.path.exists(path):
         raise AssertionError("Path does not exist: %s" % (path))
     if not os.path.isdir(path):
         raise AssertionError("Path is not a directory: %s" % (path))
     acl = AccessControlList()
     section = None
     output = fs('listacl', path)
     for line in output.splitlines():
         if line.startswith("Access list for"):
             continue
         if line.startswith("Normal rights:"):
             section = "+"
             continue
         if line.startswith("Negative rights:"):
             section = "-"
             continue
         m = re.match(r'  (\S+) (\S+)', line)
         if m:
             name,rights = (m.group(1),m.group(2))
             if not section in ('+', '-'):
                 raise AssertionError("Failed to parse fs listacl; missing section label")
             acl.add(name, section + rights)
     return acl
 def from_path(cls, path):
     """Read an ACL from AFS directory to create an ACL test object."""
     if not os.path.exists(path):
         raise AssertionError("Path does not exist: %s" % (path))
     if not os.path.isdir(path):
         raise AssertionError("Path is not a directory: %s" % (path))
     acl = AccessControlList()
     section = None
     output = fs('listacl', path)
     for line in output.splitlines():
         if line.startswith("Access list for"):
             continue
         if line.startswith("Normal rights:"):
             section = "+"
             continue
         if line.startswith("Negative rights:"):
             section = "-"
             continue
         m = re.match(r'  (\S+) (\S+)', line)
         if m:
             name, rights = (m.group(1), m.group(2))
             if not section in ('+', '-'):
                 raise AssertionError(
                     "Failed to parse fs listacl; missing section label")
             acl.add(name, section + rights)
     return acl
    def create_volume(self, name, server=None, part='a', path=None, quota='0', ro=False, acl=None, orphan=False):
        """Create and mount a volume.

        Create a volume and optionally mount the volume. Also optionally create
        a read-only clone of the volume and release the new new volume. Release the
        parent volume if it is replicated.
        """
        vid = None
        if not name:
            raise AssertionError("volume name is required!")
        if server is None or server == '': # use this host
            server = socket.gethostname()
        if path:
            path = os.path.abspath(path)
            if not path.startswith('/afs'):
                raise AssertionError("Path not in '/afs'.")
        out = vos('create', '-server', server, '-partition', part, '-name', name, '-m', quota, '-verbose')
        for line in out.splitlines():
            m = re.match(r'Volume (\d+) created on partition', line)
            if m:
                vid = m.group(1)
                break
        if vid is None:
            raise AssertionError("Created volume id not found!")
        if path:
            fs('mkmount', '-dir', path, '-vol', name)
            if acl:
               fs('setacl', '-dir', path, '-acl', *acl.split(','))
        if ro:
            vos('addsite', '-server', server, '-partition', part, '-id', name)
            vos('release', name, '-verbose')
        if path:
            release_parent(path)
        if orphan:
            # Intentionally remove the vldb entry for testing!
            vos('delent', '-id', vid)
        return vid
    def remove_volume(self, name_or_id, path=None, flush=False, server=None, part=None, zap=False):
        """Remove a volume.

        Remove the volume and any clones. Optionally remove the given mount point.
        """
        if name_or_id == '0':
            logger.info("Skipping remove for volume id 0")
            return
        volume = None
        if path and os.path.exists(path):
            path = os.path.abspath(path)
            if not path.startswith('/afs'):
                raise AssertionError("Path not in '/afs': %s" % (path))
            if flush:
                fs("flush", path)
            fs('rmmount', '-dir', path)
            release_parent(path)
        try:
            volume = get_volume_entry(name_or_id)
        except NoSuchEntryError:
            logger.info("No vldb entry found for volume '%s'" % name_or_id)
        if volume:
            if 'rosites' in volume:
                for server,part in volume['rosites']:
                    vos('remove', '-server', server, '-part', part, '-id', "%s.readonly" % name_or_id)
            vos('remove', '-id', name_or_id)
            fs("checkvolumes")
        elif zap:
            if not server:
                server = socket.gethostname()
            if part:
                try:
                    vos('zap', '-id', name_or_id, '-server', server, '-part', part);
                except NoSuchEntryError:
                    logger.info("No volume {name_or_id} to zap on server {server} part {part}".format(**locals()))
            else:
                for part in get_parts(server):
                    try:
                        vos('zap', '-id', name_or_id, '-server', server, '-part', part);
                    except NoSuchEntryError:
                        logger.info("No volume {name_or_id} to zap on server {server} part {part}".format(**locals()))
 def release_volume(self, name):
     vos('release', '-id', name, '-verbose')
     fs("checkvolumes")
 def mount_volume(self, path, vol, *options):
     """Mount an AFS volume."""
     fs('mkmount', '-dir', path, '-vol', vol, *options)
Пример #10
0
 def add_access_rights(self, path, name, rights):
     """Add access rights to a path."""
     fs('setacl', '-dir', path, '-acl', name, rights)
 def add_access_rights(self, path, name, rights):
     """Add access rights to a path."""
     fs('setacl', '-dir', path, '-acl', name, rights)