mirror of
https://github.com/mudler/luet.git
synced 2025-09-03 00:06:36 +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
|
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
|
// Compress Archives and compress (TODO) to the artifact path
|
||||||
func (a *PackageArtifact) Compress(src string, concurrency int) error {
|
func (a *PackageArtifact) Compress(src string, concurrency int) error {
|
||||||
switch a.CompressionType {
|
switch a.CompressionType {
|
||||||
|
@@ -159,5 +159,46 @@ RUN echo bar > /test2`))
|
|||||||
Expect(err).To(HaveOccurred())
|
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"`
|
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
|
src := opts.SourcePath
|
||||||
dst := opts.Destination
|
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")
|
rootfs, err := ioutil.TempDir(dst, "tmprootfs")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Error met while creating tempdir for rootfs")
|
return errors.Wrap(err, "Error met while creating tempdir for rootfs")
|
||||||
|
@@ -139,7 +139,7 @@ func (*SimpleImg) ExportImage(opts compiler.CompilerBackendOptions) error {
|
|||||||
return nil
|
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 {
|
func (*SimpleImg) ExtractRootfs(opts compiler.CompilerBackendOptions, keepPerms bool) error {
|
||||||
name := opts.ImageName
|
name := opts.ImageName
|
||||||
path := opts.Destination
|
path := opts.Destination
|
||||||
@@ -153,7 +153,6 @@ func (*SimpleImg) ExtractRootfs(opts compiler.CompilerBackendOptions, keepPerms
|
|||||||
}
|
}
|
||||||
Info(":tea: Image " + name + " extracted")
|
Info(":tea: Image " + name + " extracted")
|
||||||
return nil
|
return nil
|
||||||
//return NewSimpleDockerBackend().ExtractRootfs(opts, keepPerms)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use container-diff (https://github.com/GoogleContainerTools/container-diff) for checking out layer diffs
|
// TODO: Use container-diff (https://github.com/GoogleContainerTools/container-diff) for checking out layer diffs
|
||||||
|
@@ -114,6 +114,8 @@ type Artifact interface {
|
|||||||
|
|
||||||
GetChecksums() Checksums
|
GetChecksums() Checksums
|
||||||
SetChecksums(c Checksums)
|
SetChecksums(c Checksums)
|
||||||
|
|
||||||
|
GenerateFinalImage(string, CompilerBackend, bool) (CompilerBackendOptions, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArtifactNode struct {
|
type ArtifactNode struct {
|
||||||
|
Reference in New Issue
Block a user