main.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. resource "github.com/concourse/registry-image-resource"
  8. color "github.com/fatih/color"
  9. "github.com/google/go-containerregistry/pkg/name"
  10. "github.com/google/go-containerregistry/pkg/v1/remote"
  11. "github.com/sirupsen/logrus"
  12. )
  13. type InRequest struct {
  14. Source resource.Source `json:"source"`
  15. Version resource.Version `json:"version"`
  16. }
  17. type InResponse struct {
  18. Version resource.Version `json:"version"`
  19. Metadata []resource.MetadataField `json:"metadata"`
  20. }
  21. type ImageMetadata struct {
  22. Env []string `json:"env"`
  23. User string `json:"user"`
  24. }
  25. func main() {
  26. logrus.SetOutput(os.Stderr)
  27. logrus.SetFormatter(&logrus.TextFormatter{
  28. ForceColors: true,
  29. })
  30. color.NoColor = false
  31. var req InRequest
  32. err := json.NewDecoder(os.Stdin).Decode(&req)
  33. if err != nil {
  34. logrus.Errorf("invalid payload: %s", err)
  35. os.Exit(1)
  36. return
  37. }
  38. if req.Source.Debug {
  39. logrus.SetLevel(logrus.DebugLevel)
  40. }
  41. if len(os.Args) < 2 {
  42. logrus.Errorf("destination path not specified")
  43. os.Exit(1)
  44. return
  45. }
  46. dest := os.Args[1]
  47. ref := req.Source.Repository + "@" + req.Version.Digest
  48. n, err := name.ParseReference(ref, name.WeakValidation)
  49. if err != nil {
  50. logrus.Errorf("failed to resolve name: %s", err)
  51. os.Exit(1)
  52. return
  53. }
  54. fmt.Fprintf(os.Stderr, "fetching %s@%s\n", color.GreenString(req.Source.Repository), color.YellowString(req.Version.Digest))
  55. image, err := remote.Image(n)
  56. if err != nil {
  57. logrus.Errorf("failed to locate remote image: %s", err)
  58. os.Exit(1)
  59. return
  60. }
  61. err = unpackImage(filepath.Join(dest, "rootfs"), image, req.Source.Debug)
  62. if err != nil {
  63. logrus.Errorf("failed to extract image: %s", err)
  64. os.Exit(1)
  65. return
  66. }
  67. cfg, err := image.ConfigFile()
  68. if err != nil {
  69. logrus.Errorf("failed to inspect image config: %s", err)
  70. os.Exit(1)
  71. return
  72. }
  73. meta, err := os.Create(filepath.Join(dest, "metadata.json"))
  74. if err != nil {
  75. logrus.Errorf("failed to create image metadata: %s", err)
  76. os.Exit(1)
  77. return
  78. }
  79. err = json.NewEncoder(meta).Encode(ImageMetadata{
  80. Env: cfg.ContainerConfig.Env,
  81. User: cfg.ContainerConfig.User,
  82. })
  83. if err != nil {
  84. logrus.Errorf("failed to write image metadata: %s", err)
  85. os.Exit(1)
  86. return
  87. }
  88. err = meta.Close()
  89. if err != nil {
  90. logrus.Errorf("failed to close image metadata file: %s", err)
  91. os.Exit(1)
  92. return
  93. }
  94. json.NewEncoder(os.Stdout).Encode(InResponse{
  95. Version: req.Version,
  96. Metadata: []resource.MetadataField{},
  97. })
  98. }