Add Push to hub feature

Add to the backends the Push capabilities to push images that were correctly built.
Also expose them to the CLI, along with KeepImg which was hidden.
This commit is contained in:
Ettore Di Giacinto
2020-02-15 14:45:05 +01:00
parent d527eaed60
commit fcec6c5699
5 changed files with 59 additions and 7 deletions

View File

@@ -47,6 +47,9 @@ var buildCmd = &cobra.Command{
viper.BindPFlag("compression", cmd.Flags().Lookup("compression")) viper.BindPFlag("compression", cmd.Flags().Lookup("compression"))
viper.BindPFlag("image-repository", cmd.Flags().Lookup("image-repository")) 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.type", cmd.Flags().Lookup("solver-type"))
LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount")) LuetCfg.Viper.BindPFlag("solver.discount", cmd.Flags().Lookup("solver-discount"))
@@ -66,6 +69,9 @@ var buildCmd = &cobra.Command{
databaseType := viper.GetString("database") databaseType := viper.GetString("database")
compressionType := viper.GetString("compression") compressionType := viper.GetString("compression")
imageRepository := viper.GetString("image-repository") imageRepository := viper.GetString("image-repository")
push := viper.GetBool("push")
pull := viper.GetBool("pull")
keepImages := viper.GetBool("keep-images")
compilerSpecs := compiler.NewLuetCompilationspecs() compilerSpecs := compiler.NewLuetCompilationspecs()
var compilerBackend compiler.CompilerBackend var compilerBackend compiler.CompilerBackend
@@ -117,6 +123,9 @@ var buildCmd = &cobra.Command{
opts.SolverOptions = *LuetCfg.GetSolverOptions() opts.SolverOptions = *LuetCfg.GetSolverOptions()
opts.ImageRepository = imageRepository opts.ImageRepository = imageRepository
opts.Clean = clean opts.Clean = clean
opts.PullFirst = pull
opts.KeepImg = keepImages
opts.Push = push
luetCompiler := compiler.NewLuetCompiler(compilerBackend, generalRecipe.GetDatabase(), opts) luetCompiler := compiler.NewLuetCompiler(compilerBackend, generalRecipe.GetDatabase(), opts)
luetCompiler.SetConcurrency(concurrency) luetCompiler.SetConcurrency(concurrency)
luetCompiler.SetCompressionType(compiler.CompressionImplementation(compressionType)) luetCompiler.SetCompressionType(compiler.CompressionImplementation(compressionType))
@@ -200,6 +209,9 @@ func init() {
buildCmd.Flags().String("destination", path, "Destination folder") buildCmd.Flags().String("destination", path, "Destination folder")
buildCmd.Flags().String("compression", "none", "Compression alg: none, gzip") 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().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().String("solver-type", "", "Solver strategy")
buildCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate") buildCmd.Flags().Float32("solver-rate", 0.7, "Solver learning rate")

View File

@@ -101,6 +101,18 @@ func (*SimpleDocker) RemoveImage(opts compiler.CompilerBackendOptions) error {
return nil 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 { func (s *SimpleDocker) ImageDefinitionToTar(opts compiler.CompilerBackendOptions) error {
if err := s.BuildImage(opts); err != nil { if err := s.BuildImage(opts); err != nil {
return errors.Wrap(err, "Failed building image") return errors.Wrap(err, "Failed building image")

View File

@@ -145,3 +145,15 @@ func (*SimpleImg) ExtractRootfs(opts compiler.CompilerBackendOptions, keepPerms
func (*SimpleImg) Changes(fromImage, toImage string) ([]compiler.ArtifactLayer, error) { func (*SimpleImg) Changes(fromImage, toImage string) ([]compiler.ArtifactLayer, error) {
return NewSimpleDockerBackend().Changes(fromImage, toImage) 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
}

View File

@@ -272,7 +272,7 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage
packageImage = cs.ImageRepository + "-" + p.GetPackage().GetFingerPrint() packageImage = cs.ImageRepository + "-" + p.GetPackage().GetFingerPrint()
} }
if cs.PullFirst { if cs.Options.PullFirst {
//Best effort pull //Best effort pull
cs.Backend.DownloadImage(CompilerBackendOptions{ImageName: buildertaggedImage}) cs.Backend.DownloadImage(CompilerBackendOptions{ImageName: buildertaggedImage})
cs.Backend.DownloadImage(CompilerBackendOptions{ImageName: packageImage}) 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") 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 // Then we write the step image, which uses the builder one
p.WriteStepImageDefinition(buildertaggedImage, filepath.Join(buildDir, p.GetPackage().GetFingerPrint()+".dockerfile")) p.WriteStepImageDefinition(buildertaggedImage, filepath.Join(buildDir, p.GetPackage().GetFingerPrint()+".dockerfile"))
runnerOpts := CompilerBackendOptions{ runnerOpts := CompilerBackendOptions{
@@ -320,6 +326,13 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage
if err := cs.Backend.ExportImage(runnerOpts); err != nil { if err := cs.Backend.ExportImage(runnerOpts); err != nil {
return nil, errors.Wrap(err, "Failed exporting image") 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 var diffs []ArtifactLayer

View File

@@ -44,11 +44,11 @@ type CompilerBackendOptions struct {
} }
type CompilerOptions struct { type CompilerOptions struct {
ImageRepository string ImageRepository string
PullFirst, KeepImg bool PullFirst, KeepImg, Push bool
Concurrency int Concurrency int
CompressionType CompressionImplementation CompressionType CompressionImplementation
Clean bool Clean bool
SolverOptions config.LuetSolverOptions SolverOptions config.LuetSolverOptions
} }
@@ -56,7 +56,8 @@ type CompilerOptions struct {
func NewDefaultCompilerOptions() *CompilerOptions { func NewDefaultCompilerOptions() *CompilerOptions {
return &CompilerOptions{ return &CompilerOptions{
ImageRepository: "luet/cache", ImageRepository: "luet/cache",
PullFirst: true, PullFirst: false,
Push: false,
CompressionType: None, CompressionType: None,
KeepImg: true, KeepImg: true,
Concurrency: runtime.NumCPU(), Concurrency: runtime.NumCPU(),
@@ -74,6 +75,8 @@ type CompilerBackend interface {
CopyImage(string, string) error CopyImage(string, string) error
DownloadImage(opts CompilerBackendOptions) error DownloadImage(opts CompilerBackendOptions) error
Push(opts CompilerBackendOptions) error
} }
type Artifact interface { type Artifact interface {