Example #1
0
    def check_root_dir(self):
        """ Do the necessary checks for the destination directory depending on
        the type of the transfer.

        Raises:
             IOError: Root dir state inconsistent.
        """
        root_str = self.header['dst' if self.d2t else 'src']
        fs = self.get_fs(root_str)
        url = client.URL(root_str.encode("utf-8"))
        arg = url.path + "?eos.ruid=0&eos.rgid=0"
        st, __ = fs.stat(arg.encode("utf-8"))

        if self.d2t:
            if st.ok:
                # For PUT destination dir must NOT exist
                err_msg = "Root PUT dir={0} exists".format(root_str)
                self.logger.error(err_msg)
                raise IOError(err_msg)
            else:
                # Make sure the rest of the path exists as for the moment CASTOR
                # mkdir -p /path/to/file does not work properly
                pos = url.path.find('/', 1)

                while pos != -1:
                    dpath = url.path[:pos]
                    pos = url.path.find('/', pos + 1)
                    st, __ = fs.stat(dpath.encode("utf-8"))

                    if not st.ok:
                        st, __ = fs.mkdir(dpath.encode("utf-8"))

                        if not st.ok:
                            err_msg = ("Dir={0} failed mkdir errmsg={1}"
                                       "").format(dpath,
                                                  st.message.decode("utf-8"))
                            self.logger.error(err_msg)
                            raise IOError(err_msg)

        elif not self.d2t:
            # For GET destination must exist and contain just the archive file
            if not st.ok:
                err_msg = "Root GET dir={0} does NOT exist".format(root_str)
                self.logger.error(err_msg)
                raise IOError(err_msg)
            else:
                ffindcount = ''.join([
                    url.protocol, "://", url.hostid,
                    "//proc/user/?mgm.cmd=find&mgm.path=",
                    seal_path(url.path), "&mgm.option=Z"
                ])
                (status, stdout, stderr) = exec_cmd(ffindcount)

                if status:
                    for entry in stdout.split():
                        tag, num = entry.split('=')

                        if ((tag == 'nfiles' and num not in ['1', '2'])
                                or (tag == 'ndirectories' and num != '1')):
                            err_msg = (
                                "Root GET dir={0} should contain at least "
                                "one file and at most two - clean up and "
                                "try again").format(root_str)
                            self.logger.error(err_msg)
                            raise IOError(err_msg)
                else:
                    err_msg = ("Error doing find count on GET destination={0}"
                               ", msg={1}").format(root_str, stderr)
                    self.logger.error(err_msg)
                    raise IOError(err_msg)
Example #2
0
    def check_root_dir(self):
        """ Do the necessary checks for the destination directory depending on
        the type of the transfer.

        Raises:
             IOError: Root dir state inconsistent.
        """
        root_str = self.header['dst' if self.d2t else 'src']
        fs = self.get_fs(root_str)
        url = client.URL(root_str.encode("utf-8"))
        arg = url.path + "?eos.ruid=0&eos.rgid=0"
        st, __ = fs.stat(arg.encode("utf-8"))

        if self.d2t:
            if st.ok:
                # For PUT destination dir must NOT exist
                err_msg = "Root PUT dir={0} exists".format(root_str)
                self.logger.error(err_msg)
                raise IOError(err_msg)
            else:
                # Make sure the rest of the path exists as for the moment CASTOR
                # mkdir -p /path/to/file does not work properly
                pos = url.path.find('/', 1)

                while pos != -1:
                    dpath = url.path[: pos]
                    pos = url.path.find('/', pos + 1)
                    st, __ = fs.stat(dpath.encode("utf-8"))

                    if not st.ok:
                        st, __ = fs.mkdir(dpath.encode("utf-8"))

                        if not st.ok:
                            err_msg = ("Dir={0} failed mkdir errmsg={1}"
                                       "").format(dpath, st.message.decode("utf-8"))
                            self.logger.error(err_msg)
                            raise IOError(err_msg)

        elif not self.d2t:
            # For GET destination must exist and contain just the archive file
            if not st.ok:
                err_msg = "Root GET dir={0} does NOT exist".format(root_str)
                self.logger.error(err_msg)
                raise IOError(err_msg)
            else:
                ffindcount = ''.join([url.protocol, "://", url.hostid,
                                      "//proc/user/?mgm.cmd=find&mgm.path=",
                                      seal_path(url.path), "&mgm.option=Z"])
                (status, stdout, stderr) = exec_cmd(ffindcount)

                if status:
                    for entry in stdout.split():
                        tag, num = entry.split('=')

                        if ((tag == 'nfiles' and num not in ['1', '2']) or
                                (tag == 'ndirectories' and num != '1')):
                            err_msg = ("Root GET dir={0} should contain at least "
                                       "one file and at most two - clean up and "
                                       "try again").format(root_str)
                            self.logger.error(err_msg)
                            raise IOError(err_msg)
                else:
                    err_msg = ("Error doing find count on GET destination={0}"
                               ", msg={1}").format(root_str, stderr)
                    self.logger.error(err_msg)
                    raise IOError(err_msg)
Example #3
0
    def make_mutable(self):
        """ Make the EOS sub-tree pointed by header['src'] mutable.

        Raises:
            IOError when operation fails.
        """
        url = client.URL(self.header['src'].encode("utf-8"))

        for dentry in self.dirs():
            dir_path = url.path + dentry[1]
            fgetattr = ''.join([
                url.protocol, "://", url.hostid, "//proc/user/",
                "?mgm.cmd=attr&mgm.subcmd=get&mgm.attr.key=sys.acl",
                "&mgm.path=",
                seal_path(dir_path)
            ])
            (status, stdout, __) = exec_cmd(fgetattr)

            if not status:
                warn_msg = "No xattr sys.acl found for dir={0}".format(
                    dir_path)
                self.logger.warning(warn_msg)
            else:
                # Remove the 'z:i' rule from the acl list
                stdout = stdout.replace('"', '')
                acl_val = stdout[stdout.find('=') + 1:]
                rules = acl_val.split(',')
                new_rules = []

                for rule in rules:
                    if rule.startswith("z:"):
                        tag, definition = rule.split(':')
                        pos = definition.find('i')

                        if pos != -1:
                            definition = definition[:pos] + definition[pos +
                                                                       1:]

                            if definition:
                                new_rules.append(':'.join([tag, definition]))

                            continue

                    new_rules.append(rule)

                acl_val = ','.join(new_rules)
                self.logger.error("new acl: {0}".format(acl_val))

                if acl_val:
                    # Set the new sys.acl xattr
                    fmutable = ''.join([
                        url.protocol, "://", url.hostid, "//proc/user/?",
                        "mgm.cmd=attr&mgm.subcmd=set&mgm.attr.key=sys.acl",
                        "&mgm.attr.value=", acl_val, "&mgm.path=", dir_path
                    ])
                    (status, __, stderr) = exec_cmd(fmutable)

                    if not status:
                        err_msg = "Error making dir={0} mutable, msg={1}".format(
                            dir_path, stderr)
                        self.logger.error(err_msg)
                        raise IOError(err_msg)
                else:
                    # sys.acl empty, remove it from the xattrs
                    frmattr = ''.join([
                        url.protocol, "://", url.hostid, "//proc/user/?",
                        "mgm.cmd=attr&mgm.subcmd=rm&mgm.attr.key=sys.acl",
                        "&mgm.path=", dir_path
                    ])
                    (status, __, stderr) = exec_cmd(frmattr)

                    if not status:
                        err_msg = (
                            "Error removing xattr=sys.acl for dir={0}, msg={1}"
                            "").format(dir_path, stderr)
                        self.logger.error(err_msg)
                        raise IOError(err_msg)
Example #4
0
    def make_mutable(self):
        """ Make the EOS sub-tree pointed by header['src'] mutable.

        Raises:
            IOError when operation fails.
        """
        url = client.URL(self.header['src'].encode("utf-8"))

        for dentry in self.dirs():
            dir_path = url.path + dentry[1]
            fgetattr = ''.join([url.protocol, "://", url.hostid, "//proc/user/",
                                "?mgm.cmd=attr&mgm.subcmd=get&mgm.attr.key=sys.acl",
                                "&mgm.path=", seal_path(dir_path)])
            (status, stdout, __) = exec_cmd(fgetattr)

            if not status:
                warn_msg = "No xattr sys.acl found for dir={0}".format(dir_path)
                self.logger.warning(warn_msg)
            else:
                # Remove the 'z:i' rule from the acl list
                stdout = stdout.replace('"', '')
                acl_val = stdout[stdout.find('=') + 1:]
                rules = acl_val.split(',')
                new_rules = []

                for rule in rules:
                    if rule.startswith("z:"):
                        tag, definition = rule.split(':')
                        pos = definition.find('i')

                        if pos != -1:
                            definition = definition[:pos] + definition[pos + 1:]

                            if definition:
                                new_rules.append(':'.join([tag, definition]))

                            continue

                    new_rules.append(rule)

                acl_val = ','.join(new_rules)
                self.logger.error("new acl: {0}".format(acl_val))

                if acl_val:
                    # Set the new sys.acl xattr
                    fmutable = ''.join([url.protocol, "://", url.hostid, "//proc/user/?",
                                        "mgm.cmd=attr&mgm.subcmd=set&mgm.attr.key=sys.acl",
                                        "&mgm.attr.value=", acl_val, "&mgm.path=", dir_path])
                    (status, __, stderr) = exec_cmd(fmutable)

                    if not status:
                        err_msg = "Error making dir={0} mutable, msg={1}".format(
                            dir_path, stderr)
                        self.logger.error(err_msg)
                        raise IOError(err_msg)
                else:
                    # sys.acl empty, remove it from the xattrs
                    frmattr = ''.join([url.protocol, "://", url.hostid, "//proc/user/?",
                                       "mgm.cmd=attr&mgm.subcmd=rm&mgm.attr.key=sys.acl",
                                       "&mgm.path=", dir_path])
                    (status, __, stderr) = exec_cmd(frmattr)

                    if not status:
                        err_msg = ("Error removing xattr=sys.acl for dir={0}, msg={1}"
                                   "").format(dir_path, stderr)
                        self.logger.error(err_msg)
                        raise IOError(err_msg)