Add producer upload client package
This commit is contained in:
104
pkg/upload/archive.go
Normal file
104
pkg/upload/archive.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package upload
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"gitea.maximumdirect.net/eric/distributor/pkg/bundle"
|
||||
)
|
||||
|
||||
func archiveBundle(root string, manifest bundle.Manifest) ([]byte, error) {
|
||||
var output bytes.Buffer
|
||||
gzipWriter := gzip.NewWriter(&output)
|
||||
tarWriter := tar.NewWriter(gzipWriter)
|
||||
|
||||
manifestData, err := bundle.MarshalManifest(manifest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := writeTarEntry(tarWriter, bundle.ManifestName, manifestData, 0o600, manifest.Created); err != nil {
|
||||
_ = tarWriter.Close()
|
||||
_ = gzipWriter.Close()
|
||||
return nil, err
|
||||
}
|
||||
for _, manifestFile := range manifest.Files {
|
||||
fullPath := filepath.Join(root, filepath.FromSlash(manifestFile.Path))
|
||||
info, err := os.Lstat(fullPath)
|
||||
if err != nil {
|
||||
_ = tarWriter.Close()
|
||||
_ = gzipWriter.Close()
|
||||
return nil, fmt.Errorf("file %q stat: %w", manifestFile.Path, err)
|
||||
}
|
||||
if !info.Mode().IsRegular() {
|
||||
_ = tarWriter.Close()
|
||||
_ = gzipWriter.Close()
|
||||
return nil, fmt.Errorf("file %q must be a regular file", manifestFile.Path)
|
||||
}
|
||||
file, err := os.Open(fullPath)
|
||||
if err != nil {
|
||||
_ = tarWriter.Close()
|
||||
_ = gzipWriter.Close()
|
||||
return nil, fmt.Errorf("file %q open: %w", manifestFile.Path, err)
|
||||
}
|
||||
if err := writeTarFile(tarWriter, manifestFile.Path, file, info.Mode().Perm(), info.ModTime(), info.Size()); err != nil {
|
||||
_ = file.Close()
|
||||
_ = tarWriter.Close()
|
||||
_ = gzipWriter.Close()
|
||||
return nil, err
|
||||
}
|
||||
if err := file.Close(); err != nil {
|
||||
_ = tarWriter.Close()
|
||||
_ = gzipWriter.Close()
|
||||
return nil, fmt.Errorf("file %q close: %w", manifestFile.Path, err)
|
||||
}
|
||||
}
|
||||
if err := tarWriter.Close(); err != nil {
|
||||
_ = gzipWriter.Close()
|
||||
return nil, fmt.Errorf("close tar archive: %w", err)
|
||||
}
|
||||
if err := gzipWriter.Close(); err != nil {
|
||||
return nil, fmt.Errorf("close gzip archive: %w", err)
|
||||
}
|
||||
return output.Bytes(), nil
|
||||
}
|
||||
|
||||
func writeTarEntry(writer *tar.Writer, name string, data []byte, mode int64, modTime time.Time) error {
|
||||
header := &tar.Header{
|
||||
Name: name,
|
||||
Mode: mode,
|
||||
Size: int64(len(data)),
|
||||
ModTime: modTime,
|
||||
}
|
||||
if err := writer.WriteHeader(header); err != nil {
|
||||
return fmt.Errorf("write tar header %q: %w", name, err)
|
||||
}
|
||||
if _, err := writer.Write(data); err != nil {
|
||||
return fmt.Errorf("write tar entry %q: %w", name, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeTarFile(writer *tar.Writer, name string, file *os.File, mode os.FileMode, modTime time.Time, size int64) error {
|
||||
if mode == 0 {
|
||||
mode = 0o600
|
||||
}
|
||||
header := &tar.Header{
|
||||
Name: name,
|
||||
Mode: int64(mode),
|
||||
Size: size,
|
||||
ModTime: modTime,
|
||||
}
|
||||
if err := writer.WriteHeader(header); err != nil {
|
||||
return fmt.Errorf("write tar header %q: %w", name, err)
|
||||
}
|
||||
if _, err := io.Copy(writer, file); err != nil {
|
||||
return fmt.Errorf("write tar entry %q: %w", name, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user