Browse code

migrate to new github.com/distribution/reference module

The "reference" package was moved to a separate module, which was extracted
from https://github.com/distribution/distribution/commit/b9b19409cf458dcb9e1253ff44ba75bd0620faa6

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2023/08/31 01:31:46
Showing 104 changed files
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"fmt"
6 6
 	"strconv"
7 7
 
8
-	"github.com/docker/distribution/reference"
8
+	"github.com/distribution/reference"
9 9
 	"github.com/docker/docker/api/types"
10 10
 	"github.com/docker/docker/api/types/backend"
11 11
 	"github.com/docker/docker/api/types/events"
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"fmt"
6 6
 	"io"
7 7
 
8
-	"github.com/docker/distribution/reference"
8
+	"github.com/distribution/reference"
9 9
 	"github.com/docker/docker/image"
10 10
 	"github.com/pkg/errors"
11 11
 )
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"strconv"
7 7
 	"strings"
8 8
 
9
-	"github.com/docker/distribution/reference"
9
+	"github.com/distribution/reference"
10 10
 )
11 11
 
12 12
 // BoolValue transforms a form value in different formats into a boolean type.
... ...
@@ -3,8 +3,8 @@ package distribution // import "github.com/docker/docker/api/server/router/distr
3 3
 import (
4 4
 	"context"
5 5
 
6
+	"github.com/distribution/reference"
6 7
 	"github.com/docker/distribution"
7
-	"github.com/docker/distribution/reference"
8 8
 	"github.com/docker/docker/api/types/registry"
9 9
 )
10 10
 
... ...
@@ -5,10 +5,10 @@ import (
5 5
 	"encoding/json"
6 6
 	"net/http"
7 7
 
8
+	"github.com/distribution/reference"
8 9
 	"github.com/docker/distribution/manifest/manifestlist"
9 10
 	"github.com/docker/distribution/manifest/schema1"
10 11
 	"github.com/docker/distribution/manifest/schema2"
11
-	"github.com/docker/distribution/reference"
12 12
 	"github.com/docker/docker/api/server/httputils"
13 13
 	"github.com/docker/docker/api/types/registry"
14 14
 	"github.com/docker/docker/errdefs"
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"context"
5 5
 	"io"
6 6
 
7
-	"github.com/docker/distribution/reference"
7
+	"github.com/distribution/reference"
8 8
 	"github.com/docker/docker/api/types"
9 9
 	"github.com/docker/docker/api/types/filters"
10 10
 	"github.com/docker/docker/api/types/image"
... ...
@@ -10,7 +10,7 @@ import (
10 10
 	"time"
11 11
 
12 12
 	"github.com/containerd/containerd/platforms"
13
-	"github.com/docker/distribution/reference"
13
+	"github.com/distribution/reference"
14 14
 	"github.com/docker/docker/api/server/httputils"
15 15
 	"github.com/docker/docker/api/types"
16 16
 	"github.com/docker/docker/api/types/filters"
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"io"
6 6
 	"net/http"
7 7
 
8
-	"github.com/docker/distribution/reference"
8
+	"github.com/distribution/reference"
9 9
 	"github.com/docker/docker/api/types"
10 10
 	"github.com/docker/docker/api/types/filters"
11 11
 	"github.com/docker/docker/api/types/registry"
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"strconv"
7 7
 	"strings"
8 8
 
9
-	"github.com/docker/distribution/reference"
9
+	"github.com/distribution/reference"
10 10
 	"github.com/docker/docker/api/server/httputils"
11 11
 	"github.com/docker/docker/api/types"
12 12
 	"github.com/docker/docker/api/types/filters"
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"io"
6 6
 	"time"
7 7
 
8
-	"github.com/docker/distribution/reference"
8
+	"github.com/distribution/reference"
9 9
 	"github.com/docker/docker/api/types/container"
10 10
 )
11 11
 
... ...
@@ -20,7 +20,7 @@ import (
20 20
 	"github.com/containerd/containerd/remotes"
21 21
 	"github.com/containerd/containerd/remotes/docker"
22 22
 	"github.com/containerd/containerd/remotes/docker/schema1"
23
-	distreference "github.com/docker/distribution/reference"
23
+	distreference "github.com/distribution/reference"
24 24
 	dimages "github.com/docker/docker/daemon/images"
25 25
 	"github.com/docker/docker/distribution/metadata"
26 26
 	"github.com/docker/docker/distribution/xfer"
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"github.com/containerd/containerd/content"
9 9
 	"github.com/containerd/containerd/images"
10 10
 	"github.com/containerd/containerd/remotes/docker"
11
-	distreference "github.com/docker/distribution/reference"
11
+	distreference "github.com/distribution/reference"
12 12
 	imagestore "github.com/docker/docker/image"
13 13
 	"github.com/docker/docker/reference"
14 14
 	"github.com/moby/buildkit/cache/remotecache"
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"fmt"
7 7
 	"strings"
8 8
 
9
-	distref "github.com/docker/distribution/reference"
9
+	distref "github.com/distribution/reference"
10 10
 	"github.com/docker/docker/image"
11 11
 	"github.com/docker/docker/layer"
12 12
 	"github.com/moby/buildkit/exporter"
... ...
@@ -3,7 +3,7 @@ package overrides
3 3
 import (
4 4
 	"errors"
5 5
 
6
-	"github.com/docker/distribution/reference"
6
+	"github.com/distribution/reference"
7 7
 )
8 8
 
9 9
 // SanitizeRepoAndTags parses the raw names to a slice of repoAndTag.
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"errors"
7 7
 	"net/url"
8 8
 
9
-	"github.com/docker/distribution/reference"
9
+	"github.com/distribution/reference"
10 10
 	"github.com/docker/docker/api/types"
11 11
 )
12 12
 
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"net/url"
8 8
 	"strings"
9 9
 
10
-	"github.com/docker/distribution/reference"
10
+	"github.com/distribution/reference"
11 11
 	"github.com/docker/docker/api/types"
12 12
 	"github.com/docker/docker/api/types/registry"
13 13
 )
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"net/url"
7 7
 	"strings"
8 8
 
9
-	"github.com/docker/distribution/reference"
9
+	"github.com/distribution/reference"
10 10
 	"github.com/docker/docker/api/types"
11 11
 )
12 12
 
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"net/url"
7 7
 	"strings"
8 8
 
9
-	"github.com/docker/distribution/reference"
9
+	"github.com/distribution/reference"
10 10
 	"github.com/docker/docker/api/types"
11 11
 	"github.com/docker/docker/errdefs"
12 12
 )
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"net/http"
8 8
 	"net/url"
9 9
 
10
-	"github.com/docker/distribution/reference"
10
+	"github.com/distribution/reference"
11 11
 	"github.com/docker/docker/api/types"
12 12
 	"github.com/docker/docker/api/types/registry"
13 13
 	"github.com/docker/docker/errdefs"
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"context"
5 5
 	"net/url"
6 6
 
7
-	"github.com/docker/distribution/reference"
7
+	"github.com/distribution/reference"
8 8
 	"github.com/pkg/errors"
9 9
 )
10 10
 
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"net/http"
8 8
 	"net/url"
9 9
 
10
-	"github.com/docker/distribution/reference"
10
+	"github.com/distribution/reference"
11 11
 	"github.com/docker/docker/api/types"
12 12
 	"github.com/docker/docker/api/types/registry"
13 13
 	"github.com/docker/docker/errdefs"
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"net/http"
7 7
 	"net/url"
8 8
 
9
-	"github.com/docker/distribution/reference"
9
+	"github.com/distribution/reference"
10 10
 	"github.com/docker/docker/api/types"
11 11
 	"github.com/docker/docker/api/types/registry"
12 12
 	"github.com/pkg/errors"
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"net/http"
8 8
 	"strings"
9 9
 
10
-	"github.com/docker/distribution/reference"
10
+	"github.com/distribution/reference"
11 11
 	"github.com/docker/docker/api/types"
12 12
 	"github.com/docker/docker/api/types/registry"
13 13
 	"github.com/docker/docker/api/types/swarm"
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"net/http"
7 7
 
8 8
 	"github.com/containerd/containerd/log"
9
-	"github.com/docker/distribution/reference"
9
+	"github.com/distribution/reference"
10 10
 	"github.com/docker/docker/api/types"
11 11
 	"github.com/docker/docker/api/types/registry"
12 12
 	"github.com/docker/docker/api/types/swarm/runtime"
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"testing"
10 10
 	"time"
11 11
 
12
-	"github.com/docker/distribution/reference"
12
+	"github.com/distribution/reference"
13 13
 	"github.com/docker/docker/api/types"
14 14
 	"github.com/docker/docker/api/types/registry"
15 15
 	"github.com/docker/docker/api/types/swarm/runtime"
... ...
@@ -5,8 +5,8 @@ import (
5 5
 	"io"
6 6
 	"time"
7 7
 
8
+	"github.com/distribution/reference"
8 9
 	"github.com/docker/distribution"
9
-	"github.com/docker/distribution/reference"
10 10
 	"github.com/docker/docker/api/types"
11 11
 	"github.com/docker/docker/api/types/backend"
12 12
 	"github.com/docker/docker/api/types/container"
... ...
@@ -12,7 +12,7 @@ import (
12 12
 	"time"
13 13
 
14 14
 	"github.com/containerd/containerd/log"
15
-	"github.com/docker/distribution/reference"
15
+	"github.com/distribution/reference"
16 16
 	"github.com/docker/docker/api/types"
17 17
 	"github.com/docker/docker/api/types/backend"
18 18
 	containertypes "github.com/docker/docker/api/types/container"
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"strings"
10 10
 
11 11
 	"github.com/containerd/containerd/log"
12
-	"github.com/docker/distribution/reference"
12
+	"github.com/distribution/reference"
13 13
 	"github.com/docker/docker/api/types"
14 14
 	enginecontainer "github.com/docker/docker/api/types/container"
15 15
 	"github.com/docker/docker/api/types/events"
... ...
@@ -12,7 +12,7 @@ import (
12 12
 	"time"
13 13
 
14 14
 	"github.com/containerd/containerd/log"
15
-	"github.com/docker/distribution/reference"
15
+	"github.com/distribution/reference"
16 16
 	"github.com/docker/docker/api/types"
17 17
 	"github.com/docker/docker/api/types/backend"
18 18
 	"github.com/docker/docker/api/types/registry"
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"strings"
8 8
 	"time"
9 9
 
10
-	"github.com/docker/distribution/reference"
10
+	"github.com/distribution/reference"
11 11
 	"github.com/docker/docker/api/types/backend"
12 12
 	containertypes "github.com/docker/docker/api/types/container"
13 13
 	"github.com/docker/docker/api/types/events"
... ...
@@ -13,7 +13,7 @@ import (
13 13
 	containerdimages "github.com/containerd/containerd/images"
14 14
 	"github.com/containerd/containerd/log"
15 15
 	cplatforms "github.com/containerd/containerd/platforms"
16
-	"github.com/docker/distribution/reference"
16
+	"github.com/distribution/reference"
17 17
 	imagetype "github.com/docker/docker/api/types/image"
18 18
 	"github.com/docker/docker/daemon/images"
19 19
 	"github.com/docker/docker/errdefs"
... ...
@@ -14,7 +14,7 @@ import (
14 14
 	"github.com/containerd/containerd/mount"
15 15
 	"github.com/containerd/containerd/platforms"
16 16
 	"github.com/containerd/containerd/rootfs"
17
-	"github.com/docker/distribution/reference"
17
+	"github.com/distribution/reference"
18 18
 	"github.com/docker/docker/api/types/backend"
19 19
 	imagetypes "github.com/docker/docker/api/types/image"
20 20
 	"github.com/docker/docker/api/types/registry"
... ...
@@ -8,7 +8,7 @@ import (
8 8
 
9 9
 	"github.com/containerd/containerd/images"
10 10
 	"github.com/containerd/containerd/log"
11
-	"github.com/docker/distribution/reference"
11
+	"github.com/distribution/reference"
12 12
 	"github.com/docker/docker/api/types"
13 13
 	"github.com/docker/docker/api/types/events"
14 14
 	"github.com/docker/docker/container"
... ...
@@ -13,7 +13,7 @@ import (
13 13
 	"github.com/containerd/containerd/leases"
14 14
 	"github.com/containerd/containerd/log"
15 15
 	cplatforms "github.com/containerd/containerd/platforms"
16
-	"github.com/docker/distribution/reference"
16
+	"github.com/distribution/reference"
17 17
 	"github.com/docker/docker/api/types/events"
18 18
 	"github.com/docker/docker/container"
19 19
 	"github.com/docker/docker/errdefs"
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"sort"
6 6
 
7 7
 	cplatforms "github.com/containerd/containerd/platforms"
8
-	"github.com/docker/distribution/reference"
8
+	"github.com/distribution/reference"
9 9
 	imagetype "github.com/docker/docker/api/types/image"
10 10
 	"github.com/docker/docker/errdefs"
11 11
 	"github.com/docker/docker/pkg/platforms"
... ...
@@ -14,7 +14,7 @@ import (
14 14
 	"github.com/containerd/containerd/images"
15 15
 	"github.com/containerd/containerd/log"
16 16
 	"github.com/containerd/containerd/platforms"
17
-	"github.com/docker/distribution/reference"
17
+	"github.com/distribution/reference"
18 18
 	"github.com/docker/docker/api/types/container"
19 19
 	"github.com/docker/docker/api/types/events"
20 20
 	"github.com/docker/docker/builder/dockerfile"
... ...
@@ -13,7 +13,7 @@ import (
13 13
 	"github.com/containerd/containerd/labels"
14 14
 	"github.com/containerd/containerd/log"
15 15
 	"github.com/containerd/containerd/snapshots"
16
-	"github.com/docker/distribution/reference"
16
+	"github.com/distribution/reference"
17 17
 	"github.com/docker/docker/api/types"
18 18
 	"github.com/docker/docker/api/types/filters"
19 19
 	"github.com/docker/docker/api/types/image"
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	cerrdefs "github.com/containerd/containerd/errdefs"
8 8
 	containerdimages "github.com/containerd/containerd/images"
9 9
 	"github.com/containerd/containerd/log"
10
-	"github.com/docker/distribution/reference"
10
+	"github.com/distribution/reference"
11 11
 	"github.com/docker/docker/api/types"
12 12
 	"github.com/docker/docker/api/types/filters"
13 13
 	"github.com/docker/docker/errdefs"
... ...
@@ -10,7 +10,7 @@ import (
10 10
 	"github.com/containerd/containerd/log"
11 11
 	"github.com/containerd/containerd/pkg/snapshotters"
12 12
 	"github.com/containerd/containerd/platforms"
13
-	"github.com/docker/distribution/reference"
13
+	"github.com/distribution/reference"
14 14
 	"github.com/docker/docker/api/types/registry"
15 15
 	"github.com/docker/docker/errdefs"
16 16
 	"github.com/docker/docker/pkg/streamformatter"
... ...
@@ -15,7 +15,7 @@ import (
15 15
 	"github.com/containerd/containerd/platforms"
16 16
 	"github.com/containerd/containerd/remotes"
17 17
 	"github.com/containerd/containerd/remotes/docker"
18
-	"github.com/docker/distribution/reference"
18
+	"github.com/distribution/reference"
19 19
 	"github.com/docker/docker/api/types/registry"
20 20
 	"github.com/docker/docker/errdefs"
21 21
 	"github.com/docker/docker/pkg/progress"
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	cerrdefs "github.com/containerd/containerd/errdefs"
7 7
 	containerdimages "github.com/containerd/containerd/images"
8 8
 	"github.com/containerd/containerd/log"
9
-	"github.com/docker/distribution/reference"
9
+	"github.com/distribution/reference"
10 10
 	"github.com/docker/docker/api/types/events"
11 11
 	"github.com/docker/docker/errdefs"
12 12
 	"github.com/docker/docker/image"
... ...
@@ -11,7 +11,7 @@ import (
11 11
 	"github.com/containerd/containerd/plugin"
12 12
 	"github.com/containerd/containerd/remotes/docker"
13 13
 	"github.com/containerd/containerd/snapshots"
14
-	"github.com/docker/distribution/reference"
14
+	"github.com/distribution/reference"
15 15
 	"github.com/docker/docker/container"
16 16
 	daemonevents "github.com/docker/docker/daemon/events"
17 17
 	"github.com/docker/docker/daemon/images"
... ...
@@ -5,7 +5,7 @@ import (
5 5
 
6 6
 	"github.com/containerd/containerd/content"
7 7
 	cerrdefs "github.com/containerd/containerd/errdefs"
8
-	"github.com/docker/distribution/reference"
8
+	"github.com/distribution/reference"
9 9
 	"github.com/opencontainers/go-digest"
10 10
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
11 11
 )
... ...
@@ -25,8 +25,8 @@ import (
25 25
 	"github.com/containerd/containerd/pkg/dialer"
26 26
 	"github.com/containerd/containerd/pkg/userns"
27 27
 	"github.com/containerd/containerd/remotes/docker"
28
+	"github.com/distribution/reference"
28 29
 	dist "github.com/docker/distribution"
29
-	"github.com/docker/distribution/reference"
30 30
 	"github.com/docker/docker/api/types"
31 31
 	containertypes "github.com/docker/docker/api/types/container"
32 32
 	registrytypes "github.com/docker/docker/api/types/registry"
... ...
@@ -1,7 +1,7 @@
1 1
 package events // import "github.com/docker/docker/daemon/events"
2 2
 
3 3
 import (
4
-	"github.com/docker/distribution/reference"
4
+	"github.com/distribution/reference"
5 5
 	"github.com/docker/docker/api/types/events"
6 6
 	"github.com/docker/docker/api/types/filters"
7 7
 )
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"context"
5 5
 	"io"
6 6
 
7
-	"github.com/docker/distribution/reference"
7
+	"github.com/distribution/reference"
8 8
 	"github.com/docker/docker/api/types"
9 9
 	"github.com/docker/docker/api/types/backend"
10 10
 	"github.com/docker/docker/api/types/events"
... ...
@@ -12,7 +12,7 @@ import (
12 12
 	"github.com/containerd/containerd/leases"
13 13
 	"github.com/containerd/containerd/log"
14 14
 	"github.com/containerd/containerd/platforms"
15
-	"github.com/docker/distribution/reference"
15
+	"github.com/distribution/reference"
16 16
 	imagetypes "github.com/docker/docker/api/types/image"
17 17
 	"github.com/docker/docker/errdefs"
18 18
 	"github.com/docker/docker/image"
... ...
@@ -7,7 +7,7 @@ import (
7 7
 
8 8
 	"github.com/containerd/containerd/log"
9 9
 	"github.com/containerd/containerd/platforms"
10
-	"github.com/docker/distribution/reference"
10
+	"github.com/distribution/reference"
11 11
 	"github.com/docker/docker/api/types/backend"
12 12
 	imagetypes "github.com/docker/docker/api/types/image"
13 13
 	"github.com/docker/docker/api/types/registry"
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"strings"
7 7
 	"time"
8 8
 
9
-	"github.com/docker/distribution/reference"
9
+	"github.com/distribution/reference"
10 10
 	"github.com/docker/docker/api/types"
11 11
 	"github.com/docker/docker/api/types/events"
12 12
 	imagetypes "github.com/docker/docker/api/types/image"
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"fmt"
6 6
 	"time"
7 7
 
8
-	"github.com/docker/distribution/reference"
8
+	"github.com/distribution/reference"
9 9
 	"github.com/docker/docker/api/types/image"
10 10
 	"github.com/docker/docker/layer"
11 11
 )
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"time"
8 8
 
9 9
 	"github.com/containerd/containerd/platforms"
10
-	"github.com/docker/distribution/reference"
10
+	"github.com/distribution/reference"
11 11
 	"github.com/docker/docker/api/types/container"
12 12
 	"github.com/docker/docker/api/types/events"
13 13
 	"github.com/docker/docker/builder/dockerfile"
... ...
@@ -7,7 +7,7 @@ import (
7 7
 	"sort"
8 8
 	"time"
9 9
 
10
-	"github.com/docker/distribution/reference"
10
+	"github.com/distribution/reference"
11 11
 	"github.com/docker/docker/api/types"
12 12
 	imagetypes "github.com/docker/docker/api/types/image"
13 13
 	"github.com/docker/docker/container"
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"time"
9 9
 
10 10
 	"github.com/containerd/containerd/log"
11
-	"github.com/docker/distribution/reference"
11
+	"github.com/distribution/reference"
12 12
 	"github.com/docker/docker/api/types"
13 13
 	"github.com/docker/docker/api/types/events"
14 14
 	"github.com/docker/docker/api/types/filters"
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"github.com/containerd/containerd/leases"
10 10
 	"github.com/containerd/containerd/log"
11 11
 	"github.com/containerd/containerd/namespaces"
12
-	"github.com/docker/distribution/reference"
12
+	"github.com/distribution/reference"
13 13
 	imagetypes "github.com/docker/docker/api/types/image"
14 14
 	"github.com/docker/docker/api/types/registry"
15 15
 	"github.com/docker/docker/distribution"
... ...
@@ -5,8 +5,8 @@ import (
5 5
 	"io"
6 6
 	"time"
7 7
 
8
+	"github.com/distribution/reference"
8 9
 	"github.com/docker/distribution/manifest/schema2"
9
-	"github.com/docker/distribution/reference"
10 10
 	"github.com/docker/docker/api/types/registry"
11 11
 	"github.com/docker/docker/distribution"
12 12
 	progressutils "github.com/docker/docker/distribution/utils"
... ...
@@ -3,7 +3,7 @@ package images // import "github.com/docker/docker/daemon/images"
3 3
 import (
4 4
 	"context"
5 5
 
6
-	"github.com/docker/distribution/reference"
6
+	"github.com/distribution/reference"
7 7
 	"github.com/docker/docker/api/types/events"
8 8
 	"github.com/docker/docker/image"
9 9
 )
... ...
@@ -6,9 +6,9 @@ import (
6 6
 	"io"
7 7
 	"runtime"
8 8
 
9
+	"github.com/distribution/reference"
9 10
 	"github.com/docker/distribution"
10 11
 	"github.com/docker/distribution/manifest/schema2"
11
-	"github.com/docker/distribution/reference"
12 12
 	"github.com/docker/docker/api/types/events"
13 13
 	"github.com/docker/docker/api/types/registry"
14 14
 	"github.com/docker/docker/distribution/metadata"
... ...
@@ -8,8 +8,8 @@ import (
8 8
 	"syscall"
9 9
 
10 10
 	"github.com/containerd/containerd/log"
11
+	"github.com/distribution/reference"
11 12
 	"github.com/docker/distribution"
12
-	"github.com/docker/distribution/reference"
13 13
 	"github.com/docker/distribution/registry/api/errcode"
14 14
 	v2 "github.com/docker/distribution/registry/api/v2"
15 15
 	"github.com/docker/distribution/registry/client"
... ...
@@ -11,11 +11,11 @@ import (
11 11
 	cerrdefs "github.com/containerd/containerd/errdefs"
12 12
 	"github.com/containerd/containerd/log"
13 13
 	"github.com/containerd/containerd/remotes"
14
+	"github.com/distribution/reference"
14 15
 	"github.com/docker/distribution"
15 16
 	"github.com/docker/distribution/manifest/manifestlist"
16 17
 	"github.com/docker/distribution/manifest/schema1"
17 18
 	"github.com/docker/distribution/manifest/schema2"
18
-	"github.com/docker/distribution/reference"
19 19
 	"github.com/docker/docker/registry"
20 20
 	"github.com/opencontainers/go-digest"
21 21
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
... ...
@@ -12,12 +12,12 @@ import (
12 12
 	"github.com/containerd/containerd/content/local"
13 13
 	cerrdefs "github.com/containerd/containerd/errdefs"
14 14
 	"github.com/containerd/containerd/remotes"
15
+	"github.com/distribution/reference"
15 16
 	"github.com/docker/distribution"
16 17
 	"github.com/docker/distribution/manifest/manifestlist"
17 18
 	"github.com/docker/distribution/manifest/ocischema"
18 19
 	"github.com/docker/distribution/manifest/schema1"
19 20
 	"github.com/docker/distribution/manifest/schema2"
20
-	"github.com/docker/distribution/reference"
21 21
 	"github.com/google/go-cmp/cmp/cmpopts"
22 22
 	"github.com/opencontainers/go-digest"
23 23
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
... ...
@@ -5,7 +5,7 @@ import (
5 5
 	"fmt"
6 6
 
7 7
 	"github.com/containerd/containerd/log"
8
-	"github.com/docker/distribution/reference"
8
+	"github.com/distribution/reference"
9 9
 	"github.com/docker/docker/api"
10 10
 	"github.com/docker/docker/api/types/events"
11 11
 	refstore "github.com/docker/docker/reference"
... ...
@@ -12,12 +12,12 @@ import (
12 12
 
13 13
 	"github.com/containerd/containerd/log"
14 14
 	"github.com/containerd/containerd/platforms"
15
+	"github.com/distribution/reference"
15 16
 	"github.com/docker/distribution"
16 17
 	"github.com/docker/distribution/manifest/manifestlist"
17 18
 	"github.com/docker/distribution/manifest/ocischema"
18 19
 	"github.com/docker/distribution/manifest/schema1"
19 20
 	"github.com/docker/distribution/manifest/schema2"
20
-	"github.com/docker/distribution/reference"
21 21
 	"github.com/docker/distribution/registry/client/transport"
22 22
 	"github.com/docker/docker/distribution/metadata"
23 23
 	"github.com/docker/docker/distribution/xfer"
... ...
@@ -14,8 +14,8 @@ import (
14 14
 	"sync/atomic"
15 15
 	"testing"
16 16
 
17
+	"github.com/distribution/reference"
17 18
 	"github.com/docker/distribution/manifest/schema1"
18
-	"github.com/docker/distribution/reference"
19 19
 	registrytypes "github.com/docker/docker/api/types/registry"
20 20
 	"github.com/docker/docker/image"
21 21
 	"github.com/docker/docker/registry"
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"io"
9 9
 
10 10
 	"github.com/containerd/containerd/log"
11
-	"github.com/docker/distribution/reference"
11
+	"github.com/distribution/reference"
12 12
 	"github.com/docker/docker/api/types/events"
13 13
 	"github.com/docker/docker/pkg/progress"
14 14
 )
... ...
@@ -11,10 +11,10 @@ import (
11 11
 	"sync"
12 12
 
13 13
 	"github.com/containerd/containerd/log"
14
+	"github.com/distribution/reference"
14 15
 	"github.com/docker/distribution"
15 16
 	"github.com/docker/distribution/manifest/schema1"
16 17
 	"github.com/docker/distribution/manifest/schema2"
17
-	"github.com/docker/distribution/reference"
18 18
 	"github.com/docker/distribution/registry/api/errcode"
19 19
 	"github.com/docker/distribution/registry/client"
20 20
 	apitypes "github.com/docker/docker/api/types"
... ...
@@ -6,9 +6,9 @@ import (
6 6
 	"reflect"
7 7
 	"testing"
8 8
 
9
+	"github.com/distribution/reference"
9 10
 	"github.com/docker/distribution"
10 11
 	"github.com/docker/distribution/manifest/schema2"
11
-	"github.com/docker/distribution/reference"
12 12
 	"github.com/docker/distribution/registry/api/errcode"
13 13
 	"github.com/docker/docker/api/types/registry"
14 14
 	"github.com/docker/docker/distribution/metadata"
... ...
@@ -7,9 +7,9 @@ import (
7 7
 	"net/http"
8 8
 	"time"
9 9
 
10
+	"github.com/distribution/reference"
10 11
 	"github.com/docker/distribution"
11 12
 	"github.com/docker/distribution/manifest/schema2"
12
-	"github.com/docker/distribution/reference"
13 13
 	"github.com/docker/distribution/registry/client"
14 14
 	"github.com/docker/distribution/registry/client/auth"
15 15
 	"github.com/docker/distribution/registry/client/transport"
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"testing"
10 10
 
11 11
 	"github.com/containerd/containerd/log"
12
-	"github.com/docker/distribution/reference"
12
+	"github.com/distribution/reference"
13 13
 	"github.com/docker/docker/api/types/registry"
14 14
 	registrypkg "github.com/docker/docker/registry"
15 15
 )
... ...
@@ -3,8 +3,8 @@ package distribution
3 3
 import (
4 4
 	"context"
5 5
 
6
+	"github.com/distribution/reference"
6 7
 	"github.com/docker/distribution"
7
-	"github.com/docker/distribution/reference"
8 8
 	"github.com/docker/docker/errdefs"
9 9
 )
10 10
 
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"strings"
9 9
 	"time"
10 10
 
11
-	"github.com/docker/distribution/reference"
11
+	"github.com/distribution/reference"
12 12
 	"github.com/docker/docker/api/types/container"
13 13
 	"github.com/docker/docker/dockerversion"
14 14
 	"github.com/docker/docker/layer"
... ...
@@ -12,8 +12,8 @@ import (
12 12
 	"runtime"
13 13
 
14 14
 	"github.com/containerd/containerd/log"
15
+	"github.com/distribution/reference"
15 16
 	"github.com/docker/distribution"
16
-	"github.com/docker/distribution/reference"
17 17
 	"github.com/docker/docker/api/types/events"
18 18
 	"github.com/docker/docker/image"
19 19
 	v1 "github.com/docker/docker/image/v1"
... ...
@@ -10,8 +10,8 @@ import (
10 10
 	"time"
11 11
 
12 12
 	"github.com/containerd/containerd/images"
13
+	"github.com/distribution/reference"
13 14
 	"github.com/docker/distribution"
14
-	"github.com/docker/distribution/reference"
15 15
 	"github.com/docker/docker/api/types/events"
16 16
 	"github.com/docker/docker/image"
17 17
 	v1 "github.com/docker/docker/image/v1"
... ...
@@ -10,7 +10,7 @@ import (
10 10
 	"sync"
11 11
 	"testing"
12 12
 
13
-	"github.com/docker/distribution/reference"
13
+	"github.com/distribution/reference"
14 14
 	"github.com/docker/docker/api/types/versions"
15 15
 	"github.com/docker/docker/integration-cli/cli/build"
16 16
 	"gotest.tools/v3/assert"
... ...
@@ -20,8 +20,8 @@ import (
20 20
 	"github.com/containerd/containerd/platforms"
21 21
 	"github.com/containerd/containerd/remotes"
22 22
 	"github.com/containerd/containerd/remotes/docker"
23
+	"github.com/distribution/reference"
23 24
 	"github.com/docker/distribution/manifest/schema2"
24
-	"github.com/docker/distribution/reference"
25 25
 	"github.com/docker/docker/api/types"
26 26
 	"github.com/docker/docker/api/types/events"
27 27
 	"github.com/docker/docker/api/types/filters"
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"io"
9 9
 	"net/http"
10 10
 
11
-	"github.com/docker/distribution/reference"
11
+	"github.com/distribution/reference"
12 12
 	"github.com/docker/docker/api/types"
13 13
 	"github.com/docker/docker/api/types/filters"
14 14
 	"github.com/docker/docker/api/types/registry"
... ...
@@ -12,7 +12,7 @@ import (
12 12
 	"github.com/containerd/containerd/log"
13 13
 	"github.com/containerd/containerd/remotes"
14 14
 	"github.com/containerd/containerd/remotes/docker"
15
-	"github.com/docker/distribution/reference"
15
+	"github.com/distribution/reference"
16 16
 	"github.com/docker/docker/api/types/registry"
17 17
 	progressutils "github.com/docker/docker/distribution/utils"
18 18
 	"github.com/docker/docker/pkg/chrootarchive"
... ...
@@ -10,7 +10,7 @@ import (
10 10
 	"github.com/containerd/containerd/log"
11 11
 	"github.com/containerd/containerd/remotes"
12 12
 	"github.com/containerd/containerd/remotes/docker"
13
-	"github.com/docker/distribution/reference"
13
+	"github.com/distribution/reference"
14 14
 	"github.com/docker/docker/api/types/registry"
15 15
 	"github.com/docker/docker/dockerversion"
16 16
 	"github.com/pkg/errors"
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"strings"
7 7
 
8 8
 	"github.com/containerd/containerd/log"
9
-	"github.com/docker/distribution/reference"
9
+	"github.com/distribution/reference"
10 10
 	"github.com/docker/docker/errdefs"
11 11
 	"github.com/docker/docker/pkg/plugingetter"
12 12
 	"github.com/docker/docker/pkg/plugins"
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"sort"
9 9
 	"sync"
10 10
 
11
-	"github.com/docker/distribution/reference"
11
+	"github.com/distribution/reference"
12 12
 	"github.com/docker/docker/pkg/ioutils"
13 13
 	"github.com/opencontainers/go-digest"
14 14
 	"github.com/pkg/errors"
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"path/filepath"
7 7
 	"testing"
8 8
 
9
-	"github.com/docker/distribution/reference"
9
+	"github.com/distribution/reference"
10 10
 	"github.com/docker/docker/errdefs"
11 11
 	"github.com/opencontainers/go-digest"
12 12
 	"gotest.tools/v3/assert"
... ...
@@ -9,7 +9,7 @@ import (
9 9
 	"strings"
10 10
 
11 11
 	"github.com/containerd/containerd/log"
12
-	"github.com/docker/distribution/reference"
12
+	"github.com/distribution/reference"
13 13
 	"github.com/docker/docker/api/types/registry"
14 14
 )
15 15
 
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"os"
5 5
 	"testing"
6 6
 
7
-	"github.com/docker/distribution/reference"
7
+	"github.com/distribution/reference"
8 8
 	"github.com/docker/docker/api/types/registry"
9 9
 	"gotest.tools/v3/assert"
10 10
 	is "gotest.tools/v3/assert/cmp"
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"sync"
9 9
 
10 10
 	"github.com/containerd/containerd/log"
11
-	"github.com/docker/distribution/reference"
11
+	"github.com/distribution/reference"
12 12
 	"github.com/docker/docker/api/types/registry"
13 13
 	"github.com/docker/docker/errdefs"
14 14
 )
... ...
@@ -1,7 +1,7 @@
1 1
 package registry // import "github.com/docker/docker/registry"
2 2
 
3 3
 import (
4
-	"github.com/docker/distribution/reference"
4
+	"github.com/distribution/reference"
5 5
 	"github.com/docker/docker/api/types/registry"
6 6
 )
7 7
 
... ...
@@ -34,6 +34,7 @@ require (
34 34
 	github.com/cpuguy83/tar2go v0.3.1
35 35
 	github.com/creack/pty v1.1.18
36 36
 	github.com/deckarep/golang-set/v2 v2.3.0
37
+	github.com/distribution/reference v0.5.0
37 38
 	github.com/docker/distribution v2.8.2+incompatible
38 39
 	github.com/docker/go-connections v0.4.0
39 40
 	github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c
... ...
@@ -484,6 +484,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8
484 484
 github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
485 485
 github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
486 486
 github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
487
+github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
488
+github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
487 489
 github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
488 490
 github.com/docker/cli v0.0.0-20190925022749-754388324470/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
489 491
 github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
490 492
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+*.go text eol=lf
0 1
new file mode 100644
... ...
@@ -0,0 +1,2 @@
0
+# Cover profiles
1
+*.out
0 2
new file mode 100644
... ...
@@ -0,0 +1,18 @@
0
+linters:
1
+  enable:
2
+    - bodyclose
3
+    - dupword # Checks for duplicate words in the source code
4
+    - gofmt
5
+    - goimports
6
+    - ineffassign
7
+    - misspell
8
+    - revive
9
+    - staticcheck
10
+    - unconvert
11
+    - unused
12
+    - vet
13
+  disable:
14
+    - errcheck
15
+
16
+run:
17
+  deadline: 2m
0 18
new file mode 100644
... ...
@@ -0,0 +1,5 @@
0
+# Code of Conduct
1
+
2
+We follow the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).
3
+
4
+Please contact the [CNCF Code of Conduct Committee](mailto:conduct@cncf.io) in order to report violations of the Code of Conduct.
0 5
new file mode 100644
... ...
@@ -0,0 +1,114 @@
0
+# Contributing to the reference library
1
+
2
+## Community help
3
+
4
+If you need help, please ask in the [#distribution](https://cloud-native.slack.com/archives/C01GVR8SY4R) channel on CNCF community slack.
5
+[Click here for an invite to the CNCF community slack](https://slack.cncf.io/)
6
+
7
+## Reporting security issues
8
+
9
+The maintainers take security seriously. If you discover a security
10
+issue, please bring it to their attention right away!
11
+
12
+Please **DO NOT** file a public issue, instead send your report privately to
13
+[cncf-distribution-security@lists.cncf.io](mailto:cncf-distribution-security@lists.cncf.io).
14
+
15
+## Reporting an issue properly
16
+
17
+By following these simple rules you will get better and faster feedback on your issue.
18
+
19
+ - search the bugtracker for an already reported issue
20
+
21
+### If you found an issue that describes your problem:
22
+
23
+ - please read other user comments first, and confirm this is the same issue: a given error condition might be indicative of different problems - you may also find a workaround in the comments
24
+ - please refrain from adding "same thing here" or "+1" comments
25
+ - you don't need to comment on an issue to get notified of updates: just hit the "subscribe" button
26
+ - comment if you have some new, technical and relevant information to add to the case
27
+ - __DO NOT__ comment on closed issues or merged PRs. If you think you have a related problem, open up a new issue and reference the PR or issue.
28
+
29
+### If you have not found an existing issue that describes your problem:
30
+
31
+ 1. create a new issue, with a succinct title that describes your issue:
32
+   - bad title: "It doesn't work with my docker"
33
+   - good title: "Private registry push fail: 400 error with E_INVALID_DIGEST"
34
+ 2. copy the output of (or similar for other container tools):
35
+   - `docker version`
36
+   - `docker info`
37
+   - `docker exec <registry-container> registry --version`
38
+ 3. copy the command line you used to launch your Registry
39
+ 4. restart your docker daemon in debug mode (add `-D` to the daemon launch arguments)
40
+ 5. reproduce your problem and get your docker daemon logs showing the error
41
+ 6. if relevant, copy your registry logs that show the error
42
+ 7. provide any relevant detail about your specific Registry configuration (e.g., storage backend used)
43
+ 8. indicate if you are using an enterprise proxy, Nginx, or anything else between you and your Registry
44
+
45
+## Contributing Code
46
+
47
+Contributions should be made via pull requests. Pull requests will be reviewed
48
+by one or more maintainers or reviewers and merged when acceptable.
49
+
50
+You should follow the basic GitHub workflow:
51
+
52
+ 1. Use your own [fork](https://help.github.com/en/articles/about-forks)
53
+ 2. Create your [change](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes)
54
+ 3. Test your code
55
+ 4. [Commit](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages) your work, always [sign your commits](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages)
56
+ 5. Push your change to your fork and create a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork)
57
+
58
+Refer to [containerd's contribution guide](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes)
59
+for tips on creating a successful contribution.
60
+
61
+## Sign your work
62
+
63
+The sign-off is a simple line at the end of the explanation for the patch. Your
64
+signature certifies that you wrote the patch or otherwise have the right to pass
65
+it on as an open-source patch. The rules are pretty simple: if you can certify
66
+the below (from [developercertificate.org](http://developercertificate.org/)):
67
+
68
+```
69
+Developer Certificate of Origin
70
+Version 1.1
71
+
72
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
73
+660 York Street, Suite 102,
74
+San Francisco, CA 94110 USA
75
+
76
+Everyone is permitted to copy and distribute verbatim copies of this
77
+license document, but changing it is not allowed.
78
+
79
+Developer's Certificate of Origin 1.1
80
+
81
+By making a contribution to this project, I certify that:
82
+
83
+(a) The contribution was created in whole or in part by me and I
84
+    have the right to submit it under the open source license
85
+    indicated in the file; or
86
+
87
+(b) The contribution is based upon previous work that, to the best
88
+    of my knowledge, is covered under an appropriate open source
89
+    license and I have the right under that license to submit that
90
+    work with modifications, whether created in whole or in part
91
+    by me, under the same open source license (unless I am
92
+    permitted to submit under a different license), as indicated
93
+    in the file; or
94
+
95
+(c) The contribution was provided directly to me by some other
96
+    person who certified (a), (b) or (c) and I have not modified
97
+    it.
98
+
99
+(d) I understand and agree that this project and the contribution
100
+    are public and that a record of the contribution (including all
101
+    personal information I submit with it, including my sign-off) is
102
+    maintained indefinitely and may be redistributed consistent with
103
+    this project or the open source license(s) involved.
104
+```
105
+
106
+Then you just add a line to every git commit message:
107
+
108
+    Signed-off-by: Joe Smith <joe.smith@email.com>
109
+
110
+Use your real name (sorry, no pseudonyms or anonymous contributions.)
111
+
112
+If you set your `user.name` and `user.email` git configs, you can sign your
113
+commit automatically with `git commit -s`.
0 114
new file mode 100644
... ...
@@ -0,0 +1,144 @@
0
+# distribution/reference Project Governance
1
+
2
+Distribution [Code of Conduct](./CODE-OF-CONDUCT.md) can be found here.
3
+
4
+For specific guidance on practical contribution steps please
5
+see our [CONTRIBUTING.md](./CONTRIBUTING.md) guide.
6
+
7
+## Maintainership
8
+
9
+There are different types of maintainers, with different responsibilities, but
10
+all maintainers have 3 things in common:
11
+
12
+1) They share responsibility in the project's success.
13
+2) They have made a long-term, recurring time investment to improve the project.
14
+3) They spend that time doing whatever needs to be done, not necessarily what
15
+is the most interesting or fun.
16
+
17
+Maintainers are often under-appreciated, because their work is harder to appreciate.
18
+It's easy to appreciate a really cool and technically advanced feature. It's harder
19
+to appreciate the absence of bugs, the slow but steady improvement in stability,
20
+or the reliability of a release process. But those things distinguish a good
21
+project from a great one.
22
+
23
+## Reviewers
24
+
25
+A reviewer is a core role within the project.
26
+They share in reviewing issues and pull requests and their LGTM counts towards the
27
+required LGTM count to merge a code change into the project.
28
+
29
+Reviewers are part of the organization but do not have write access.
30
+Becoming a reviewer is a core aspect in the journey to becoming a maintainer.
31
+
32
+## Adding maintainers
33
+
34
+Maintainers are first and foremost contributors that have shown they are
35
+committed to the long term success of a project. Contributors wanting to become
36
+maintainers are expected to be deeply involved in contributing code, pull
37
+request review, and triage of issues in the project for more than three months.
38
+
39
+Just contributing does not make you a maintainer, it is about building trust
40
+with the current maintainers of the project and being a person that they can
41
+depend on and trust to make decisions in the best interest of the project.
42
+
43
+Periodically, the existing maintainers curate a list of contributors that have
44
+shown regular activity on the project over the prior months. From this list,
45
+maintainer candidates are selected and proposed in a pull request or a
46
+maintainers communication channel.
47
+
48
+After a candidate has been announced to the maintainers, the existing
49
+maintainers are given five business days to discuss the candidate, raise
50
+objections and cast their vote. Votes may take place on the communication
51
+channel or via pull request comment. Candidates must be approved by at least 66%
52
+of the current maintainers by adding their vote on the mailing list. The
53
+reviewer role has the same process but only requires 33% of current maintainers.
54
+Only maintainers of the repository that the candidate is proposed for are
55
+allowed to vote.
56
+
57
+If a candidate is approved, a maintainer will contact the candidate to invite
58
+the candidate to open a pull request that adds the contributor to the
59
+MAINTAINERS file. The voting process may take place inside a pull request if a
60
+maintainer has already discussed the candidacy with the candidate and a
61
+maintainer is willing to be a sponsor by opening the pull request. The candidate
62
+becomes a maintainer once the pull request is merged.
63
+
64
+## Stepping down policy
65
+
66
+Life priorities, interests, and passions can change. If you're a maintainer but
67
+feel you must remove yourself from the list, inform other maintainers that you
68
+intend to step down, and if possible, help find someone to pick up your work.
69
+At the very least, ensure your work can be continued where you left off.
70
+
71
+After you've informed other maintainers, create a pull request to remove
72
+yourself from the MAINTAINERS file.
73
+
74
+## Removal of inactive maintainers
75
+
76
+Similar to the procedure for adding new maintainers, existing maintainers can
77
+be removed from the list if they do not show significant activity on the
78
+project. Periodically, the maintainers review the list of maintainers and their
79
+activity over the last three months.
80
+
81
+If a maintainer has shown insufficient activity over this period, a neutral
82
+person will contact the maintainer to ask if they want to continue being
83
+a maintainer. If the maintainer decides to step down as a maintainer, they
84
+open a pull request to be removed from the MAINTAINERS file.
85
+
86
+If the maintainer wants to remain a maintainer, but is unable to perform the
87
+required duties they can be removed with a vote of at least 66% of the current
88
+maintainers. In this case, maintainers should first propose the change to
89
+maintainers via the maintainers communication channel, then open a pull request
90
+for voting. The voting period is five business days. The voting pull request
91
+should not come as a surpise to any maintainer and any discussion related to
92
+performance must not be discussed on the pull request.
93
+
94
+## How are decisions made?
95
+
96
+Docker distribution is an open-source project with an open design philosophy.
97
+This means that the repository is the source of truth for EVERY aspect of the
98
+project, including its philosophy, design, road map, and APIs. *If it's part of
99
+the project, it's in the repo. If it's in the repo, it's part of the project.*
100
+
101
+As a result, all decisions can be expressed as changes to the repository. An
102
+implementation change is a change to the source code. An API change is a change
103
+to the API specification. A philosophy change is a change to the philosophy
104
+manifesto, and so on.
105
+
106
+All decisions affecting distribution, big and small, follow the same 3 steps:
107
+
108
+* Step 1: Open a pull request. Anyone can do this.
109
+
110
+* Step 2: Discuss the pull request. Anyone can do this.
111
+
112
+* Step 3: Merge or refuse the pull request. Who does this depends on the nature
113
+of the pull request and which areas of the project it affects.
114
+
115
+## Helping contributors with the DCO
116
+
117
+The [DCO or `Sign your work`](./CONTRIBUTING.md#sign-your-work)
118
+requirement is not intended as a roadblock or speed bump.
119
+
120
+Some contributors are not as familiar with `git`, or have used a web
121
+based editor, and thus asking them to `git commit --amend -s` is not the best
122
+way forward.
123
+
124
+In this case, maintainers can update the commits based on clause (c) of the DCO.
125
+The most trivial way for a contributor to allow the maintainer to do this, is to
126
+add a DCO signature in a pull requests's comment, or a maintainer can simply
127
+note that the change is sufficiently trivial that it does not substantially
128
+change the existing contribution - i.e., a spelling change.
129
+
130
+When you add someone's DCO, please also add your own to keep a log.
131
+
132
+## I'm a maintainer. Should I make pull requests too?
133
+
134
+Yes. Nobody should ever push to master directly. All changes should be
135
+made through a pull request.
136
+
137
+## Conflict Resolution
138
+
139
+If you have a technical dispute that you feel has reached an impasse with a
140
+subset of the community, any contributor may open an issue, specifically
141
+calling for a resolution vote of the current core maintainers to resolve the
142
+dispute. The same voting quorums required (2/3) for adding and removing
143
+maintainers will apply to conflict resolution.
0 144
new file mode 100644
... ...
@@ -0,0 +1,202 @@
0
+Apache License
1
+                           Version 2.0, January 2004
2
+                        http://www.apache.org/licenses/
3
+
4
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
5
+
6
+   1. Definitions.
7
+
8
+      "License" shall mean the terms and conditions for use, reproduction,
9
+      and distribution as defined by Sections 1 through 9 of this document.
10
+
11
+      "Licensor" shall mean the copyright owner or entity authorized by
12
+      the copyright owner that is granting the License.
13
+
14
+      "Legal Entity" shall mean the union of the acting entity and all
15
+      other entities that control, are controlled by, or are under common
16
+      control with that entity. For the purposes of this definition,
17
+      "control" means (i) the power, direct or indirect, to cause the
18
+      direction or management of such entity, whether by contract or
19
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
20
+      outstanding shares, or (iii) beneficial ownership of such entity.
21
+
22
+      "You" (or "Your") shall mean an individual or Legal Entity
23
+      exercising permissions granted by this License.
24
+
25
+      "Source" form shall mean the preferred form for making modifications,
26
+      including but not limited to software source code, documentation
27
+      source, and configuration files.
28
+
29
+      "Object" form shall mean any form resulting from mechanical
30
+      transformation or translation of a Source form, including but
31
+      not limited to compiled object code, generated documentation,
32
+      and conversions to other media types.
33
+
34
+      "Work" shall mean the work of authorship, whether in Source or
35
+      Object form, made available under the License, as indicated by a
36
+      copyright notice that is included in or attached to the work
37
+      (an example is provided in the Appendix below).
38
+
39
+      "Derivative Works" shall mean any work, whether in Source or Object
40
+      form, that is based on (or derived from) the Work and for which the
41
+      editorial revisions, annotations, elaborations, or other modifications
42
+      represent, as a whole, an original work of authorship. For the purposes
43
+      of this License, Derivative Works shall not include works that remain
44
+      separable from, or merely link (or bind by name) to the interfaces of,
45
+      the Work and Derivative Works thereof.
46
+
47
+      "Contribution" shall mean any work of authorship, including
48
+      the original version of the Work and any modifications or additions
49
+      to that Work or Derivative Works thereof, that is intentionally
50
+      submitted to Licensor for inclusion in the Work by the copyright owner
51
+      or by an individual or Legal Entity authorized to submit on behalf of
52
+      the copyright owner. For the purposes of this definition, "submitted"
53
+      means any form of electronic, verbal, or written communication sent
54
+      to the Licensor or its representatives, including but not limited to
55
+      communication on electronic mailing lists, source code control systems,
56
+      and issue tracking systems that are managed by, or on behalf of, the
57
+      Licensor for the purpose of discussing and improving the Work, but
58
+      excluding communication that is conspicuously marked or otherwise
59
+      designated in writing by the copyright owner as "Not a Contribution."
60
+
61
+      "Contributor" shall mean Licensor and any individual or Legal Entity
62
+      on behalf of whom a Contribution has been received by Licensor and
63
+      subsequently incorporated within the Work.
64
+
65
+   2. Grant of Copyright License. Subject to the terms and conditions of
66
+      this License, each Contributor hereby grants to You a perpetual,
67
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
68
+      copyright license to reproduce, prepare Derivative Works of,
69
+      publicly display, publicly perform, sublicense, and distribute the
70
+      Work and such Derivative Works in Source or Object form.
71
+
72
+   3. Grant of Patent License. Subject to the terms and conditions of
73
+      this License, each Contributor hereby grants to You a perpetual,
74
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
75
+      (except as stated in this section) patent license to make, have made,
76
+      use, offer to sell, sell, import, and otherwise transfer the Work,
77
+      where such license applies only to those patent claims licensable
78
+      by such Contributor that are necessarily infringed by their
79
+      Contribution(s) alone or by combination of their Contribution(s)
80
+      with the Work to which such Contribution(s) was submitted. If You
81
+      institute patent litigation against any entity (including a
82
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
83
+      or a Contribution incorporated within the Work constitutes direct
84
+      or contributory patent infringement, then any patent licenses
85
+      granted to You under this License for that Work shall terminate
86
+      as of the date such litigation is filed.
87
+
88
+   4. Redistribution. You may reproduce and distribute copies of the
89
+      Work or Derivative Works thereof in any medium, with or without
90
+      modifications, and in Source or Object form, provided that You
91
+      meet the following conditions:
92
+
93
+      (a) You must give any other recipients of the Work or
94
+          Derivative Works a copy of this License; and
95
+
96
+      (b) You must cause any modified files to carry prominent notices
97
+          stating that You changed the files; and
98
+
99
+      (c) You must retain, in the Source form of any Derivative Works
100
+          that You distribute, all copyright, patent, trademark, and
101
+          attribution notices from the Source form of the Work,
102
+          excluding those notices that do not pertain to any part of
103
+          the Derivative Works; and
104
+
105
+      (d) If the Work includes a "NOTICE" text file as part of its
106
+          distribution, then any Derivative Works that You distribute must
107
+          include a readable copy of the attribution notices contained
108
+          within such NOTICE file, excluding those notices that do not
109
+          pertain to any part of the Derivative Works, in at least one
110
+          of the following places: within a NOTICE text file distributed
111
+          as part of the Derivative Works; within the Source form or
112
+          documentation, if provided along with the Derivative Works; or,
113
+          within a display generated by the Derivative Works, if and
114
+          wherever such third-party notices normally appear. The contents
115
+          of the NOTICE file are for informational purposes only and
116
+          do not modify the License. You may add Your own attribution
117
+          notices within Derivative Works that You distribute, alongside
118
+          or as an addendum to the NOTICE text from the Work, provided
119
+          that such additional attribution notices cannot be construed
120
+          as modifying the License.
121
+
122
+      You may add Your own copyright statement to Your modifications and
123
+      may provide additional or different license terms and conditions
124
+      for use, reproduction, or distribution of Your modifications, or
125
+      for any such Derivative Works as a whole, provided Your use,
126
+      reproduction, and distribution of the Work otherwise complies with
127
+      the conditions stated in this License.
128
+
129
+   5. Submission of Contributions. Unless You explicitly state otherwise,
130
+      any Contribution intentionally submitted for inclusion in the Work
131
+      by You to the Licensor shall be under the terms and conditions of
132
+      this License, without any additional terms or conditions.
133
+      Notwithstanding the above, nothing herein shall supersede or modify
134
+      the terms of any separate license agreement you may have executed
135
+      with Licensor regarding such Contributions.
136
+
137
+   6. Trademarks. This License does not grant permission to use the trade
138
+      names, trademarks, service marks, or product names of the Licensor,
139
+      except as required for reasonable and customary use in describing the
140
+      origin of the Work and reproducing the content of the NOTICE file.
141
+
142
+   7. Disclaimer of Warranty. Unless required by applicable law or
143
+      agreed to in writing, Licensor provides the Work (and each
144
+      Contributor provides its Contributions) on an "AS IS" BASIS,
145
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
146
+      implied, including, without limitation, any warranties or conditions
147
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
148
+      PARTICULAR PURPOSE. You are solely responsible for determining the
149
+      appropriateness of using or redistributing the Work and assume any
150
+      risks associated with Your exercise of permissions under this License.
151
+
152
+   8. Limitation of Liability. In no event and under no legal theory,
153
+      whether in tort (including negligence), contract, or otherwise,
154
+      unless required by applicable law (such as deliberate and grossly
155
+      negligent acts) or agreed to in writing, shall any Contributor be
156
+      liable to You for damages, including any direct, indirect, special,
157
+      incidental, or consequential damages of any character arising as a
158
+      result of this License or out of the use or inability to use the
159
+      Work (including but not limited to damages for loss of goodwill,
160
+      work stoppage, computer failure or malfunction, or any and all
161
+      other commercial damages or losses), even if such Contributor
162
+      has been advised of the possibility of such damages.
163
+
164
+   9. Accepting Warranty or Additional Liability. While redistributing
165
+      the Work or Derivative Works thereof, You may choose to offer,
166
+      and charge a fee for, acceptance of support, warranty, indemnity,
167
+      or other liability obligations and/or rights consistent with this
168
+      License. However, in accepting such obligations, You may act only
169
+      on Your own behalf and on Your sole responsibility, not on behalf
170
+      of any other Contributor, and only if You agree to indemnify,
171
+      defend, and hold each Contributor harmless for any liability
172
+      incurred by, or claims asserted against, such Contributor by reason
173
+      of your accepting any such warranty or additional liability.
174
+
175
+   END OF TERMS AND CONDITIONS
176
+
177
+   APPENDIX: How to apply the Apache License to your work.
178
+
179
+      To apply the Apache License to your work, attach the following
180
+      boilerplate notice, with the fields enclosed by brackets "{}"
181
+      replaced with your own identifying information. (Don't include
182
+      the brackets!)  The text should be enclosed in the appropriate
183
+      comment syntax for the file format. We also recommend that a
184
+      file or class name and description of purpose be included on the
185
+      same "printed page" as the copyright notice for easier
186
+      identification within third-party archives.
187
+
188
+   Copyright {yyyy} {name of copyright owner}
189
+
190
+   Licensed under the Apache License, Version 2.0 (the "License");
191
+   you may not use this file except in compliance with the License.
192
+   You may obtain a copy of the License at
193
+
194
+       http://www.apache.org/licenses/LICENSE-2.0
195
+
196
+   Unless required by applicable law or agreed to in writing, software
197
+   distributed under the License is distributed on an "AS IS" BASIS,
198
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
199
+   See the License for the specific language governing permissions and
200
+   limitations under the License.
201
+
0 202
new file mode 100644
... ...
@@ -0,0 +1,26 @@
0
+# Distribution project maintainers & reviewers
1
+#
2
+# See GOVERNANCE.md for maintainer versus reviewer roles
3
+#
4
+# MAINTAINERS (cncf-distribution-maintainers@lists.cncf.io)
5
+# GitHub ID, Name, Email address
6
+"chrispat","Chris Patterson","chrispat@github.com"
7
+"clarkbw","Bryan Clark","clarkbw@github.com"
8
+"corhere","Cory Snider","csnider@mirantis.com"
9
+"deleteriousEffect","Hayley Swimelar","hswimelar@gitlab.com"
10
+"heww","He Weiwei","hweiwei@vmware.com"
11
+"joaodrp","João Pereira","jpereira@gitlab.com"
12
+"justincormack","Justin Cormack","justin.cormack@docker.com"
13
+"squizzi","Kyle Squizzato","ksquizzato@mirantis.com"
14
+"milosgajdos","Milos Gajdos","milosthegajdos@gmail.com"
15
+"sargun","Sargun Dhillon","sargun@sargun.me"
16
+"wy65701436","Wang Yan","wangyan@vmware.com"
17
+"stevelasker","Steve Lasker","steve.lasker@microsoft.com"
18
+#
19
+# REVIEWERS
20
+# GitHub ID, Name, Email address
21
+"dmcgowan","Derek McGowan","derek@mcgstyle.net"
22
+"stevvooe","Stephen Day","stevvooe@gmail.com"
23
+"thajeztah","Sebastiaan van Stijn","github@gone.nl"
24
+"DavidSpek", "David van der Spek", "vanderspek.david@gmail.com"
25
+"Jamstah", "James Hewitt", "james.hewitt@gmail.com"
0 26
new file mode 100644
... ...
@@ -0,0 +1,25 @@
0
+# Project packages.
1
+PACKAGES=$(shell go list ./...)
2
+
3
+# Flags passed to `go test`
4
+BUILDFLAGS ?= 
5
+TESTFLAGS ?= 
6
+
7
+.PHONY: all build test coverage
8
+.DEFAULT: all
9
+
10
+all: build
11
+
12
+build: ## no binaries to build, so just check compilation suceeds
13
+	go build ${BUILDFLAGS} ./...
14
+
15
+test: ## run tests
16
+	go test ${TESTFLAGS} ./...
17
+
18
+coverage: ## generate coverprofiles from the unit tests
19
+	rm -f coverage.txt
20
+	go test ${TESTFLAGS} -cover -coverprofile=cover.out ./...
21
+
22
+.PHONY: help
23
+help:
24
+	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m\033[0m\n"} /^[a-zA-Z_\/%-]+:.*?##/ { printf "  \033[36m%-27s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
0 25
new file mode 100644
... ...
@@ -0,0 +1,30 @@
0
+# Distribution reference
1
+
2
+Go library to handle references to container images.
3
+
4
+<img src="/distribution-logo.svg" width="200px" />
5
+
6
+[![Build Status](https://github.com/distribution/reference/actions/workflows/test.yml/badge.svg?branch=main&event=push)](https://github.com/distribution/reference/actions?query=workflow%3ACI)
7
+[![GoDoc](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/distribution/reference)
8
+[![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE)
9
+[![codecov](https://codecov.io/gh/distribution/reference/branch/main/graph/badge.svg)](https://codecov.io/gh/distribution/reference)
10
+[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Freference.svg?type=shield)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Freference?ref=badge_shield)
11
+
12
+This repository contains a library for handling refrences to container images held in container registries. Please see [godoc](https://pkg.go.dev/github.com/distribution/reference) for details.
13
+
14
+## Contribution
15
+
16
+Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute
17
+issues, fixes, and patches to this project.
18
+
19
+## Communication
20
+
21
+For async communication and long running discussions please use issues and pull requests on the github repo.
22
+This will be the best place to discuss design and implementation.
23
+
24
+For sync communication we have a #distribution channel in the [CNCF Slack](https://slack.cncf.io/)
25
+that everyone is welcome to join and chat about development.
26
+
27
+## Licenses
28
+
29
+The distribution codebase is released under the [Apache 2.0 license](LICENSE).
0 30
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+# Security Policy
1
+
2
+## Reporting a Vulnerability
3
+
4
+The maintainers take security seriously. If you discover a security issue, please bring it to their attention right away!
5
+
6
+Please DO NOT file a public issue, instead send your report privately to cncf-distribution-security@lists.cncf.io.
0 7
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 564.27793 654.82002"><defs><style>.cls-1{fill:#416ba9;}.cls-2{fill:#74c3d5;}</style></defs><path class="cls-1" d="M17.48582,567.55941c0-3.66375,2.2168-4.91716,4.91609-4.91716H36.66877c18.70153,0,28.24476,9.06127,28.24476,33.64387,0,22.26771-7.51889,35.57065-27.95526,35.57065H22.40191c-2.69929,0-4.91609-1.25341-4.91609-4.91609Zm20.33987,49.741c7.61539,0,10.60365-6.94043,10.60365-20.72586,0-15.13429-3.85568-19.376-10.70015-19.376H33.97v40.10182Z"/><path class="cls-1" d="M72.43613,567.55941c0-3.66375,2.21681-4.91716,4.9161-4.91716h6.36251c2.69876,0,4.91609,1.25341,4.91609,4.91716v59.38127c0,3.66268-2.21733,4.91609-4.91609,4.91609H77.35223c-2.69929,0-4.9161-1.25341-4.9161-4.91609Z"/><path class="cls-1" d="M99.718,613.05875l5.78405-1.06042c4.33764-.77092,4.53063,1.15692,5.78352,3.85674a6.70953,6.70953,0,0,0,6.5555,3.95218c3.56672,0,6.26548-1.83134,6.26548-5.59158,0-12.82046-27.6663-11.08561-27.6663-34.31724,0-10.79718,7.80839-18.1236,20.43637-18.1236,11.08614,0,16.96615,4.8196,20.05091,12.918.96445,2.31277,1.44641,4.7231-2.98826,5.59052l-5.20559,1.06042c-3.95218.77092-4.33764-1.06042-6.073-3.66269a6.39679,6.39679,0,0,0-5.49456-3.08475c-3.18125,0-5.20559,1.83134-5.20559,4.7231,0,12.24252,27.56981,10.60418,27.56981,33.73931,0,12.532-8.77231,19.66545-22.36422,19.66545-11.47159,0-17.93007-4.43467-20.82236-14.07387C95.57286,616.24,95.1874,613.92617,99.718,613.05875Z"/><path class="cls-1" d="M154.86187,576.62068h-8.09735c-3.66321,0-4.91662-2.21734-4.91662-4.91716v-4.14411c0-2.69983,1.25341-4.91716,4.91662-4.91716H179.058c3.66321,0,4.91609,2.21733,4.91609,4.91716v4.14411c0,2.69982-1.25288,4.91716-4.91609,4.91716h-8.09788v50.32c0,3.66268-2.21681,4.91609-4.9161,4.91609h-6.266c-2.69876,0-4.9161-1.25341-4.9161-4.91609Z"/><path class="cls-1" d="M189.76022,567.55941c0-3.66375,2.21681-4.91716,4.9161-4.91716h16.2912c15.13481,0,23.03969,5.68808,23.03969,20.05144,0,8.38684-3.27775,13.68787-8.29034,16.77369l9.35076,27.76173c1.34938,4.04974-.96445,4.62766-3.37425,4.62766h-8.67581c-2.89176,0-4.53063-1.92783-5.30208-4.7231L211.546,605.92532h-5.68755v21.01536c0,3.66268-2.2168,4.91609-4.91609,4.91609h-6.266c-2.69929,0-4.9161-1.25341-4.9161-4.91609Zm20.14688,25.35246c4.14517,0,7.61592-1.6394,7.61592-8.57984,0-7.61486-3.37425-8.19384-7.22993-8.19384h-4.43467v16.77368Z"/><path class="cls-1" d="M241.91422,567.55941c0-3.66375,2.2168-4.91716,4.91609-4.91716h6.36251c2.69876,0,4.9161,1.25341,4.9161,4.91716v59.38127c0,3.66268-2.21734,4.91609-4.9161,4.91609h-6.36251c-2.69929,0-4.91609-1.25341-4.91609-4.91609Z"/><path class="cls-1" d="M267.75024,567.55941c0-3.66375,2.2168-4.91716,4.91609-4.91716h14.94182c16.77316,0,24.09958,5.49508,24.09958,18.31659,0,6.94044-3.08475,11.953-8.96477,14.5553v.193c6.74744,2.31384,10.41065,7.13343,10.41065,15.80977,0,16.58069-11.3751,20.33987-25.449,20.33987H272.66633c-2.69929,0-4.91609-1.25341-4.91609-4.91609Zm20.72533,22.5572c4.33817,0,6.84447-2.12083,6.84447-7.32642,0-4.91716-2.79579-6.36251-6.84447-6.36251h-4.9161v13.68893Zm.386,27.95473c5.88,0,7.90436-2.40926,7.90436-7.80785,0-5.88-3.18126-7.80786-7.80839-7.80786h-5.39806v15.61571Z"/><path class="cls-1" d="M320.09776,567.55941c0-3.66375,2.21733-4.91716,4.91662-4.91716h6.362c2.69929,0,4.91663,1.25341,4.91663,4.91716v43.282c0,5.78457,2.3133,8.38684,6.748,8.38684,4.43413,0,7.13343-2.60227,7.13343-8.38684v-43.282c0-3.66375,2.21733-4.91716,4.91609-4.91716H361.26c2.6993,0,4.91663,1.25341,4.91663,4.91716v41.06573c0,15.80871-7.13343,24.00256-23.42516,24.00256-16.0982,0-22.6537-8.19385-22.6537-24.00256Z"/><path class="cls-1" d="M384.59236,576.62068H376.495c-3.66322,0-4.91663-2.21734-4.91663-4.91716v-4.14411c0-2.69983,1.25341-4.91716,4.91663-4.91716h32.29343c3.66321,0,4.91609,2.21733,4.91609,4.91716v4.14411c0,2.69982-1.25288,4.91716-4.91609,4.91716H400.6911v50.32c0,3.66268-2.21734,4.91609-4.91663,4.91609h-6.266c-2.69929,0-4.9161-1.25341-4.9161-4.91609Z"/><path class="cls-1" d="M419.49071,567.55941c0-3.66375,2.21681-4.91716,4.9161-4.91716h6.36251c2.69876,0,4.91609,1.25341,4.91609,4.91716v59.38127c0,3.66268-2.21733,4.91609-4.91609,4.91609h-6.36251c-2.69929,0-4.9161-1.25341-4.9161-4.91609Z"/><path class="cls-1" d="M443.20536,597.34654c0-21.30485,5.59106-35.57171,24.48505-35.57171s24.48505,14.26686,24.48505,35.57171c0,22.07472-6.84394,35.37766-24.485,35.37766S443.20536,619.42126,443.20536,597.34654Zm32.48643,0c0-16.29226-2.12083-22.26877-8.00138-22.26877-5.88,0-8.00085,5.97651-8.00085,22.26877,0,17.06212,2.4098,22.17121,8.00085,22.17121C473.378,619.51775,475.69179,614.40866,475.69179,597.34654Z"/><path class="cls-1" d="M499.69859,567.55941c0-3.66375,2.2168-4.91716,4.9161-4.91716h6.941a7.56728,7.56728,0,0,1,6.84394,4.43467l13.207,29.88363h.19247V567.55941c0-3.66375,2.21733-4.91716,4.91662-4.91716h4.62714c2.69876,0,4.91609,1.25341,4.91609,4.91716v59.38127c0,3.66268-2.21733,4.91609-4.91609,4.91609h-5.68756c-2.98878,0-4.72363-1.83134-5.977-4.43466L514.15792,593.5863h-.19247v33.35438c0,3.66268-2.21733,4.91609-4.91663,4.91609h-4.43413c-2.6993,0-4.9161-1.25341-4.9161-4.91609Z"/><g id="F1L4Xu"><path class="cls-2" d="M461.28162,365.26377c14.626-14.99573,31.51073-27.88581,43.901-45.3001,23.6055-33.17709,21.5881-53.98611-9.08528-79.89549-5.54727-4.68571-8.18237-7.96252-5.187-15.251,2.57641-6.26934,3.76528-13.21711,4.83156-19.981,5.90314-37.44659-11.00082-60.70078-48.64828-63.33267-13.137-.91842-16.45015-5.43062-19.21754-16.935-9.30387-38.67663-34.59038-53.67167-74.13662-44.585-10.18443,2.3401-17.05741,2.2529-24.8593-6.77926-30.175-34.93317-59.58084-35.22646-91.95222-.348-9.64337,10.39025-15.6225,11.83918-28.62783,5.4055-32.90341-16.27713-59.8387-3.10046-69.78437,35.47712-4.6848,18.17164-11.36854,26.3489-30.24471,30.1582-31.33028,6.32259-44.78933,33.5759-35.57532,69.531,3.76252,14.68215,4.6826,23.43655-10.28992,33.26423-22.74913,14.93216-25.22052,35.33713-11.0953,59.39875a163.06863,163.06863,0,0,0,18.46085,24.68707c6.40258,7.28037,13.94521,13.55817,19.80434,21.482C65.25053,338.04809,43.116,321.28746,27.8598,297.29993c-17.05057-26.80876-13.40609-48.15088,13.33187-65.26212,13.64688-8.73344,14.87507-15.92347,10.65871-30.93464-12.7269-45.31048,5.12054-71.29348,52.09339-78.34017,9.12234-1.36851,13.24368-4.37134,14.93358-13.09156a120.37358,120.37358,0,0,1,6.91928-23.66458C140.26672,51.59355,166.89048,40.64934,200.93587,56.76c12.995,6.14933,20.16447,5.77862,30.68022-5.2998C268.21035,12.90788,301.23887,13.957,336.089,53.95609c7.03437,8.07364,13.32723,7.58749,21.51782,5.54845,49.26567-12.26462,82.34232,9.66738,86.80352,52.02378.85563,8.12375,4.89151,12.49189,13.59822,11.06745a9.08058,9.08058,0,0,1,2.06083.01162c48.42775,3.32745,67.90447,29.37216,55.65225,76.28488-3.68675,14.11627-5.266,23.35647,9.83168,33.3918,24.025,15.96919,26.43605,40.908,10.89058,67.22194C523.519,321.384,492.3391,349.49056,461.28162,365.26377Z"/><path class="cls-2" d="M222.21166,412.15994c-43.3335,8.71069-88.628,7.98395-130.77907,28.38523,94.59324,34.57588,265.86321,39.32494,381.28659.87883-20.80256-13.03877-43.25235-15.46757-64.96771-19.52875-21.46582-4.01455-43.21049-6.53754-65.22855-9.773,2.32155-9.0906,5.71941-13.26155,14.6818-11.53506,34.9755,6.73747,70.6065,10.43856,104.30053,22.96341,8.18218,3.04152,18.89124,4.40911,19.86455,15.15614,1.09622,12.10448-6.10692,24.09739-16.79915,25.67409-30.25013,4.46064-56.38559,26.36212-84.9133,26.506-28.47048.14371-52.82989-.52977-79.492,14.17476-20.18156,11.13047-46.332,2.83194-64.16335-15.45408-6.83775-7.01216-11.13794-6.37864-19.02114-2.85829-23.91278,10.67842-47.24546,8.5124-67.31614-8.79886-7.10279-6.12627-13.27536-7.629-22.06165-6.68907a44.08867,44.08867,0,0,1-27.74743-5.86122C89.8179,459.38315,82.0507,451.437,82.898,439.18832c.77048-11.13889,11.49627-12.35089,19.55689-15.40536,33.62848-12.74306,69.18754-16.82889,104.26785-23.14551C215.75685,399.01074,219.15407,403.38339,222.21166,412.15994Z"/></g><rect class="cls-1" x="157.9184" y="278.28554" width="63.75238" height="63.75238"/><rect class="cls-1" x="241.008" y="278.28554" width="63.75238" height="63.75238"/><rect class="cls-1" x="157.9184" y="361.37514" width="63.75238" height="63.75238"/><rect class="cls-1" x="367.09657" y="153.06724" width="63.75176" height="63.75177" transform="translate(-13.91822 336.28471) rotate(-45)"/><polygon class="cls-1" points="239.799 221.785 239.799 222.389 296.3 250.79 325.004 193.987 268.201 165.284 239.799 221.785"/><rect class="cls-1" x="341.49858" y="264.8759" width="63.75384" height="63.75383" transform="translate(-59.8512 496.2174) rotate(-63.19922)"/><rect class="cls-1" x="157.9184" y="195.19594" width="63.75238" height="63.75238"/><rect class="cls-1" x="241.008" y="361.37514" width="63.75238" height="63.75238"/><rect class="cls-1" x="324.39973" y="361.37514" width="63.75238" height="63.75238"/></svg>
0 1
\ No newline at end of file
1 2
new file mode 100644
... ...
@@ -0,0 +1,42 @@
0
+package reference
1
+
2
+import "path"
3
+
4
+// IsNameOnly returns true if reference only contains a repo name.
5
+func IsNameOnly(ref Named) bool {
6
+	if _, ok := ref.(NamedTagged); ok {
7
+		return false
8
+	}
9
+	if _, ok := ref.(Canonical); ok {
10
+		return false
11
+	}
12
+	return true
13
+}
14
+
15
+// FamiliarName returns the familiar name string
16
+// for the given named, familiarizing if needed.
17
+func FamiliarName(ref Named) string {
18
+	if nn, ok := ref.(normalizedNamed); ok {
19
+		return nn.Familiar().Name()
20
+	}
21
+	return ref.Name()
22
+}
23
+
24
+// FamiliarString returns the familiar string representation
25
+// for the given reference, familiarizing if needed.
26
+func FamiliarString(ref Reference) string {
27
+	if nn, ok := ref.(normalizedNamed); ok {
28
+		return nn.Familiar().String()
29
+	}
30
+	return ref.String()
31
+}
32
+
33
+// FamiliarMatch reports whether ref matches the specified pattern.
34
+// See [path.Match] for supported patterns.
35
+func FamiliarMatch(pattern string, ref Reference) (bool, error) {
36
+	matched, err := path.Match(pattern, FamiliarString(ref))
37
+	if namedRef, isNamed := ref.(Named); isNamed && !matched {
38
+		matched, _ = path.Match(pattern, FamiliarName(namedRef))
39
+	}
40
+	return matched, err
41
+}
0 42
new file mode 100644
... ...
@@ -0,0 +1,224 @@
0
+package reference
1
+
2
+import (
3
+	"fmt"
4
+	"strings"
5
+
6
+	"github.com/opencontainers/go-digest"
7
+)
8
+
9
+const (
10
+	// legacyDefaultDomain is the legacy domain for Docker Hub (which was
11
+	// originally named "the Docker Index"). This domain is still used for
12
+	// authentication and image search, which were part of the "v1" Docker
13
+	// registry specification.
14
+	//
15
+	// This domain will continue to be supported, but there are plans to consolidate
16
+	// legacy domains to new "canonical" domains. Once those domains are decided
17
+	// on, we must update the normalization functions, but preserve compatibility
18
+	// with existing installs, clients, and user configuration.
19
+	legacyDefaultDomain = "index.docker.io"
20
+
21
+	// defaultDomain is the default domain used for images on Docker Hub.
22
+	// It is used to normalize "familiar" names to canonical names, for example,
23
+	// to convert "ubuntu" to "docker.io/library/ubuntu:latest".
24
+	//
25
+	// Note that actual domain of Docker Hub's registry is registry-1.docker.io.
26
+	// This domain will continue to be supported, but there are plans to consolidate
27
+	// legacy domains to new "canonical" domains. Once those domains are decided
28
+	// on, we must update the normalization functions, but preserve compatibility
29
+	// with existing installs, clients, and user configuration.
30
+	defaultDomain = "docker.io"
31
+
32
+	// officialRepoPrefix is the namespace used for official images on Docker Hub.
33
+	// It is used to normalize "familiar" names to canonical names, for example,
34
+	// to convert "ubuntu" to "docker.io/library/ubuntu:latest".
35
+	officialRepoPrefix = "library/"
36
+
37
+	// defaultTag is the default tag if no tag is provided.
38
+	defaultTag = "latest"
39
+)
40
+
41
+// normalizedNamed represents a name which has been
42
+// normalized and has a familiar form. A familiar name
43
+// is what is used in Docker UI. An example normalized
44
+// name is "docker.io/library/ubuntu" and corresponding
45
+// familiar name of "ubuntu".
46
+type normalizedNamed interface {
47
+	Named
48
+	Familiar() Named
49
+}
50
+
51
+// ParseNormalizedNamed parses a string into a named reference
52
+// transforming a familiar name from Docker UI to a fully
53
+// qualified reference. If the value may be an identifier
54
+// use ParseAnyReference.
55
+func ParseNormalizedNamed(s string) (Named, error) {
56
+	if ok := anchoredIdentifierRegexp.MatchString(s); ok {
57
+		return nil, fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings", s)
58
+	}
59
+	domain, remainder := splitDockerDomain(s)
60
+	var remote string
61
+	if tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 {
62
+		remote = remainder[:tagSep]
63
+	} else {
64
+		remote = remainder
65
+	}
66
+	if strings.ToLower(remote) != remote {
67
+		return nil, fmt.Errorf("invalid reference format: repository name (%s) must be lowercase", remote)
68
+	}
69
+
70
+	ref, err := Parse(domain + "/" + remainder)
71
+	if err != nil {
72
+		return nil, err
73
+	}
74
+	named, isNamed := ref.(Named)
75
+	if !isNamed {
76
+		return nil, fmt.Errorf("reference %s has no name", ref.String())
77
+	}
78
+	return named, nil
79
+}
80
+
81
+// namedTaggedDigested is a reference that has both a tag and a digest.
82
+type namedTaggedDigested interface {
83
+	NamedTagged
84
+	Digested
85
+}
86
+
87
+// ParseDockerRef normalizes the image reference following the docker convention,
88
+// which allows for references to contain both a tag and a digest. It returns a
89
+// reference that is either tagged or digested. For references containing both
90
+// a tag and a digest, it returns a digested reference. For example, the following
91
+// reference:
92
+//
93
+//	docker.io/library/busybox:latest@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
94
+//
95
+// Is returned as a digested reference (with the ":latest" tag removed):
96
+//
97
+//	docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
98
+//
99
+// References that are already "tagged" or "digested" are returned unmodified:
100
+//
101
+//	// Already a digested reference
102
+//	docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa
103
+//
104
+//	// Already a named reference
105
+//	docker.io/library/busybox:latest
106
+func ParseDockerRef(ref string) (Named, error) {
107
+	named, err := ParseNormalizedNamed(ref)
108
+	if err != nil {
109
+		return nil, err
110
+	}
111
+	if canonical, ok := named.(namedTaggedDigested); ok {
112
+		// The reference is both tagged and digested; only return digested.
113
+		newNamed, err := WithName(canonical.Name())
114
+		if err != nil {
115
+			return nil, err
116
+		}
117
+		return WithDigest(newNamed, canonical.Digest())
118
+	}
119
+	return TagNameOnly(named), nil
120
+}
121
+
122
+// splitDockerDomain splits a repository name to domain and remote-name.
123
+// If no valid domain is found, the default domain is used. Repository name
124
+// needs to be already validated before.
125
+func splitDockerDomain(name string) (domain, remainder string) {
126
+	i := strings.IndexRune(name, '/')
127
+	if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != localhost && strings.ToLower(name[:i]) == name[:i]) {
128
+		domain, remainder = defaultDomain, name
129
+	} else {
130
+		domain, remainder = name[:i], name[i+1:]
131
+	}
132
+	if domain == legacyDefaultDomain {
133
+		domain = defaultDomain
134
+	}
135
+	if domain == defaultDomain && !strings.ContainsRune(remainder, '/') {
136
+		remainder = officialRepoPrefix + remainder
137
+	}
138
+	return
139
+}
140
+
141
+// familiarizeName returns a shortened version of the name familiar
142
+// to the Docker UI. Familiar names have the default domain
143
+// "docker.io" and "library/" repository prefix removed.
144
+// For example, "docker.io/library/redis" will have the familiar
145
+// name "redis" and "docker.io/dmcgowan/myapp" will be "dmcgowan/myapp".
146
+// Returns a familiarized named only reference.
147
+func familiarizeName(named namedRepository) repository {
148
+	repo := repository{
149
+		domain: named.Domain(),
150
+		path:   named.Path(),
151
+	}
152
+
153
+	if repo.domain == defaultDomain {
154
+		repo.domain = ""
155
+		// Handle official repositories which have the pattern "library/<official repo name>"
156
+		if strings.HasPrefix(repo.path, officialRepoPrefix) {
157
+			// TODO(thaJeztah): this check may be too strict, as it assumes the
158
+			//  "library/" namespace does not have nested namespaces. While this
159
+			//  is true (currently), technically it would be possible for Docker
160
+			//  Hub to use those (e.g. "library/distros/ubuntu:latest").
161
+			//  See https://github.com/distribution/distribution/pull/3769#issuecomment-1302031785.
162
+			if remainder := strings.TrimPrefix(repo.path, officialRepoPrefix); !strings.ContainsRune(remainder, '/') {
163
+				repo.path = remainder
164
+			}
165
+		}
166
+	}
167
+	return repo
168
+}
169
+
170
+func (r reference) Familiar() Named {
171
+	return reference{
172
+		namedRepository: familiarizeName(r.namedRepository),
173
+		tag:             r.tag,
174
+		digest:          r.digest,
175
+	}
176
+}
177
+
178
+func (r repository) Familiar() Named {
179
+	return familiarizeName(r)
180
+}
181
+
182
+func (t taggedReference) Familiar() Named {
183
+	return taggedReference{
184
+		namedRepository: familiarizeName(t.namedRepository),
185
+		tag:             t.tag,
186
+	}
187
+}
188
+
189
+func (c canonicalReference) Familiar() Named {
190
+	return canonicalReference{
191
+		namedRepository: familiarizeName(c.namedRepository),
192
+		digest:          c.digest,
193
+	}
194
+}
195
+
196
+// TagNameOnly adds the default tag "latest" to a reference if it only has
197
+// a repo name.
198
+func TagNameOnly(ref Named) Named {
199
+	if IsNameOnly(ref) {
200
+		namedTagged, err := WithTag(ref, defaultTag)
201
+		if err != nil {
202
+			// Default tag must be valid, to create a NamedTagged
203
+			// type with non-validated input the WithTag function
204
+			// should be used instead
205
+			panic(err)
206
+		}
207
+		return namedTagged
208
+	}
209
+	return ref
210
+}
211
+
212
+// ParseAnyReference parses a reference string as a possible identifier,
213
+// full digest, or familiar name.
214
+func ParseAnyReference(ref string) (Reference, error) {
215
+	if ok := anchoredIdentifierRegexp.MatchString(ref); ok {
216
+		return digestReference("sha256:" + ref), nil
217
+	}
218
+	if dgst, err := digest.Parse(ref); err == nil {
219
+		return digestReference(dgst), nil
220
+	}
221
+
222
+	return ParseNormalizedNamed(ref)
223
+}
0 224
new file mode 100644
... ...
@@ -0,0 +1,436 @@
0
+// Package reference provides a general type to represent any way of referencing images within the registry.
1
+// Its main purpose is to abstract tags and digests (content-addressable hash).
2
+//
3
+// Grammar
4
+//
5
+//	reference                       := name [ ":" tag ] [ "@" digest ]
6
+//	name                            := [domain '/'] remote-name
7
+//	domain                          := host [':' port-number]
8
+//	host                            := domain-name | IPv4address | \[ IPv6address \]	; rfc3986 appendix-A
9
+//	domain-name                     := domain-component ['.' domain-component]*
10
+//	domain-component                := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
11
+//	port-number                     := /[0-9]+/
12
+//	path-component                  := alpha-numeric [separator alpha-numeric]*
13
+//	path (or "remote-name")         := path-component ['/' path-component]*
14
+//	alpha-numeric                   := /[a-z0-9]+/
15
+//	separator                       := /[_.]|__|[-]*/
16
+//
17
+//	tag                             := /[\w][\w.-]{0,127}/
18
+//
19
+//	digest                          := digest-algorithm ":" digest-hex
20
+//	digest-algorithm                := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]*
21
+//	digest-algorithm-separator      := /[+.-_]/
22
+//	digest-algorithm-component      := /[A-Za-z][A-Za-z0-9]*/
23
+//	digest-hex                      := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
24
+//
25
+//	identifier                      := /[a-f0-9]{64}/
26
+package reference
27
+
28
+import (
29
+	"errors"
30
+	"fmt"
31
+	"strings"
32
+
33
+	"github.com/opencontainers/go-digest"
34
+)
35
+
36
+const (
37
+	// NameTotalLengthMax is the maximum total number of characters in a repository name.
38
+	NameTotalLengthMax = 255
39
+)
40
+
41
+var (
42
+	// ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference.
43
+	ErrReferenceInvalidFormat = errors.New("invalid reference format")
44
+
45
+	// ErrTagInvalidFormat represents an error while trying to parse a string as a tag.
46
+	ErrTagInvalidFormat = errors.New("invalid tag format")
47
+
48
+	// ErrDigestInvalidFormat represents an error while trying to parse a string as a tag.
49
+	ErrDigestInvalidFormat = errors.New("invalid digest format")
50
+
51
+	// ErrNameContainsUppercase is returned for invalid repository names that contain uppercase characters.
52
+	ErrNameContainsUppercase = errors.New("repository name must be lowercase")
53
+
54
+	// ErrNameEmpty is returned for empty, invalid repository names.
55
+	ErrNameEmpty = errors.New("repository name must have at least one component")
56
+
57
+	// ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax.
58
+	ErrNameTooLong = fmt.Errorf("repository name must not be more than %v characters", NameTotalLengthMax)
59
+
60
+	// ErrNameNotCanonical is returned when a name is not canonical.
61
+	ErrNameNotCanonical = errors.New("repository name must be canonical")
62
+)
63
+
64
+// Reference is an opaque object reference identifier that may include
65
+// modifiers such as a hostname, name, tag, and digest.
66
+type Reference interface {
67
+	// String returns the full reference
68
+	String() string
69
+}
70
+
71
+// Field provides a wrapper type for resolving correct reference types when
72
+// working with encoding.
73
+type Field struct {
74
+	reference Reference
75
+}
76
+
77
+// AsField wraps a reference in a Field for encoding.
78
+func AsField(reference Reference) Field {
79
+	return Field{reference}
80
+}
81
+
82
+// Reference unwraps the reference type from the field to
83
+// return the Reference object. This object should be
84
+// of the appropriate type to further check for different
85
+// reference types.
86
+func (f Field) Reference() Reference {
87
+	return f.reference
88
+}
89
+
90
+// MarshalText serializes the field to byte text which
91
+// is the string of the reference.
92
+func (f Field) MarshalText() (p []byte, err error) {
93
+	return []byte(f.reference.String()), nil
94
+}
95
+
96
+// UnmarshalText parses text bytes by invoking the
97
+// reference parser to ensure the appropriately
98
+// typed reference object is wrapped by field.
99
+func (f *Field) UnmarshalText(p []byte) error {
100
+	r, err := Parse(string(p))
101
+	if err != nil {
102
+		return err
103
+	}
104
+
105
+	f.reference = r
106
+	return nil
107
+}
108
+
109
+// Named is an object with a full name
110
+type Named interface {
111
+	Reference
112
+	Name() string
113
+}
114
+
115
+// Tagged is an object which has a tag
116
+type Tagged interface {
117
+	Reference
118
+	Tag() string
119
+}
120
+
121
+// NamedTagged is an object including a name and tag.
122
+type NamedTagged interface {
123
+	Named
124
+	Tag() string
125
+}
126
+
127
+// Digested is an object which has a digest
128
+// in which it can be referenced by
129
+type Digested interface {
130
+	Reference
131
+	Digest() digest.Digest
132
+}
133
+
134
+// Canonical reference is an object with a fully unique
135
+// name including a name with domain and digest
136
+type Canonical interface {
137
+	Named
138
+	Digest() digest.Digest
139
+}
140
+
141
+// namedRepository is a reference to a repository with a name.
142
+// A namedRepository has both domain and path components.
143
+type namedRepository interface {
144
+	Named
145
+	Domain() string
146
+	Path() string
147
+}
148
+
149
+// Domain returns the domain part of the [Named] reference.
150
+func Domain(named Named) string {
151
+	if r, ok := named.(namedRepository); ok {
152
+		return r.Domain()
153
+	}
154
+	domain, _ := splitDomain(named.Name())
155
+	return domain
156
+}
157
+
158
+// Path returns the name without the domain part of the [Named] reference.
159
+func Path(named Named) (name string) {
160
+	if r, ok := named.(namedRepository); ok {
161
+		return r.Path()
162
+	}
163
+	_, path := splitDomain(named.Name())
164
+	return path
165
+}
166
+
167
+func splitDomain(name string) (string, string) {
168
+	match := anchoredNameRegexp.FindStringSubmatch(name)
169
+	if len(match) != 3 {
170
+		return "", name
171
+	}
172
+	return match[1], match[2]
173
+}
174
+
175
+// SplitHostname splits a named reference into a
176
+// hostname and name string. If no valid hostname is
177
+// found, the hostname is empty and the full value
178
+// is returned as name
179
+//
180
+// Deprecated: Use [Domain] or [Path].
181
+func SplitHostname(named Named) (string, string) {
182
+	if r, ok := named.(namedRepository); ok {
183
+		return r.Domain(), r.Path()
184
+	}
185
+	return splitDomain(named.Name())
186
+}
187
+
188
+// Parse parses s and returns a syntactically valid Reference.
189
+// If an error was encountered it is returned, along with a nil Reference.
190
+func Parse(s string) (Reference, error) {
191
+	matches := ReferenceRegexp.FindStringSubmatch(s)
192
+	if matches == nil {
193
+		if s == "" {
194
+			return nil, ErrNameEmpty
195
+		}
196
+		if ReferenceRegexp.FindStringSubmatch(strings.ToLower(s)) != nil {
197
+			return nil, ErrNameContainsUppercase
198
+		}
199
+		return nil, ErrReferenceInvalidFormat
200
+	}
201
+
202
+	if len(matches[1]) > NameTotalLengthMax {
203
+		return nil, ErrNameTooLong
204
+	}
205
+
206
+	var repo repository
207
+
208
+	nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1])
209
+	if len(nameMatch) == 3 {
210
+		repo.domain = nameMatch[1]
211
+		repo.path = nameMatch[2]
212
+	} else {
213
+		repo.domain = ""
214
+		repo.path = matches[1]
215
+	}
216
+
217
+	ref := reference{
218
+		namedRepository: repo,
219
+		tag:             matches[2],
220
+	}
221
+	if matches[3] != "" {
222
+		var err error
223
+		ref.digest, err = digest.Parse(matches[3])
224
+		if err != nil {
225
+			return nil, err
226
+		}
227
+	}
228
+
229
+	r := getBestReferenceType(ref)
230
+	if r == nil {
231
+		return nil, ErrNameEmpty
232
+	}
233
+
234
+	return r, nil
235
+}
236
+
237
+// ParseNamed parses s and returns a syntactically valid reference implementing
238
+// the Named interface. The reference must have a name and be in the canonical
239
+// form, otherwise an error is returned.
240
+// If an error was encountered it is returned, along with a nil Reference.
241
+func ParseNamed(s string) (Named, error) {
242
+	named, err := ParseNormalizedNamed(s)
243
+	if err != nil {
244
+		return nil, err
245
+	}
246
+	if named.String() != s {
247
+		return nil, ErrNameNotCanonical
248
+	}
249
+	return named, nil
250
+}
251
+
252
+// WithName returns a named object representing the given string. If the input
253
+// is invalid ErrReferenceInvalidFormat will be returned.
254
+func WithName(name string) (Named, error) {
255
+	if len(name) > NameTotalLengthMax {
256
+		return nil, ErrNameTooLong
257
+	}
258
+
259
+	match := anchoredNameRegexp.FindStringSubmatch(name)
260
+	if match == nil || len(match) != 3 {
261
+		return nil, ErrReferenceInvalidFormat
262
+	}
263
+	return repository{
264
+		domain: match[1],
265
+		path:   match[2],
266
+	}, nil
267
+}
268
+
269
+// WithTag combines the name from "name" and the tag from "tag" to form a
270
+// reference incorporating both the name and the tag.
271
+func WithTag(name Named, tag string) (NamedTagged, error) {
272
+	if !anchoredTagRegexp.MatchString(tag) {
273
+		return nil, ErrTagInvalidFormat
274
+	}
275
+	var repo repository
276
+	if r, ok := name.(namedRepository); ok {
277
+		repo.domain = r.Domain()
278
+		repo.path = r.Path()
279
+	} else {
280
+		repo.path = name.Name()
281
+	}
282
+	if canonical, ok := name.(Canonical); ok {
283
+		return reference{
284
+			namedRepository: repo,
285
+			tag:             tag,
286
+			digest:          canonical.Digest(),
287
+		}, nil
288
+	}
289
+	return taggedReference{
290
+		namedRepository: repo,
291
+		tag:             tag,
292
+	}, nil
293
+}
294
+
295
+// WithDigest combines the name from "name" and the digest from "digest" to form
296
+// a reference incorporating both the name and the digest.
297
+func WithDigest(name Named, digest digest.Digest) (Canonical, error) {
298
+	if !anchoredDigestRegexp.MatchString(digest.String()) {
299
+		return nil, ErrDigestInvalidFormat
300
+	}
301
+	var repo repository
302
+	if r, ok := name.(namedRepository); ok {
303
+		repo.domain = r.Domain()
304
+		repo.path = r.Path()
305
+	} else {
306
+		repo.path = name.Name()
307
+	}
308
+	if tagged, ok := name.(Tagged); ok {
309
+		return reference{
310
+			namedRepository: repo,
311
+			tag:             tagged.Tag(),
312
+			digest:          digest,
313
+		}, nil
314
+	}
315
+	return canonicalReference{
316
+		namedRepository: repo,
317
+		digest:          digest,
318
+	}, nil
319
+}
320
+
321
+// TrimNamed removes any tag or digest from the named reference.
322
+func TrimNamed(ref Named) Named {
323
+	repo := repository{}
324
+	if r, ok := ref.(namedRepository); ok {
325
+		repo.domain, repo.path = r.Domain(), r.Path()
326
+	} else {
327
+		repo.domain, repo.path = splitDomain(ref.Name())
328
+	}
329
+	return repo
330
+}
331
+
332
+func getBestReferenceType(ref reference) Reference {
333
+	if ref.Name() == "" {
334
+		// Allow digest only references
335
+		if ref.digest != "" {
336
+			return digestReference(ref.digest)
337
+		}
338
+		return nil
339
+	}
340
+	if ref.tag == "" {
341
+		if ref.digest != "" {
342
+			return canonicalReference{
343
+				namedRepository: ref.namedRepository,
344
+				digest:          ref.digest,
345
+			}
346
+		}
347
+		return ref.namedRepository
348
+	}
349
+	if ref.digest == "" {
350
+		return taggedReference{
351
+			namedRepository: ref.namedRepository,
352
+			tag:             ref.tag,
353
+		}
354
+	}
355
+
356
+	return ref
357
+}
358
+
359
+type reference struct {
360
+	namedRepository
361
+	tag    string
362
+	digest digest.Digest
363
+}
364
+
365
+func (r reference) String() string {
366
+	return r.Name() + ":" + r.tag + "@" + r.digest.String()
367
+}
368
+
369
+func (r reference) Tag() string {
370
+	return r.tag
371
+}
372
+
373
+func (r reference) Digest() digest.Digest {
374
+	return r.digest
375
+}
376
+
377
+type repository struct {
378
+	domain string
379
+	path   string
380
+}
381
+
382
+func (r repository) String() string {
383
+	return r.Name()
384
+}
385
+
386
+func (r repository) Name() string {
387
+	if r.domain == "" {
388
+		return r.path
389
+	}
390
+	return r.domain + "/" + r.path
391
+}
392
+
393
+func (r repository) Domain() string {
394
+	return r.domain
395
+}
396
+
397
+func (r repository) Path() string {
398
+	return r.path
399
+}
400
+
401
+type digestReference digest.Digest
402
+
403
+func (d digestReference) String() string {
404
+	return digest.Digest(d).String()
405
+}
406
+
407
+func (d digestReference) Digest() digest.Digest {
408
+	return digest.Digest(d)
409
+}
410
+
411
+type taggedReference struct {
412
+	namedRepository
413
+	tag string
414
+}
415
+
416
+func (t taggedReference) String() string {
417
+	return t.Name() + ":" + t.tag
418
+}
419
+
420
+func (t taggedReference) Tag() string {
421
+	return t.tag
422
+}
423
+
424
+type canonicalReference struct {
425
+	namedRepository
426
+	digest digest.Digest
427
+}
428
+
429
+func (c canonicalReference) String() string {
430
+	return c.Name() + "@" + c.digest.String()
431
+}
432
+
433
+func (c canonicalReference) Digest() digest.Digest {
434
+	return c.digest
435
+}
0 436
new file mode 100644
... ...
@@ -0,0 +1,163 @@
0
+package reference
1
+
2
+import (
3
+	"regexp"
4
+	"strings"
5
+)
6
+
7
+// DigestRegexp matches well-formed digests, including algorithm (e.g. "sha256:<encoded>").
8
+var DigestRegexp = regexp.MustCompile(digestPat)
9
+
10
+// DomainRegexp matches hostname or IP-addresses, optionally including a port
11
+// number. It defines the structure of potential domain components that may be
12
+// part of image names. This is purposely a subset of what is allowed by DNS to
13
+// ensure backwards compatibility with Docker image names. It may be a subset of
14
+// DNS domain name, an IPv4 address in decimal format, or an IPv6 address between
15
+// square brackets (excluding zone identifiers as defined by [RFC 6874] or special
16
+// addresses such as IPv4-Mapped).
17
+//
18
+// [RFC 6874]: https://www.rfc-editor.org/rfc/rfc6874.
19
+var DomainRegexp = regexp.MustCompile(domainAndPort)
20
+
21
+// IdentifierRegexp is the format for string identifier used as a
22
+// content addressable identifier using sha256. These identifiers
23
+// are like digests without the algorithm, since sha256 is used.
24
+var IdentifierRegexp = regexp.MustCompile(identifier)
25
+
26
+// NameRegexp is the format for the name component of references, including
27
+// an optional domain and port, but without tag or digest suffix.
28
+var NameRegexp = regexp.MustCompile(namePat)
29
+
30
+// ReferenceRegexp is the full supported format of a reference. The regexp
31
+// is anchored and has capturing groups for name, tag, and digest
32
+// components.
33
+var ReferenceRegexp = regexp.MustCompile(referencePat)
34
+
35
+// TagRegexp matches valid tag names. From [docker/docker:graph/tags.go].
36
+//
37
+// [docker/docker:graph/tags.go]: https://github.com/moby/moby/blob/v1.6.0/graph/tags.go#L26-L28
38
+var TagRegexp = regexp.MustCompile(tag)
39
+
40
+const (
41
+	// alphanumeric defines the alphanumeric atom, typically a
42
+	// component of names. This only allows lower case characters and digits.
43
+	alphanumeric = `[a-z0-9]+`
44
+
45
+	// separator defines the separators allowed to be embedded in name
46
+	// components. This allows one period, one or two underscore and multiple
47
+	// dashes. Repeated dashes and underscores are intentionally treated
48
+	// differently. In order to support valid hostnames as name components,
49
+	// supporting repeated dash was added. Additionally double underscore is
50
+	// now allowed as a separator to loosen the restriction for previously
51
+	// supported names.
52
+	separator = `(?:[._]|__|[-]+)`
53
+
54
+	// localhost is treated as a special value for domain-name. Any other
55
+	// domain-name without a "." or a ":port" are considered a path component.
56
+	localhost = `localhost`
57
+
58
+	// domainNameComponent restricts the registry domain component of a
59
+	// repository name to start with a component as defined by DomainRegexp.
60
+	domainNameComponent = `(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`
61
+
62
+	// optionalPort matches an optional port-number including the port separator
63
+	// (e.g. ":80").
64
+	optionalPort = `(?::[0-9]+)?`
65
+
66
+	// tag matches valid tag names. From docker/docker:graph/tags.go.
67
+	tag = `[\w][\w.-]{0,127}`
68
+
69
+	// digestPat matches well-formed digests, including algorithm (e.g. "sha256:<encoded>").
70
+	//
71
+	// TODO(thaJeztah): this should follow the same rules as https://pkg.go.dev/github.com/opencontainers/go-digest@v1.0.0#DigestRegexp
72
+	// so that go-digest defines the canonical format. Note that the go-digest is
73
+	// more relaxed:
74
+	//   - it allows multiple algorithms (e.g. "sha256+b64:<encoded>") to allow
75
+	//     future expansion of supported algorithms.
76
+	//   - it allows the "<encoded>" value to use urlsafe base64 encoding as defined
77
+	//     in [rfc4648, section 5].
78
+	//
79
+	// [rfc4648, section 5]: https://www.rfc-editor.org/rfc/rfc4648#section-5.
80
+	digestPat = `[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`
81
+
82
+	// identifier is the format for a content addressable identifier using sha256.
83
+	// These identifiers are like digests without the algorithm, since sha256 is used.
84
+	identifier = `([a-f0-9]{64})`
85
+
86
+	// ipv6address are enclosed between square brackets and may be represented
87
+	// in many ways, see rfc5952. Only IPv6 in compressed or uncompressed format
88
+	// are allowed, IPv6 zone identifiers (rfc6874) or Special addresses such as
89
+	// IPv4-Mapped are deliberately excluded.
90
+	ipv6address = `\[(?:[a-fA-F0-9:]+)\]`
91
+)
92
+
93
+var (
94
+	// domainName defines the structure of potential domain components
95
+	// that may be part of image names. This is purposely a subset of what is
96
+	// allowed by DNS to ensure backwards compatibility with Docker image
97
+	// names. This includes IPv4 addresses on decimal format.
98
+	domainName = domainNameComponent + anyTimes(`\.`+domainNameComponent)
99
+
100
+	// host defines the structure of potential domains based on the URI
101
+	// Host subcomponent on rfc3986. It may be a subset of DNS domain name,
102
+	// or an IPv4 address in decimal format, or an IPv6 address between square
103
+	// brackets (excluding zone identifiers as defined by rfc6874 or special
104
+	// addresses such as IPv4-Mapped).
105
+	host = `(?:` + domainName + `|` + ipv6address + `)`
106
+
107
+	// allowed by the URI Host subcomponent on rfc3986 to ensure backwards
108
+	// compatibility with Docker image names.
109
+	domainAndPort = host + optionalPort
110
+
111
+	// anchoredTagRegexp matches valid tag names, anchored at the start and
112
+	// end of the matched string.
113
+	anchoredTagRegexp = regexp.MustCompile(anchored(tag))
114
+
115
+	// anchoredDigestRegexp matches valid digests, anchored at the start and
116
+	// end of the matched string.
117
+	anchoredDigestRegexp = regexp.MustCompile(anchored(digestPat))
118
+
119
+	// pathComponent restricts path-components to start with an alphanumeric
120
+	// character, with following parts able to be separated by a separator
121
+	// (one period, one or two underscore and multiple dashes).
122
+	pathComponent = alphanumeric + anyTimes(separator+alphanumeric)
123
+
124
+	// remoteName matches the remote-name of a repository. It consists of one
125
+	// or more forward slash (/) delimited path-components:
126
+	//
127
+	//	pathComponent[[/pathComponent] ...] // e.g., "library/ubuntu"
128
+	remoteName = pathComponent + anyTimes(`/`+pathComponent)
129
+	namePat    = optional(domainAndPort+`/`) + remoteName
130
+
131
+	// anchoredNameRegexp is used to parse a name value, capturing the
132
+	// domain and trailing components.
133
+	anchoredNameRegexp = regexp.MustCompile(anchored(optional(capture(domainAndPort), `/`), capture(remoteName)))
134
+
135
+	referencePat = anchored(capture(namePat), optional(`:`, capture(tag)), optional(`@`, capture(digestPat)))
136
+
137
+	// anchoredIdentifierRegexp is used to check or match an
138
+	// identifier value, anchored at start and end of string.
139
+	anchoredIdentifierRegexp = regexp.MustCompile(anchored(identifier))
140
+)
141
+
142
+// optional wraps the expression in a non-capturing group and makes the
143
+// production optional.
144
+func optional(res ...string) string {
145
+	return `(?:` + strings.Join(res, "") + `)?`
146
+}
147
+
148
+// anyTimes wraps the expression in a non-capturing group that can occur
149
+// any number of times.
150
+func anyTimes(res ...string) string {
151
+	return `(?:` + strings.Join(res, "") + `)*`
152
+}
153
+
154
+// capture wraps the expression in a capturing group.
155
+func capture(res ...string) string {
156
+	return `(` + strings.Join(res, "") + `)`
157
+}
158
+
159
+// anchored anchors the regular expression by adding start and end delimiters.
160
+func anchored(res ...string) string {
161
+	return `^` + strings.Join(res, "") + `$`
162
+}
0 163
new file mode 100644
... ...
@@ -0,0 +1,75 @@
0
+/*
1
+   Copyright The containerd Authors.
2
+
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
+
7
+       http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+   Unless required by applicable law or agreed to in writing, software
10
+   distributed under the License is distributed on an "AS IS" BASIS,
11
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+   See the License for the specific language governing permissions and
13
+   limitations under the License.
14
+*/
15
+
16
+package reference
17
+
18
+import (
19
+	"sort"
20
+)
21
+
22
+// Sort sorts string references preferring higher information references.
23
+//
24
+// The precedence is as follows:
25
+//
26
+//  1. [Named] + [Tagged] + [Digested] (e.g., "docker.io/library/busybox:latest@sha256:<digest>")
27
+//  2. [Named] + [Tagged]              (e.g., "docker.io/library/busybox:latest")
28
+//  3. [Named] + [Digested]            (e.g., "docker.io/library/busybo@sha256:<digest>")
29
+//  4. [Named]                         (e.g., "docker.io/library/busybox")
30
+//  5. [Digested]                      (e.g., "docker.io@sha256:<digest>")
31
+//  6. Parse error
32
+func Sort(references []string) []string {
33
+	var prefs []Reference
34
+	var bad []string
35
+
36
+	for _, ref := range references {
37
+		pref, err := ParseAnyReference(ref)
38
+		if err != nil {
39
+			bad = append(bad, ref)
40
+		} else {
41
+			prefs = append(prefs, pref)
42
+		}
43
+	}
44
+	sort.Slice(prefs, func(a, b int) bool {
45
+		ar := refRank(prefs[a])
46
+		br := refRank(prefs[b])
47
+		if ar == br {
48
+			return prefs[a].String() < prefs[b].String()
49
+		}
50
+		return ar < br
51
+	})
52
+	sort.Strings(bad)
53
+	var refs []string
54
+	for _, pref := range prefs {
55
+		refs = append(refs, pref.String())
56
+	}
57
+	return append(refs, bad...)
58
+}
59
+
60
+func refRank(ref Reference) uint8 {
61
+	if _, ok := ref.(Named); ok {
62
+		if _, ok = ref.(Tagged); ok {
63
+			if _, ok = ref.(Digested); ok {
64
+				return 1
65
+			}
66
+			return 2
67
+		}
68
+		if _, ok = ref.(Digested); ok {
69
+			return 3
70
+		}
71
+		return 4
72
+	}
73
+	return 5
74
+}
... ...
@@ -386,6 +386,9 @@ github.com/deckarep/golang-set/v2
386 386
 # github.com/dimchansky/utfbom v1.1.1
387 387
 ## explicit
388 388
 github.com/dimchansky/utfbom
389
+# github.com/distribution/reference v0.5.0
390
+## explicit; go 1.20
391
+github.com/distribution/reference
389 392
 # github.com/docker/distribution v2.8.2+incompatible
390 393
 ## explicit
391 394
 github.com/docker/distribution