Пример #1
0
func hashForFile(buildDir, path string, info os.FileInfo) (h *fileHash, err error) {
	sha512sum := ""
	// pointer so that omitempty works (we don't want size for
	// directories or symlinks)
	var size *int64
	if info.Mode().IsRegular() {
		sha512sum, err = helpers.Sha512sum(path)
		if err != nil {
			return nil, err
		}
		fsize := info.Size()
		size = &fsize
	}

	// major/minor handling
	device := ""
	major, minor, err := helpers.MajorMinor(info)
	if err == nil {
		device = fmt.Sprintf("%v,%v", major, minor)
	}

	if buildDir != "" {
		path = path[len(buildDir)+1:]
	}

	return &fileHash{
		Name:   path,
		Size:   size,
		Sha512: sha512sum,
		Device: device,
		// FIXME: not portable, this output is different on
		//        windows, macos
		Mode: newYamlFileMode(info.Mode()),
	}, nil
}
Пример #2
0
// tarCreate creates a tarfile for a clickdeb, all files in the archive
// belong to root (same as dpkg-deb)
func tarCreate(tarname string, sourceDir string, fn tarExcludeFunc) error {
	w, err := os.Create(tarname)
	if err != nil {
		return err
	}
	defer w.Close()

	var compressor io.WriteCloser
	switch {
	case strings.HasSuffix(tarname, ".gz"):
		compressor, err = gzip.NewWriterLevel(w, 9)
	case strings.HasSuffix(tarname, ".xz"):
		compressor = newXZPipeWriter(w)
	default:
		return fmt.Errorf("unknown compression extension %s", tarname)
	}
	if err != nil {
		return err
	}
	defer compressor.Close()

	tarWriter := tar.NewWriter(compressor)
	defer tarWriter.Close()

	err = filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error {
		st, err := os.Lstat(path)
		if err != nil {
			return err
		}

		// check if we support this type
		if !st.Mode().IsRegular() && !helpers.IsSymlink(st.Mode()) && !st.Mode().IsDir() && !helpers.IsDevice(st.Mode()) {
			return fmt.Errorf("unsupported file type for %s", path)
		}

		// check our exclude function
		if fn != nil {
			if !fn(path) {
				return nil
			}
		}

		// huh? golang, come on! the symlink stuff is a bit complicated
		target, _ := os.Readlink(path)
		hdr, err := tar.FileInfoHeader(info, target)
		if err != nil {
			return err
		}

		// tar.FileInfoHeader does include the fact that its a
		// char/block device, but does not set major/minor :/
		if helpers.IsDevice(st.Mode()) {
			major, minor, err := helpers.MajorMinor(st)
			if err != nil {
				return err
			}
			hdr.Devmajor = int64(major)
			hdr.Devminor = int64(minor)
		}

		// exclude "."
		relativePath := "." + path[len(sourceDir):]
		if relativePath == "." {
			return nil
		}

		// add header, note that all files belong to root
		hdr.Name = relativePath
		hdr.Uid = 0
		hdr.Gid = 0
		hdr.Uname = "root"
		hdr.Gname = "root"

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

		// add content
		if st.Mode().IsRegular() {
			f, err := os.Open(path)
			if err != nil {
				return err
			}
			defer f.Close()
			_, err = io.Copy(tarWriter, f)
			if err != nil {
				return err
			}
		}

		return nil
	})

	return err
}