GitOps for k8s
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

registry.go 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package cache
  2. import (
  3. "encoding/json"
  4. "time"
  5. "github.com/pkg/errors"
  6. fluxerr "github.com/weaveworks/flux/errors"
  7. "github.com/weaveworks/flux/image"
  8. "github.com/weaveworks/flux/registry"
  9. )
  10. var (
  11. ErrNotCached = &fluxerr.Error{
  12. Type: fluxerr.Missing,
  13. Err: errors.New("item not in cache"),
  14. Help: `Image not yet cached
  15. It takes time to initially cache all the images. Please wait.
  16. If you have waited for a long time, check the Flux logs. Potential
  17. reasons for the error are: no internet, no cache, error with the remote
  18. repository.
  19. `,
  20. }
  21. )
  22. // Cache is a local cache of image metadata.
  23. type Cache struct {
  24. Reader Reader
  25. }
  26. // GetImageRepositoryMetadata returns the metadata from an image
  27. // repository (e.g,. at "docker.io/weaveworks/flux")
  28. func (c *Cache) GetImageRepositoryMetadata(id image.Name) (image.RepositoryMetadata, error) {
  29. repoKey := NewRepositoryKey(id.CanonicalName())
  30. bytes, _, err := c.Reader.GetKey(repoKey)
  31. if err != nil {
  32. return image.RepositoryMetadata{}, err
  33. }
  34. var repo ImageRepository
  35. if err = json.Unmarshal(bytes, &repo); err != nil {
  36. return image.RepositoryMetadata{}, err
  37. }
  38. // We only care about the error if we've never successfully
  39. // updated the result.
  40. if repo.LastUpdate.IsZero() {
  41. if repo.LastError != "" {
  42. return image.RepositoryMetadata{}, errors.New(repo.LastError)
  43. }
  44. return image.RepositoryMetadata{}, ErrNotCached
  45. }
  46. return repo.RepositoryMetadata, nil
  47. }
  48. // GetImage gets the manifest of a specific image ref, from its
  49. // registry.
  50. func (c *Cache) GetImage(id image.Ref) (image.Info, error) {
  51. key := NewManifestKey(id.CanonicalRef())
  52. val, _, err := c.Reader.GetKey(key)
  53. if err != nil {
  54. return image.Info{}, err
  55. }
  56. var img registry.ImageEntry
  57. err = json.Unmarshal(val, &img)
  58. if err != nil {
  59. return image.Info{}, err
  60. }
  61. if img.ExcludedReason != "" {
  62. return image.Info{}, errors.New(img.ExcludedReason)
  63. }
  64. return img.Info, nil
  65. }
  66. // ImageRepository holds the last good information on an image
  67. // repository.
  68. //
  69. // Whenever we successfully fetch a set (partial or full) of image metadata,
  70. // `LastUpdate`, `Tags` and `Images` shall each be assigned a value, and
  71. // `LastError` will be cleared.
  72. //
  73. // If we cannot for any reason obtain the set of image metadata,
  74. // `LastError` shall be assigned a value, and the other fields left
  75. // alone.
  76. //
  77. // It's possible to have all fields populated: this means at some
  78. // point it was successfully fetched, but since then, there's been an
  79. // error. It's then up to the caller to decide what to do with the
  80. // value (show the images, but also indicate there's a problem, for
  81. // example).
  82. type ImageRepository struct {
  83. image.RepositoryMetadata
  84. LastError string
  85. LastUpdate time.Time
  86. }