mirror of
https://github.com/mudler/luet.git
synced 2025-09-02 07:45:02 +00:00
Add GenerateFinalImage to package artifacts
GenerateFinalImage generates a docker image from scratch with the artifact content. Related to #169
This commit is contained in:
@@ -241,6 +241,46 @@ func (a *PackageArtifact) SetPath(p string) {
|
||||
a.Path = p
|
||||
}
|
||||
|
||||
func (a *PackageArtifact) genDockerfile() string {
|
||||
return `
|
||||
FROM scratch
|
||||
COPY * /`
|
||||
}
|
||||
|
||||
// GenerateFinalImage takes an artifact and builds a Docker image with its content
|
||||
func (a *PackageArtifact) GenerateFinalImage(imageprefix string, b CompilerBackend, keepPerms bool) (CompilerBackendOptions, error) {
|
||||
builderOpts := CompilerBackendOptions{}
|
||||
archive, err := LuetCfg.GetSystem().TempDir("archive")
|
||||
if err != nil {
|
||||
return builderOpts, errors.Wrap(err, "error met while creating tempdir for "+a.Path)
|
||||
}
|
||||
defer os.RemoveAll(archive) // clean up
|
||||
|
||||
uncompressedFiles := filepath.Join(archive, "files")
|
||||
dockerFile := filepath.Join(archive, "Dockerfile")
|
||||
|
||||
if err := os.MkdirAll(uncompressedFiles, os.ModePerm); err != nil {
|
||||
return builderOpts, errors.Wrap(err, "error met while creating tempdir for "+a.Path)
|
||||
}
|
||||
|
||||
data := a.genDockerfile()
|
||||
if err := ioutil.WriteFile(dockerFile, []byte(data), 0644); err != nil {
|
||||
return builderOpts, errors.Wrap(err, "error met while rendering artifact dockerfile "+a.Path)
|
||||
}
|
||||
|
||||
if err := a.Unpack(uncompressedFiles, keepPerms); err != nil {
|
||||
return builderOpts, errors.Wrap(err, "error met while uncompressing artifact "+a.Path)
|
||||
}
|
||||
|
||||
builderOpts = CompilerBackendOptions{
|
||||
ImageName: imageprefix + a.CompileSpec.Package.GetFingerPrint(),
|
||||
SourcePath: archive,
|
||||
DockerFileName: dockerFile,
|
||||
Context: uncompressedFiles,
|
||||
}
|
||||
return builderOpts, b.BuildImage(builderOpts)
|
||||
}
|
||||
|
||||
// Compress Archives and compress (TODO) to the artifact path
|
||||
func (a *PackageArtifact) Compress(src string, concurrency int) error {
|
||||
switch a.CompressionType {
|
||||
|
@@ -159,5 +159,46 @@ RUN echo bar > /test2`))
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("Generates packages images", func() {
|
||||
b := NewSimpleDockerBackend()
|
||||
imageprefix := "foo/"
|
||||
testString := []byte(`funky test data`)
|
||||
|
||||
tmpdir, err := ioutil.TempDir(os.TempDir(), "artifact")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer os.RemoveAll(tmpdir) // clean up
|
||||
|
||||
tmpWork, err := ioutil.TempDir(os.TempDir(), "artifact2")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer os.RemoveAll(tmpWork) // clean up
|
||||
|
||||
err = ioutil.WriteFile(filepath.Join(tmpdir, "test"), testString, 0644)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
artifact := NewPackageArtifact(filepath.Join(tmpWork, "fake.tar"))
|
||||
artifact.SetCompileSpec(&LuetCompilationSpec{Package: &pkg.DefaultPackage{Name: "foo", Version: "1.0"}})
|
||||
|
||||
err = artifact.Compress(tmpdir, 1)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
resultingImage := imageprefix + "foo--1.0"
|
||||
opts, err := artifact.GenerateFinalImage(imageprefix, b, false)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(opts.ImageName).To(Equal(resultingImage))
|
||||
|
||||
Expect(b.ImageExists(resultingImage)).To(BeTrue())
|
||||
|
||||
result, err := ioutil.TempDir(os.TempDir(), "result")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
defer os.RemoveAll(result) // clean up
|
||||
|
||||
err = b.ExtractRootfs(CompilerBackendOptions{ImageName: resultingImage, Destination: result}, false)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
content, err := ioutil.ReadFile(filepath.Join(result, "test"))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
Expect(content).To(Equal(testString))
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
@@ -183,10 +183,23 @@ type ManifestEntry struct {
|
||||
Layers []string `json:"Layers"`
|
||||
}
|
||||
|
||||
func (*SimpleDocker) ExtractRootfs(opts compiler.CompilerBackendOptions, keepPerms bool) error {
|
||||
func (b *SimpleDocker) ExtractRootfs(opts compiler.CompilerBackendOptions, keepPerms bool) error {
|
||||
src := opts.SourcePath
|
||||
dst := opts.Destination
|
||||
|
||||
if src == "" && opts.ImageName != "" {
|
||||
tempUnpack, err := ioutil.TempDir(dst, "tempUnpack")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error met while creating tempdir for rootfs")
|
||||
}
|
||||
defer os.RemoveAll(tempUnpack) // clean up
|
||||
imageExport := filepath.Join(tempUnpack, "image.tar")
|
||||
if err := b.ExportImage(compiler.CompilerBackendOptions{ImageName: opts.ImageName, Destination: imageExport}); err != nil {
|
||||
return errors.Wrap(err, "while exporting image before extraction")
|
||||
}
|
||||
src = imageExport
|
||||
}
|
||||
|
||||
rootfs, err := ioutil.TempDir(dst, "tmprootfs")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error met while creating tempdir for rootfs")
|
||||
|
@@ -139,7 +139,7 @@ func (*SimpleImg) ExportImage(opts compiler.CompilerBackendOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: Dup in docker, refactor common code in helpers for shared parts
|
||||
// ExtractRootfs extracts the docker image content inside the destination
|
||||
func (*SimpleImg) ExtractRootfs(opts compiler.CompilerBackendOptions, keepPerms bool) error {
|
||||
name := opts.ImageName
|
||||
path := opts.Destination
|
||||
@@ -153,7 +153,6 @@ func (*SimpleImg) ExtractRootfs(opts compiler.CompilerBackendOptions, keepPerms
|
||||
}
|
||||
Info(":tea: Image " + name + " extracted")
|
||||
return nil
|
||||
//return NewSimpleDockerBackend().ExtractRootfs(opts, keepPerms)
|
||||
}
|
||||
|
||||
// TODO: Use container-diff (https://github.com/GoogleContainerTools/container-diff) for checking out layer diffs
|
||||
|
@@ -114,6 +114,8 @@ type Artifact interface {
|
||||
|
||||
GetChecksums() Checksums
|
||||
SetChecksums(c Checksums)
|
||||
|
||||
GenerateFinalImage(string, CompilerBackend, bool) (CompilerBackendOptions, error)
|
||||
}
|
||||
|
||||
type ArtifactNode struct {
|
||||
|
Reference in New Issue
Block a user