main.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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 []MetadataField `json:"metadata"`
  20. }
  21. type ImageMetadata struct {
  22. Env []string `json:"env"`
  23. User string `json:"user"`
  24. }
  25. type MetadataField struct {
  26. Name string `json:"name"`
  27. Value string `json:"value"`
  28. }
  29. func main() {
  30. logrus.SetOutput(os.Stderr)
  31. logrus.SetFormatter(&logrus.TextFormatter{
  32. ForceColors: true,
  33. })
  34. color.NoColor = false
  35. var req InRequest
  36. err := json.NewDecoder(os.Stdin).Decode(&req)
  37. if err != nil {
  38. logrus.Errorf("invalid payload: %s", err)
  39. os.Exit(1)
  40. return
  41. }
  42. if len(os.Args) < 2 {
  43. logrus.Errorf("destination path not specified")
  44. os.Exit(1)
  45. return
  46. }
  47. dest := os.Args[1]
  48. ref := req.Source.Repository + "@" + req.Version.Digest
  49. n, err := name.ParseReference(ref, name.WeakValidation)
  50. if err != nil {
  51. logrus.Errorf("failed to resolve name: %s", err)
  52. os.Exit(1)
  53. return
  54. }
  55. fmt.Fprintf(os.Stderr, "fetching %s@%s\n", color.GreenString(req.Source.Repository), color.YellowString(req.Version.Digest))
  56. image, err := remote.Image(n)
  57. if err != nil {
  58. logrus.Errorf("failed to locate remote image: %s", err)
  59. os.Exit(1)
  60. return
  61. }
  62. err = unpackImage(filepath.Join(dest, "rootfs"), image)
  63. if err != nil {
  64. logrus.Errorf("failed to extract image: %s", err)
  65. os.Exit(1)
  66. return
  67. }
  68. cfg, err := image.ConfigFile()
  69. if err != nil {
  70. logrus.Errorf("failed to inspect image config: %s", err)
  71. os.Exit(1)
  72. return
  73. }
  74. meta, err := os.Create(filepath.Join(dest, "metadata.json"))
  75. if err != nil {
  76. logrus.Errorf("failed to create image metadata: %s", err)
  77. os.Exit(1)
  78. return
  79. }
  80. err = json.NewEncoder(meta).Encode(ImageMetadata{
  81. Env: cfg.ContainerConfig.Env,
  82. User: cfg.ContainerConfig.User,
  83. })
  84. if err != nil {
  85. logrus.Errorf("failed to write image metadata: %s", err)
  86. os.Exit(1)
  87. return
  88. }
  89. err = meta.Close()
  90. if err != nil {
  91. logrus.Errorf("failed to close image metadata file: %s", err)
  92. os.Exit(1)
  93. return
  94. }
  95. json.NewEncoder(os.Stdout).Encode(InResponse{
  96. Version: req.Version,
  97. Metadata: []MetadataField{},
  98. })
  99. }