WIP - add archive writer

This commit is contained in:
Matt Nikkel
2021-04-02 11:48:34 -04:00
parent d9b0ed7c5c
commit 3cdf8b8f5c
5 changed files with 212 additions and 13 deletions

9
pkg/archive/doc.go Normal file
View File

@@ -0,0 +1,9 @@
/*
The archive's format is intended to be a black box, and as such the generation
process includes metadata regarding which version was used for creating the
artifact.
Even so, the archive's format will be well-documented as to allow easier
collaboration and implementation.
*/
package archive

7
pkg/archive/reader.go Normal file
View File

@@ -0,0 +1,7 @@
package archive
type Reader struct{}
func NewReader() *Reader {
return &Reader{}
}

133
pkg/archive/writer.go Normal file
View File

@@ -0,0 +1,133 @@
package archive
import (
"archive/tar"
"errors"
"fmt"
"io"
"path"
)
type WriterKind int
const (
WriterKindUnknown = iota
WriterKindTar
)
var ErrNoKind = errors.New("no kind specified for Writer")
type writerOptions struct {
// kind WriterKind
}
type WriterOption interface {
Apply(*writerOptions)
}
type Writer struct {
kind WriterKind
tarWriter *tar.Writer
}
func NewWriter(dst io.Writer, kind WriterKind, opts ...WriterOption) (*Writer, error) {
// opt := &writerOptions{}
// for _, o := range opts {
// o.Apply(opt)
// }
w := &Writer{}
switch kind {
case WriterKindTar:
w.tarWriter = tar.NewWriter(dst)
default:
return nil, fmt.Errorf("unknown writer type provided")
}
return w, nil
}
// func (w *Writer) MkdirP(path string) error {
// switch w.kind {
// case WriterKindTar:
// return errors.New("unimplemented")
// default:
// return ErrNoKind
// }
// }
type writerFileOptions struct {
fileMode int64
// subdirectory string
}
func defaultWriterFileOptions() *writerFileOptions {
return &writerFileOptions{
fileMode: 0644,
}
}
type WriterFileOption interface {
Apply(*writerFileOptions)
}
type withFileMode int64
func (w withFileMode) Apply(o *writerFileOptions) {
o.fileMode = int64(w)
}
func WithFileMode(mode int64) WriterFileOption {
return withFileMode(mode)
}
func (w *Writer) CreateFile(
packageKind string,
packageName string,
fileName string,
fileSize int64,
opts ...WriterFileOption,
) error {
opt := defaultWriterFileOptions()
for _, o := range opts {
o.Apply(opt)
}
cleanFileName := "./" + path.Clean(path.Join(".", packageKind, packageName, fileName))
switch w.kind {
case WriterKindTar:
tarHeader := &tar.Header{
Typeflag: tar.TypeReg,
Name: cleanFileName,
Size: fileSize,
Mode: opt.fileMode,
}
return w.tarWriter.WriteHeader(tarHeader)
default:
return ErrNoKind
}
}
func (w *Writer) Write(b []byte) (int, error) {
switch w.kind {
case WriterKindTar:
return w.tarWriter.Write(b)
default:
return 0, ErrNoKind
}
}
func (w *Writer) Close() error {
switch w.kind {
case WriterKindTar:
return w.tarWriter.Close()
default:
return ErrNoKind
}
}

5
pkg/packager_new/doc.go Normal file
View File

@@ -0,0 +1,5 @@
/*
Package packager implements a Packager that collects dependencies and generates
an archive used by a Deployer.
*/
package packager

View File

@@ -1,12 +1,15 @@
package packager
import (
"github.com/rancherfederal/hauler/pkg/apis/hauler.cattle.io/v1alpha1"
"github.com/rancherfederal/hauler/pkg/util"
"archive/tar"
"errors"
"fmt"
"io"
"net/http"
"strings"
"github.com/rancherfederal/hauler/pkg/apis/hauler.cattle.io/v1alpha1"
"github.com/rancherfederal/hauler/pkg/archive"
"github.com/rancherfederal/hauler/pkg/util"
)
type Packager struct {
@@ -32,37 +35,79 @@ func New(config *v1alpha1.EnvConfig) *Packager {
}
}
func (p *Packager) Collect(
func (p *Packager) Package(
dst io.Writer,
pkgConfig v1alpha1.PackageConfig,
) error {
// wrap around dst
aw, err := archive.NewWriter(dst, archive.WriterKindTar)
if err != nil {
return fmt.Errorf("create archive writer: %v", err)
}
var packageErrors []error
for _, config := range pkgConfig.Packages {
switch cfg := config.GetDef().(type) {
case v1alpha1.PackageK3s:
if err := p.PackageK3s(aw, cfg); err != nil {
packageErrors = append(
packageErrors,
fmt.Errorf("package id %s: collect k3s: %w", config.Name, err),
)
}
default:
packageErrors = append(
packageErrors,
fmt.Errorf("package id %s: unknown package type", config.Name),
)
}
}
if len(packageErrors) != 0 {
b := &strings.Builder{}
b.WriteString("collect errors:")
for _, err := range packageErrors {
b.WriteString("\n")
b.WriteString(err.Error())
}
return errors.New(b.String())
}
return nil
}
func (p *Packager) CollectK3s(
tarDst *tar.Writer,
const (
k3sReleaseDownloadFmtStr = `https://github.com/k3s-io/k3s/releases/download/%s/%s`
k3sRawFmtStr = `https://raw.githubusercontent.com/k3s-io/k3s/%s/%s`
k3sDefaultInstallScriptRef = "master"
)
func (p *Packager) PackageK3s(
writer *archive.Writer,
config v1alpha1.PackageK3s,
) error {
fmt.Printf("release %s\n", config.Release)
fmt.Printf("install script ref %s\n", config.InstallScriptRef)
return nil
}
func (p *Packager) CollectContainerImages(
tarDst *tar.Writer,
func (p *Packager) PackageContainerImages(
writer *archive.Writer,
config v1alpha1.PackageContainerImages,
) error {
return nil
}
func (p *Packager) CollectGitRepository(
tarDst *tar.Writer,
func (p *Packager) PackageGitRepository(
writer *archive.Writer,
config v1alpha1.PackageGitRepository,
) error {
return nil
}
func (p *Packager) CollectFileTree(
tarDst *tar.Writer,
func (p *Packager) PackageFileTree(
writer *archive.Writer,
config v1alpha1.PackageFileTree,
) error {
return nil