docker-multi-arch-builder/internal/image.go

94 lines
2.5 KiB
Go

package internal
import (
"fmt"
log "github.com/sirupsen/logrus"
)
type Image struct {
Name string
tag string
}
func (image Image) String() string {
imageName := image.Name
if image.tag != "" {
imageName = fmt.Sprintf("%s:%s", imageName, image.tag)
}
return imageName
}
type ManifestImage struct {
Image
BuildDir string
buildOpt string
layers Layers
}
func NewManifest(imageName string, imageTag string, buildDir string, platforms []Platform, buildOpt string) ManifestImage {
return ManifestImage{
Image: Image{
imageName,
imageTag,
},
layers: NewLayers(imageName, platforms),
BuildDir: buildDir,
buildOpt: buildOpt,
}
}
// CreateLayers build and push each layer image
func (manifest *ManifestImage) CreateLayers(registry Registry) {
for _, layer := range manifest.layers {
layer.CreateLayer(registry, manifest.BuildDir, manifest.buildOpt)
}
}
// CreateManifest produce manifest list of layers
func (manifest *ManifestImage) CreateManifest(registry Registry) {
const insecureRegistryOpt = "--insecure"
// $(OCI_CLI) manifest create $(OCI_OPT) $(REGISTRY_IP):5000/$(1) --amend docker.registry:5000/registry-ui:linux-armv6
var amend []string
for _, layer := range manifest.layers {
amend = append(amend, "--amend")
amend = append(amend, fmt.Sprintf("%s/%s", registry.String(), layer.Image.String()))
}
if stdout, err := runOciCli("docker", "manifest create", insecureRegistryOpt, registry, manifest.Image, amend...); err != nil {
log.Fatalf("manifest creation failed : %v%v", stdout, err)
} else {
log.Debug(stdout)
}
// $(OCI_CLI) manifest annotate --os linux --arch arm --variant v6 $(REGISTRY_IP):5000/$(1) $(REGISTRY_IP):5000/$(1):linux-armv6
for _, layer := range manifest.layers {
manifest.annotateManifest(registry, layer)
}
// $(OCI_CLI) manifest push $(OCI_OPT) $(REGISTRY_IP):5000/$(1)
if stdout, err := runOciCli("docker", "manifest push", insecureRegistryOpt, registry, manifest.Image); err != nil {
log.Fatalf("manifest push failed : %v%v", stdout, err)
} else {
log.Debug(stdout)
}
}
func (manifest *ManifestImage) annotateManifest(registry Registry, layer Layer) {
annotation := fmt.Sprintf("--os %s --arch %s", layer.os, layer.arch)
if layer.variant != "" {
annotation = fmt.Sprintf("%s --variant %s", annotation, layer.variant)
}
stdout, err := runOciCli("docker", "manifest annotate",
annotation,
registry, manifest.Image,
fmt.Sprintf("%s/%s", registry.String(), layer.Image.String()),
)
if err != nil {
log.Warnf("layer %s not annotated", layer.String())
} else {
log.Debug(stdout)
}
}