github.com/containers/podman/v4@v4.9.4/pkg/machine/ocipull/oci.go (about)

     1  package ocipull
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/blang/semver/v4"
    10  	"github.com/containers/image/v5/pkg/compression"
    11  	"github.com/containers/image/v5/types"
    12  	"github.com/containers/podman/v4/pkg/machine/define"
    13  	"github.com/containers/podman/v4/version"
    14  	"github.com/containers/storage/pkg/archive"
    15  	"github.com/sirupsen/logrus"
    16  )
    17  
    18  // quay.io/libpod/podman-machine-images:4.6
    19  
    20  const (
    21  	diskImages = "podman-machine-images"
    22  	registry   = "quay.io"
    23  	repo       = "libpod"
    24  )
    25  
    26  type OSVersion struct {
    27  	*semver.Version
    28  }
    29  
    30  type Disker interface {
    31  	Pull() error
    32  	Decompress(compressedFile *define.VMFile) (*define.VMFile, error)
    33  	DiskEndpoint() string
    34  	Unpack() (*define.VMFile, error)
    35  }
    36  
    37  type OCIOpts struct {
    38  	Scheme *OCIKind
    39  	Dir    *string
    40  }
    41  
    42  type OCIKind string
    43  
    44  var (
    45  	OCIDir      OCIKind = "oci-dir"
    46  	OCIRegistry OCIKind = "docker"
    47  	OCIUnknown  OCIKind = "unknown"
    48  )
    49  
    50  func (o OCIKind) String() string {
    51  	switch o {
    52  	case OCIDir:
    53  		return string(OCIDir)
    54  	case OCIRegistry:
    55  		return string(OCIRegistry)
    56  	}
    57  	return string(OCIUnknown)
    58  }
    59  
    60  func (o OCIKind) IsOCIDir() bool {
    61  	return o == OCIDir
    62  }
    63  
    64  func StripOCIReference(input string) string {
    65  	return strings.TrimPrefix(input, "docker://")
    66  }
    67  
    68  func getVersion() *OSVersion {
    69  	v := version.Version
    70  
    71  	// OVERRIDES FOR DEV ONLY
    72  	v.Minor = 6
    73  	v.Pre = nil
    74  	// OVERRIDES FOR DEV ONLY
    75  
    76  	return &OSVersion{&v}
    77  }
    78  
    79  func (o *OSVersion) majorMinor() string {
    80  	return fmt.Sprintf("%d.%d", o.Major, o.Minor)
    81  }
    82  
    83  func (o *OSVersion) diskImage(diskFlavor define.ImageFormat) string {
    84  	return fmt.Sprintf("%s/%s/%s:%s-%s", registry, repo, diskImages, o.majorMinor(), diskFlavor.Kind())
    85  }
    86  
    87  func unpackOCIDir(ociTb, machineImageDir string) (*define.VMFile, error) {
    88  	imageFileName, err := findTarComponent(ociTb)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	unpackedFileName := filepath.Join(machineImageDir, imageFileName)
    94  
    95  	f, err := os.Open(ociTb)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  	defer func() {
   100  		if err := f.Close(); err != nil {
   101  			logrus.Error(err)
   102  		}
   103  	}()
   104  
   105  	uncompressedReader, _, err := compression.AutoDecompress(f)
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  
   110  	defer func() {
   111  		if err := uncompressedReader.Close(); err != nil {
   112  			logrus.Error(err)
   113  		}
   114  	}()
   115  
   116  	logrus.Debugf("untarring %q to %q", ociTb, machineImageDir)
   117  	if err := archive.Untar(uncompressedReader, machineImageDir, &archive.TarOptions{
   118  		NoLchown: true,
   119  	}); err != nil {
   120  		return nil, err
   121  	}
   122  
   123  	return define.NewMachineFile(unpackedFileName, nil)
   124  }
   125  
   126  func localOCIDiskImageDir(blobDirPath string, localBlob *types.BlobInfo) string {
   127  	return filepath.Join(blobDirPath, "blobs", "sha256", localBlob.Digest.Hex())
   128  }
   129  
   130  func finalFQImagePathName(vmName, imageName string) string {
   131  	// imageName here is fully qualified. we need to break
   132  	// it apart and add the vmname
   133  	baseDir, filename := filepath.Split(imageName)
   134  	return filepath.Join(baseDir, fmt.Sprintf("%s-%s", vmName, filename))
   135  }