| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- package main
- import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- "path"
- "path/filepath"
- resource "github.com/concourse/registry-image-resource"
- color "github.com/fatih/color"
- "github.com/google/go-containerregistry/pkg/name"
- "github.com/google/go-containerregistry/pkg/v1"
- "github.com/google/go-containerregistry/pkg/v1/remote"
- "github.com/google/go-containerregistry/pkg/v1/tarball"
- "github.com/sirupsen/logrus"
- )
- type InRequest struct {
- Source resource.Source `json:"source"`
- Params resource.GetParams `json:"params"`
- Version resource.Version `json:"version"`
- }
- type InResponse struct {
- Version resource.Version `json:"version"`
- Metadata []resource.MetadataField `json:"metadata"`
- }
- type ImageMetadata struct {
- Env []string `json:"env"`
- User string `json:"user"`
- }
- func main() {
- logrus.SetOutput(os.Stderr)
- logrus.SetFormatter(&logrus.TextFormatter{
- ForceColors: true,
- })
- color.NoColor = false
- var req InRequest
- decoder := json.NewDecoder(os.Stdin)
- decoder.DisallowUnknownFields()
- err := decoder.Decode(&req)
- if err != nil {
- logrus.Errorf("invalid payload: %s", err)
- os.Exit(1)
- return
- }
- if req.Source.Debug {
- logrus.SetLevel(logrus.DebugLevel)
- }
- if len(os.Args) < 2 {
- logrus.Errorf("destination path not specified")
- os.Exit(1)
- return
- }
- dest := os.Args[1]
- ref := req.Source.Repository + "@" + req.Version.Digest
- n, err := name.ParseReference(ref, name.WeakValidation)
- if err != nil {
- logrus.Errorf("failed to resolve name: %s", err)
- os.Exit(1)
- return
- }
- fmt.Fprintf(os.Stderr, "fetching %s@%s\n", color.GreenString(req.Source.Repository), color.YellowString(req.Version.Digest))
- image, err := remote.Image(n)
- if err != nil {
- logrus.Errorf("failed to locate remote image: %s", err)
- os.Exit(1)
- return
- }
- switch req.Params.Format() {
- case "oci":
- ociFormat(dest, req, image)
- case "rootfs":
- rootfsFormat(dest, req, image)
- }
- err = saveDigest(dest, image)
- if err != nil {
- logrus.Errorf("failed to save image digest: %s", err)
- os.Exit(1)
- return
- }
- json.NewEncoder(os.Stdout).Encode(InResponse{
- Version: req.Version,
- Metadata: []resource.MetadataField{},
- })
- }
- func saveDigest(dest string, image v1.Image) error {
- digest, err := image.Digest()
- if err != nil {
- return err
- }
- digestDest := path.Join(dest, "digest")
- return ioutil.WriteFile(digestDest, []byte(digest.String()), 0644)
- }
- func ociFormat(dest string, req InRequest, image v1.Image) {
- tag, err := name.NewTag(req.Source.Name(), name.WeakValidation)
- if err != nil {
- logrus.Errorf("failed to construct tag reference: %s", err)
- os.Exit(1)
- return
- }
- err = tarball.WriteToFile(filepath.Join(dest, "image.tar"), tag, image)
- if err != nil {
- logrus.Errorf("failed to write OCI image: %s", err)
- os.Exit(1)
- return
- }
- }
- func rootfsFormat(dest string, req InRequest, image v1.Image) {
- err := unpackImage(filepath.Join(dest, "rootfs"), image, req.Source.Debug)
- if err != nil {
- logrus.Errorf("failed to extract image: %s", err)
- os.Exit(1)
- return
- }
- cfg, err := image.ConfigFile()
- if err != nil {
- logrus.Errorf("failed to inspect image config: %s", err)
- os.Exit(1)
- return
- }
- meta, err := os.Create(filepath.Join(dest, "metadata.json"))
- if err != nil {
- logrus.Errorf("failed to create image metadata: %s", err)
- os.Exit(1)
- return
- }
- env := cfg.Config.Env
- if len(env) == 0 {
- env = cfg.ContainerConfig.Env
- }
- user := cfg.Config.User
- if user == "" {
- user = cfg.ContainerConfig.User
- }
- err = json.NewEncoder(meta).Encode(ImageMetadata{
- Env: env,
- User: user,
- })
- if err != nil {
- logrus.Errorf("failed to write image metadata: %s", err)
- os.Exit(1)
- return
- }
- err = meta.Close()
- if err != nil {
- logrus.Errorf("failed to close image metadata file: %s", err)
- os.Exit(1)
- return
- }
- }
|