diff --git a/cmd/build.go b/cmd/build.go index cf5adc2f..758e6185 100644 --- a/cmd/build.go +++ b/cmd/build.go @@ -47,6 +47,9 @@ var buildCmd = &cobra.Command{ viper.BindPFlag("compression", cmd.Flags().Lookup("compression")) viper.BindPFlag("image-repository", cmd.Flags().Lookup("image-repository")) + viper.BindPFlag("push", cmd.Flags().Lookup("push")) + viper.BindPFlag("pull", cmd.Flags().Lookup("pull")) + viper.BindPFlag("keep-images", cmd.Flags().Lookup("keep-images")) LuetCfg.Viper.BindPFlag("solver.type", cmd.Flags().Lookup("solver-type")) LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount")) @@ -66,6 +69,9 @@ var buildCmd = &cobra.Command{ databaseType := viper.GetString("database") compressionType := viper.GetString("compression") imageRepository := viper.GetString("image-repository") + push := viper.GetBool("push") + pull := viper.GetBool("pull") + keepImages := viper.GetBool("keep-images") compilerSpecs := compiler.NewLuetCompilationspecs() var compilerBackend compiler.CompilerBackend @@ -117,6 +123,9 @@ var buildCmd = &cobra.Command{ opts.SolverOptions = *LuetCfg.GetSolverOptions() opts.ImageRepository = imageRepository opts.Clean = clean + opts.PullFirst = pull + opts.KeepImg = keepImages + opts.Push = push luetCompiler := compiler.NewLuetCompiler(compilerBackend, generalRecipe.GetDatabase(), opts) luetCompiler.SetConcurrency(concurrency) luetCompiler.SetCompressionType(compiler.CompressionImplementation(compressionType)) @@ -200,6 +209,9 @@ func init() { buildCmd.Flags().String("destination", path, "Destination folder") buildCmd.Flags().String("compression", "none", "Compression alg: none, gzip") buildCmd.Flags().String("image-repository", "luet/cache", "Default base image string for generated image") + buildCmd.Flags().Bool("push", false, "Push images to a hub") + buildCmd.Flags().Bool("pull", false, "Pull images from a hub") + buildCmd.Flags().Bool("keep-images", true, "Keep built docker images in the host") buildCmd.Flags().String("solver-type", "", "Solver strategy") buildCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") diff --git a/pkg/compiler/backend/simpledocker.go b/pkg/compiler/backend/simpledocker.go index 7a84f5bb..a8a720e3 100644 --- a/pkg/compiler/backend/simpledocker.go +++ b/pkg/compiler/backend/simpledocker.go @@ -101,6 +101,18 @@ func (*SimpleDocker) RemoveImage(opts compiler.CompilerBackendOptions) error { return nil } +func (*SimpleDocker) Push(opts compiler.CompilerBackendOptions) error { + name := opts.ImageName + pusharg := []string{"push", name} + out, err := exec.Command("docker", pusharg...).CombinedOutput() + if err != nil { + return errors.Wrap(err, "Failed pushing image: "+string(out)) + } + Info(":whale: Pushed image:", name) + //Info(string(out)) + return nil +} + func (s *SimpleDocker) ImageDefinitionToTar(opts compiler.CompilerBackendOptions) error { if err := s.BuildImage(opts); err != nil { return errors.Wrap(err, "Failed building image") diff --git a/pkg/compiler/backend/simpleimg.go b/pkg/compiler/backend/simpleimg.go index 809a644a..23edb493 100644 --- a/pkg/compiler/backend/simpleimg.go +++ b/pkg/compiler/backend/simpleimg.go @@ -145,3 +145,15 @@ func (*SimpleImg) ExtractRootfs(opts compiler.CompilerBackendOptions, keepPerms func (*SimpleImg) Changes(fromImage, toImage string) ([]compiler.ArtifactLayer, error) { return NewSimpleDockerBackend().Changes(fromImage, toImage) } + +func (*SimpleImg) Push(opts compiler.CompilerBackendOptions) error { + name := opts.ImageName + pusharg := []string{"push", name} + out, err := exec.Command("img", pusharg...).CombinedOutput() + if err != nil { + return errors.Wrap(err, "Failed pushing image: "+string(out)) + } + Info(":tea: Pushed image:", name) + //Info(string(out)) + return nil +} diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index 925c5388..eca00f42 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -272,7 +272,7 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage packageImage = cs.ImageRepository + "-" + p.GetPackage().GetFingerPrint() } - if cs.PullFirst { + if cs.Options.PullFirst { //Best effort pull cs.Backend.DownloadImage(CompilerBackendOptions{ImageName: buildertaggedImage}) cs.Backend.DownloadImage(CompilerBackendOptions{ImageName: packageImage}) @@ -299,6 +299,12 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage return nil, errors.Wrap(err, "Could not export image") } + if cs.Options.Push { + err = cs.Backend.Push(builderOpts) + if err != nil { + return nil, errors.Wrap(err, "Could not push image: "+image+" "+builderOpts.DockerFileName) + } + } // Then we write the step image, which uses the builder one p.WriteStepImageDefinition(buildertaggedImage, filepath.Join(buildDir, p.GetPackage().GetFingerPrint()+".dockerfile")) runnerOpts := CompilerBackendOptions{ @@ -320,6 +326,13 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage if err := cs.Backend.ExportImage(runnerOpts); err != nil { return nil, errors.Wrap(err, "Failed exporting image") } + + if cs.Options.Push { + err = cs.Backend.Push(runnerOpts) + if err != nil { + return nil, errors.Wrap(err, "Could not push image: "+image+" "+builderOpts.DockerFileName) + } + } // } var diffs []ArtifactLayer diff --git a/pkg/compiler/interface.go b/pkg/compiler/interface.go index a9342820..6bba9567 100644 --- a/pkg/compiler/interface.go +++ b/pkg/compiler/interface.go @@ -44,11 +44,11 @@ type CompilerBackendOptions struct { } type CompilerOptions struct { - ImageRepository string - PullFirst, KeepImg bool - Concurrency int - CompressionType CompressionImplementation - Clean bool + ImageRepository string + PullFirst, KeepImg, Push bool + Concurrency int + CompressionType CompressionImplementation + Clean bool SolverOptions config.LuetSolverOptions } @@ -56,7 +56,8 @@ type CompilerOptions struct { func NewDefaultCompilerOptions() *CompilerOptions { return &CompilerOptions{ ImageRepository: "luet/cache", - PullFirst: true, + PullFirst: false, + Push: false, CompressionType: None, KeepImg: true, Concurrency: runtime.NumCPU(), @@ -74,6 +75,8 @@ type CompilerBackend interface { CopyImage(string, string) error DownloadImage(opts CompilerBackendOptions) error + + Push(opts CompilerBackendOptions) error } type Artifact interface {