mirror of
https://github.com/mudler/luet.git
synced 2025-09-04 16:50:50 +00:00
Add virtual packages support
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
package compiler
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -427,29 +426,33 @@ func (cs *LuetCompiler) genArtifact(p CompilationSpec, builderOpts, runnerOpts C
|
||||
var artifact Artifact
|
||||
var rootfs string
|
||||
var err error
|
||||
unpack := p.ImageUnpack()
|
||||
pkgTag := ":package: " + p.GetPackage().HumanReadableString()
|
||||
|
||||
// If package_dir was specified in the spec, we want to treat the content of the directory
|
||||
// as the root of our archive. ImageUnpack is implied to be true. override it
|
||||
if p.GetPackageDir() != "" {
|
||||
unpack = true
|
||||
}
|
||||
|
||||
if len(p.BuildSteps()) == 0 && len(p.GetPreBuildSteps()) == 0 && !unpack {
|
||||
fakePackage := p.Rel(p.GetPackage().GetFingerPrint() + ".package.tar")
|
||||
// We can't generate delta in this case. It implies the package is a virtual, and nothing has to be done really
|
||||
if p.EmptyPackage() {
|
||||
fakePackage := p.Rel(p.GetPackage().GetFingerPrint() + ".package.tar")
|
||||
|
||||
file, err := os.Create(fakePackage)
|
||||
rootfs, err = ioutil.TempDir(p.GetOutputPath(), "rootfs")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed creating virtual package")
|
||||
return nil, errors.Wrap(err, "Could not create tempdir")
|
||||
}
|
||||
defer file.Close()
|
||||
tw := tar.NewWriter(file)
|
||||
defer tw.Close()
|
||||
defer os.RemoveAll(rootfs) // clean up
|
||||
|
||||
artifact := NewPackageArtifact(fakePackage)
|
||||
artifact.SetCompressionType(cs.CompressionType)
|
||||
|
||||
if err := artifact.Compress(rootfs, concurrency); err != nil {
|
||||
return nil, errors.Wrap(err, "Error met while creating package archive")
|
||||
}
|
||||
|
||||
artifact.SetCompileSpec(p)
|
||||
artifact.GetCompileSpec().GetPackage().SetBuildTimestamp(time.Now().String())
|
||||
|
||||
err = artifact.WriteYaml(p.GetOutputPath())
|
||||
if err != nil {
|
||||
return artifact, errors.Wrap(err, "Failed while writing metadata file")
|
||||
}
|
||||
Info(pkgTag, " :white_check_mark: done (empty virtual package)")
|
||||
return artifact, nil
|
||||
}
|
||||
|
||||
@@ -476,7 +479,7 @@ func (cs *LuetCompiler) genArtifact(p CompilationSpec, builderOpts, runnerOpts C
|
||||
return nil, errors.Wrap(err, "Could not extract rootfs")
|
||||
}
|
||||
|
||||
if unpack {
|
||||
if p.UnpackedPackage() {
|
||||
// Take content of container as a base for our package files
|
||||
artifact, err = cs.unpackFs(rootfs, concurrency, p)
|
||||
if err != nil {
|
||||
@@ -524,6 +527,13 @@ func (cs *LuetCompiler) compileWithImage(image, buildertaggedImage, packageImage
|
||||
keepPermissions, keepImg bool,
|
||||
p CompilationSpec, generateArtifact bool) (Artifact, error) {
|
||||
|
||||
// If it is a virtual, check if we have to generate an empty artifact or not.
|
||||
if generateArtifact && p.EmptyPackage() {
|
||||
return cs.genArtifact(p, CompilerBackendOptions{}, CompilerBackendOptions{}, concurrency, keepPermissions)
|
||||
} else if p.EmptyPackage() {
|
||||
return &PackageArtifact{}, nil
|
||||
}
|
||||
|
||||
if !generateArtifact {
|
||||
exists := cs.Backend.ImageExists(packageImage)
|
||||
if art, err := LoadArtifactFromYaml(p); err == nil && exists { // If YAML is correctly loaded, and both images exists, no reason to rebuild.
|
||||
@@ -649,10 +659,13 @@ func (cs *LuetCompiler) Compile(keepPermissions bool, p CompilationSpec) (Artifa
|
||||
func (cs *LuetCompiler) compile(concurrency int, keepPermissions bool, p CompilationSpec) (Artifact, error) {
|
||||
Info(":package: Compiling", p.GetPackage().HumanReadableString(), ".... :coffee:")
|
||||
|
||||
if len(p.GetPackage().GetRequires()) == 0 && p.GetImage() == "" {
|
||||
Error("Package with no deps and no seed image supplied, bailing out")
|
||||
return nil, errors.New("Package " + p.GetPackage().GetFingerPrint() +
|
||||
" with no deps and no seed image supplied, bailing out")
|
||||
Debug(fmt.Sprintf("%s: has images %t, empty package: %t", p.GetPackage().HumanReadableString(), p.HasImageSource(), p.EmptyPackage()))
|
||||
if !p.HasImageSource() && !p.EmptyPackage() {
|
||||
return nil,
|
||||
fmt.Errorf(
|
||||
"%s is invalid: package has no dependencies and no seed image supplied while it has steps defined",
|
||||
p.GetPackage().GetFingerPrint(),
|
||||
)
|
||||
}
|
||||
|
||||
targetAssertion := p.GetSourceAssertion().Search(p.GetPackage().GetFingerPrint())
|
||||
|
@@ -178,6 +178,10 @@ type CompilationSpec interface {
|
||||
|
||||
SetPackageDir(string)
|
||||
GetPackageDir() string
|
||||
|
||||
EmptyPackage() bool
|
||||
UnpackedPackage() bool
|
||||
HasImageSource() bool
|
||||
}
|
||||
|
||||
type CompilationSpecs interface {
|
||||
|
@@ -185,6 +185,24 @@ func (cs *LuetCompilationSpec) SetSeedImage(s string) {
|
||||
cs.Seed = s
|
||||
}
|
||||
|
||||
func (cs *LuetCompilationSpec) EmptyPackage() bool {
|
||||
return len(cs.BuildSteps()) == 0 && len(cs.GetPreBuildSteps()) == 0 && !cs.UnpackedPackage()
|
||||
}
|
||||
|
||||
func (cs *LuetCompilationSpec) UnpackedPackage() bool {
|
||||
// If package_dir was specified in the spec, we want to treat the content of the directory
|
||||
// as the root of our archive. ImageUnpack is implied to be true. override it
|
||||
unpack := cs.ImageUnpack()
|
||||
if cs.GetPackageDir() != "" {
|
||||
unpack = true
|
||||
}
|
||||
return unpack
|
||||
}
|
||||
|
||||
func (cs *LuetCompilationSpec) HasImageSource() bool {
|
||||
return len(cs.GetPackage().GetRequires()) != 0 || cs.GetImage() != ""
|
||||
}
|
||||
|
||||
func (cs *LuetCompilationSpec) CopyRetrieves(dest string) error {
|
||||
var err error
|
||||
if len(cs.Retrieve) > 0 {
|
||||
|
0
tests/fixtures/virtuals/a/build.yaml
vendored
Normal file
0
tests/fixtures/virtuals/a/build.yaml
vendored
Normal file
3
tests/fixtures/virtuals/a/definition.yaml
vendored
Normal file
3
tests/fixtures/virtuals/a/definition.yaml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
category: test
|
||||
name: "a"
|
||||
version: "1.0"
|
4
tests/fixtures/virtuals/b/build.yaml
vendored
Normal file
4
tests/fixtures/virtuals/b/build.yaml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
requires:
|
||||
- category: "test"
|
||||
name: "a"
|
||||
version: ">=0"
|
3
tests/fixtures/virtuals/b/definition.yaml
vendored
Normal file
3
tests/fixtures/virtuals/b/definition.yaml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
category: test
|
||||
name: "b"
|
||||
version: "1.0"
|
4
tests/fixtures/virtuals/c/build.yaml
vendored
Normal file
4
tests/fixtures/virtuals/c/build.yaml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Invalid, no source image or requires defined, but we define steps
|
||||
|
||||
steps:
|
||||
- echo "fail!"
|
3
tests/fixtures/virtuals/c/definition.yaml
vendored
Normal file
3
tests/fixtures/virtuals/c/definition.yaml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
category: test
|
||||
name: "c"
|
||||
version: "1.0"
|
42
tests/integration/25_virtuals.sh
Executable file
42
tests/integration/25_virtuals.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
export LUET_NOLOCK=true
|
||||
|
||||
oneTimeSetUp() {
|
||||
export tmpdir="$(mktemp -d)"
|
||||
}
|
||||
|
||||
oneTimeTearDown() {
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
testBuildA() {
|
||||
mkdir $tmpdir/testbuild1
|
||||
luet build --tree "$ROOT_DIR/tests/fixtures/virtuals" --debug --compression "gzip" --destination $tmpdir/testbuild1 test/a
|
||||
buildst=$?
|
||||
assertEquals 'builds successfully' "$buildst" "0"
|
||||
assertTrue 'create package A 1.0' "[ -e '$tmpdir/testbuild1/a-test-1.0.package.tar.gz' ]"
|
||||
assertTrue 'create package A 1.0' "[ -e '$tmpdir/testbuild1/a-test-1.0.metadata.yaml' ]"
|
||||
}
|
||||
|
||||
testBuildB() {
|
||||
mkdir $tmpdir/testbuild2
|
||||
luet build --tree "$ROOT_DIR/tests/fixtures/virtuals" --debug --compression "gzip" --destination $tmpdir/testbuild2 test/b
|
||||
buildst=$?
|
||||
assertEquals 'builds successfully' "$buildst" "0"
|
||||
assertTrue 'create package A 1.0' "[ -e '$tmpdir/testbuild2/a-test-1.0.package.tar.gz' ]"
|
||||
assertTrue 'create package A 1.0' "[ -e '$tmpdir/testbuild2/a-test-1.0.metadata.yaml' ]"
|
||||
assertTrue 'create package B 1.0' "[ -e '$tmpdir/testbuild2/b-test-1.0.package.tar.gz' ]"
|
||||
assertTrue 'create package B 1.0' "[ -e '$tmpdir/testbuild2/b-test-1.0.metadata.yaml' ]"
|
||||
}
|
||||
|
||||
testBuildC() {
|
||||
mkdir $tmpdir/testbuild3
|
||||
luet build --tree "$ROOT_DIR/tests/fixtures/virtuals" --debug --destination $tmpdir/testbuild3 test/c
|
||||
buildst=$?
|
||||
assertEquals 'builds of C expected to fail' "$buildst" "1"
|
||||
}
|
||||
|
||||
# Load shUnit2.
|
||||
. "$ROOT_DIR/tests/integration/shunit2"/shunit2
|
||||
|
Reference in New Issue
Block a user