diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index 5a3dce55..ed372148 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -21,8 +21,6 @@ import ( "os" "path/filepath" - "github.com/ghodss/yaml" - "regexp" "strings" "sync" @@ -456,7 +454,6 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage } artifact.SetFiles(filelist) - artifact.GetCompileSpec().GetPackage().SetBuildTimestamp(time.Now().String()) err = artifact.WriteYaml(p.GetOutputPath()) @@ -658,31 +655,11 @@ func (cs *LuetCompiler) FromPackage(p pkg.Package) (CompilationSpec, error) { return nil, err } - buildFile := pack.Rel(BuildFile) - if !helpers.Exists(buildFile) { - return nil, errors.New("No build file present for " + p.GetFingerPrint()) - } - defFile := pack.Rel(DefinitionFile) - if !helpers.Exists(defFile) { - return nil, errors.New("No build file present for " + p.GetFingerPrint()) - } - def, err := ioutil.ReadFile(defFile) + out, err := helpers.RenderFiles(pack.Rel(BuildFile), pack.Rel(DefinitionFile)) if err != nil { - return nil, err + return nil, errors.Wrap(err, "rendering file "+pack.Rel(BuildFile)) } - build, err := ioutil.ReadFile(buildFile) - if err != nil { - return nil, err - } - var values templatedata - if err = yaml.Unmarshal(def, &values); err != nil { - return nil, err - } - out, err := helpers.RenderHelm(string(build), values) - if err != nil { - return nil, err - } return NewLuetCompilationSpec([]byte(out), pack) } diff --git a/pkg/helpers/helm.go b/pkg/helpers/helm.go index 13d1f1e9..2f038fbc 100644 --- a/pkg/helpers/helm.go +++ b/pkg/helpers/helm.go @@ -1,7 +1,10 @@ package helpers import ( + "io/ioutil" + "github.com/pkg/errors" + "gopkg.in/yaml.v2" "helm.sh/helm/v3/pkg/chart" "helm.sh/helm/v3/pkg/chartutil" "helm.sh/helm/v3/pkg/engine" @@ -31,3 +34,26 @@ func RenderHelm(template string, values map[string]interface{}) (string, error) return out["templates"], nil } + +type templatedata map[string]interface{} + +func RenderFiles(toTemplate, valuesFile string) (string, error) { + raw, err := ioutil.ReadFile(toTemplate) + if err != nil { + return "", errors.Wrap(err, "reading file "+toTemplate) + } + + if !Exists(valuesFile) { + return "", errors.Wrap(err, "file not existing "+valuesFile) + } + def, err := ioutil.ReadFile(valuesFile) + if err != nil { + return "", errors.Wrap(err, "reading file "+valuesFile) + } + + var values templatedata + if err = yaml.Unmarshal(def, &values); err != nil { + return "", errors.Wrap(err, "unmarshalling file "+toTemplate) + } + return RenderHelm(string(raw), values) +} diff --git a/pkg/installer/installer.go b/pkg/installer/installer.go index bcc5bc18..f8056cec 100644 --- a/pkg/installer/installer.go +++ b/pkg/installer/installer.go @@ -30,7 +30,6 @@ import ( . "github.com/mudler/luet/pkg/logger" pkg "github.com/mudler/luet/pkg/package" "github.com/mudler/luet/pkg/solver" - "github.com/mudler/luet/pkg/tree" "github.com/pkg/errors" ) @@ -453,8 +452,7 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp pkg.Packages, s *Sy return errors.Wrap(err, "Failed creating package") } } - executedFinalizer := map[string]bool{} - + var toFinalize []pkg.Package if !l.Options.NoDeps { // TODO: Lower those errors as warning for _, w := range p { @@ -466,36 +464,17 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp pkg.Packages, s *Sy ORDER: for _, ass := range ordered { if ass.Value { - installed, ok := toInstall[ass.Package.GetFingerPrint()] if !ok { // It was a dep already installed in the system, so we can skip it safely continue ORDER } - treePackage, err := installed.Repository.GetTree().GetDatabase().FindPackage(ass.Package) if err != nil { return errors.Wrap(err, "Error getting package "+ass.Package.HumanReadableString()) } - if helpers.Exists(treePackage.Rel(tree.FinalizerFile)) { - finalizerRaw, err := ioutil.ReadFile(treePackage.Rel(tree.FinalizerFile)) - if err != nil && !l.Options.Force { - return errors.Wrap(err, "Error reading file "+treePackage.Rel(tree.FinalizerFile)) - } - if _, exists := executedFinalizer[ass.Package.GetFingerPrint()]; !exists { - Info("Executing finalizer for " + ass.Package.HumanReadableString()) - finalizer, err := NewLuetFinalizerFromYaml(finalizerRaw) - if err != nil && !l.Options.Force { - return errors.Wrap(err, "Error reading finalizer "+treePackage.Rel(tree.FinalizerFile)) - } - err = finalizer.RunInstall(s) - if err != nil && !l.Options.Force { - return errors.Wrap(err, "Error executing install finalizer "+treePackage.Rel(tree.FinalizerFile)) - } - executedFinalizer[ass.Package.GetFingerPrint()] = true - } - } + toFinalize = append(toFinalize, treePackage) } } @@ -506,29 +485,11 @@ func (l *LuetInstaller) install(syncedRepos Repositories, cp pkg.Packages, s *Sy if err != nil { return errors.Wrap(err, "Error getting package "+c.Package.HumanReadableString()) } - if helpers.Exists(treePackage.Rel(tree.FinalizerFile)) { - finalizerRaw, err := ioutil.ReadFile(treePackage.Rel(tree.FinalizerFile)) - if err != nil && !l.Options.Force { - return errors.Wrap(err, "Error reading file "+treePackage.Rel(tree.FinalizerFile)) - } - if _, exists := executedFinalizer[c.Package.GetFingerPrint()]; !exists { - Info(":shell: Executing finalizer for " + c.Package.HumanReadableString()) - finalizer, err := NewLuetFinalizerFromYaml(finalizerRaw) - if err != nil && !l.Options.Force { - return errors.Wrap(err, "Error reading finalizer "+treePackage.Rel(tree.FinalizerFile)) - } - err = finalizer.RunInstall(s) - if err != nil && !l.Options.Force { - return errors.Wrap(err, "Error executing install finalizer "+treePackage.Rel(tree.FinalizerFile)) - } - executedFinalizer[c.Package.GetFingerPrint()] = true - } - } + toFinalize = append(toFinalize, treePackage) } } - return nil - + return s.ExecuteFinalizers(toFinalize, l.Options.Force) } func (l *LuetInstaller) downloadPackage(a ArtifactMatch) (compiler.Artifact, error) { diff --git a/pkg/installer/system.go b/pkg/installer/system.go index e66d6eb4..eb4e91da 100644 --- a/pkg/installer/system.go +++ b/pkg/installer/system.go @@ -1,7 +1,12 @@ package installer import ( + . "github.com/mudler/luet/pkg/logger" + + "github.com/mudler/luet/pkg/helpers" pkg "github.com/mudler/luet/pkg/package" + "github.com/mudler/luet/pkg/tree" + "github.com/pkg/errors" ) type System struct { @@ -12,3 +17,31 @@ type System struct { func (s *System) World() (pkg.Packages, error) { return s.Database.World(), nil } + +type templatedata map[string]interface{} + +func (s *System) ExecuteFinalizers(packs []pkg.Package, force bool) error { + executedFinalizer := map[string]bool{} + for _, p := range packs { + if helpers.Exists(p.Rel(tree.FinalizerFile)) { + out, err := helpers.RenderFiles(p.Rel(tree.FinalizerFile), p.Rel(tree.DefinitionFile)) + if err != nil && !force { + return errors.Wrap(err, "reading file "+p.Rel(tree.FinalizerFile)) + } + + if _, exists := executedFinalizer[p.GetFingerPrint()]; !exists { + Info("Executing finalizer for " + p.HumanReadableString()) + finalizer, err := NewLuetFinalizerFromYaml([]byte(out)) + if err != nil && !force { + return errors.Wrap(err, "Error reading finalizer "+p.Rel(tree.FinalizerFile)) + } + err = finalizer.RunInstall(s) + if err != nil && !force { + return errors.Wrap(err, "Error executing install finalizer "+p.Rel(tree.FinalizerFile)) + } + executedFinalizer[p.GetFingerPrint()] = true + } + } + } + return nil +} diff --git a/tests/fixtures/templatedfinalizers/alpine/build.yaml b/tests/fixtures/templatedfinalizers/alpine/build.yaml new file mode 100644 index 00000000..19a2ec56 --- /dev/null +++ b/tests/fixtures/templatedfinalizers/alpine/build.yaml @@ -0,0 +1,2 @@ +image: "alpine" +unpack: true diff --git a/tests/fixtures/templatedfinalizers/alpine/definition.yaml b/tests/fixtures/templatedfinalizers/alpine/definition.yaml new file mode 100644 index 00000000..cf8247ba --- /dev/null +++ b/tests/fixtures/templatedfinalizers/alpine/definition.yaml @@ -0,0 +1,3 @@ +category: "seed" +name: "alpine" +version: "1.0" diff --git a/tests/fixtures/templatedfinalizers/alpine/finalize.yaml b/tests/fixtures/templatedfinalizers/alpine/finalize.yaml new file mode 100644 index 00000000..1f690f69 --- /dev/null +++ b/tests/fixtures/templatedfinalizers/alpine/finalize.yaml @@ -0,0 +1,2 @@ +install: +- echo "{{.Values.name}}" > /tmp/foo \ No newline at end of file diff --git a/tests/integration/19_finalizer_templated.sh b/tests/integration/19_finalizer_templated.sh new file mode 100755 index 00000000..b6a55101 --- /dev/null +++ b/tests/integration/19_finalizer_templated.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +export LUET_NOLOCK=true + +oneTimeSetUp() { +export tmpdir="$(mktemp -d)" +} + +oneTimeTearDown() { + rm -rf "$tmpdir" +} + +testBuild() { + mkdir $tmpdir/testbuild + luet build --tree "$ROOT_DIR/tests/fixtures/templatedfinalizers" --destination $tmpdir/testbuild --compression gzip --all > /dev/null + buildst=$? + assertEquals 'builds successfully' "$buildst" "0" + assertTrue 'create package' "[ -e '$tmpdir/testbuild/alpine-seed-1.0.package.tar.gz' ]" +} + +testRepo() { + assertTrue 'no repository' "[ ! -e '$tmpdir/testbuild/repository.yaml' ]" + luet create-repo --tree "$ROOT_DIR/tests/fixtures/templatedfinalizers" \ + --output $tmpdir/testbuild \ + --packages $tmpdir/testbuild \ + --name "test" \ + --descr "Test Repo" \ + --urls $tmpdir/testrootfs \ + --type disk > /dev/null + + createst=$? + assertEquals 'create repo successfully' "$createst" "0" + assertTrue 'create repository' "[ -e '$tmpdir/testbuild/repository.yaml' ]" +} + +testConfig() { + mkdir $tmpdir/testrootfs + cat < $tmpdir/luet.yaml +general: + debug: true +system: + rootfs: $tmpdir/testrootfs + database_path: "/" + database_engine: "boltdb" +config_from_host: true +repositories: + - name: "main" + type: "disk" + enable: true + urls: + - "$tmpdir/testbuild" +EOF + luet config --config $tmpdir/luet.yaml + res=$? + assertEquals 'config test successfully' "$res" "0" +} + +testInstall() { + luet install --config $tmpdir/luet.yaml seed/alpine + #luet install --config $tmpdir/luet.yaml test/c-1.0 > /dev/null + installst=$? + assertEquals 'install test successfully' "$installst" "0" + assertTrue 'package installed' "[ -e '$tmpdir/testrootfs/bin/busybox' ]" + assertTrue 'finalizer runs' "[ -e '$tmpdir/testrootfs/tmp/foo' ]" + assertEquals 'finalizer printed used shell' "$(cat $tmpdir/testrootfs/tmp/foo)" 'alpine' +} + + +testCleanup() { + luet cleanup --config $tmpdir/luet.yaml + installst=$? + assertEquals 'install test successfully' "$installst" "0" +} + +# Load shUnit2. +. "$ROOT_DIR/tests/integration/shunit2"/shunit2 +