2023-05-16 15:59:04 +00:00
|
|
|
package utils
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"github.com/containerd/containerd/archive"
|
|
|
|
"github.com/google/go-containerregistry/pkg/authn"
|
|
|
|
"github.com/google/go-containerregistry/pkg/name"
|
|
|
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
|
|
|
"github.com/google/go-containerregistry/pkg/v1/daemon"
|
|
|
|
"github.com/google/go-containerregistry/pkg/v1/mutate"
|
|
|
|
"github.com/google/go-containerregistry/pkg/v1/remote"
|
|
|
|
"net/http"
|
|
|
|
"runtime"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ExtractOCIImage will extract a given targetImage into a given targetDestination and pull from the local repo if set.
|
2023-05-17 08:04:20 +00:00
|
|
|
func ExtractOCIImage(targetImage, targetDestination, targetPlatform string, isLocal bool) error {
|
|
|
|
var platform *v1.Platform
|
|
|
|
var err error
|
|
|
|
|
|
|
|
if targetPlatform != "" {
|
|
|
|
platform, err = v1.ParsePlatform(targetPlatform)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
platform, err = v1.ParsePlatform(fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-05-16 15:59:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ref, err := name.ParseReference(targetImage)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
img, err := getimage(ref, *platform, isLocal)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
reader := mutate.Extract(img)
|
|
|
|
|
|
|
|
_, err = archive.Apply(context.Background(), targetDestination, reader)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// image returns the proper image to pull with transport and auth
|
|
|
|
func getimage(ref name.Reference, platform v1.Platform, local bool) (v1.Image, error) {
|
|
|
|
if local {
|
|
|
|
return daemon.Image(ref)
|
|
|
|
}
|
|
|
|
|
|
|
|
return remote.Image(ref,
|
|
|
|
remote.WithTransport(http.DefaultTransport),
|
|
|
|
remote.WithPlatform(platform),
|
|
|
|
remote.WithAuthFromKeychain(authn.DefaultKeychain),
|
|
|
|
)
|
|
|
|
}
|