Beispiel #1
0
    def filecopy(self, src, dst, base=None, **kwargs):
        if has_scheme(src):
            src_uri = self.sanitize_path(src)
        else:
            src_uri = self.uri(src, cmd="filecopy", base=base)

        if has_scheme(dst):
            dst_uri = self.sanitize_path(dst)
        else:
            dst_uri = self.uri(dst, cmd="filecopy", base=base)

        with self.context() as ctx, self.transfer_parameters(ctx) as params:
            try:
                logger.debug("invoking gfal2 filecopy({}, {})".format(
                    src_uri, dst_uri))
                ctx.filecopy(params, src_uri, dst_uri)

            except gfal2.GError:
                e = GFALError_filecopy(src_uri, dst_uri)
                # check if the operation should be retried or raised immediately
                if e.reason == e.UNKNOWN:
                    raise e
                e.reraise()

        return src_uri, dst_uri
Beispiel #2
0
    def filecopy(self, src, dst, base=None):
        if has_scheme(src):
            src = self.gfal_str(src)
        else:
            src = self.uri(src, cmd="filecopy", base=base)

        if has_scheme(dst):
            dst = self.gfal_str(dst)
        else:
            dst = self.uri(dst, cmd="filecopy", base=base)

        with self.context() as ctx, self.transfer_parameters(ctx) as params:
            ctx.filecopy(params, src, dst)

        return src, dst
Beispiel #3
0
    def _cached_copy(self,
                     src,
                     dst,
                     cache=None,
                     prefer_cache=False,
                     validate=None,
                     **kwargs):
        cache = self._use_cache(cache)

        # ensure absolute paths
        src = self.abspath(src)
        dst = self.abspath(dst) if dst else None

        # determine the copy mode for code readability
        # (remote-remote: "rr", remote-local: "rl", remote-cache: "rc", ...)
        src_local = self.is_local(src)
        dst_local = dst and self.is_local(dst)
        mode = "rl"[src_local] + ("rl"[dst_local] if dst is not None else "c")

        # disable caching when the mode is local-local, local-cache or remote-remote
        if mode in ("ll", "lc", "rr"):
            cache = False

        # dst can be None, but in this case, caching should be enabled
        if dst is None and not cache:
            raise Exception(
                "copy destination must not be empty when caching is disabled")

        # paths including scheme and base
        full_src = src if has_scheme(src) else self.gfal.url(src,
                                                             cmd="filecopy")
        full_dst = None
        if dst:
            full_dst = dst if has_scheme(dst) else self.gfal.url(
                dst, cmd="filecopy")

        if cache:
            kwargs_no_retries = kwargs.copy()
            kwargs_no_retries["retries"] = 0
            kwargs_no_retries = kwargs

            # handle 3 cases: lr, rl, rc
            if mode == "lr":
                # strategy: copy to remote, copy to cache, sync stats

                # copy to remote, no need to validate as we need the stat anyway
                self._atomic_copy(src, full_dst, validate=False, **kwargs)
                rstat = self.stat(dst, **kwargs_no_retries)

                # remove the cache entry
                if dst in self.cache:
                    self.cache.remove(dst)

                # allocate cache space and copy to cache
                lstat = _local_fs.stat(src)
                self.cache.allocate(lstat.st_size)
                full_cdst = add_scheme(self.cache.cache_path(dst), "file")
                with self.cache.lock(dst):
                    self._atomic_copy(src, full_cdst, validate=False)
                    self.cache.touch(dst, (int(time.time()), rstat.st_mtime))

                return dst

            else:  # rl, rc
                # strategy: copy to cache when not up to date, sync stats, opt. copy to local

                # build the full cache path of the src file
                full_csrc = add_scheme(self.cache.cache_path(src), "file")

                # if the file is cached and prefer_cache is true,
                # return the cache path, no questions asked
                # otherwise, check if the file is there and up to date
                if not prefer_cache or src not in self.cache:
                    with self.cache.lock(src):
                        # in cache and outdated?
                        rstat = self.stat(src, **kwargs_no_retries)
                        if src in self.cache and abs(
                                self.cache.mtime(src) - rstat.st_mtime) > 1:
                            self.cache.remove(src, lock=False)
                        # in cache at all?
                        if src not in self.cache:
                            self.cache.allocate(rstat.st_size)
                            self._atomic_copy(full_src,
                                              full_csrc,
                                              validate=validate,
                                              **kwargs)
                            self.cache.touch(
                                src, (int(time.time()), rstat.st_mtime))

                if mode == "rl":
                    # copy to local without permission bits
                    copy_no_perm(remove_scheme(full_csrc),
                                 remove_scheme(full_dst))
                    return dst
                else:  # rc
                    return full_csrc

        else:
            # simply copy and return the dst path
            self._atomic_copy(full_src, full_dst, validate=validate, **kwargs)

            return full_dst if dst_local else dst