Files
Daniel J Walsh 11e83a0952 Update vendor of containers/buildah v1.28.0
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2022-10-03 10:17:14 -04:00

155 lines
4.8 KiB
Go

package util
import (
"fmt"
"io"
"os"
"path/filepath"
"github.com/containers/buildah/define"
"github.com/containers/common/libimage"
"github.com/containers/image/v5/types"
encconfig "github.com/containers/ocicrypt/config"
enchelpers "github.com/containers/ocicrypt/helpers"
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive"
"github.com/containers/storage/pkg/unshare"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
)
// LookupImage returns *Image to corresponding imagename or id
func LookupImage(ctx *types.SystemContext, store storage.Store, image string) (*libimage.Image, error) {
systemContext := ctx
if systemContext == nil {
systemContext = &types.SystemContext{}
}
runtime, err := libimage.RuntimeFromStore(store, &libimage.RuntimeOptions{SystemContext: systemContext})
if err != nil {
return nil, err
}
localImage, _, err := runtime.LookupImage(image, nil)
if err != nil {
return nil, err
}
return localImage, nil
}
// NormalizePlatform validates and translate the platform to the canonical value.
//
// For example, if "Aarch64" is encountered, we change it to "arm64" or if
// "x86_64" is encountered, it becomes "amd64".
//
// Wrapper around libimage.NormalizePlatform to return and consume
// v1.Platform instead of independent os, arch and variant.
func NormalizePlatform(platform v1.Platform) v1.Platform {
os, arch, variant := libimage.NormalizePlatform(platform.OS, platform.Architecture, platform.Variant)
return v1.Platform{
OS: os,
Architecture: arch,
Variant: variant,
}
}
// GetTempDir returns base for a temporary directory on host.
func GetTempDir() string {
if tmpdir, ok := os.LookupEnv("TMPDIR"); ok {
return tmpdir
}
return "/var/tmp"
}
// ExportFromReader reads bytes from given reader and exports to external tar, directory or stdout.
func ExportFromReader(input io.Reader, opts define.BuildOutputOption) error {
var err error
if !filepath.IsAbs(opts.Path) {
opts.Path, err = filepath.Abs(opts.Path)
if err != nil {
return err
}
}
if opts.IsDir {
// In order to keep this feature as close as possible to
// buildkit it was decided to preserve ownership when
// invoked as root since caller already has access to artifacts
// therefore we can preserve ownership as is, however for rootless users
// ownership has to be changed so exported artifacts can still
// be accessible by unpriviledged users.
// See: https://github.com/containers/buildah/pull/3823#discussion_r829376633
noLChown := false
if unshare.IsRootless() {
noLChown = true
}
err = os.MkdirAll(opts.Path, 0700)
if err != nil {
return fmt.Errorf("failed while creating the destination path %q: %w", opts.Path, err)
}
err = chrootarchive.Untar(input, opts.Path, &archive.TarOptions{NoLchown: noLChown})
if err != nil {
return fmt.Errorf("failed while performing untar at %q: %w", opts.Path, err)
}
} else {
outFile := os.Stdout
if !opts.IsStdout {
outFile, err = os.Create(opts.Path)
if err != nil {
return fmt.Errorf("failed while creating destination tar at %q: %w", opts.Path, err)
}
defer outFile.Close()
}
_, err = io.Copy(outFile, input)
if err != nil {
return fmt.Errorf("failed while performing copy to %q: %w", opts.Path, err)
}
}
return nil
}
// DecryptConfig translates decryptionKeys into a DescriptionConfig structure
func DecryptConfig(decryptionKeys []string) (*encconfig.DecryptConfig, error) {
decryptConfig := &encconfig.DecryptConfig{}
if len(decryptionKeys) > 0 {
// decryption
dcc, err := enchelpers.CreateCryptoConfig([]string{}, decryptionKeys)
if err != nil {
return nil, fmt.Errorf("invalid decryption keys: %w", err)
}
cc := encconfig.CombineCryptoConfigs([]encconfig.CryptoConfig{dcc})
decryptConfig = cc.DecryptConfig
}
return decryptConfig, nil
}
// EncryptConfig translates encryptionKeys into a EncriptionsConfig structure
func EncryptConfig(encryptionKeys []string, encryptLayers []int) (*encconfig.EncryptConfig, *[]int, error) {
var encLayers *[]int
var encConfig *encconfig.EncryptConfig
if len(encryptionKeys) > 0 {
// encryption
encLayers = &encryptLayers
ecc, err := enchelpers.CreateCryptoConfig(encryptionKeys, []string{})
if err != nil {
return nil, nil, fmt.Errorf("invalid encryption keys: %w", err)
}
cc := encconfig.CombineCryptoConfigs([]encconfig.CryptoConfig{ecc})
encConfig = cc.EncryptConfig
}
return encConfig, encLayers, nil
}
// GetFormat translates format string into either docker or OCI format constant
func GetFormat(format string) (string, error) {
switch format {
case define.OCI:
return define.OCIv1ImageManifest, nil
case define.DOCKER:
return define.Dockerv2ImageManifest, nil
default:
return "", fmt.Errorf("unrecognized image type %q", format)
}
}