diff --git a/cmd/haulerctl/app/bootstrap.go b/cmd/haulerctl/app/bootstrap.go index 83c8250..827da70 100644 --- a/cmd/haulerctl/app/bootstrap.go +++ b/cmd/haulerctl/app/bootstrap.go @@ -2,13 +2,12 @@ package app import ( "context" - "github.com/mholt/archiver/v3" - "github.com/rancherfederal/hauler/pkg/apis/haul" - "github.com/rancherfederal/hauler/pkg/bootstrap" + "github.com/rancherfederal/hauler/pkg/bundle" + "github.com/rancherfederal/hauler/pkg/bundle/boot" + "github.com/rancherfederal/hauler/pkg/packager" "github.com/spf13/cobra" "gopkg.in/yaml.v3" "os" - "path/filepath" ) type deployOpts struct { @@ -38,29 +37,38 @@ func NewBootstrapCommand() *cobra.Command { } // Run performs the operation. -func (o *deployOpts) Run(haulPath string) error { +func (o *deployOpts) Run(bootPath string) error { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - z := archiver.NewTarZstd() - z.OverwriteExisting = true - z.MkdirAll = true - - err := z.Unarchive(haulPath, o.haulerDir) + tmpdir, err := os.MkdirTemp("", "hauler") if err != nil { return err } - haulerCfgPath := filepath.Join(o.haulerDir, "hauler.yaml") - data, err := os.ReadFile(haulerCfgPath) + tp := bundle.Path(tmpdir) - var h haul.Haul - if err := yaml.Unmarshal(data, &h); err != nil { + if err := packager.Decompress(bootPath, tmpdir); err != nil { return err } - bstrp := bootstrap.NewBootstrapper(h, o.haulerDir) - err = bstrp.Bootstrap(ctx) + _, err = os.Stat(tp.Path("boot.bundle.yaml")) + if err != nil { + return err + } + + data, err := os.ReadFile(tp.Path("boot.bundle.yaml")) + if err != nil { + return err + } + + var b *boot.Bundle + err = yaml.Unmarshal(data, &b) + if err != nil { + return err + } + + err := b.Install(tp.Path()) if err != nil { return err } diff --git a/cmd/haulerctl/app/bundle_boot.go b/cmd/haulerctl/app/bundle_boot.go index 152d4a0..c1e9eee 100644 --- a/cmd/haulerctl/app/bundle_boot.go +++ b/cmd/haulerctl/app/bundle_boot.go @@ -2,15 +2,27 @@ package app import ( "context" - "github.com/rancherfederal/hauler/pkg/apis/hauler.cattle.io/v1beta1" + "github.com/rancherfederal/hauler/pkg/bundle" + "github.com/rancherfederal/hauler/pkg/bundle/boot" + "github.com/rancherfederal/hauler/pkg/packager" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "os" + "path/filepath" + "sigs.k8s.io/yaml" ) type bundleBootOpts struct { bundleOpts bundleOpts name string - new bool + save bool + path string + skipDriver bool + images []string + config string + driverType string + driverVersion string } func NewBundleBootCommand() *cobra.Command { @@ -20,16 +32,23 @@ func NewBundleBootCommand() *cobra.Command { Use: "boot", Short: "does something", RunE: func(cmd *cobra.Command, args []string) error { - return opts.Run() }, } f := cmd.Flags() - f.StringVarP(&opts.name, "name", "n", "hauler", + f.StringVarP(&opts.name, "name", "n", "boot", "Name of the bundle to new") - f.BoolVar(&opts.new, "new", false, - "Toggle creation of an empty bundle in the current directory") + f.StringVarP(&opts.config, "config", "c", "boot.bundle.yaml", + "Name of the config file to use for bundling") + f.StringVar(&opts.driverType, "driver-type", "k3s", + "Type of driver to use for the boot bundle (k3s or rke2)") + f.StringVar(&opts.driverVersion, "driver-version", "v1.21.1+k3s1", + "Version of the driver to use, must match appropriately with driver-type") + f.StringSliceVarP(&opts.images, "images", "i", []string{}, + "Images to include in bundle, can be specified multiple times") + f.BoolVarP(&opts.save, "save", "s", false, + "Save bundle") return cmd } @@ -38,15 +57,74 @@ func (o *bundleBootOpts) Run() error { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - var b *v1beta1.BootBundle - if o.new { - b = v1beta1.NewBootBundle(o.name) - err := b.Save() + bundlePath := filepath.Join(o.path, o.name) + + logrus.Infof("loading boot bundle: %s", bundlePath) + b, err := o.load(bundlePath) + if err != nil { + return err + } + + err = b.Sync(ctx, bundlePath) + if err != nil { + return err + } + + if o.save { + logrus.Infof("Exporting bundle to compressed archive") + //TODO: This is lazy + err := packager.Export(b, bundlePath, b.Name) if err != nil { return err } } - _ = ctx return nil } + +func (o *bundleBootOpts) load(path string) (*boot.Bundle, error) { + var b *boot.Bundle + + p := bundle.Path(path) + _, err := os.Stat(p.Path(o.config)) + if os.IsNotExist(err) { + b = o.newDefault() + data, _ := yaml.Marshal(b) + if err := p.WriteFile(o.config, data, 0644); err != nil { + return nil, err + } + + //Make the dir structure if we're starting from scratch + if err = os.MkdirAll(p.Path("bin"), os.ModePerm); err != nil { + return nil, err + } + if err = os.MkdirAll(p.Path("images"), os.ModePerm); err != nil { + return nil, err + } + if err = os.MkdirAll(p.Path("manifests"), os.ModePerm); err != nil { + return nil, err + } + if err = os.MkdirAll(p.Path("charts"), os.ModePerm); err != nil { + return nil, err + } + } + + data, err := os.ReadFile(p.Path(o.config)) + err = yaml.Unmarshal(data, &b) + if err != nil { + return nil, err + } + + return b, nil +} + +func (o *bundleBootOpts) newDefault() *boot.Bundle { + return &boot.Bundle{ + Name: "hauler", + Images: o.images, + Driver: boot.K3sDriver{ Version: o.driverVersion }, + + //TODO: Chart support, maybe specify list of "repo/chart"? + Charts: []string{}, + } +} \ No newline at end of file diff --git a/cmd/haulerctl/app/bundle_images.go b/cmd/haulerctl/app/bundle_images.go index 261106a..31caf73 100644 --- a/cmd/haulerctl/app/bundle_images.go +++ b/cmd/haulerctl/app/bundle_images.go @@ -2,14 +2,24 @@ package app import ( "context" - "fmt" - + "github.com/rancherfederal/hauler/pkg/bundle" + "github.com/rancherfederal/hauler/pkg/bundle/image" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" + "os" + "path/filepath" + "sigs.k8s.io/yaml" ) type bundleImagesOpts struct { bundleOpts bundleOpts + + name string + save bool + path string + images []string + config string } // NewBundleImagesCommand creates a new sub command of bundle for images @@ -26,28 +36,67 @@ func NewBundleImagesCommand() *cobra.Command { }, } + f := cmd.Flags() + f.StringVarP(&opts.name, "name", "n", "hauler", + "Name of the bundle to new") + f.StringVarP(&opts.config, "config", "c", "image.bundle.yaml", + "Name of the config file to use for bundling") + f.StringVarP(&opts.path, "path", "p", "", + "OCILayoutName to an existing directory to create a bundle from") + f.BoolVarP(&opts.save, "save", "s", false, + "Save bundle") + f.StringSliceVarP(&opts.images, "image", "i", []string{}, + "image to append to layout, can be specified multiple times") + return cmd } func (o *bundleImagesOpts) Run() error { - - //TODO ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - //b := bundle.NewLayoutStore(o.bundleDir) - // - //images := []string{"alpine:latest", "registry:2.7.1"} - // - //for _, i := range images { - // if err := b.Add(ctx, i); err != nil { - // return err - // } - //} - _ = ctx + bundlePath := filepath.Join(o.path, o.name) - fmt.Println("bundle images") - fmt.Println(o.bundleOpts.bundleDir) + logrus.Infof("loading image bundle: %s", o.name) + b, err := o.load(bundlePath) + if err != nil { + return err + } + + err = b.Sync(ctx, bundlePath) + if err != nil { + return err + } return nil } + +func (o *bundleImagesOpts) load(path string) (*image.Bundle, error) { + var i *image.Bundle + + p := bundle.Path(path) + _, err := os.Stat(p.Path(o.config)) + if os.IsNotExist(err) { + // Create a new default bundle + i = o.newDefault() + data, _ := yaml.Marshal(i) + if err := p.WriteFile(o.config, data, 0644); err != nil { + return &image.Bundle{}, err + } + } + + data, err := os.ReadFile(p.Path(o.config)) + err = yaml.Unmarshal(data, &i) + if err != nil { + return &image.Bundle{}, err + } + + return i, nil +} + +func (o *bundleImagesOpts) newDefault() *image.Bundle { + return &image.Bundle{ + Name: "hauler", + Images: o.images, + } +} \ No newline at end of file diff --git a/cmd/haulerctl/app/copy.go b/cmd/haulerctl/app/copy.go index 19d5af6..3fa7c87 100644 --- a/cmd/haulerctl/app/copy.go +++ b/cmd/haulerctl/app/copy.go @@ -2,8 +2,6 @@ package app import ( "context" - "github.com/rancherfederal/hauler/pkg/fetcher/image" - "github.com/spf13/cobra" ) @@ -45,16 +43,7 @@ func (o *copyOpts) Run() error { //if err := cp.Get(ctx, o.src); err != nil { // return err //} - - client, err := image.NewClient() - if err != nil { - return err - } - - err = client.Save(ctx, "registry:2", "hauler") - if err != nil { - return err - } + _ = ctx return nil } diff --git a/cmd/haulerctl/app/create.go b/cmd/haulerctl/app/create.go index e24fd57..ede60f7 100644 --- a/cmd/haulerctl/app/create.go +++ b/cmd/haulerctl/app/create.go @@ -1,17 +1,10 @@ package app import ( - "context" - "github.com/rancherfederal/hauler/pkg/apis/bundle" - - "github.com/rancherfederal/hauler/pkg/apis/driver" - "github.com/rancherfederal/hauler/pkg/apis/haul" "github.com/rancherfederal/hauler/pkg/apis/hauler.cattle.io/v1alpha1" - "github.com/rancherfederal/hauler/pkg/create" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) type createOpts struct { @@ -72,32 +65,5 @@ func (o *createOpts) PreRun() error { // Run performs the operation. func (o *createOpts) Run() error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - d := driver.K3sDriver{ - Version: "v1.21.1+k3s1", - Config: driver.K3sConfig{}, - } - - h := haul.Haul{ - TypeMeta: metav1.TypeMeta{}, - Metadata: metav1.ObjectMeta{ - Name: "haul", - }, - Spec: haul.HaulSpec{ - Driver: d, - Bundles: []bundle.Bundle{ - bundle.CreateDriverBundle(d), - { Name: "test", Path: "testdata/bundle-a" }, - }, - }, - } - - creator, _ := create.NewCreator() - if err := creator.Create(ctx, h); err != nil { - return err - } - return nil } diff --git a/go.mod b/go.mod index 83d1a05..d45393c 100644 --- a/go.mod +++ b/go.mod @@ -3,22 +3,28 @@ module github.com/rancherfederal/hauler go 1.16 require ( + github.com/Microsoft/go-winio v0.5.0 // indirect + github.com/Microsoft/hcsshim v0.8.17 // indirect github.com/containerd/containerd v1.5.1 - github.com/containers/image/v5 v5.12.0 - github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a // indirect - github.com/containers/storage v1.32.1 // indirect github.com/docker/docker v20.10.6+incompatible // indirect + github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect github.com/go-git/go-git/v5 v5.4.0 github.com/google/go-containerregistry v0.4.1 + github.com/gorilla/mux v1.7.4 // indirect + github.com/json-iterator/go v1.1.11 // indirect + github.com/klauspost/compress v1.12.3 // indirect + github.com/klauspost/pgzip v1.2.5 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mholt/archiver/v3 v3.5.0 github.com/mitchellh/go-homedir v1.1.0 github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 github.com/oras-project/oras-go v0.1.0 + github.com/otiai10/copy v1.6.0 github.com/pterm/pterm v0.12.18 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.1.3 github.com/spf13/viper v1.7.0 + github.com/ulikunitz/xz v0.5.10 // indirect golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect golang.org/x/net v0.0.0-20210525063256-abc453219eb5 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect diff --git a/go.sum b/go.sum index 64158ba..9eb1668 100644 --- a/go.sum +++ b/go.sum @@ -24,10 +24,7 @@ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiy cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg= -github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= @@ -39,7 +36,6 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= @@ -73,10 +69,6 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= -github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM= -github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -124,7 +116,6 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= -github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -132,7 +123,6 @@ github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmE github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= -github.com/cilium/ebpf v0.5.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -221,18 +211,9 @@ github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= -github.com/containers/image/v5 v5.12.0 h1:1hNS2QkzFQ4lH3GYQLyAXB0acRMhS1Ubm6oV++8vw4w= -github.com/containers/image/v5 v5.12.0/go.mod h1:VasTuHmOw+uD0oHCfApQcMO2+36SfyncoSahU7513Xs= -github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= -github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a h1:spAGlqziZjCJL25C6F1zsQY05tfCKE9F5YwtEWWe6hU= -github.com/containers/libtrust v0.0.0-20200511145503-9c3a6c22cd9a/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= -github.com/containers/ocicrypt v1.1.1 h1:prL8l9w3ntVqXvNH1CiNn5ENjcCnr38JqpSyvKKB4GI= github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= -github.com/containers/storage v1.30.1/go.mod h1:NDJkiwxnSHD1Is+4DGcyR3SIEYSDOa0xnAW+uGQFx9E= -github.com/containers/storage v1.32.1 h1:JgvHY5dokiff+Ee4TdvPYO++Oq2BAave5DmyPetH2iU= -github.com/containers/storage v1.32.1/go.mod h1:do6oIF71kfkVS3CPUZr+6He94fIaj6pzF8ywevPuuOw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -246,7 +227,6 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -274,20 +254,17 @@ github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v1.4.2-0.20191219165747-a9416c67da9f/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.6+incompatible h1:oXI3Vas8TI8Eu/EjH4srKHJBVqraSzJybhxY7Om9faQ= github.com/docker/docker v20.10.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= -github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= @@ -322,7 +299,6 @@ github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXt github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= @@ -363,7 +339,6 @@ github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblf github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -420,8 +395,6 @@ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.4.1 h1:Lrcj2AOoZ7WKawsoKAh2O0dH0tBqMW2lTEmozmK4Z3k= github.com/google/go-containerregistry v0.4.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= -github.com/google/go-intervals v0.0.2 h1:FGrVEiUnTRKR8yE04qzXYaJMtnIYqobR5QbblK3ixcM= -github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCjbbr4TQlcT6Y= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -436,7 +409,6 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -463,15 +435,12 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= @@ -513,7 +482,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= @@ -525,7 +493,6 @@ github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= @@ -545,7 +512,6 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -553,7 +519,6 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/manifoldco/promptui v0.8.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= @@ -561,13 +526,10 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.11 h1:vCoR9VPpsk/TZFW2JwK5I9S0xdrtUq2bph6/YjEPnaw= -github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -575,9 +537,7 @@ github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88J github.com/mholt/archiver/v3 v3.5.0 h1:nE8gZIrw66cu4osS/U7UW7YDuGMHssxKutU8IfWxwWE= github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -597,7 +557,6 @@ github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2J github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -605,11 +564,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= -github.com/mtrmac/gpgme v0.1.2 h1:dNOmvYmsrakgW7LcgiprD0yfRuQQe8/C8F6Z+zogO3s= -github.com/mtrmac/gpgme v0.1.2/go.mod h1:GYYHnGSuS7HK3zVS2n3y73y0okK/BeKzwnn5jgiVFNI= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -652,24 +608,23 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= -github.com/opencontainers/runc v1.0.0-rc95 h1:RMuWVfY3E1ILlVsC3RhIq38n4sJtlOFwU9gfFZSqrd0= -github.com/opencontainers/runc v1.0.0-rc95/go.mod h1:z+bZxa/+Tz/FmYVWkhUajJdzFeOqjc5vrqskhVyHGUM= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= -github.com/opencontainers/selinux v1.8.1 h1:yvEZh7CsfnJNwKzG9ZeXwbvR05RAZsu5RS/3vA6qFTA= -github.com/opencontainers/selinux v1.8.1/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/oras-project/oras-go v0.1.0 h1:mWWO1nAdcHQSC/zTUkckgDUOeGu1Tnxwyph1C8zKqsE= github.com/oras-project/oras-go v0.1.0/go.mod h1:uts4oKaEWR4D+pajh79zPDGFJrx2aAtcVqC2jNb/8vM= -github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913 h1:TnbXhKzrTOyuvWrjI8W6pcoI9XPbLHFXCdN2dtUw7Rw= -github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc= +github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= +github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= +github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= @@ -688,8 +643,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= -github.com/pquerna/ffjson v0.0.0-20190813045741-dac163c6c0a9/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= @@ -777,7 +730,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 h1:lIOOHPEbXzO3vnmx2gok1Tfs31Q8GQqKLc8vVqyQq/I= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -795,11 +747,8 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= -github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs= -github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -811,10 +760,6 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE= -github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g= -github.com/vbauerster/mpb/v6 v6.0.3 h1:j+twHHhSUe8aXWaT/27E98G5cSBeqEuJSVCMjmLg0PI= -github.com/vbauerster/mpb/v6 v6.0.3/go.mod h1:5luBx4rDLWxpA4t6I5sdeeQuZhqDxc+wr5Nqf35+tnM= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= @@ -822,18 +767,12 @@ github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmF github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b h1:6cLsL+2FW6dRAdl5iMtHgRogVCff0QpRi9653YmdcJA= -github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= @@ -850,10 +789,8 @@ github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1 github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= -go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -981,7 +918,6 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1044,7 +980,6 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea h1:+WiDlPBBaO+h9vPNZi8uJ3k4BkKQB7Iow3aqwHVA5hI= golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1066,7 +1001,6 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1215,7 +1149,6 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= diff --git a/pkg/apis/hauler.cattle.io/v1beta1/boot.go b/pkg/apis/hauler.cattle.io/v1beta1/boot.go index ce649c1..30fa818 100644 --- a/pkg/apis/hauler.cattle.io/v1beta1/boot.go +++ b/pkg/apis/hauler.cattle.io/v1beta1/boot.go @@ -1,7 +1,16 @@ package v1beta1 import ( + "context" "fmt" + "github.com/google/go-containerregistry/pkg/name" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/layout" + "github.com/google/go-containerregistry/pkg/v1/tarball" + "github.com/mholt/archiver/v3" + "github.com/otiai10/copy" + "github.com/rancherfederal/hauler/pkg/fetcher/image" + "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "os" "path/filepath" @@ -9,9 +18,10 @@ import ( ) const ( + Name = "bundle" BootBundleKind = "BootBundle" BootBundleManifestDir = "manifests" - BootBundleImagesDir = "images" + BootBundleImagesDir = "oci" BootBundleChartsDir = "charts" ) @@ -19,6 +29,9 @@ type BootBundle struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + //TODO: Make below (de)serializable interface: Driver + Driver K3sDriver `json:"driver,omitempty"` + Charts []string `json:"charts,omitempty"` Images []string `json:"images,omitempty"` } @@ -32,10 +45,39 @@ func NewBootBundle(name string) *BootBundle { ObjectMeta: metav1.ObjectMeta{ Name: name, }, + Driver: K3sDriver{ + Type: K3sDriverName, + Version: K3sDefaultVersion, + Config: K3sConfig{ + NodeName: "hauler", + Selinux: false, + KubeConfigMode: 0644, + }, + }, } } -func (b BootBundle) Save() error { +//Load will load a bundle given a directory containing a BootBundle config file +func Load(path string) (*BootBundle, error) { + cfgPath := filepath.Join(path, fmt.Sprintf("%s.yaml", Name)) + if _, err := os.Stat(cfgPath); err != nil { + return nil, err + } + + data, _ := os.ReadFile(cfgPath) + + var b *BootBundle + err := yaml.Unmarshal(data, &b) + if err != nil { + return nil, err + } + + return b, err +} + +func (b BootBundle) Create() error { + logrus.Infof("creating new bundle...") + // Create dir for bundle if it doesn't exist if _, err := os.Stat(b.Name); os.IsNotExist(err) { err := os.Mkdir(b.Name, os.ModePerm) @@ -49,15 +91,34 @@ func (b BootBundle) Save() error { return err } - configFilePath := filepath.Join(b.Name, fmt.Sprintf("%s.yaml", b.Name)) + configFilePath := filepath.Join(b.Name, fmt.Sprintf("%s.yaml", Name)) err = os.WriteFile(configFilePath, data, os.ModePerm) if err != nil { return err } - dirs := []string{BootBundleManifestDir, BootBundleImagesDir, BootBundleChartsDir} + dirs := []string{BootBundleManifestDir, BootBundleChartsDir, BootBundleImagesDir} for _, d := range dirs { err := os.Mkdir(filepath.Join(b.Name, d), os.ModePerm) + if !os.IsExist(err) && err != nil { + return err + } + } + + return nil +} + +func (b BootBundle) Update(ctx context.Context) error { + imgs, err := image.NormalizeImages(b.Images) + if err != nil { + return err + } + + if len(imgs) > 0 { + logrus.Infof("saving images...") + c, _ := image.NewClient() + o := image.Options{} + err := c.SaveOCI(ctx, imgs, filepath.Join(b.Name, "images"), o) if err != nil { return err } @@ -65,3 +126,82 @@ func (b BootBundle) Save() error { return nil } + +func (b BootBundle) Save(ctx context.Context) error { + tmpdir, err := os.MkdirTemp("", "hauler") + if err != nil { + return err + } + defer os.RemoveAll(tmpdir) + + dirs := []string{b.imagesPath(""), b.staticPath(""), b.manifestsPath("")} + for _, d := range dirs { + err := os.MkdirAll(filepath.Join(tmpdir, d), os.ModePerm) + if !os.IsExist(err) && err != nil { + return err + } + } + + //Save images from layout to single tarball + imgRefs := make(map[name.Reference]v1.Image) + li, err := layout.ImageIndexFromPath(filepath.Join(b.Name, "images")) + im, err := li.IndexManifest() + for _, m := range im.Manifests { + i, err := li.Image(m.Digest) + if err != nil { + return err + } + + ref, err := name.ParseReference(m.Annotations["name"]) + if err != nil { + return err + } + + imgRefs[ref] = i + } + + err = tarball.MultiRefWriteToFile(filepath.Join(b.imagesPath(tmpdir), "images.tar"), imgRefs) + if err != nil { + return err + } + + //TODO: Make this more robust, right now just copy/paste pre-packaged charts + chartsPath := filepath.Join(b.Name, "charts") + err = copy.Copy(chartsPath, b.staticPath(tmpdir)) + if err != nil { + return err + } + + //TODO: Make this more robust, right now just copy/paste manifests + manifestsPath := filepath.Join(b.Name, "manifests") + err = copy.Copy(manifestsPath, b.manifestsPath(tmpdir)) + if err != nil { + return err + } + + //TODO: Centralize this + zstd := archiver.NewTarZstd() + zstd.OverwriteExisting = true + err = zstd.Archive([]string{tmpdir}, fmt.Sprintf("%s.bundle.tar.zst", b.Name)) + if err != nil { + return err + } + + return nil +} + +func (b BootBundle) imagesPath(root string) string { + return filepath.Join(root, "agent", "images", "hauler") +} + +func (b BootBundle) staticPath(root string) string { + return filepath.Join(root, "server", "static", "hauler") +} + +func (b BootBundle) manifestsPath(root string) string { + return filepath.Join(root, "server", "manifests", "hauler") +} + +func (b BootBundle) RefMap() map[name.Reference]v1.Image { + return nil +} \ No newline at end of file diff --git a/pkg/apis/hauler.cattle.io/v1beta1/driver.go b/pkg/apis/hauler.cattle.io/v1beta1/driver.go new file mode 100644 index 0000000..057d777 --- /dev/null +++ b/pkg/apis/hauler.cattle.io/v1beta1/driver.go @@ -0,0 +1,6 @@ +package v1beta1 + +type Driver interface { + Name() string + Images() ([]string, error) +} diff --git a/pkg/apis/hauler.cattle.io/v1beta1/k3s.go b/pkg/apis/hauler.cattle.io/v1beta1/k3s.go new file mode 100644 index 0000000..f1db171 --- /dev/null +++ b/pkg/apis/hauler.cattle.io/v1beta1/k3s.go @@ -0,0 +1,45 @@ +package v1beta1 + +import ( + "fmt" + "github.com/rancherfederal/hauler/pkg/util" + "net/http" + "net/url" + "os" +) + +const ( + K3sDriverName = "k3s" + K3sExecutable = "k3s" + + K3sDefaultReleasesURL = "https://github.com/k3s-io/k3s/releases/download" + K3sDefaultVersion = "v1.21.1+k3s1" +) + +type K3sDriver struct { + Type string `json:"type"` + Version string `json:"version"` + + Config K3sConfig `json:"config"` +} + +type K3sConfig struct { + NodeName string `json:"node-name"` + Selinux bool `json:"selinux"` + KubeConfigMode os.FileMode `json:"write-kubeconfig-mode"` +} + +func (k K3sDriver) Name() string { return K3sDriverName } +func (k K3sDriver) Images() ([]string, error) { + u, err := url.Parse(fmt.Sprintf("%s/%s/%s-images.txt", K3sDefaultReleasesURL, k.Version, k.Name)) + if err != nil { + return nil, fmt.Errorf("error building %s url", k.Name) + } + + resp, err := http.Get(u.String()) + if err != nil { + return nil, err + } + defer resp.Body.Close() + return util.LinesToSlice(resp.Body) +} \ No newline at end of file diff --git a/pkg/bundle/boot/boot.go b/pkg/bundle/boot/boot.go new file mode 100644 index 0000000..841d48e --- /dev/null +++ b/pkg/bundle/boot/boot.go @@ -0,0 +1,70 @@ +package boot + +import ( + "context" + "fmt" + "github.com/rancherfederal/hauler/pkg/bundle/image" + "github.com/rancherfederal/hauler/pkg/util" + "net/http" + "net/url" + "path/filepath" +) + +const ( + bootCfgFile = "boot.bundle.json" +) + +type Bundle struct { + Name string `json:"name"` + Images []string `json:"images,omitempty"` + Charts []string `json:"charts,omitempty"` + + Driver K3sDriver `json:"driver"` + + imageBundle *image.Bundle +} + +func (b Bundle) GetName() string { return b.Name } + +func (b Bundle) Sync(ctx context.Context, path string) error { + driverImages, err := b.Driver.Images() + if err != nil { + return err + } + + bundleImages := append(driverImages, b.Images...) + + //TODO: There's a better way to do this + b.imageBundle = &image.Bundle{ Images: bundleImages } + + err = b.imageBundle.Sync(ctx, filepath.Join(path, "images")) + if err != nil { + return err + } + + return nil +} + +//Relocate will move all the necessary driver artifacts into their appropriate places on the host system +func (b Bundle) Install(src string) error { + return nil +} + +type K3sDriver struct { + Version string +} + +func (k K3sDriver) Name() string { return "k3s" } +func (k K3sDriver) Images() ([]string, error) { + u, err := url.Parse(fmt.Sprintf("%s/%s/%s-images.txt", "https://github.com/k3s-io/k3s/releases/download", k.Version, k.Name())) + if err != nil { + return nil, fmt.Errorf("error building k3s url") + } + + resp, err := http.Get(u.String()) + if err != nil { + return nil, err + } + defer resp.Body.Close() + return util.LinesToSlice(resp.Body) +} \ No newline at end of file diff --git a/pkg/bundle/bundle.go b/pkg/bundle/bundle.go new file mode 100644 index 0000000..4182721 --- /dev/null +++ b/pkg/bundle/bundle.go @@ -0,0 +1,29 @@ +package bundle + +import ( + "context" + "io/ioutil" + "os" + "path/filepath" +) + +type Bundle interface { + //Sync + Sync(context.Context, string) error +} + +//Path represents a Bundle layout rooted in a filesystem +type Path string + +func (p Path) Path(elem ...string) string { + full := []string{string(p)} + return filepath.Join(append(full, elem...)...) +} + +//WriteFile is a helper function to write arbitrary data to path +func (p Path) WriteFile(name string, data []byte, perm os.FileMode) error { + if err := os.MkdirAll(p.Path(), os.ModePerm); err != nil && !os.IsExist(err) { + return err + } + return ioutil.WriteFile(p.Path(name), data, perm) +} diff --git a/pkg/bundle/doc.go b/pkg/bundle/doc.go new file mode 100644 index 0000000..5992d19 --- /dev/null +++ b/pkg/bundle/doc.go @@ -0,0 +1 @@ +package bundle \ No newline at end of file diff --git a/pkg/bundle/image/image.go b/pkg/bundle/image/image.go new file mode 100644 index 0000000..e74363d --- /dev/null +++ b/pkg/bundle/image/image.go @@ -0,0 +1,80 @@ +package image + +import ( + "context" + "github.com/google/go-containerregistry/pkg/authn" + "github.com/google/go-containerregistry/pkg/name" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/empty" + "github.com/google/go-containerregistry/pkg/v1/layout" + "github.com/google/go-containerregistry/pkg/v1/match" + "github.com/google/go-containerregistry/pkg/v1/remote" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/sirupsen/logrus" + "os" + "path/filepath" +) + +type Bundle struct { + Name string `json:"name"` + Images []string `json:"images,omitempty"` +} + +func (i Bundle) layout(path string) (layout.Path, error) { + p, err := layout.FromPath(path) + if os.IsNotExist(err) { + p, err = layout.Write(path, empty.Index) + if err != nil { + return "", err + } + } + return p, nil +} + +//Sync will ensure the image bundle is synchronized with the filesystem at path provided +func (i Bundle) Sync(ctx context.Context, path string) error { + lp, err := i.layout(filepath.Join(path, "layout")) + if err != nil { + return err + } + + for _, image := range i.Images { + logrus.Infof("storing %s", image) + ref, err := name.ParseReference(image) + if err != nil { + return err + } + + img, err := remote.Image(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain)) + if err != nil { + return err + } + + annotations := make(map[string]string) + annotations[ocispec.AnnotationRefName] = ref.Name() + + //TODO: Address all errors at the end? + err = i.add(lp, img, layout.WithAnnotations(annotations)) + if err != nil { + return err + } + } + + return nil +} + +//Add is a wrapper around layout.Append and layout.Replace to ensure images are added to layout idempotently +func (i Bundle) add(l layout.Path, img v1.Image, options ...layout.Option) error { + d, err := img.Digest() + if err != nil { + return err + } + + m := match.Digests(d) + + return l.ReplaceImage(img, m, options...) +} + +func (i Bundle) Relocate() error { + return nil +} \ No newline at end of file diff --git a/pkg/bundle/image/testdata/blobs/sha256/540db60ca9383eac9e418f78490994d0af424aab7bf6d0e47ac8ed4e2e9bcbba b/pkg/bundle/image/testdata/blobs/sha256/540db60ca9383eac9e418f78490994d0af424aab7bf6d0e47ac8ed4e2e9bcbba new file mode 100644 index 0000000..f301fc6 Binary files /dev/null and b/pkg/bundle/image/testdata/blobs/sha256/540db60ca9383eac9e418f78490994d0af424aab7bf6d0e47ac8ed4e2e9bcbba differ diff --git a/pkg/bundle/image/testdata/blobs/sha256/6dbb9cc54074106d46d4ccb330f2a40a682d49dda5f4844962b7dce9fe44aaec b/pkg/bundle/image/testdata/blobs/sha256/6dbb9cc54074106d46d4ccb330f2a40a682d49dda5f4844962b7dce9fe44aaec new file mode 100644 index 0000000..21b9526 --- /dev/null +++ b/pkg/bundle/image/testdata/blobs/sha256/6dbb9cc54074106d46d4ccb330f2a40a682d49dda5f4844962b7dce9fe44aaec @@ -0,0 +1 @@ +{"architecture":"amd64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh"],"Image":"sha256:d3d4554f8b07cf59894bfb3551e10f89a559b24ee0992c4900c54175596b1389","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"60a3cdd128a8b373b313ed3e1083ff45e6badaad5dca5187282b005c38d04712","container_config":{"Hostname":"60a3cdd128a8","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/bin/sh\"]"],"Image":"sha256:d3d4554f8b07cf59894bfb3551e10f89a559b24ee0992c4900c54175596b1389","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2021-04-14T19:19:39.643236135Z","docker_version":"19.03.12","history":[{"created":"2021-04-14T19:19:39.267885491Z","created_by":"/bin/sh -c #(nop) ADD file:8ec69d882e7f29f0652d537557160e638168550f738d0d49f90a7ef96bf31787 in / "},{"created":"2021-04-14T19:19:39.643236135Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:b2d5eeeaba3a22b9b8aa97261957974a6bd65274ebd43e1d81d0a7b8b752b116"]}} \ No newline at end of file diff --git a/pkg/bundle/image/testdata/blobs/sha256/92f8b3f0730fef84ba9825b3af6ad90de454c4c77cde732208cf84ff7dd41208 b/pkg/bundle/image/testdata/blobs/sha256/92f8b3f0730fef84ba9825b3af6ad90de454c4c77cde732208cf84ff7dd41208 new file mode 100644 index 0000000..42e5d42 Binary files /dev/null and b/pkg/bundle/image/testdata/blobs/sha256/92f8b3f0730fef84ba9825b3af6ad90de454c4c77cde732208cf84ff7dd41208 differ diff --git a/pkg/bundle/image/testdata/blobs/sha256/d3cd072556c21c1f1940bd536675b97d7d419a2287d6bb3bd5044ea7466db788 b/pkg/bundle/image/testdata/blobs/sha256/d3cd072556c21c1f1940bd536675b97d7d419a2287d6bb3bd5044ea7466db788 new file mode 100644 index 0000000..abc73f1 --- /dev/null +++ b/pkg/bundle/image/testdata/blobs/sha256/d3cd072556c21c1f1940bd536675b97d7d419a2287d6bb3bd5044ea7466db788 @@ -0,0 +1 @@ +{"architecture":"amd64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["sh"],"Image":"sha256:6d9f95301d7c0f104d09993ddf1f91b5c34f33f0b766a51104eab48b08ed5829","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"4a5b57c70c4dcae582bc7424a1b3f2870f696739c3adf974b1471f63f72e7c00","container_config":{"Hostname":"4a5b57c70c4d","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"sh\"]"],"Image":"sha256:6d9f95301d7c0f104d09993ddf1f91b5c34f33f0b766a51104eab48b08ed5829","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2021-05-17T22:19:41.415620059Z","docker_version":"19.03.12","history":[{"created":"2021-05-17T22:19:41.221281057Z","created_by":"/bin/sh -c #(nop) ADD file:c423dc64e02718dd363f6eb4926ae165411ff45c985aad898da690f8f00abc49 in / "},{"created":"2021-05-17T22:19:41.415620059Z","created_by":"/bin/sh -c #(nop) CMD [\"sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:d0d0905d7be4eff6a63efe4a38647a679de1e024101f67db4fe4b5736c1e7f48"]}} \ No newline at end of file diff --git a/pkg/bundle/image/testdata/blobs/sha256/def822f9851ca422481ec6fee59a9966f12b351c62ccb9aca841526ffaa9f748 b/pkg/bundle/image/testdata/blobs/sha256/def822f9851ca422481ec6fee59a9966f12b351c62ccb9aca841526ffaa9f748 new file mode 100644 index 0000000..ae5e2e2 --- /dev/null +++ b/pkg/bundle/image/testdata/blobs/sha256/def822f9851ca422481ec6fee59a9966f12b351c62ccb9aca841526ffaa9f748 @@ -0,0 +1,16 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "size": 1472, + "digest": "sha256:6dbb9cc54074106d46d4ccb330f2a40a682d49dda5f4844962b7dce9fe44aaec" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 2811969, + "digest": "sha256:540db60ca9383eac9e418f78490994d0af424aab7bf6d0e47ac8ed4e2e9bcbba" + } + ] +} \ No newline at end of file diff --git a/pkg/bundle/image/testdata/blobs/sha256/f3cfc9d0dbf931d3db4685ec659b7ac68e2a578219da4aae65427886e649b06b b/pkg/bundle/image/testdata/blobs/sha256/f3cfc9d0dbf931d3db4685ec659b7ac68e2a578219da4aae65427886e649b06b new file mode 100644 index 0000000..674497a --- /dev/null +++ b/pkg/bundle/image/testdata/blobs/sha256/f3cfc9d0dbf931d3db4685ec659b7ac68e2a578219da4aae65427886e649b06b @@ -0,0 +1,16 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "config": { + "mediaType": "application/vnd.docker.container.image.v1+json", + "size": 1457, + "digest": "sha256:d3cd072556c21c1f1940bd536675b97d7d419a2287d6bb3bd5044ea7466db788" + }, + "layers": [ + { + "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", + "size": 766640, + "digest": "sha256:92f8b3f0730fef84ba9825b3af6ad90de454c4c77cde732208cf84ff7dd41208" + } + ] +} \ No newline at end of file diff --git a/pkg/bundle/image/testdata/index.json b/pkg/bundle/image/testdata/index.json new file mode 100755 index 0000000..25dfe3d --- /dev/null +++ b/pkg/bundle/image/testdata/index.json @@ -0,0 +1,23 @@ +{ + "schemaVersion": 2, + "manifests": [ + { + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "size": 527, + "digest": "sha256:f3cfc9d0dbf931d3db4685ec659b7ac68e2a578219da4aae65427886e649b06b", + "platform": { + "architecture": "amd64", + "os": "linux" + } + }, + { + "mediaType": "application/vnd.docker.distribution.manifest.v2+json", + "size": 528, + "digest": "sha256:def822f9851ca422481ec6fee59a9966f12b351c62ccb9aca841526ffaa9f748", + "platform": { + "architecture": "amd64", + "os": "linux" + } + } + ] +} \ No newline at end of file diff --git a/pkg/bundle/image/testdata/oci-layout b/pkg/bundle/image/testdata/oci-layout new file mode 100755 index 0000000..224a869 --- /dev/null +++ b/pkg/bundle/image/testdata/oci-layout @@ -0,0 +1,3 @@ +{ + "imageLayoutVersion": "1.0.0" +} \ No newline at end of file diff --git a/pkg/create/create.go b/pkg/create/create.go deleted file mode 100644 index a1c64f7..0000000 --- a/pkg/create/create.go +++ /dev/null @@ -1,99 +0,0 @@ -package create - -import ( - "context" - "fmt" - "github.com/mholt/archiver/v3" - "github.com/rancherfederal/hauler/pkg/apis/bundle" - "github.com/sirupsen/logrus" - "gopkg.in/yaml.v3" - "os" - "path/filepath" - - "github.com/rancherfederal/hauler/pkg/apis/driver" - "github.com/rancherfederal/hauler/pkg/apis/haul" - "github.com/rancherfederal/hauler/pkg/fetcher" -) - -type Creator struct{} - -func NewCreator() (*Creator, error) { - return &Creator{}, nil -} - -func (c Creator) Create(ctx context.Context, h haul.Haul) error { - tmpdir, err := os.MkdirTemp("", "hauler") - if err != nil { - return err - } - defer os.Remove(tmpdir) - - layout := h.CreateLayout(tmpdir) - if err := layout.Create(); err != nil { - return err - } - - err = saveDriverExecutable(ctx, h.Spec.Driver, tmpdir) - if err != nil { - return err - } - - for _, b := range h.Spec.Bundles { - logrus.Infof("Packaging bundle %s", b.Name) - - err = b.ResolveBundleFromPath() - if err != nil { - return err - } - - bundlePath := filepath.Join(tmpdir, "bundles", b.Name) - bl := b.CreateLayout(bundlePath) - if err := bl.Create(); err != nil { - return err - } - - imagesPath := filepath.Join(bundlePath, bundle.ImagePreloadDirectory, fmt.Sprintf("%s.tar", b.Name)) - err = SavePreloadImages(ctx, b.Images, imagesPath) - if err != nil { - return err - } - } - - if data, err := yaml.Marshal(h); err != nil { - return err - } else { - haulerConfigPath := filepath.Join(tmpdir, "hauler.yaml") - err = os.WriteFile(haulerConfigPath, data, os.ModePerm) - if err != nil { - return err - } - } - - zstd := archiver.NewTarZstd() - zstd.OverwriteExisting = true - err = layout.Archive(zstd, h.Metadata.Name) - if err != nil { - return err - } - - return nil -} - -func saveDriverExecutable(ctx context.Context, d driver.Driver, dir string) error { - rawUrl := fmt.Sprintf("%s/%s", d.ReleaseArtifactsURL(), d.Name()) - - f := fetcher.FileFetcher{} - dst := filepath.Join(dir, driver.ExecutableBin, driver.K3sExecutable) - - err := f.Get(ctx, rawUrl, dst) - if err != nil { - return err - } - - err = os.Chmod(dst, 0755) - if err != nil { - return err - } - - return nil -} diff --git a/pkg/create/preload.go b/pkg/create/preload.go deleted file mode 100644 index bbcdf13..0000000 --- a/pkg/create/preload.go +++ /dev/null @@ -1,37 +0,0 @@ -package create - -import ( - "context" - "github.com/google/go-containerregistry/pkg/authn" - "github.com/google/go-containerregistry/pkg/name" - v1 "github.com/google/go-containerregistry/pkg/v1" - "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/google/go-containerregistry/pkg/v1/tarball" -) - -func SavePreloadImages(ctx context.Context, images []string, archivePath string) error { - imageRefs := make(map[name.Reference]v1.Image) - - for _, image := range images { - ref, err := name.ParseReference(image) - if err != nil { - return err - } - - img, err := remote.Image(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain)) - if err != nil { - return err - } - - imageRefs[ref] = img - } - - if len(images) == 0 { - return nil - } - - if err := tarball.MultiRefWriteToFile(archivePath, imageRefs); err != nil { - return err - } - return nil -} diff --git a/pkg/fetcher/fetcher.go b/pkg/fetcher/fetcher.go deleted file mode 100644 index a7db03e..0000000 --- a/pkg/fetcher/fetcher.go +++ /dev/null @@ -1,9 +0,0 @@ -package fetcher - -import "context" - -type fetcher struct {} - -type Fetcher interface { - Get(context.Context, string, string) error -} \ No newline at end of file diff --git a/pkg/fetcher/file.go b/pkg/fetcher/file.go deleted file mode 100644 index 744acba..0000000 --- a/pkg/fetcher/file.go +++ /dev/null @@ -1,47 +0,0 @@ -package fetcher - -import ( - "context" - "fmt" - "github.com/pterm/pterm" - "io" - "net/http" - "net/url" - "os" - "strings" -) - -type FileFetcher struct { - fetcher -} - -func (f FileFetcher) Get(ctx context.Context, src string, dst string) error { - out, err := os.Create(dst) - if err != nil { - return fmt.Errorf("creating file: %w", err) - } - defer out.Close() - - spinner, _ := pterm.DefaultSpinner.Start("Fetching ", src, " and saving to ", dst) - resp, err := http.Get(src) - if err != nil { - return fmt.Errorf("getting file: %w", err) - } - defer resp.Body.Close() - - _, err = io.Copy(out, resp.Body) - - spinner.Success("Finished fetching ", src) - return err -} - -func GetFileNameFromURL(rawurl string) string { - u, err := url.Parse(rawurl) - if err != nil { - fmt.Errorf("nop %v", err) - } - - path := u.Path - segments := strings.Split(path, "/") - return segments[len(segments)-1] -} \ No newline at end of file diff --git a/pkg/fetcher/file_test.go b/pkg/fetcher/file_test.go deleted file mode 100644 index 176eb89..0000000 --- a/pkg/fetcher/file_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package fetcher - -import "testing" - -func TestGetFileNameFromURL(t *testing.T) { - type args struct { - furl string - } - tests := []struct { - name string - args args - want string - }{ - { - name: "shouldn't need extension", - args: args{ - furl: "https://github.com/k3s-io/k3s/releases/download/v1.21.1%2Bk3s1/k3s", - }, - want: "k3s", - }, - { - name: "should work with extension", - args: args{ - furl: "https://github.com/k3s-io/k3s/releases/download/v1.21.1%2Bk3s1/k3s-airgap-images-arm.tar.zst", - }, - want: "k3s-airgap-images-arm.tar.zst", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := GetFileNameFromURL(tt.args.furl); got != tt.want { - t.Errorf("GetFileNameFromURL() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/pkg/fetcher/git.go b/pkg/fetcher/git.go deleted file mode 100644 index 5799576..0000000 --- a/pkg/fetcher/git.go +++ /dev/null @@ -1,27 +0,0 @@ -package fetcher - -import ( - "context" - "github.com/sirupsen/logrus" - "github.com/go-git/go-git/v5" - "os" -) - -type GitFetcher struct { - fetcher - Bare bool -} - -func (f GitFetcher) Get(ctx context.Context, src string, dst string) error { - logrus.Infof("Cloning %s to %s", src, dst) - - _, err := git.PlainCloneContext(ctx, dst, f.Bare, &git.CloneOptions{ - URL: src, - Progress: os.Stdout, - }) - if err != nil { - return err - } - - return nil -} diff --git a/pkg/fetcher/image.go b/pkg/fetcher/image.go deleted file mode 100644 index 7c6020b..0000000 --- a/pkg/fetcher/image.go +++ /dev/null @@ -1,35 +0,0 @@ -package fetcher - -import ( - "context" - - "github.com/google/go-containerregistry/pkg/authn" - "github.com/google/go-containerregistry/pkg/name" - "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/sirupsen/logrus" -) - -type ImageFetcher struct { - fetcher -} - -func (f ImageFetcher) Get(ctx context.Context, src string, dst string) error { - logrus.Infof("Saving remote image %s to local path %s", src, dst) - - ref, err := name.ParseReference(src) - if err != nil { - return err - } - - img, err := remote.Image(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain)) - if err != nil { - return err - } - - // TODO - _ = img - - //if err := tarball.MultiRefWriteToFile() - - return nil -} diff --git a/pkg/fetcher/image/image.go b/pkg/fetcher/image/image.go deleted file mode 100644 index 4c216ad..0000000 --- a/pkg/fetcher/image/image.go +++ /dev/null @@ -1,111 +0,0 @@ -package image - -import ( - "context" - "fmt" - "github.com/containers/image/v5/signature" - "github.com/containers/image/v5/transports/alltransports" - "github.com/containers/image/v5/types" - "github.com/containers/image/v5/copy" - "os" -) - -type Fetcher interface { - Save() error -} - -type client struct { - policyContext *signature.PolicyContext -} - -func NewClient() (*client, error) { - p, err := DefaultPolicyContext() - if err != nil { - return nil, err - } - - c := &client{ - policyContext: p, - } - - return c, nil -} - -func (c client) Save(ctx context.Context, src string, dest string) error { - srcCtx := DefaultSystemContext() - destCtx := DefaultSystemContext() - - srcRef, err := alltransports.ParseImageName(fmt.Sprintf("docker://%s", src)) - if err != nil { - return err - } - - destRef, err := alltransports.ParseImageName(fmt.Sprintf("oci-archive:%s", dest)) - if err != nil { - return err - } - - manifest, err := copy.Image(ctx, c.policyContext, destRef, srcRef, ©.Options{ - RemoveSignatures: false, - SignBy: "", - ReportWriter: os.Stdout, - SourceCtx: srcCtx, - DestinationCtx: destCtx, - ProgressInterval: 0, - Progress: nil, - ForceManifestMIMEType: "", - //ImageListSelection: copy.CopySpecificImages, - Instances: nil, - }) - if err != nil { - return err - } - - _ = manifest - - return nil -} - -func DefaultSystemContext() *types.SystemContext { - ctx := &types.SystemContext{ - RegistriesDirPath: "", - SystemRegistriesConfPath: "", - //AuthFilePath: "", - ArchitectureChoice: "amd64", - OSChoice: "linux", - //VariantChoice: "amd", - BigFilesTemporaryDir: "", - OCIInsecureSkipTLSVerify: false, - OCISharedBlobDirPath: "", - OCIAcceptUncompressedLayers: false, - DockerCertPath: "", - DockerPerHostCertDirPath: "", - DockerInsecureSkipTLSVerify: 0, - DockerAuthConfig: nil, - DockerBearerRegistryToken: "", - DockerRegistryUserAgent: "", - DockerDisableV1Ping: false, - DockerDisableDestSchema1MIMETypes: false, - DockerLogMirrorChoice: false, - OSTreeTmpDirPath: "", - DockerDaemonCertPath: "", - DockerDaemonHost: "", - DockerDaemonInsecureSkipTLSVerify: false, - DirForceCompress: false, - CompressionFormat: nil, - CompressionLevel: nil, - } - - return ctx -} - -func DefaultPolicyContext() (*signature.PolicyContext, error) { - var policy *signature.Policy - - policy, err := signature.DefaultPolicy(nil) - if err != nil { - return nil, err - } - - return signature.NewPolicyContext(policy) -} \ No newline at end of file diff --git a/pkg/packager/packager.go b/pkg/packager/packager.go new file mode 100644 index 0000000..c453186 --- /dev/null +++ b/pkg/packager/packager.go @@ -0,0 +1,50 @@ +package packager + +import ( + "fmt" + "github.com/mholt/archiver/v3" + "github.com/rancherfederal/hauler/pkg/bundle" + "os" + "path/filepath" +) + +//Export packages a bundle to a compressed tarball +func Export(b bundle.Bundle, bundleDir string, name string) error { + z := newZstdArchiver() + + cwd, err := os.Getwd() + if err != nil { + return err + } + defer os.Chdir(cwd) + + if err = os.Chdir(bundleDir); err != nil { + return err + } + + exportFileName := filepath.Join(cwd, fmt.Sprintf("%s.%s", name, z.String())) + err = z.Archive([]string{"."}, exportFileName) + if err != nil { + return err + } + + return nil +} + +//Decompress will load a compressed archive bundle and unarchive it to dest +func Decompress(src string, dest string) error { + z := newZstdArchiver() + return z.Unarchive(src, dest) +} + +func newZstdArchiver() archiver.TarZstd { + return archiver.TarZstd{ + Tar: &archiver.Tar{ + OverwriteExisting: true, + MkdirAll: true, + ImplicitTopLevelFolder: false, + StripComponents: 0, + ContinueOnError: false, + }, + } +} \ No newline at end of file diff --git a/yaml/registry.yaml b/yaml/registry.yaml deleted file mode 100644 index bd14b21..0000000 --- a/yaml/registry.yaml +++ /dev/null @@ -1,169 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: registry - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: docker-registry - namespace: registry -data: - registry-config.yml: | - version: 0.1 - log: - fields: - service: registry - storage: - cache: - blobdescriptor: inmemory - filesystem: - rootdirectory: /var/lib/registry - http: - addr: :5000 - headers: - X-Content-Type-Options: [nosniff] - # auth: - # htpasswd: - # realm: basic-realm - # path: /auth/htpasswd - health: - storagedriver: - enabled: true - interval: 10s - threshold: 3 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - cattle.io/creator: norman - workload.user.cattle.io/workloadselector: deployment-registry-registry - name: registry - namespace: registry -spec: - replicas: 1 - selector: - matchLabels: - workload.user.cattle.io/workloadselector: deployment-registry-registry - template: - metadata: - labels: - workload.user.cattle.io/workloadselector: deployment-registry-registry - spec: - containers: - - image: registry:2 - imagePullPolicy: Always - name: registry - resources: {} - securityContext: - allowPrivilegeEscalation: false - capabilities: {} - privileged: false - readOnlyRootFilesystem: false - runAsNonRoot: false - stdin: true - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - tty: true - volumeMounts: - - mountPath: /var/lib/registry - name: registryvol - - name: config - mountPath: /etc/docker/registry - readOnly: true - dnsPolicy: ClusterFirst - restartPolicy: Always - schedulerName: default-scheduler - securityContext: {} - terminationGracePeriodSeconds: 30 - volumes: - - name: registryvol - persistentVolumeClaim: - claimName: registryvol - - name: config - configMap: - name: docker-registry - items: - - key: registry-config.yml - path: config.yml - ---- - -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - labels: - cattle.io/creator: norman - name: registryvol - namespace: registry -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi - - ---- - -apiVersion: v1 -kind: Service -metadata: - labels: - cattle.io/creator: norman - name: registrysvc - namespace: registry -spec: - ports: - - name: httpregistry - port: 5000 - protocol: TCP - targetPort: 5000 - selector: - workload.user.cattle.io/workloadselector: deployment-registry-registry - sessionAffinity: None - type: ClusterIP - ---- - -apiVersion: v1 -kind: Service -metadata: - labels: - cattle.io/creator: norman - foo: bar - name: registrynodeport - namespace: registry -spec: - ports: - - name: http - nodePort: 30500 - port: 5000 - protocol: TCP - targetPort: 5000 - selector: - workload.user.cattle.io/workloadselector: deployment-registry-registry - sessionAffinity: None - type: NodePort - ---- - -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - labels: - cattle.io/creator: norman - name: registryingress - namespace: registry -spec: - rules: - - host: registry - http: - paths: - - backend: - serviceName: registrysvc - servicePort: 5000 - pathType: ImplementationSpecific