/* Copyright (c) Edgeless Systems GmbH SPDX-License-Identifier: AGPL-3.0-only */ /* This package provides container image names, registry info and digests. It should only be used by the CLI and never be imported by any package that ends up in a container image to avoid circular dependencies. */ package containerimage import ( "errors" "path" "regexp" ) // Image is a container image reference. // It has the following format: // //:@ // where is the registry where the image is located, // is the (optional) prefix of the image name, // is the name of the image, // is the (optional) tag of the image, // is the digest of the image. type Image struct { // Registry is the registry where the image is located. Registry string // Prefix is the prefix of the image name. Prefix string // Name is the name of the image. Name string // Tag is the tag of the image. Tag string // Digest is the digest of the image. Digest string } // Validate validates the image. func (i Image) Validate() error { if i.Registry == "" { return errors.New("image registry is empty") } if i.Name == "" { return errors.New("image name is empty") } if i.Digest == "" { return errors.New("image digest is empty") } if matched := digestRegexp.MatchString(i.Digest); !matched { return errors.New("image digest is not valid") } return nil } // String returns the image as a string. // The format is //:@ // or a shorter version if prefix or tag are empty. func (i Image) String() string { var base string if i.Prefix == "" { base = path.Join(i.Registry, i.Name) } else { base = path.Join(i.Registry, i.Prefix, i.Name) } var tag string if i.Tag != "" { tag = ":" + i.Tag } return base + tag + "@" + i.Digest } // Builder is a builder for container images. type Builder struct { Default Image Registry string Prefix string } // NewBuilder creates a new builder for container images. func NewBuilder(def Image, registry, prefix string) *Builder { return &Builder{ Default: def, Registry: registry, Prefix: prefix, } } // Build builds a container image. func (b *Builder) Build() Image { img := Image{} if b.Registry == "" { img.Registry = b.Default.Registry } else { img.Registry = b.Registry } if b.Prefix == "" { img.Prefix = b.Default.Prefix } else { img.Prefix = b.Prefix } img.Name = b.Default.Name img.Tag = b.Default.Tag img.Digest = b.Default.Digest return img } var digestRegexp = regexp.MustCompile(`^sha256:[a-f0-9]{64}$`)