reference.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. Copyright The containerd Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package archive
  14. import (
  15. "strings"
  16. "github.com/containerd/cri/pkg/util"
  17. digest "github.com/opencontainers/go-digest"
  18. "github.com/pkg/errors"
  19. )
  20. // FilterRefPrefix restricts references to having the given image
  21. // prefix. Tag-only references will have the prefix prepended.
  22. func FilterRefPrefix(image string) func(string) string {
  23. return refTranslator(image, true)
  24. }
  25. // AddRefPrefix prepends the given image prefix to tag-only references,
  26. // while leaving returning full references unmodified.
  27. func AddRefPrefix(image string) func(string) string {
  28. return refTranslator(image, false)
  29. }
  30. // refTranslator creates a reference which only has a tag or verifies
  31. // a full reference.
  32. func refTranslator(image string, checkPrefix bool) func(string) string {
  33. return func(ref string) string {
  34. // Check if ref is full reference
  35. if strings.ContainsAny(ref, "/:@") {
  36. // If not prefixed, don't include image
  37. if checkPrefix && !isImagePrefix(ref, image) {
  38. return ""
  39. }
  40. return ref
  41. }
  42. return image + ":" + ref
  43. }
  44. }
  45. func isImagePrefix(s, prefix string) bool {
  46. if !strings.HasPrefix(s, prefix) {
  47. return false
  48. }
  49. if len(s) > len(prefix) {
  50. switch s[len(prefix)] {
  51. case '/', ':', '@':
  52. // Prevent matching partial namespaces
  53. default:
  54. return false
  55. }
  56. }
  57. return true
  58. }
  59. func normalizeReference(ref string) (string, error) {
  60. // TODO: Replace this function to not depend on reference package
  61. normalized, err := util.NormalizeImageRef(ref)
  62. if err != nil {
  63. return "", errors.Wrapf(err, "normalize image ref %q", ref)
  64. }
  65. return normalized.String(), nil
  66. }
  67. // DigestTranslator creates a digest reference by adding the
  68. // digest to an image name
  69. func DigestTranslator(prefix string) func(digest.Digest) string {
  70. return func(dgst digest.Digest) string {
  71. return prefix + "@" + dgst.String()
  72. }
  73. }