diff --git a/pkg/compiler/artifact.go b/pkg/compiler/artifact.go index 92cfbaa3..42b09eb8 100644 --- a/pkg/compiler/artifact.go +++ b/pkg/compiler/artifact.go @@ -516,7 +516,7 @@ func worker(i int, wg *sync.WaitGroup, s <-chan CopyJob) { } // ExtractArtifactFromDelta extracts deltas from ArtifactLayer from an image in tar format -func ExtractArtifactFromDelta(src, dst string, layers []ArtifactLayer, concurrency int, keepPerms bool, includes []string, t CompressionImplementation) (Artifact, error) { +func ExtractArtifactFromDelta(src, dst string, layers []ArtifactLayer, concurrency int, keepPerms bool, includes []string, excludes []string, t CompressionImplementation) (Artifact, error) { archive, err := LuetCfg.GetSystem().TempDir("archive") if err != nil { @@ -546,7 +546,8 @@ func ExtractArtifactFromDelta(src, dst string, layers []ArtifactLayer, concurren } // Handle includes in spec. If specified they filter what gets in the package - if len(includes) > 0 { + + if len(includes) > 0 && len(excludes) == 0 { var includeRegexp []*regexp.Regexp for _, i := range includes { r, e := regexp.Compile(i) @@ -574,6 +575,81 @@ func ExtractArtifactFromDelta(src, dst string, layers []ArtifactLayer, concurren Debug("File ", a.Name, " deleted") } } + + } else if len(includes) == 0 && len(excludes) != 0 { + var excludeRegexp []*regexp.Regexp + for _, i := range excludes { + r, e := regexp.Compile(i) + if e != nil { + Warning("Failed compiling regex:", e) + continue + } + excludeRegexp = append(excludeRegexp, r) + } + for _, l := range layers { + // Consider d.Additions (and d.Changes? - warn at least) only + ADD: + for _, a := range l.Diffs.Additions { + for _, i := range excludeRegexp { + if i.MatchString(a.Name) { + continue ADD + } + } + toCopy <- CopyJob{Src: filepath.Join(src, a.Name), Dst: filepath.Join(archive, a.Name), Artifact: a.Name} + } + for _, a := range l.Diffs.Changes { + Debug("File ", a.Name, " changed") + } + for _, a := range l.Diffs.Deletions { + Debug("File ", a.Name, " deleted") + } + } + + } else if len(includes) != 0 && len(excludes) != 0 { + + var includeRegexp []*regexp.Regexp + for _, i := range includes { + r, e := regexp.Compile(i) + if e != nil { + Warning("Failed compiling regex:", e) + continue + } + includeRegexp = append(includeRegexp, r) + } + var excludeRegexp []*regexp.Regexp + for _, i := range excludes { + r, e := regexp.Compile(i) + if e != nil { + Warning("Failed compiling regex:", e) + continue + } + excludeRegexp = append(excludeRegexp, r) + } + + for _, l := range layers { + // Consider d.Additions (and d.Changes? - warn at least) only + EXCLUDES: + for _, a := range l.Diffs.Additions { + for _, i := range includeRegexp { + if i.MatchString(a.Name) { + for _, e := range excludeRegexp { + if e.MatchString(a.Name) { + continue EXCLUDES + } + } + toCopy <- CopyJob{Src: filepath.Join(src, a.Name), Dst: filepath.Join(archive, a.Name), Artifact: a.Name} + continue EXCLUDES + } + } + } + for _, a := range l.Diffs.Changes { + Debug("File ", a.Name, " changed") + } + for _, a := range l.Diffs.Deletions { + Debug("File ", a.Name, " deleted") + } + } + } else { // Otherwise just grab all for _, l := range layers { diff --git a/pkg/compiler/artifact_test.go b/pkg/compiler/artifact_test.go index 3dae63e4..39fbdebf 100644 --- a/pkg/compiler/artifact_test.go +++ b/pkg/compiler/artifact_test.go @@ -130,7 +130,7 @@ RUN echo bar > /test2`)) err = b.ExtractRootfs(CompilerBackendOptions{SourcePath: filepath.Join(tmpdir, "output2.tar"), Destination: rootfs}, false) Expect(err).ToNot(HaveOccurred()) - artifact, err := ExtractArtifactFromDelta(rootfs, filepath.Join(tmpdir, "package.tar"), diffs, 2, false, []string{}, None) + artifact, err := ExtractArtifactFromDelta(rootfs, filepath.Join(tmpdir, "package.tar"), diffs, 2, false, []string{}, []string{}, None) Expect(err).ToNot(HaveOccurred()) Expect(helpers.Exists(filepath.Join(tmpdir, "package.tar"))).To(BeTrue()) err = helpers.Untar(artifact.GetPath(), unpacked, false) diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index 635abefb..5a3dce55 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -181,7 +181,7 @@ func (cs *LuetCompiler) CompileParallel(keepPermissions bool, ps CompilationSpec return artifacts, allErrors } -func (cs *LuetCompiler) stripIncludesFromRootfs(includes []string, rootfs string) error { +func (cs *LuetCompiler) stripFromRootfs(includes []string, rootfs string, include bool) error { var includeRegexp []*regexp.Regexp for _, i := range includes { r, e := regexp.Compile(i) @@ -213,7 +213,7 @@ func (cs *LuetCompiler) stripIncludesFromRootfs(includes []string, rootfs string } } - if !match { + if include && !match || !include && match { toRemove = append(toRemove, currentpath) } @@ -421,7 +421,11 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage if len(p.GetIncludes()) > 0 { // strip from includes - cs.stripIncludesFromRootfs(p.GetIncludes(), rootfs) + cs.stripFromRootfs(p.GetIncludes(), rootfs, true) + } + if len(p.GetExcludes()) > 0 { + // strip from includes + cs.stripFromRootfs(p.GetExcludes(), rootfs, false) } artifact = NewPackageArtifact(p.Rel(p.GetPackage().GetFingerPrint() + ".package.tar")) artifact.SetCompressionType(cs.CompressionType) @@ -438,7 +442,7 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage if err != nil { return nil, errors.Wrap(err, "Could not generate changes from layers") } - artifact, err = ExtractArtifactFromDelta(rootfs, p.Rel(p.GetPackage().GetFingerPrint()+".package.tar"), diffs, concurrency, keepPermissions, p.GetIncludes(), cs.CompressionType) + artifact, err = ExtractArtifactFromDelta(rootfs, p.Rel(p.GetPackage().GetFingerPrint()+".package.tar"), diffs, concurrency, keepPermissions, p.GetIncludes(), p.GetExcludes(), cs.CompressionType) if err != nil { return nil, errors.Wrap(err, "Could not generate deltas") } diff --git a/pkg/compiler/interface.go b/pkg/compiler/interface.go index 777b2916..e80a21ae 100644 --- a/pkg/compiler/interface.go +++ b/pkg/compiler/interface.go @@ -147,6 +147,7 @@ type ArtifactLayersSummary struct { type CompilationSpec interface { ImageUnpack() bool // tells if the definition is just an image GetIncludes() []string + GetExcludes() []string RenderBuildImage() (string, error) WriteBuildImageDefinition(string) error diff --git a/pkg/compiler/spec.go b/pkg/compiler/spec.go index 47e3e830..30496eed 100644 --- a/pkg/compiler/spec.go +++ b/pkg/compiler/spec.go @@ -102,6 +102,7 @@ type LuetCompilationSpec struct { OutputPath string `json:"-"` // Where the build processfiles go Unpack bool `json:"unpack"` Includes []string `json:"includes"` + Excludes []string `json:"excludes"` } func NewLuetCompilationSpec(b []byte, p pkg.Package) (CompilationSpec, error) { @@ -148,6 +149,10 @@ func (cs *LuetCompilationSpec) GetIncludes() []string { return cs.Includes } +func (cs *LuetCompilationSpec) GetExcludes() []string { + return cs.Excludes +} + func (cs *LuetCompilationSpec) GetRetrieve() []string { return cs.Retrieve }