Browse Source

Bugfixes to have working image build for registry.hcl

layerset
Till Wegmueller 3 years ago
parent
commit
8f6162da45
  1. 18
      cmd/imageadm/build.go
  2. 2
      cmd/imageadm/root.go
  3. 9
      go.sum
  4. 32
      host/build.go
  5. 214
      image/build/build.go
  6. 42
      image/build/config.go
  7. 154
      image/build/copy.go
  8. 6
      image/destroy.go
  9. 6
      image/global.go
  10. 5
      image/image.go
  11. 12
      image/oci.go
  12. 9
      image/oci/metadata_compat.go
  13. 16
      image/oci/tar_reader.go
  14. 22
      image/oci/tar_writer.go
  15. 16
      image/oci/writer.go
  16. 21
      image/unpack.go
  17. 15
      layer_ls.go
  18. 14
      supportfiles/image-build-files/registry.hcl
  19. 10
      supportfiles/image-build-files/registry/build-script.sh
  20. 52
      supportfiles/image-build-files/registry/go.mod
  21. 183
      supportfiles/image-build-files/registry/go.sum
  22. 22
      supportfiles/image-build-files/registry/main.go
  23. 37
      tar_ls.go
  24. 1
      volume/volume.go

18
cmd/imageadm/build.go

@ -27,24 +27,32 @@ var buildCmd = &cobra.Command{
return tracerr.Wrap(err)
}
opt := pod.Options{}
buildOpts := build.Opts{
Context: "./",
}
podOpts := pod.Options{}
if len(args) > 0 {
buildOpts.Context = args[0]
}
opt.MountSpecs, err = f.GetStringArray("mount")
podOpts.MountSpecs, err = f.GetStringArray("mount")
if err != nil {
return tracerr.Wrap(err)
}
opt.Labels, err = f.GetStringArray("label")
podOpts.Labels, err = f.GetStringArray("label")
if err != nil {
return tracerr.Wrap(err)
}
opt.Network, err = f.GetString("network")
podOpts.Network, err = f.GetString("network")
if err != nil {
return tracerr.Wrap(err)
}
return h.RunBuild(cfg, &opt)
return h.RunBuild(cfg, buildOpts, podOpts)
},
}

2
cmd/imageadm/root.go

@ -63,7 +63,7 @@ var RootCmd = &cobra.Command{
func Execute(version string) {
RootCmd.Version = version
if err := RootCmd.Execute(); err != nil {
if viper.GetBool("debug") {
if logrus.GetLevel() >= logrus.DebugLevel {
tracerr.PrintSource(err)
}
os.Exit(1)

9
go.sum

@ -41,8 +41,10 @@ git.wegmueller.it/toasterson/glog v0.0.0-20180725211246-3619df391249 h1:wOGVu7ex
git.wegmueller.it/toasterson/glog v0.0.0-20180725211246-3619df391249/go.mod h1:y11hBpN5HjKJd9MkVTLqohOaXxHB3SS0uejuF0IBhsY=
git.wegmueller.it/toasterson/uxfiletool v0.0.0-20170928184011-ba45dba7b5d7 h1:S2kMq8WD5+fUWN7kcKSe+aAEYYyOXc9z4mTeSnlTaQM=
git.wegmueller.it/toasterson/uxfiletool v0.0.0-20170928184011-ba45dba7b5d7/go.mod h1:0Vjau8VzCmFzO7IVOWvtxNHN6202i2oiAkqT60g9oP8=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible h1:KnPIugL51v3N3WwvaSmZbxukD1WuWXOiE9fRdu32f2I=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-autorest v10.8.1+incompatible h1:u0jVQf+a6k6x8A+sT60l6EY9XZu+kHdnZVPAYqpVRo0=
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg=
github.com/Azure/go-autorest/autorest v0.5.0/go.mod h1:9HLKlQjVBH6U3oDfsXOeVc56THsLPw1L03yban4xThw=
@ -87,6 +89,7 @@ github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195 h1:c4mLfegoDw6Oh
github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/aws/aws-sdk-go v1.15.11 h1:m45+Ru/wA+73cOZXiEGLDH2d9uLN3iHqMc0/z4noDXE=
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/aws/aws-sdk-go v1.23.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
@ -132,7 +135,9 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba h1:p6poVbjHDkKa+wtC8frBMwQtT3BmqGYBjzMwJ63tuR4=
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c h1:KJAnOBuY9cTKVqB5cfbynpvFgeHRTREkRk8C977oFu4=
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
@ -186,6 +191,7 @@ github.com/go-gitea/yaml v0.0.0-20170812160011-eb3733d160e7/go.mod h1:WjJPyqjAk/
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo=
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
@ -290,6 +296,7 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7 h1:SMvOWPJCES2GdFracYbBQh93GXac8fq7HeN6JnpduB8=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@ -333,6 +340,7 @@ github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDe
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=
github.com/marstr/guid v1.1.0 h1:/M4H/1G4avsieL6BbUwCOBzulmoeKVP5ux/3mQNnbyI=
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
@ -373,6 +381,7 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/ncw/swift v1.0.47 h1:4DQRPj35Y41WogBxyhOXlrI37nzGlyEcsforeudyYPQ=
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/nrdcg/auroradns v1.0.1/go.mod h1:y4pc0i9QXYlFCWrhWrUSIETnZgrf4KuwjDIWmmXo3JI=
github.com/nrdcg/dnspod-go v0.4.0/go.mod h1:vZSoFSFeQVm2gWLMkyX61LZ8HI3BaqtHZWgPTGKr6KQ=

32
host/build.go

@ -28,7 +28,7 @@ const buildHelperName = "buildhelper"
const helperPath = "/usr/lib/brand/pod/helpers/%s/" + buildHelperName
func (h *Host) RunBuild(cfg *build.ImageConfig, opts *pod.Options) error {
func (h *Host) RunBuild(cfg *build.ImageConfig, opts build.Opts, podOpts pod.Options) error {
buildImages := make(map[string]*image.Repository)
for _, imgCfg := range cfg.Images {
@ -39,7 +39,7 @@ func (h *Host) RunBuild(cfg *build.ImageConfig, opts *pod.Options) error {
nameRef := reference.NewReferenceString(imgCfg.Name)
logrus.Tracef("name reference for new image %s", nameRef)
container, err := h.CreateBuildContainer(imgCfg, opts)
container, err := h.CreateBuildContainer(imgCfg, &podOpts)
if err != nil {
return tracerr.Wrap(err)
}
@ -47,7 +47,7 @@ func (h *Host) RunBuild(cfg *build.ImageConfig, opts *pod.Options) error {
// Run all copy operations to get any files from other images the we might need
for _, op := range imgCfg.CopyOperations {
logrus.Debugf("copying %s from source Image %s", op.Name, op.SourceImage)
logrus.Infof("copying %s from source Image %s", op.Name, op.SourceImage)
srcRefString := reference.NewReferenceString(op.SourceImage)
srcRepository, ok := buildImages[srcRefString.String()]
@ -60,18 +60,23 @@ func (h *Host) RunBuild(cfg *build.ImageConfig, opts *pod.Options) error {
return fmt.Errorf("no tag named %s available in source Image", srcRefString.Tag)
}
layers := srcImage.GetLayers()
if err := srcImage.OpenLayers(); err != nil {
return tracerr.Wrap(err)
}
srcImgDS := image.GetLayerDS(layers[len(layers)-1])
err = build.CopyFilesBetweenImages(op, srcImgDS.VFSPath(), container.Path())
if err != nil {
parentLayer := srcImage.GetTopLayer()
if parentLayer.Dataset == nil {
return fmt.Errorf("error: layer %s of source image %s could not be opened: dataset is nil", parentLayer.Descriptor.Digest, srcImage.Name)
}
if err := build.CopyFilesBetweenImages(op, parentLayer.Dataset.VFSPath(), container.Path("root")); err != nil {
return tracerr.Wrap(err)
}
}
// Ensure all sources are copied into the container including extracted as path
if err := build.CopySourcesIntoZone(imgCfg, container.Zone.Zonepath, true); err != nil {
if err := build.CopySourcesIntoZone(imgCfg, container.Zone.Zonepath, true, opts); err != nil {
return tracerr.Wrap(err)
}
@ -332,11 +337,12 @@ func (h *Host) ExportToImage(ref reference.Reference, container *pod.Container,
logrus.Infof("saving volume metadata")
for iter, volBuildConfig := range imageConfig.Volumes {
vol := volume.Config{
Name: volBuildConfig.Name,
MountPath: volBuildConfig.Path,
Persist: volBuildConfig.Persist,
Backup: volBuildConfig.Backup,
Properties: volBuildConfig.Properties,
Name: volBuildConfig.Name,
Description: volBuildConfig.Description,
MountPath: volBuildConfig.Path,
Persist: volBuildConfig.Persist,
Backup: volBuildConfig.Backup,
Properties: volBuildConfig.Properties,
}
if vol.Name == "" {

214
image/build/build.go

@ -16,6 +16,59 @@ import (
"github.com/ztrue/tracerr"
)
type Opts struct {
Context string //Directory where sources are located
}
func downloadHTTPFunc(src SourceDescription) error {
tmpFile, err := ioutil.TempFile(os.TempDir(), ".sourceHTTP")
if err != nil {
return tracerr.Wrap(err)
}
resp, err := http.Get(src.Source)
defer func() {
_ = tmpFile.Close()
_ = os.Remove(tmpFile.Name())
_ = resp.Close
}()
if err != nil {
return tracerr.Wrap(err)
}
if _, err := io.Copy(tmpFile, resp.Body); err != nil {
return tracerr.Wrap(err)
}
if src.IsArchive {
logrus.Infof("Extracting archive into %s", src.Target)
compressor := oci.ArchiveCompressorNone
if strings.Contains(src.Source, "gz") {
compressor = oci.ArchiveCompressorGzip
}
rd, err := oci.NewTarReader(compressor, tmpFile.Name())
if err != nil {
return tracerr.Wrap(err)
}
if err = rd.ExtractTreeInto(src.Target); err != nil {
return tracerr.Wrap(err)
}
if err = rd.Close(); err != nil {
return tracerr.Wrap(err)
}
} else {
if _, err = fileutils.CopyFile(tmpFile.Name(), src.Target); err != nil {
return tracerr.Wrap(err)
}
}
return nil
}
func InstallSourcesInsideZone(config Image) error {
for _, src := range config.Sources {
switch src.Type {
@ -29,79 +82,46 @@ func InstallSourcesInsideZone(config Image) error {
return tracerr.Wrap(err)
}
if src.Target[len(src.Target)-1] == '/' || src.IsArchive {
if src.IsArchive {
logrus.Infof("Extracting archive %s to %s", src.Name, src.Target)
compressor := oci.ArchiveCompressorNone
if strings.Contains(src.Source, "gz") {
if strings.HasSuffix(src.Source, ".gz") {
compressor = oci.ArchiveCompressorGzip
}
rd, err := oci.NewTarReader(compressor, absSRC)
if err != nil {
return tracerr.Wrap(err)
}
if err = rd.ExtractTreeInto(src.Target); err != nil {
return tracerr.Wrap(err)
}
if err = rd.Close(); err != nil {
return tracerr.Wrap(err)
}
if err = os.Remove(src.Source); err != nil {
return tracerr.Wrap(err)
}
logrus.Info("successful")
}
case SourceTypeHttp:
f := func(src SourceDescription) error {
tmpFile, err := ioutil.TempFile(os.TempDir(), ".sourceHTTP")
if err != nil {
return tracerr.Wrap(err)
}
resp, err := http.Get(src.Source)
defer func() {
_ = tmpFile.Close()
_ = os.Remove(tmpFile.Name())
_ = resp.Close
}()
if err != nil {
return tracerr.Wrap(err)
}
if _, err := io.Copy(tmpFile, resp.Body); err != nil {
return tracerr.Wrap(err)
}
if src.IsArchive {
logrus.Infof("Extracting archive into %s", src.Target)
compressor := oci.ArchiveCompressorNone
if strings.Contains(src.Source, "gz") {
compressor = oci.ArchiveCompressorGzip
}
rd, err := oci.NewTarReader(compressor, tmpFile.Name())
if err != nil {
return tracerr.Wrap(err)
}
if err = rd.ExtractTreeInto(src.Target); err != nil {
return tracerr.Wrap(err)
}
if err = rd.Close(); err != nil {
return tracerr.Wrap(err)
}
} else {
if _, err = fileutils.CopyFile(tmpFile.Name(), src.Target); err != nil {
return tracerr.Wrap(err)
}
}
return nil
}
case SourceTypeHttp:
logrus.Infof("Downloading http(s) source %s from %s", src.Name, src.Source)
if err := f(src); err != nil {
return err
if err := downloadHTTPFunc(src); err != nil {
return tracerr.Wrap(err)
}
logrus.Info("successful")
case SourceTypeGit:
git, err := exec.LookPath("git")
if err != nil {
return tracerr.Wrap(err)
}
var repo, branch string
if idx := strings.Index(src.Source, "@"); idx >= 0 {
repo, branch = src.Source[:idx], src.Source[idx+1:]
@ -109,58 +129,72 @@ func InstallSourcesInsideZone(config Image) error {
repo = src.Source
branch = "master"
}
logrus.Infof("Cloning git repo %s", src.Source)
gitCmd := exec.Command(git, "clone", "--single-branch", "-b", branch, repo, src.Target)
if out, err := gitCmd.CombinedOutput(); err != nil {
logrus.Errorf("failed git clone %s", out)
return tracerr.Wrap(err)
}
logrus.Info("successful")
}
}
return nil
}
func CopySourcesIntoZone(config Image, zonepath string, allowLocal bool) error {
func CopySourcesIntoZone(config Image, zonepath string, allowLocal bool, buildOpts Opts) error {
for i, src := range config.Sources {
if !allowLocal {
logrus.Debugf("local file source not allowed on this host ignoring Source %s", src.Name)
return nil
}
switch src.Type {
case SourceTypeFile:
logrus.Infof("Copying local file %s into zonepath %s", src.Name, zonepath)
absSRC, err := filepath.Abs(src.Source)
absSRC, err := filepath.Abs(filepath.Join(buildOpts.Context, src.Source))
if err != nil {
return tracerr.Wrap(err)
}
if src.Target[len(src.Target)-1] == '/' || src.IsArchive {
if src.IsArchive {
if src.IsRoot {
//TODO move this code into the zone context by implementing podinit and empty container base
logrus.Infof("Extracting Rootfilesystem into %s, inside %s", src.Target, zonepath)
absTarget, err := filepath.Abs(zonepath + "/root/" + src.Target)
absTarget, err := filepath.Abs(filepath.Join(zonepath, "root", src.Target))
if err != nil {
return tracerr.Wrap(err)
}
compressor := oci.ArchiveCompressorNone
if strings.Contains(src.Source, "gz") {
compressor = oci.ArchiveCompressorGzip
}
rd, err := oci.NewTarReader(compressor, absSRC)
if err != nil {
return tracerr.Wrap(err)
}
if err = rd.ExtractTreeInto(absTarget); err != nil {
return tracerr.Wrap(err)
}
if err = rd.Close(); err != nil {
return tracerr.Wrap(err)
}
logrus.Info("successful")
} else {
logrus.Debugf("Copying archive %s into zonepath %s", src.Source, zonepath)
src.Source = fmt.Sprintf("/.sourceArchive.%d", i)
absTarget, err := filepath.Abs(zonepath + src.Source)
if strings.HasSuffix(src.Source, ".gz") {
src.Source = fmt.Sprintf("/.sourceArchive.%d.gz", i)
} else {
src.Source = fmt.Sprintf("/.sourceArchive.%d", i)
}
absTarget, err := filepath.Abs(filepath.Join(zonepath, "root", src.Source))
if err != nil {
return tracerr.Wrap(err)
}
@ -173,7 +207,7 @@ func CopySourcesIntoZone(config Image, zonepath string, allowLocal bool) error {
}
} else {
logrus.Debugf("Copying file %s into zonepath %s", src.Source, zonepath)
absTarget, err := filepath.Abs(zonepath + "/" + src.Target)
absTarget, err := filepath.Abs(filepath.Join(zonepath, "root", src.Target))
if err != nil {
return tracerr.Wrap(err)
}
@ -181,8 +215,47 @@ func CopySourcesIntoZone(config Image, zonepath string, allowLocal bool) error {
if _, err = fileutils.CopyFile(absSRC, absTarget); err != nil {
return tracerr.Wrap(err)
}
}
case SourceTypeDirectory:
// Create a tar archive of the directory and copy it into the zone
absSRC, err := filepath.Abs(filepath.Join(buildOpts.Context, src.Source))
if err != nil {
return tracerr.Wrap(err)
}
src.Source = fmt.Sprintf("/.sourceArchive.%d.tar.gz", i)
src.IsArchive = true
src.Type = SourceTypeFile
err = func() error {
f, err := os.Create(filepath.Join(zonepath, "root", src.Source))
if err != nil {
return tracerr.Wrap(err)
}
defer f.Close()
wr, err := oci.NewTarWriter(oci.ArchiveCompressorGzip, f)
if err != nil {
return err
}
if err := wr.AddTree(absSRC, src.Target); err != nil {
return err
}
if err := wr.Close(); err != nil {
return err
}
return nil
}()
if err != nil {
return tracerr.Wrap(err)
}
config.Sources[i] = src
}
}
return nil
@ -204,14 +277,15 @@ func CopyFilesBetweenImages(config CopyOperation, srcImagePath, destImagePath st
return tracerr.Wrap(err)
}
logrus.Debugf("Copying %s -> %s", absSRC, absTgt)
if _, err := fileutils.CopyFile(absSRC, absTgt); err != nil {
return tracerr.Wrap(err)
}
logrus.Debugf("Done")
return nil
}
//
func PerformActions(imageConfig Image) error {
for _, act := range imageConfig.Actions {
if act.Provide {
@ -227,7 +301,23 @@ func PerformActions(imageConfig Image) error {
if err != nil {
return tracerr.Wrap(err)
}
} else {
//Make non executable files executable. We assume that this was a user error
stat, err := os.Stat(cmdBin)
if err != nil && os.IsNotExist(err) {
logrus.Debugf("Tried to call nonexitent binary %s", cmdBin)
return tracerr.Wrap(err)
} else if err != nil {
return tracerr.Wrap(err)
}
if !IsExecAny(stat.Mode()) {
if err := os.Chmod(cmdBin, stat.Mode()|0111); err != nil {
return tracerr.Wrap(err)
}
}
}
cmd := exec.Command(cmdBin, cmdArg...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@ -237,6 +327,7 @@ func PerformActions(imageConfig Image) error {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
}
}
//OK to whoever got the idea that the locale should determine the encoding of any file you open with your program
// screw you. I am talking to you Python, Ruby and Perl....
cmd.Env = append(cmd.Env, "LANG=C.UTF-8")
@ -246,7 +337,24 @@ func PerformActions(imageConfig Image) error {
logrus.Error("failed")
return tracerr.Wrap(err)
}
logrus.Info("successful")
}
return nil
}
func IsExecOwner(mode os.FileMode) bool {
return mode&0100 != 0
}
func IsExecGroup(mode os.FileMode) bool {
return mode&0010 != 0
}
func IsExecOther(mode os.FileMode) bool {
return mode&0001 != 0
}
func IsExecAny(mode os.FileMode) bool {
return mode&0111 != 0
}

42
image/build/config.go

@ -1,6 +1,7 @@
package build
import (
"os"
"runtime"
"strings"
@ -15,6 +16,7 @@ type SourceDescriptionType int
const (
SourceTypeFile SourceDescriptionType = iota
SourceTypeDirectory
SourceTypeGit
SourceTypeHttp
)
@ -27,15 +29,50 @@ type ImageConfig struct {
func (c *ImageConfig) PostDecode() {
for idx, img := range c.Images {
for i, v := range img.Volumes {
if strings.Contains(v.Name, " ") {
v.Description = v.Name
v.Name = ""
img.Volumes[i] = v
}
}
for i, s := range img.Sources {
if strings.Contains(s.Source, "tar") {
if strings.Contains(s.Source, ".tar") {
s.IsArchive = true
img.Sources[i] = s
}
if strings.HasPrefix(s.Source, "http://") || strings.HasPrefix(s.Source, "https://") {
s.Type = SourceTypeHttp
}
if strings.HasPrefix(s.Source, "git@") || strings.HasSuffix(s.Source, ".git") {
s.Type = SourceTypeGit
}
if s.Source[len(s.Source)-1] == '/' {
s.Type = SourceTypeDirectory
}
if s.Type == SourceTypeFile {
stat, err := os.Stat(s.Source)
if err != nil {
continue
}
if stat.IsDir() {
s.Type = SourceTypeDirectory
}
}
img.Sources[i] = s
}
if img.OSFlavour == "" {
img.OSFlavour = runtime.GOOS
}
c.Images[idx] = img
}
}
@ -91,6 +128,7 @@ type User struct {
type VolumeConfig struct {
Name string `hcl:"name,optional"`
Description string `hcl:"description,optional"`
Path string `hcl:"path,label"`
Persist bool `hcl:"persist,optional"`
Backup bool `hcl:"backup,optional"`

154
image/build/copy.go

@ -0,0 +1,154 @@
/* MIT License
*
* Copyright (c) 2017 Roland Singer [roland.singer@desertbit.com]
* Copyright (c) 2020 Till Wegmüller [till.wegmueller@openflowlabs.com]
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package build
import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
)
// CopyFile copies the contents of the file named src to the file named
// by dst. The file will be created if it does not already exist. If the
// destination file exists, all it's contents will be replaced by the contents
// of the source file. The file mode will be copied from the source and
// the copied data is synced/flushed to stable storage.
func CopyFile(src, dst string) (err error) {
cleanSrc := filepath.Clean(src)
cleanDst := filepath.Clean(dst)
if cleanSrc == cleanDst {
return nil
}
in, err := os.Open(cleanSrc)
if err != nil {
return
}
defer in.Close()
if err := os.Remove(cleanDst); err != nil && !os.IsNotExist(err) {
return err
}
out, err := os.Create(cleanDst)
if err != nil {
return
}
defer func() {
if e := out.Close(); e != nil {
err = e
}
}()
_, err = io.Copy(out, in)
if err != nil {
return
}
err = out.Sync()
if err != nil {
return
}
si, err := os.Stat(src)
if err != nil {
return
}
err = os.Chmod(dst, si.Mode())
if err != nil {
return
}
return
}
// CopyDir recursively copies a directory tree, attempting to preserve permissions.
// Source directory must exist, destination directory must *not* exist.
// Symlinks are ignored and skipped.
func CopyDir(src string, dst string) (err error) {
src = filepath.Clean(src)
dst = filepath.Clean(dst)
si, err := os.Stat(src)
if err != nil {
return err
}
if !si.IsDir() {
return fmt.Errorf("source is not a directory")
}
dSi, err := os.Stat(dst)
if err != nil && !os.IsNotExist(err) {
return
}
if err == nil && !dSi.IsDir() {
return fmt.Errorf("destination already exists and is not a directory")
}
err = os.MkdirAll(dst, si.Mode())
if err != nil {
return
}
entries, err := ioutil.ReadDir(src)
if err != nil {
return
}
for _, entry := range entries {
srcPath := filepath.Join(src, entry.Name())
dstPath := filepath.Join(dst, entry.Name())
if entry.IsDir() {
err = CopyDir(srcPath, dstPath)
if err != nil {
return
}
} else {
// Skip anything but regular files
switch entry.Mode() & os.ModeType {
case os.ModeSocket,
os.ModeNamedPipe,
os.ModeSticky,
os.ModeExclusive,
os.ModeDevice,
os.ModeCharDevice,
os.ModeSymlink:
continue
}
err = CopyFile(srcPath, dstPath)
if err != nil {
return
}
}
}
return
}

6
image/destroy.go

@ -48,14 +48,10 @@ func (r *Repository) Destroy(imageRef *reference.Reference) error {
delete(r.LayerList, layer.Descriptor.Digest.Encoded())
}
}
ds := GetLayerDS(layer.Descriptor.Digest)
if ds == nil {
continue
}
// Delete the layer dataset.
logrus.Debugf("deleting layer dataset %s", layer.Descriptor.Digest)
if err := ds.Destroy(true); err != nil {
if err := layer.Dataset.Destroy(true); err != nil {
return tracerr.Wrap(err)
}
}

6
image/global.go

@ -11,6 +11,12 @@ import (
)
func GetLayerDS(digest digest.Digest) *zfs.Dataset {
// Reload the images dataset and try again
// this can happen if the Dataset has been opened for too long
if err := openImagesDataset(); err != nil {
return nil
}
for _, child := range imagesDataset.Children {
if child.GetName() == digest.Encoded() {
return &child

5
image/image.go

@ -170,6 +170,11 @@ func (i *Image) openLayer(l *Layer) error {
return nil
}
func (i *Image) GetTopLayer() Layer {
idx := len(i.Layers) - 1
return i.Layers[idx]
}
func (i *Image) GetLayers() []digest.Digest {
layers := make([]digest.Digest, 0)
for _, l := range i.Layers {

12
image/oci.go

@ -1,11 +1,10 @@
package image
import (
"fmt"
"git.wegmueller.it/opencloud/opencloud/image/oci"
"git.wegmueller.it/opencloud/opencloud/image/reference"
"github.com/opencontainers/go-digest"
"github.com/ztrue/tracerr"
)
func (r *Repository) NewOCIWriter() (*oci.Writer, error) {
@ -19,16 +18,19 @@ func (r *Repository) NewOCIReader() (*oci.Reader, error) {
func (r *Repository) ImportImageFromOCIDirectory(ref reference.Reference, manifestDigest digest.Digest, keepOCIFiles bool) error {
rd, err := r.NewOCIReader()
if err != nil {
return fmt.Errorf("could not open oci directory %s: %w", r.VFSPath(), err)
//return fmt.Errorf("could not open oci directory %s: %w", r.VFSPath(), err)
return tracerr.Wrap(err)
}
img, err := OpenImageFromOCIStorage(ref, manifestDigest, rd)
if err != nil {
return fmt.Errorf("could not import OCI image %s from known storage directory: %w", ref, err)
//return fmt.Errorf("could not import OCI image %s from known storage directory: %w", ref, err)
return tracerr.Wrap(err)
}
if err := img.UnpackLayers(rd, keepOCIFiles); err != nil {
return fmt.Errorf("failed to unpack layers: %w", err)
//return fmt.Errorf("failed to unpack layers: %w", err)
return tracerr.Wrap(err)
}
return r.AddImage(ref.Tag, img)

9
image/oci/metadata_compat.go

@ -6,6 +6,7 @@ import (
"io/ioutil"
"github.com/opencontainers/go-digest"
"github.com/ztrue/tracerr"
)
const (
@ -22,7 +23,13 @@ func (w *Writer) AddMetadata(label string, data interface{}) error {
return fmt.Errorf("could not marshal medatata %s: %w", label, err)
}
metadataDigest := digest.NewDigestFromBytes(w.algorithm, blob)
hasher := w.algorithm.Hash()
if _, err := hasher.Write(blob); err != nil {
return tracerr.Wrap(err)
}
metadataDigest := digest.NewDigestFromBytes(w.algorithm, hasher.Sum(nil))
if err := ioutil.WriteFile(w.GetBlobPath(metadataDigest.Encoded()), blob, 0644); err != nil {
return fmt.Errorf("could not write extra blob file %s: %w", metadataDigest, err)

16
image/oci/tar_reader.go

@ -78,27 +78,27 @@ func (tarReader *TarReader) ExtractTreeInto(dir string) error {
}
_, _ = io.Copy(ioutil.Discard, tarReader.archiveReader)
} else {
path := filepath.Join(dir, th.Name)
fileOrDirPath := filepath.Join(dir, th.Name)
switch th.Typeflag {
case tar.TypeDir:
logrus.Tracef("Extracting Directory %s", path)
if err := unpackDir(th, path); err != nil {
logrus.Tracef("Extracting Directory %s", fileOrDirPath)
if err := unpackDir(th, fileOrDirPath); err != nil {
return tracerr.Wrap(err)
}
case tar.TypeSymlink:
//Defer symlink creation to later to avoid file not exist errors
logrus.Tracef("Saving Symlink %s for later extraction", path)
logrus.Tracef("Saving Symlink %s for later extraction", fileOrDirPath)
symLinkList = append(symLinkList, *th)
case tar.TypeLink:
// Links must be created relative to dir in order to find a file that already exists
// Hardlinks are resolved at link time rather than symlinks which are resolved at runtime
logrus.Tracef("Extracting Hardlink %s", path)
if err := os.Link(filepath.Join(dir, th.Linkname), path); err != nil {
logrus.Tracef("Extracting Hardlink %s", fileOrDirPath)
if err := os.Link(filepath.Join(dir, th.Linkname), fileOrDirPath); err != nil {
return tracerr.Wrap(err)
}
case tar.TypeReg:
logrus.Tracef("Extracting File %s", path)
if err := unpackFile(th, tarReader.archiveReader, path); err != nil {
logrus.Tracef("Extracting File %s", fileOrDirPath)
if err := unpackFile(th, tarReader.archiveReader, fileOrDirPath); err != nil {
return tracerr.Wrap(err)
}
case tar.TypeChar, tar.TypeBlock:

22
image/oci/tar_writer.go

@ -201,6 +201,28 @@ func (tarWriter *TarWriter) AddEntry(realPath string, inImagePath string, info o
return nil
}
func (tarWriter *TarWriter) AddTree(path, targetBasePath string) error {
logrus.Debugf("packing directory %s as %s", path, targetBasePath)
if err := filepath.Walk(path, func(fPath string, info os.FileInfo, err error) error {
if err != nil {
return err
}
tPath := strings.ReplaceAll(fPath, path, "")
logrus.Debugf("Adding %s -> %s", fPath, filepath.Join(targetBasePath, tPath))
err = tarWriter.AddEntry(fPath, tPath, info, false)
if err != nil {
return err
}
return nil
}); err != nil {
return tracerr.Wrap(err)
}
return nil
}
func (tarWriter *TarWriter) WhiteoutFile(name string) error {
whName := filepath.Join(filepath.Dir(name), ".wh."+filepath.Base(name))
hdr := tar.Header{

16
image/oci/writer.go

@ -249,9 +249,14 @@ func (w *Writer) AddDiff(layer1 string, layer2 string) error {
}
err := filepath.Walk(layer1, func(path string, info os.FileInfo, err error) error {
//Do nothing with the root directory of the layer
inImagePath := strings.Replace(path, layer1+"/", "", -1)
if path == inImagePath {
return nil
}
//First check if file has been deleted
l2Path := strings.Replace(path, layer1, layer2, -1)
inImagePath := strings.Replace(path, layer1+"/", "", -1)
newstat, err := os.Lstat(l2Path)
if os.IsNotExist(err) {
//This means we whiteout the file in the new Layer
@ -292,10 +297,15 @@ func (w *Writer) AddDiff(layer1 string, layer2 string) error {
// Check for new Files only
err = filepath.Walk(layer2, func(path string, info os.FileInfo, err error) error {
//First check if file has been deleted
l1Path := strings.Replace(path, layer2, layer1, -1)
//Do nothing with the root directory of the layer
inImagePath := strings.Replace(path, layer2+"/", "", -1)
if path == inImagePath {
return nil
}
l1Path := strings.Replace(path, layer2, layer1, -1)
_, err = os.Lstat(l1Path)
//Check if the file does not exist in the previous layer
if os.IsNotExist(err) {
// Add new file to the layer
if err = w.clw.AddEntry(path, inImagePath, info, false); err != nil {

21
image/unpack.go

@ -29,6 +29,7 @@ func (i *Image) UnpackLayers(rd *oci.Reader, keepLayerFile bool) (Gerr error) {
for layerId, layer := range i.Layers {
if layer.Dataset != nil {
logrus.Debugf("Layer %s already unpacked skipping", layer.Descriptor.Digest)
continue
}
@ -40,17 +41,18 @@ func (i *Image) UnpackLayers(rd *oci.Reader, keepLayerFile bool) (Gerr error) {
}
if layerId == 0 {
logrus.Debugf("Unpacking topmost layer %s", layer.Descriptor.Digest)
var err error
layer.Dataset, err = imagesDataset.CreateChildDataset(layer.Descriptor.Digest.Encoded(), zfs.Properties{
zfs.PropertyCompression: zfs.CompressionLZ4,
})
layerDatasets = append(layerDatasets, layer.Dataset)
if err != nil {
return tracerr.Wrap(err)
}
logrus.Debugf("Dataset for layer %s successfully created", layer.Descriptor.Digest)
for _, vol := range i.Volumes {
vol, err := volume.CreateVolume(vol.Config, layer.Dataset)
if err != nil {
@ -66,7 +68,10 @@ func (i *Image) UnpackLayers(rd *oci.Reader, keepLayerFile bool) (Gerr error) {
}
i.Layers[layerId] = layer
logrus.Debugf("Volume datasets for layer %s successfully created", layer.Descriptor.Digest)
} else if parentLayer := i.Layers[layerId-1]; parentLayer.Dataset != nil {
logrus.Debugf("Cloning parent Layer %s to new dataset for unpacking", parentLayer.Descriptor.Digest)
snap, err := parentLayer.Dataset.GetSnapshot(config.SealSnapshotName)
if err != nil {
return tracerr.Wrap(err)
@ -77,6 +82,7 @@ func (i *Image) UnpackLayers(rd *oci.Reader, keepLayerFile bool) (Gerr error) {
}
layerDatasets = append(layerDatasets, layer.Dataset)
logrus.Debugf("Successfully created layer %s from parent %s", layer.Descriptor.Digest, parentLayer.Descriptor.Digest)
// First we go through all already added volumes and clone them into the new layer dataset new
for _, vol := range parentLayer.volumeList {
@ -109,8 +115,10 @@ func (i *Image) UnpackLayers(rd *oci.Reader, keepLayerFile bool) (Gerr error) {
}
i.Layers[layerId] = layer
logrus.Debugf("Successfully created volume datasets for layer %s", layer.Descriptor.Digest)
} else {
logrus.Debugf("Creating dataset for disjointed layer %s", layer.Descriptor.Digest)
var err error
layer.Dataset, err = imagesDataset.CreateChildDataset(layer.Descriptor.Digest.Encoded(), zfs.Properties{
zfs.PropertyCompression: zfs.CompressionLZ4,
@ -122,6 +130,7 @@ func (i *Image) UnpackLayers(rd *oci.Reader, keepLayerFile bool) (Gerr error) {
return tracerr.Wrap(err)
}
logrus.Debugf("Dataset for disjointed layer %s successfully created", layer.Descriptor.Digest)
for _, vol := range i.Volumes {
vol, err := volume.CreateVolume(vol.Config, layer.Dataset)
if err != nil {
@ -137,8 +146,10 @@ func (i *Image) UnpackLayers(rd *oci.Reader, keepLayerFile bool) (Gerr error) {
}
i.Layers[layerId] = layer
logrus.Debugf("Volume datasets for layer %s successfully created", layer.Descriptor.Digest)
}
logrus.Debugf("Extracting layer %s", layer.Descriptor.Digest)
layerReader, err := rd.GetLayerReader(layer.Descriptor)
if err != nil {
return tracerr.Wrap(err)
@ -149,11 +160,13 @@ func (i *Image) UnpackLayers(rd *oci.Reader, keepLayerFile bool) (Gerr error) {
return tracerr.Wrap(err)
}
logrus.Debugf("Sealing layer %s", layer.Descriptor.Digest)
_, err = layer.Dataset.Snapshot(config.SealSnapshotName)
if err != nil {
return tracerr.Wrap(err)
}
logrus.Debugf("Sealing volumes for layer %s", layer.Descriptor.Digest)
for _, vol := range layer.volumeList {
if err := vol.Seal(); err != nil {
return fmt.Errorf("could not seal volume %s: %w", vol.GetName(), err)
@ -165,10 +178,14 @@ func (i *Image) UnpackLayers(rd *oci.Reader, keepLayerFile bool) (Gerr error) {
return tracerr.Wrap(err)
}
logrus.Debugf("Successful")
if keepLayerFile {
continue
}
logrus.Debugf("Cleaning layer file for layer %s", layer.Descriptor.Digest)
if err := os.Remove(layerReader.GetFilePath()); err != nil {
return tracerr.Wrap(err)
}

15
layer_ls.go

@ -0,0 +1,15 @@
package main
import (
"fmt"
"git.wegmueller.it/opencloud/opencloud/config"
"git.wegmueller.it/opencloud/opencloud/image"
"github.com/spf13/viper"
)
func main() {
viper.SetDefault(config.HostDatasetConfigKey, "rpool/podhost")
c := image.GetLayerDS("sha256:8ffd5eb265e9c9f70c78ec1db9d1ec7f662c534fcbcf812422fac4790abe6e2f")
fmt.Println(c)
}

14
supportfiles/image-build-files/registry.hcl

@ -9,16 +9,18 @@ image "builders/registry" {
PATH = "/usr/sbin:/sbin:/usr/bin"
}
action "Download Registry From Git" {
cmd = "git clone https://github.com/docker/distribution.git /root/distribution"
source "Docker Distribution git" {
source = "https://github.com/docker/distribution.git"
target = "/root/distribution"
}
action "Get Custom main.go file" {
cmd = "wget -O /root/distribution/cmd/registry/main.go https://gist.githubusercontent.com/Toasterson/62b19dd85e4151561081391fa9987f51/raw/1c0e14a7480b0a29f469334b889969af9a48b497/main.go"
source "Add patches" {
source = "supportfiles/image-build-files/registry/"
target = "/root/distribution"
}
action "Build the registry binary" {
cmd = "go build -o /dest/registry /root/distribution/cmd/registry/main.go"
cmd = "/root/distribution/build-script.sh"
}
}
@ -41,7 +43,7 @@ image "aurora-opencloud/registry" {
}
volume "/var/lib/registry" {
name = "Registry layer directory"
description = "Registry layer directory"
}
expose = [ "5000" ]

10
supportfiles/image-build-files/registry/build-script.sh

@ -0,0 +1,10 @@
#!/usr/bin/bash -ex
export GO111MODULE=on
export GOCACHE=/gocache
export GOPATH=/go
export CGO_ENABLED=0
mkdir -p /dest
cd /root/distribution
mv main.go cmd/registry/main.go
go build -o /dest/registry ./cmd/registry/main.go

52
supportfiles/image-build-files/registry/go.mod

@ -0,0 +1,52 @@
module github.com/docker/distribution
go 1.12
require (
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible
github.com/Azure/go-autorest v10.8.1+incompatible // indirect
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d
github.com/aws/aws-sdk-go v1.15.11
github.com/bitly/go-simplejson v0.5.0 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/bshuster-repo/logrus-logstash-hook v0.4.1
github.com/bugsnag/bugsnag-go v1.5.3
github.com/bugsnag/panicwrap v1.2.0 // indirect
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c // indirect
github.com/dnaeon/go-vcr v1.0.1 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c
github.com/docker/go-metrics v0.0.1
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7
github.com/gofrs/uuid v3.2.0+incompatible // indirect
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33
github.com/gorilla/mux v1.7.2
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7 // indirect
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/marstr/guid v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.1.2
github.com/ncw/swift v1.0.47
github.com/opencontainers/go-digest v1.0.0-rc1
github.com/opencontainers/image-spec v1.0.1
github.com/satori/go.uuid v1.2.0 // indirect
github.com/sirupsen/logrus v1.4.2
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.3 // indirect
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 // indirect
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f // indirect
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b // indirect
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a // indirect
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789
gopkg.in/yaml.v2 v2.2.2
)
replace github.com/bugsnag/panicwrap => github.com/Toasterson/panicwrap v1.2.1-0.20200330134625-69b16f7ec2ac

183
supportfiles/image-build-files/registry/go.sum

@ -0,0 +1,183 @@
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible h1:KnPIugL51v3N3WwvaSmZbxukD1WuWXOiE9fRdu32f2I=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-autorest v10.8.1+incompatible h1:u0jVQf+a6k6x8A+sT60l6EY9XZu+kHdnZVPAYqpVRo0=
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
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/Toasterson/panicwrap v1.2.1-0.20200330134625-69b16f7ec2ac h1:bsWRM3jb1H/hGD/zC0nh3g73yycZ1Yb2ongfjcDXEmw=
github.com/Toasterson/panicwrap v1.2.1-0.20200330134625-69b16f7ec2ac/go.mod h1:4NsyTG/4bMpwGH6o4OTsUts44MDTP60oi4wvUWIAVp4=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aws/aws-sdk-go v1.15.11 h1:m45+Ru/wA+73cOZXiEGLDH2d9uLN3iHqMc0/z4noDXE=
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/bshuster-repo/logrus-logstash-hook v0.4.1 h1:pgAtgj+A31JBVtEHu2uHuEx0n+2ukqUJnS2vVe5pQNA=
github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
github.com/bugsnag/bugsnag-go v1.5.3 h1:yeRUT3mUE13jL1tGwvoQsKdVbAsQx9AJ+fqahKveP04=
github.com/bugsnag/bugsnag-go v1.5.3/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba h1:p6poVbjHDkKa+wtC8frBMwQtT3BmqGYBjzMwJ63tuR4=
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c h1:KJAnOBuY9cTKVqB5cfbynpvFgeHRTREkRk8C977oFu4=
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=