func()

in commands/helpers/archive/tarzstd/tarzstd_archiver.go [46:127]


func (a *archiver) Archive(ctx context.Context, files map[string]os.FileInfo) error {
	sorted := make([]string, 0, len(files))
	for filename := range files {
		sorted = append(sorted, filename)
	}
	sort.Strings(sorted)

	zw, err := zstd.NewWriter(a.w, zstd.WithEncoderLevel(zstd.EncoderLevel(levels[a.level])))
	if err != nil {
		return err
	}
	defer zw.Close()

	tw := tar.NewWriter(zw)
	defer tw.Close()

	for _, name := range sorted {
		fi := files[name]
		if fi.Mode()&irregularModes != 0 {
			continue
		}

		path, err := filepath.Abs(name)
		if err != nil {
			return err
		}
		if !strings.HasPrefix(path, a.dir+string(filepath.Separator)) && path != a.dir {
			return fmt.Errorf("%s cannot be archived from outside of chroot (%s)", name, a.dir)
		}

		rel, err := filepath.Rel(a.dir, path)
		if err != nil {
			return err
		}

		if ctx.Err() != nil {
			return ctx.Err()
		}

		var link string
		if fi.Mode()&os.ModeSymlink != 0 {
			link, err = os.Readlink(path)
			if err != nil {
				return err
			}
		}

		hdr, err := tar.FileInfoHeader(fi, link)
		if err != nil {
			return err
		}
		hdr.Name = rel
		if fi.IsDir() {
			hdr.Name += "/"
		}

		if err := tw.WriteHeader(hdr); err != nil {
			return err
		}

		if !fi.Mode().IsRegular() {
			continue
		}

		f, err := os.Open(path)
		if err != nil {
			return err
		}

		if _, err = io.Copy(tw, f); err != nil {
			f.Close()
			return err
		}
		f.Close()
	}

	if err := tw.Close(); err != nil {
		return err
	}

	return zw.Close()
}