Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
| ... | ... |
@@ -50,12 +50,13 @@ func New(opt Opt) (exporter.Exporter, error) {
|
| 50 | 50 |
return im, nil |
| 51 | 51 |
} |
| 52 | 52 |
|
| 53 |
-func (e *imageExporter) Resolve(ctx context.Context, id int, opt map[string]string) (exporter.ExporterInstance, error) {
|
|
| 53 |
+func (e *imageExporter) Resolve(ctx context.Context, id int, attrs map[string]string) (exporter.ExporterInstance, error) {
|
|
| 54 | 54 |
i := &imageExporterInstance{
|
| 55 | 55 |
imageExporter: e, |
| 56 | 56 |
id: id, |
| 57 |
+ attrs: attrs, |
|
| 57 | 58 |
} |
| 58 |
- for k, v := range opt {
|
|
| 59 |
+ for k, v := range attrs {
|
|
| 59 | 60 |
switch exptypes.ImageExporterOptKey(k) {
|
| 60 | 61 |
case exptypes.OptKeyName: |
| 61 | 62 |
for _, v := range strings.Split(v, ",") {
|
| ... | ... |
@@ -80,12 +81,17 @@ type imageExporterInstance struct {
|
| 80 | 80 |
id int |
| 81 | 81 |
targetNames []distref.Named |
| 82 | 82 |
meta map[string][]byte |
| 83 |
+ attrs map[string]string |
|
| 83 | 84 |
} |
| 84 | 85 |
|
| 85 | 86 |
func (e *imageExporterInstance) ID() int {
|
| 86 | 87 |
return e.id |
| 87 | 88 |
} |
| 88 | 89 |
|
| 90 |
+func (e *imageExporterInstance) Type() string {
|
|
| 91 |
+ return "image" |
|
| 92 |
+} |
|
| 93 |
+ |
|
| 89 | 94 |
func (e *imageExporterInstance) Name() string {
|
| 90 | 95 |
return "exporting to image" |
| 91 | 96 |
} |
| ... | ... |
@@ -94,6 +100,10 @@ func (e *imageExporterInstance) Config() *exporter.Config {
|
| 94 | 94 |
return exporter.NewConfig() |
| 95 | 95 |
} |
| 96 | 96 |
|
| 97 |
+func (e *imageExporterInstance) Attrs() map[string]string {
|
|
| 98 |
+ return e.attrs |
|
| 99 |
+} |
|
| 100 |
+ |
|
| 97 | 101 |
func (e *imageExporterInstance) Export(ctx context.Context, inp *exporter.Source, inlineCache exptypes.InlineCache, sessionID string) (map[string]string, exporter.DescriptorReference, error) {
|
| 98 | 102 |
if len(inp.Refs) > 1 {
|
| 99 | 103 |
return nil, nil, fmt.Errorf("exporting multiple references to image store is currently unsupported")
|
| ... | ... |
@@ -35,7 +35,7 @@ require ( |
| 35 | 35 |
github.com/cpuguy83/tar2go v0.3.1 |
| 36 | 36 |
github.com/creack/pty v1.1.18 |
| 37 | 37 |
github.com/deckarep/golang-set/v2 v2.3.0 |
| 38 |
- github.com/distribution/reference v0.5.0 |
|
| 38 |
+ github.com/distribution/reference v0.6.0 |
|
| 39 | 39 |
github.com/docker/distribution v2.8.3+incompatible |
| 40 | 40 |
github.com/docker/go-connections v0.5.0 |
| 41 | 41 |
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c |
| ... | ... |
@@ -61,7 +61,7 @@ require ( |
| 61 | 61 |
github.com/miekg/dns v1.1.57 |
| 62 | 62 |
github.com/mistifyio/go-zfs/v3 v3.0.1 |
| 63 | 63 |
github.com/mitchellh/copystructure v1.2.0 |
| 64 |
- github.com/moby/buildkit v0.14.0-rc2 |
|
| 64 |
+ github.com/moby/buildkit v0.14.0 |
|
| 65 | 65 |
github.com/moby/docker-image-spec v1.3.1 |
| 66 | 66 |
github.com/moby/ipvs v1.1.0 |
| 67 | 67 |
github.com/moby/locker v1.0.1 |
| ... | ... |
@@ -93,7 +93,7 @@ require ( |
| 93 | 93 |
github.com/vbatts/tar-split v0.11.5 |
| 94 | 94 |
github.com/vishvananda/netlink v1.2.1-beta.2 |
| 95 | 95 |
github.com/vishvananda/netns v0.0.4 |
| 96 |
- go.etcd.io/bbolt v1.3.9 |
|
| 96 |
+ go.etcd.io/bbolt v1.3.10 |
|
| 97 | 97 |
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 |
| 98 | 98 |
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 |
| 99 | 99 |
go.opentelemetry.io/otel v1.21.0 |
| ... | ... |
@@ -210,8 +210,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm |
| 210 | 210 |
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= |
| 211 | 211 |
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= |
| 212 | 212 |
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= |
| 213 |
-github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= |
|
| 214 |
-github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= |
|
| 213 |
+github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= |
|
| 214 |
+github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= |
|
| 215 | 215 |
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= |
| 216 | 216 |
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= |
| 217 | 217 |
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= |
| ... | ... |
@@ -480,8 +480,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh |
| 480 | 480 |
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= |
| 481 | 481 |
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= |
| 482 | 482 |
github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs= |
| 483 |
-github.com/moby/buildkit v0.14.0-rc2 h1:qvl0hOKeyAWReOkksNtstQjPNaAD4jN3Dvq4r7slqYM= |
|
| 484 |
-github.com/moby/buildkit v0.14.0-rc2/go.mod h1:/ZJNHNVso1nf063XlDhEkNEcRNW19utVpUKixCUo9Ks= |
|
| 483 |
+github.com/moby/buildkit v0.14.0 h1:mHv2lFS8znLDRc4SMyM2B9tPjxWh2blMvr0H7ARquNM= |
|
| 484 |
+github.com/moby/buildkit v0.14.0/go.mod h1:1XssG7cAqv5Bz1xcGMxJL123iCv5TYN4Z/qf647gfuk= |
|
| 485 | 485 |
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= |
| 486 | 486 |
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= |
| 487 | 487 |
github.com/moby/ipvs v1.1.0 h1:ONN4pGaZQgAx+1Scz5RvWV4Q7Gb+mvfRh3NsPS+1XQQ= |
| ... | ... |
@@ -718,8 +718,8 @@ github.com/zmap/zlint/v3 v3.1.0 h1:WjVytZo79m/L1+/Mlphl09WBob6YTGljN5IGWZFpAv0= |
| 718 | 718 |
github.com/zmap/zlint/v3 v3.1.0/go.mod h1:L7t8s3sEKkb0A2BxGy1IWrxt1ZATa1R4QfJZaQOD3zU= |
| 719 | 719 |
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= |
| 720 | 720 |
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= |
| 721 |
-go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= |
|
| 722 |
-go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= |
|
| 721 |
+go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= |
|
| 722 |
+go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= |
|
| 723 | 723 |
go.etcd.io/etcd/api/v3 v3.5.6/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= |
| 724 | 724 |
go.etcd.io/etcd/client/pkg/v3 v3.5.6 h1:TXQWYceBKqLp4sa87rcPs11SXxUA/mHwH975v+BDvLU= |
| 725 | 725 |
go.etcd.io/etcd/client/pkg/v3 v3.5.6/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= |
| ... | ... |
@@ -10,7 +10,7 @@ Go library to handle references to container images. |
| 10 | 10 |
[](https://codecov.io/gh/distribution/reference) |
| 11 | 11 |
[](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Freference?ref=badge_shield) |
| 12 | 12 |
|
| 13 |
-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 |
+This repository contains a library for handling references to container images held in container registries. Please see [godoc](https://pkg.go.dev/github.com/distribution/reference) for details. |
|
| 14 | 14 |
|
| 15 | 15 |
## Contribution |
| 16 | 16 |
|
| ... | ... |
@@ -123,20 +123,51 @@ func ParseDockerRef(ref string) (Named, error) {
|
| 123 | 123 |
// splitDockerDomain splits a repository name to domain and remote-name. |
| 124 | 124 |
// If no valid domain is found, the default domain is used. Repository name |
| 125 | 125 |
// needs to be already validated before. |
| 126 |
-func splitDockerDomain(name string) (domain, remainder string) {
|
|
| 127 |
- i := strings.IndexRune(name, '/') |
|
| 128 |
- if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != localhost && strings.ToLower(name[:i]) == name[:i]) {
|
|
| 129 |
- domain, remainder = defaultDomain, name |
|
| 130 |
- } else {
|
|
| 131 |
- domain, remainder = name[:i], name[i+1:] |
|
| 132 |
- } |
|
| 133 |
- if domain == legacyDefaultDomain {
|
|
| 134 |
- domain = defaultDomain |
|
| 135 |
- } |
|
| 136 |
- if domain == defaultDomain && !strings.ContainsRune(remainder, '/') {
|
|
| 137 |
- remainder = officialRepoPrefix + remainder |
|
| 138 |
- } |
|
| 139 |
- return |
|
| 126 |
+func splitDockerDomain(name string) (domain, remoteName string) {
|
|
| 127 |
+ maybeDomain, maybeRemoteName, ok := strings.Cut(name, "/") |
|
| 128 |
+ if !ok {
|
|
| 129 |
+ // Fast-path for single element ("familiar" names), such as "ubuntu"
|
|
| 130 |
+ // or "ubuntu:latest". Familiar names must be handled separately, to |
|
| 131 |
+ // prevent them from being handled as "hostname:port". |
|
| 132 |
+ // |
|
| 133 |
+ // Canonicalize them as "docker.io/library/name[:tag]" |
|
| 134 |
+ |
|
| 135 |
+ // FIXME(thaJeztah): account for bare "localhost" or "example.com" names, which SHOULD be considered a domain. |
|
| 136 |
+ return defaultDomain, officialRepoPrefix + name |
|
| 137 |
+ } |
|
| 138 |
+ |
|
| 139 |
+ switch {
|
|
| 140 |
+ case maybeDomain == localhost: |
|
| 141 |
+ // localhost is a reserved namespace and always considered a domain. |
|
| 142 |
+ domain, remoteName = maybeDomain, maybeRemoteName |
|
| 143 |
+ case maybeDomain == legacyDefaultDomain: |
|
| 144 |
+ // canonicalize the Docker Hub and legacy "Docker Index" domains. |
|
| 145 |
+ domain, remoteName = defaultDomain, maybeRemoteName |
|
| 146 |
+ case strings.ContainsAny(maybeDomain, ".:"): |
|
| 147 |
+ // Likely a domain or IP-address: |
|
| 148 |
+ // |
|
| 149 |
+ // - contains a "." (e.g., "example.com" or "127.0.0.1") |
|
| 150 |
+ // - contains a ":" (e.g., "example:5000", "::1", or "[::1]:5000") |
|
| 151 |
+ domain, remoteName = maybeDomain, maybeRemoteName |
|
| 152 |
+ case strings.ToLower(maybeDomain) != maybeDomain: |
|
| 153 |
+ // Uppercase namespaces are not allowed, so if the first element |
|
| 154 |
+ // is not lowercase, we assume it to be a domain-name. |
|
| 155 |
+ domain, remoteName = maybeDomain, maybeRemoteName |
|
| 156 |
+ default: |
|
| 157 |
+ // None of the above: it's not a domain, so use the default, and |
|
| 158 |
+ // use the name input the remote-name. |
|
| 159 |
+ domain, remoteName = defaultDomain, name |
|
| 160 |
+ } |
|
| 161 |
+ |
|
| 162 |
+ if domain == defaultDomain && !strings.ContainsRune(remoteName, '/') {
|
|
| 163 |
+ // Canonicalize "familiar" names, but only on Docker Hub, not |
|
| 164 |
+ // on other domains: |
|
| 165 |
+ // |
|
| 166 |
+ // "docker.io/ubuntu[:tag]" => "docker.io/library/ubuntu[:tag]" |
|
| 167 |
+ remoteName = officialRepoPrefix + remoteName |
|
| 168 |
+ } |
|
| 169 |
+ |
|
| 170 |
+ return domain, remoteName |
|
| 140 | 171 |
} |
| 141 | 172 |
|
| 142 | 173 |
// familiarizeName returns a shortened version of the name familiar |
| ... | ... |
@@ -35,8 +35,13 @@ import ( |
| 35 | 35 |
) |
| 36 | 36 |
|
| 37 | 37 |
const ( |
| 38 |
+ // RepositoryNameTotalLengthMax is the maximum total number of characters in a repository name. |
|
| 39 |
+ RepositoryNameTotalLengthMax = 255 |
|
| 40 |
+ |
|
| 38 | 41 |
// NameTotalLengthMax is the maximum total number of characters in a repository name. |
| 39 |
- NameTotalLengthMax = 255 |
|
| 42 |
+ // |
|
| 43 |
+ // Deprecated: use [RepositoryNameTotalLengthMax] instead. |
|
| 44 |
+ NameTotalLengthMax = RepositoryNameTotalLengthMax |
|
| 40 | 45 |
) |
| 41 | 46 |
|
| 42 | 47 |
var ( |
| ... | ... |
@@ -55,8 +60,8 @@ var ( |
| 55 | 55 |
// ErrNameEmpty is returned for empty, invalid repository names. |
| 56 | 56 |
ErrNameEmpty = errors.New("repository name must have at least one component")
|
| 57 | 57 |
|
| 58 |
- // ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax. |
|
| 59 |
- ErrNameTooLong = fmt.Errorf("repository name must not be more than %v characters", NameTotalLengthMax)
|
|
| 58 |
+ // ErrNameTooLong is returned when a repository name is longer than RepositoryNameTotalLengthMax. |
|
| 59 |
+ ErrNameTooLong = fmt.Errorf("repository name must not be more than %v characters", RepositoryNameTotalLengthMax)
|
|
| 60 | 60 |
|
| 61 | 61 |
// ErrNameNotCanonical is returned when a name is not canonical. |
| 62 | 62 |
ErrNameNotCanonical = errors.New("repository name must be canonical")
|
| ... | ... |
@@ -165,6 +170,9 @@ func Path(named Named) (name string) {
|
| 165 | 165 |
return path |
| 166 | 166 |
} |
| 167 | 167 |
|
| 168 |
+// splitDomain splits a named reference into a hostname and path string. |
|
| 169 |
+// If no valid hostname is found, the hostname is empty and the full value |
|
| 170 |
+// is returned as name |
|
| 168 | 171 |
func splitDomain(name string) (string, string) {
|
| 169 | 172 |
match := anchoredNameRegexp.FindStringSubmatch(name) |
| 170 | 173 |
if len(match) != 3 {
|
| ... | ... |
@@ -173,19 +181,6 @@ func splitDomain(name string) (string, string) {
|
| 173 | 173 |
return match[1], match[2] |
| 174 | 174 |
} |
| 175 | 175 |
|
| 176 |
-// SplitHostname splits a named reference into a |
|
| 177 |
-// hostname and name string. If no valid hostname is |
|
| 178 |
-// found, the hostname is empty and the full value |
|
| 179 |
-// is returned as name |
|
| 180 |
-// |
|
| 181 |
-// Deprecated: Use [Domain] or [Path]. |
|
| 182 |
-func SplitHostname(named Named) (string, string) {
|
|
| 183 |
- if r, ok := named.(namedRepository); ok {
|
|
| 184 |
- return r.Domain(), r.Path() |
|
| 185 |
- } |
|
| 186 |
- return splitDomain(named.Name()) |
|
| 187 |
-} |
|
| 188 |
- |
|
| 189 | 176 |
// Parse parses s and returns a syntactically valid Reference. |
| 190 | 177 |
// If an error was encountered it is returned, along with a nil Reference. |
| 191 | 178 |
func Parse(s string) (Reference, error) {
|
| ... | ... |
@@ -200,10 +195,6 @@ func Parse(s string) (Reference, error) {
|
| 200 | 200 |
return nil, ErrReferenceInvalidFormat |
| 201 | 201 |
} |
| 202 | 202 |
|
| 203 |
- if len(matches[1]) > NameTotalLengthMax {
|
|
| 204 |
- return nil, ErrNameTooLong |
|
| 205 |
- } |
|
| 206 |
- |
|
| 207 | 203 |
var repo repository |
| 208 | 204 |
|
| 209 | 205 |
nameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1]) |
| ... | ... |
@@ -215,6 +206,10 @@ func Parse(s string) (Reference, error) {
|
| 215 | 215 |
repo.path = matches[1] |
| 216 | 216 |
} |
| 217 | 217 |
|
| 218 |
+ if len(repo.path) > RepositoryNameTotalLengthMax {
|
|
| 219 |
+ return nil, ErrNameTooLong |
|
| 220 |
+ } |
|
| 221 |
+ |
|
| 218 | 222 |
ref := reference{
|
| 219 | 223 |
namedRepository: repo, |
| 220 | 224 |
tag: matches[2], |
| ... | ... |
@@ -253,14 +248,15 @@ func ParseNamed(s string) (Named, error) {
|
| 253 | 253 |
// WithName returns a named object representing the given string. If the input |
| 254 | 254 |
// is invalid ErrReferenceInvalidFormat will be returned. |
| 255 | 255 |
func WithName(name string) (Named, error) {
|
| 256 |
- if len(name) > NameTotalLengthMax {
|
|
| 257 |
- return nil, ErrNameTooLong |
|
| 258 |
- } |
|
| 259 |
- |
|
| 260 | 256 |
match := anchoredNameRegexp.FindStringSubmatch(name) |
| 261 | 257 |
if match == nil || len(match) != 3 {
|
| 262 | 258 |
return nil, ErrReferenceInvalidFormat |
| 263 | 259 |
} |
| 260 |
+ |
|
| 261 |
+ if len(match[2]) > RepositoryNameTotalLengthMax {
|
|
| 262 |
+ return nil, ErrNameTooLong |
|
| 263 |
+ } |
|
| 264 |
+ |
|
| 264 | 265 |
return repository{
|
| 265 | 266 |
domain: match[1], |
| 266 | 267 |
path: match[2], |
| ... | ... |
@@ -372,6 +372,7 @@ func (c *Controller) Solve(ctx context.Context, req *controlapi.SolveRequest) (* |
| 372 | 372 |
if err != nil {
|
| 373 | 373 |
return nil, err |
| 374 | 374 |
} |
| 375 |
+ bklog.G(ctx).Debugf("resolve exporter %s with %v", ex.Type, ex.Attrs)
|
|
| 375 | 376 |
expi, err := exp.Resolve(ctx, i, ex.Attrs) |
| 376 | 377 |
if err != nil {
|
| 377 | 378 |
return nil, err |
| ... | ... |
@@ -20,6 +20,7 @@ import ( |
| 20 | 20 |
cerrdefs "github.com/containerd/errdefs" |
| 21 | 21 |
"github.com/moby/buildkit/cache" |
| 22 | 22 |
cacheconfig "github.com/moby/buildkit/cache/config" |
| 23 |
+ "github.com/moby/buildkit/client" |
|
| 23 | 24 |
"github.com/moby/buildkit/exporter" |
| 24 | 25 |
"github.com/moby/buildkit/exporter/containerimage/exptypes" |
| 25 | 26 |
"github.com/moby/buildkit/session" |
| ... | ... |
@@ -68,6 +69,7 @@ func (e *imageExporter) Resolve(ctx context.Context, id int, opt map[string]stri |
| 68 | 68 |
i := &imageExporterInstance{
|
| 69 | 69 |
imageExporter: e, |
| 70 | 70 |
id: id, |
| 71 |
+ attrs: opt, |
|
| 71 | 72 |
opts: ImageCommitOpts{
|
| 72 | 73 |
RefCfg: cacheconfig.RefConfig{
|
| 73 | 74 |
Compression: compression.New(compression.Default), |
| ... | ... |
@@ -168,7 +170,8 @@ func (e *imageExporter) Resolve(ctx context.Context, id int, opt map[string]stri |
| 168 | 168 |
|
| 169 | 169 |
type imageExporterInstance struct {
|
| 170 | 170 |
*imageExporter |
| 171 |
- id int |
|
| 171 |
+ id int |
|
| 172 |
+ attrs map[string]string |
|
| 172 | 173 |
|
| 173 | 174 |
opts ImageCommitOpts |
| 174 | 175 |
push bool |
| ... | ... |
@@ -194,6 +197,14 @@ func (e *imageExporterInstance) Config() *exporter.Config {
|
| 194 | 194 |
return exporter.NewConfigWithCompression(e.opts.RefCfg.Compression) |
| 195 | 195 |
} |
| 196 | 196 |
|
| 197 |
+func (e *imageExporterInstance) Type() string {
|
|
| 198 |
+ return client.ExporterImage |
|
| 199 |
+} |
|
| 200 |
+ |
|
| 201 |
+func (e *imageExporterInstance) Attrs() map[string]string {
|
|
| 202 |
+ return e.attrs |
|
| 203 |
+} |
|
| 204 |
+ |
|
| 197 | 205 |
func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source, inlineCache exptypes.InlineCache, sessionID string) (_ map[string]string, descref exporter.DescriptorReference, err error) {
|
| 198 | 206 |
src = src.Clone() |
| 199 | 207 |
if src.Metadata == nil {
|
| ... | ... |
@@ -22,6 +22,8 @@ type ExporterInstance interface {
|
| 22 | 22 |
ID() int |
| 23 | 23 |
Name() string |
| 24 | 24 |
Config() *Config |
| 25 |
+ Type() string |
|
| 26 |
+ Attrs() map[string]string |
|
| 25 | 27 |
Export(ctx context.Context, src *Source, inlineCache exptypes.InlineCache, sessionID string) (map[string]string, DescriptorReference, error) |
| 26 | 28 |
} |
| 27 | 29 |
|
| ... | ... |
@@ -8,6 +8,7 @@ import ( |
| 8 | 8 |
"time" |
| 9 | 9 |
|
| 10 | 10 |
"github.com/moby/buildkit/cache" |
| 11 |
+ "github.com/moby/buildkit/client" |
|
| 11 | 12 |
"github.com/moby/buildkit/exporter" |
| 12 | 13 |
"github.com/moby/buildkit/exporter/containerimage/exptypes" |
| 13 | 14 |
"github.com/moby/buildkit/exporter/util/epoch" |
| ... | ... |
@@ -38,6 +39,7 @@ func New(opt Opt) (exporter.Exporter, error) {
|
| 38 | 38 |
func (e *localExporter) Resolve(ctx context.Context, id int, opt map[string]string) (exporter.ExporterInstance, error) {
|
| 39 | 39 |
i := &localExporterInstance{
|
| 40 | 40 |
id: id, |
| 41 |
+ attrs: opt, |
|
| 41 | 42 |
localExporter: e, |
| 42 | 43 |
} |
| 43 | 44 |
_, err := i.opts.Load(opt) |
| ... | ... |
@@ -50,7 +52,8 @@ func (e *localExporter) Resolve(ctx context.Context, id int, opt map[string]stri |
| 50 | 50 |
|
| 51 | 51 |
type localExporterInstance struct {
|
| 52 | 52 |
*localExporter |
| 53 |
- id int |
|
| 53 |
+ id int |
|
| 54 |
+ attrs map[string]string |
|
| 54 | 55 |
|
| 55 | 56 |
opts CreateFSOpts |
| 56 | 57 |
} |
| ... | ... |
@@ -63,6 +66,14 @@ func (e *localExporterInstance) Name() string {
|
| 63 | 63 |
return "exporting to client directory" |
| 64 | 64 |
} |
| 65 | 65 |
|
| 66 |
+func (e *localExporterInstance) Type() string {
|
|
| 67 |
+ return client.ExporterLocal |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+func (e *localExporterInstance) Attrs() map[string]string {
|
|
| 71 |
+ return e.attrs |
|
| 72 |
+} |
|
| 73 |
+ |
|
| 66 | 74 |
func (e *localExporter) Config() *exporter.Config {
|
| 67 | 75 |
return exporter.NewConfig() |
| 68 | 76 |
} |
| ... | ... |
@@ -14,6 +14,7 @@ import ( |
| 14 | 14 |
"github.com/distribution/reference" |
| 15 | 15 |
"github.com/moby/buildkit/cache" |
| 16 | 16 |
cacheconfig "github.com/moby/buildkit/cache/config" |
| 17 |
+ "github.com/moby/buildkit/client" |
|
| 17 | 18 |
"github.com/moby/buildkit/exporter" |
| 18 | 19 |
"github.com/moby/buildkit/exporter/containerimage" |
| 19 | 20 |
"github.com/moby/buildkit/exporter/containerimage/exptypes" |
| ... | ... |
@@ -34,8 +35,8 @@ import ( |
| 34 | 34 |
type ExporterVariant string |
| 35 | 35 |
|
| 36 | 36 |
const ( |
| 37 |
- VariantOCI = "oci" |
|
| 38 |
- VariantDocker = "docker" |
|
| 37 |
+ VariantOCI = client.ExporterOCI |
|
| 38 |
+ VariantDocker = client.ExporterDocker |
|
| 39 | 39 |
) |
| 40 | 40 |
|
| 41 | 41 |
const ( |
| ... | ... |
@@ -62,6 +63,7 @@ func (e *imageExporter) Resolve(ctx context.Context, id int, opt map[string]stri |
| 62 | 62 |
i := &imageExporterInstance{
|
| 63 | 63 |
imageExporter: e, |
| 64 | 64 |
id: id, |
| 65 |
+ attrs: opt, |
|
| 65 | 66 |
tar: true, |
| 66 | 67 |
opts: containerimage.ImageCommitOpts{
|
| 67 | 68 |
RefCfg: cacheconfig.RefConfig{
|
| ... | ... |
@@ -100,7 +102,8 @@ func (e *imageExporter) Resolve(ctx context.Context, id int, opt map[string]stri |
| 100 | 100 |
|
| 101 | 101 |
type imageExporterInstance struct {
|
| 102 | 102 |
*imageExporter |
| 103 |
- id int |
|
| 103 |
+ id int |
|
| 104 |
+ attrs map[string]string |
|
| 104 | 105 |
|
| 105 | 106 |
opts containerimage.ImageCommitOpts |
| 106 | 107 |
tar bool |
| ... | ... |
@@ -115,6 +118,14 @@ func (e *imageExporterInstance) Name() string {
|
| 115 | 115 |
return fmt.Sprintf("exporting to %s image format", e.opt.Variant)
|
| 116 | 116 |
} |
| 117 | 117 |
|
| 118 |
+func (e *imageExporterInstance) Type() string {
|
|
| 119 |
+ return string(e.opt.Variant) |
|
| 120 |
+} |
|
| 121 |
+ |
|
| 122 |
+func (e *imageExporterInstance) Attrs() map[string]string {
|
|
| 123 |
+ return e.attrs |
|
| 124 |
+} |
|
| 125 |
+ |
|
| 118 | 126 |
func (e *imageExporterInstance) Config() *exporter.Config {
|
| 119 | 127 |
return exporter.NewConfigWithCompression(e.opts.RefCfg.Compression) |
| 120 | 128 |
} |
| ... | ... |
@@ -7,6 +7,7 @@ import ( |
| 7 | 7 |
"time" |
| 8 | 8 |
|
| 9 | 9 |
"github.com/moby/buildkit/cache" |
| 10 |
+ "github.com/moby/buildkit/client" |
|
| 10 | 11 |
"github.com/moby/buildkit/exporter" |
| 11 | 12 |
"github.com/moby/buildkit/exporter/containerimage/exptypes" |
| 12 | 13 |
"github.com/moby/buildkit/exporter/local" |
| ... | ... |
@@ -37,6 +38,7 @@ func (e *localExporter) Resolve(ctx context.Context, id int, opt map[string]stri |
| 37 | 37 |
li := &localExporterInstance{
|
| 38 | 38 |
localExporter: e, |
| 39 | 39 |
id: id, |
| 40 |
+ attrs: opt, |
|
| 40 | 41 |
} |
| 41 | 42 |
_, err := li.opts.Load(opt) |
| 42 | 43 |
if err != nil {
|
| ... | ... |
@@ -49,7 +51,8 @@ func (e *localExporter) Resolve(ctx context.Context, id int, opt map[string]stri |
| 49 | 49 |
|
| 50 | 50 |
type localExporterInstance struct {
|
| 51 | 51 |
*localExporter |
| 52 |
- id int |
|
| 52 |
+ id int |
|
| 53 |
+ attrs map[string]string |
|
| 53 | 54 |
|
| 54 | 55 |
opts local.CreateFSOpts |
| 55 | 56 |
} |
| ... | ... |
@@ -62,6 +65,14 @@ func (e *localExporterInstance) Name() string {
|
| 62 | 62 |
return "exporting to client tarball" |
| 63 | 63 |
} |
| 64 | 64 |
|
| 65 |
+func (e *localExporterInstance) Type() string {
|
|
| 66 |
+ return client.ExporterTar |
|
| 67 |
+} |
|
| 68 |
+ |
|
| 69 |
+func (e *localExporterInstance) Attrs() map[string]string {
|
|
| 70 |
+ return e.attrs |
|
| 71 |
+} |
|
| 72 |
+ |
|
| 65 | 73 |
func (e *localExporterInstance) Config() *exporter.Config {
|
| 66 | 74 |
return exporter.NewConfig() |
| 67 | 75 |
} |
| ... | ... |
@@ -276,10 +276,10 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS |
| 276 | 276 |
// The `dockerfile.Warnings` *should* only contain warnings about empty continuation |
| 277 | 277 |
// lines, but we'll check the warning message to be sure, so that we don't accidentally |
| 278 | 278 |
// process warnings that are not related to empty continuation lines twice. |
| 279 |
- if warning.URL == linter.RuleNoEmptyContinuations.URL {
|
|
| 279 |
+ if warning.URL == linter.RuleNoEmptyContinuation.URL {
|
|
| 280 | 280 |
location := []parser.Range{*warning.Location}
|
| 281 |
- msg := linter.RuleNoEmptyContinuations.Format() |
|
| 282 |
- lint.Run(&linter.RuleNoEmptyContinuations, location, msg) |
|
| 281 |
+ msg := linter.RuleNoEmptyContinuation.Format() |
|
| 282 |
+ lint.Run(&linter.RuleNoEmptyContinuation, location, msg) |
|
| 283 | 283 |
} |
| 284 | 284 |
} |
| 285 | 285 |
|
| ... | ... |
@@ -92,7 +92,7 @@ func (rule *LinterRule[F]) Run(warn LintWarnFunc, location []parser.Range, txt . |
| 92 | 92 |
} |
| 93 | 93 |
|
| 94 | 94 |
func LintFormatShort(rulename, msg string, startLine int) string {
|
| 95 |
- return fmt.Sprintf("Lint Rule '%s': %s (line %d)", rulename, msg, startLine)
|
|
| 95 |
+ return fmt.Sprintf("%s: %s (line %d)", rulename, msg, startLine)
|
|
| 96 | 96 |
} |
| 97 | 97 |
|
| 98 | 98 |
type LintWarnFunc func(rulename, description, url, fmtmsg string, location []parser.Range) |
| ... | ... |
@@ -21,10 +21,10 @@ var ( |
| 21 | 21 |
return fmt.Sprintf("'%s' and '%s' keywords' casing do not match", as, from)
|
| 22 | 22 |
}, |
| 23 | 23 |
} |
| 24 |
- RuleNoEmptyContinuations = LinterRule[func() string]{
|
|
| 25 |
- Name: "NoEmptyContinuations", |
|
| 24 |
+ RuleNoEmptyContinuation = LinterRule[func() string]{
|
|
| 25 |
+ Name: "NoEmptyContinuation", |
|
| 26 | 26 |
Description: "Empty continuation lines will become errors in a future release", |
| 27 |
- URL: "https://docs.docker.com/go/dockerfile/rule/no-empty-continuations/", |
|
| 27 |
+ URL: "https://docs.docker.com/go/dockerfile/rule/no-empty-continuation/", |
|
| 28 | 28 |
Format: func() string {
|
| 29 | 29 |
return "Empty continuation line" |
| 30 | 30 |
}, |
| ... | ... |
@@ -338,7 +338,7 @@ func Parse(rwc io.Reader) (*Result, error) {
|
| 338 | 338 |
warnings = append(warnings, Warning{
|
| 339 | 339 |
Short: "Empty continuation line found in: " + line, |
| 340 | 340 |
Detail: [][]byte{[]byte("Empty continuation lines will become errors in a future release")},
|
| 341 |
- URL: "https://docs.docker.com/go/dockerfile/rule/no-empty-continuations/", |
|
| 341 |
+ URL: "https://docs.docker.com/go/dockerfile/rule/no-empty-continuation/", |
|
| 342 | 342 |
Location: &Range{Start: Position{Line: currentLine}, End: Position{Line: currentLine}},
|
| 343 | 343 |
}) |
| 344 | 344 |
} |
| ... | ... |
@@ -53,8 +53,6 @@ const ( |
| 53 | 53 |
) |
| 54 | 54 |
|
| 55 | 55 |
type ExporterRequest struct {
|
| 56 |
- Type string |
|
| 57 |
- Attrs map[string]string |
|
| 58 | 56 |
Exporters []exporter.ExporterInstance |
| 59 | 57 |
CacheExporters []RemoteCacheExporter |
| 60 | 58 |
} |
| ... | ... |
@@ -173,11 +171,11 @@ func (s *Solver) recordBuildHistory(ctx context.Context, id string, req frontend |
| 173 | 173 |
CreatedAt: &st, |
| 174 | 174 |
} |
| 175 | 175 |
|
| 176 |
- if exp.Type != "" {
|
|
| 177 |
- rec.Exporters = []*controlapi.Exporter{{
|
|
| 178 |
- Type: exp.Type, |
|
| 179 |
- Attrs: exp.Attrs, |
|
| 180 |
- }} |
|
| 176 |
+ for _, e := range exp.Exporters {
|
|
| 177 |
+ rec.Exporters = append(rec.Exporters, &controlapi.Exporter{
|
|
| 178 |
+ Type: e.Type(), |
|
| 179 |
+ Attrs: e.Attrs(), |
|
| 180 |
+ }) |
|
| 181 | 181 |
} |
| 182 | 182 |
|
| 183 | 183 |
if err := s.history.Update(ctx, &controlapi.BuildHistoryEvent{
|
| ... | ... |
@@ -3,7 +3,7 @@ package flightcontrol |
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 | 5 |
"io" |
| 6 |
- "runtime" |
|
| 6 |
+ "math/rand" |
|
| 7 | 7 |
"sort" |
| 8 | 8 |
"sync" |
| 9 | 9 |
"time" |
| ... | ... |
@@ -43,13 +43,14 @@ func (g *Group[T]) Do(ctx context.Context, key string, fn func(ctx context.Conte |
| 43 | 43 |
err = errors.Wrapf(errRetryTimeout, "flightcontrol") |
| 44 | 44 |
return v, err |
| 45 | 45 |
} |
| 46 |
- runtime.Gosched() |
|
| 47 | 46 |
if backoff > 0 {
|
| 48 |
- time.Sleep(backoff) |
|
| 49 |
- backoff *= 2 |
|
| 47 |
+ backoff = time.Duration(float64(backoff) * 1.2) |
|
| 50 | 48 |
} else {
|
| 51 |
- backoff = time.Millisecond |
|
| 49 |
+ // randomize initial backoff to avoid all goroutines retrying at once |
|
| 50 |
+ //nolint:gosec // using math/rand pseudo-randomness is acceptable here |
|
| 51 |
+ backoff = time.Millisecond + time.Duration(rand.Intn(1e7))*time.Nanosecond |
|
| 52 | 52 |
} |
| 53 |
+ time.Sleep(backoff) |
|
| 53 | 54 |
} |
| 54 | 55 |
} |
| 55 | 56 |
|
| ... | ... |
@@ -421,10 +421,19 @@ Prev() Move to the previous key. |
| 421 | 421 |
``` |
| 422 | 422 |
|
| 423 | 423 |
Each of those functions has a return signature of `(key []byte, value []byte)`. |
| 424 |
-When you have iterated to the end of the cursor then `Next()` will return a |
|
| 425 |
-`nil` key. You must seek to a position using `First()`, `Last()`, or `Seek()` |
|
| 426 |
-before calling `Next()` or `Prev()`. If you do not seek to a position then |
|
| 427 |
-these functions will return a `nil` key. |
|
| 424 |
+You must seek to a position using `First()`, `Last()`, or `Seek()` before calling |
|
| 425 |
+`Next()` or `Prev()`. If you do not seek to a position then these functions will |
|
| 426 |
+return a `nil` key. |
|
| 427 |
+ |
|
| 428 |
+When you have iterated to the end of the cursor, then `Next()` will return a |
|
| 429 |
+`nil` key and the cursor still points to the last element if present. When you |
|
| 430 |
+have iterated to the beginning of the cursor, then `Prev()` will return a `nil` |
|
| 431 |
+key and the cursor still points to the first element if present. |
|
| 432 |
+ |
|
| 433 |
+If you remove key/value pairs during iteration, the cursor may automatically |
|
| 434 |
+move to the next position if present in current node each time removing a key. |
|
| 435 |
+When you call `c.Next()` after removing a key, it may skip one key/value pair. |
|
| 436 |
+Refer to [pull/611](https://github.com/etcd-io/bbolt/pull/611) to get more detailed info. |
|
| 428 | 437 |
|
| 429 | 438 |
During iteration, if the key is non-`nil` but the value is `nil`, that means |
| 430 | 439 |
the key refers to a bucket rather than a value. Use `Bucket.Bucket()` to |
| ... | ... |
@@ -850,6 +859,12 @@ Here are a few things to note when evaluating and using Bolt: |
| 850 | 850 |
to grow. However, it's important to note that deleting large chunks of data |
| 851 | 851 |
will not allow you to reclaim that space on disk. |
| 852 | 852 |
|
| 853 |
+* Removing key/values pairs in a bucket during iteration on the bucket using |
|
| 854 |
+ cursor may not work properly. Each time when removing a key/value pair, the |
|
| 855 |
+ cursor may automatically move to the next position if present. When users |
|
| 856 |
+ call `c.Next()` after removing a key, it may skip one key/value pair. |
|
| 857 |
+ Refer to https://github.com/etcd-io/bbolt/pull/611 for more detailed info. |
|
| 858 |
+ |
|
| 853 | 859 |
For more information on page allocation, [see this comment][page-allocation]. |
| 854 | 860 |
|
| 855 | 861 |
[page-allocation]: https://github.com/boltdb/bolt/issues/308#issuecomment-74811638 |
| ... | ... |
@@ -71,7 +71,7 @@ func (c *Cursor) Last() (key []byte, value []byte) {
|
| 71 | 71 |
|
| 72 | 72 |
// If this is an empty page (calling Delete may result in empty pages) |
| 73 | 73 |
// we call prev to find the last page that is not empty |
| 74 |
- for len(c.stack) > 0 && c.stack[len(c.stack)-1].count() == 0 {
|
|
| 74 |
+ for len(c.stack) > 1 && c.stack[len(c.stack)-1].count() == 0 {
|
|
| 75 | 75 |
c.prev() |
| 76 | 76 |
} |
| 77 | 77 |
|
| ... | ... |
@@ -254,6 +254,15 @@ func (c *Cursor) prev() (key []byte, value []byte, flags uint32) {
|
| 254 | 254 |
elem.index-- |
| 255 | 255 |
break |
| 256 | 256 |
} |
| 257 |
+ // If we've hit the beginning, we should stop moving the cursor, |
|
| 258 |
+ // and stay at the first element, so that users can continue to |
|
| 259 |
+ // iterate over the elements in reverse direction by calling `Next`. |
|
| 260 |
+ // We should return nil in such case. |
|
| 261 |
+ // Refer to https://github.com/etcd-io/bbolt/issues/733 |
|
| 262 |
+ if len(c.stack) == 1 {
|
|
| 263 |
+ c.first() |
|
| 264 |
+ return nil, nil, 0 |
|
| 265 |
+ } |
|
| 257 | 266 |
c.stack = c.stack[:i] |
| 258 | 267 |
} |
| 259 | 268 |
|
| ... | ... |
@@ -282,9 +282,8 @@ func (f *freelist) read(p *page) {
|
| 282 | 282 |
if count == 0 {
|
| 283 | 283 |
f.ids = nil |
| 284 | 284 |
} else {
|
| 285 |
- var ids []pgid |
|
| 286 |
- data := unsafeIndex(unsafe.Pointer(p), unsafe.Sizeof(*p), unsafe.Sizeof(ids[0]), idx) |
|
| 287 |
- unsafeSlice(unsafe.Pointer(&ids), data, count) |
|
| 285 |
+ data := unsafeIndex(unsafe.Pointer(p), unsafe.Sizeof(*p), unsafe.Sizeof(pgid(0)), idx) |
|
| 286 |
+ ids := unsafe.Slice((*pgid)(data), count) |
|
| 288 | 287 |
|
| 289 | 288 |
// copy the ids, so we don't modify on the freelist page directly |
| 290 | 289 |
idsCopy := make([]pgid, count) |
| ... | ... |
@@ -322,15 +321,13 @@ func (f *freelist) write(p *page) error {
|
| 322 | 322 |
p.count = uint16(l) |
| 323 | 323 |
} else if l < 0xFFFF {
|
| 324 | 324 |
p.count = uint16(l) |
| 325 |
- var ids []pgid |
|
| 326 | 325 |
data := unsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p)) |
| 327 |
- unsafeSlice(unsafe.Pointer(&ids), data, l) |
|
| 326 |
+ ids := unsafe.Slice((*pgid)(data), l) |
|
| 328 | 327 |
f.copyall(ids) |
| 329 | 328 |
} else {
|
| 330 | 329 |
p.count = 0xFFFF |
| 331 |
- var ids []pgid |
|
| 332 | 330 |
data := unsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p)) |
| 333 |
- unsafeSlice(unsafe.Pointer(&ids), data, l+1) |
|
| 331 |
+ ids := unsafe.Slice((*pgid)(data), l+1) |
|
| 334 | 332 |
ids[0] = pgid(l) |
| 335 | 333 |
f.copyall(ids[1:]) |
| 336 | 334 |
} |
| ... | ... |
@@ -74,9 +74,8 @@ func (p *page) leafPageElements() []leafPageElement {
|
| 74 | 74 |
if p.count == 0 {
|
| 75 | 75 |
return nil |
| 76 | 76 |
} |
| 77 |
- var elems []leafPageElement |
|
| 78 | 77 |
data := unsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p)) |
| 79 |
- unsafeSlice(unsafe.Pointer(&elems), data, int(p.count)) |
|
| 78 |
+ elems := unsafe.Slice((*leafPageElement)(data), int(p.count)) |
|
| 80 | 79 |
return elems |
| 81 | 80 |
} |
| 82 | 81 |
|
| ... | ... |
@@ -91,9 +90,8 @@ func (p *page) branchPageElements() []branchPageElement {
|
| 91 | 91 |
if p.count == 0 {
|
| 92 | 92 |
return nil |
| 93 | 93 |
} |
| 94 |
- var elems []branchPageElement |
|
| 95 | 94 |
data := unsafeAdd(unsafe.Pointer(p), unsafe.Sizeof(*p)) |
| 96 |
- unsafeSlice(unsafe.Pointer(&elems), data, int(p.count)) |
|
| 95 |
+ elems := unsafe.Slice((*branchPageElement)(data), int(p.count)) |
|
| 97 | 96 |
return elems |
| 98 | 97 |
} |
| 99 | 98 |
|
| ... | ... |
@@ -1,7 +1,6 @@ |
| 1 | 1 |
package bbolt |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "reflect" |
|
| 5 | 4 |
"unsafe" |
| 6 | 5 |
) |
| 7 | 6 |
|
| ... | ... |
@@ -26,14 +25,3 @@ func unsafeByteSlice(base unsafe.Pointer, offset uintptr, i, j int) []byte {
|
| 26 | 26 |
// all), so this is believed to be correct. |
| 27 | 27 |
return (*[maxAllocSize]byte)(unsafeAdd(base, offset))[i:j:j] |
| 28 | 28 |
} |
| 29 |
- |
|
| 30 |
-// unsafeSlice modifies the data, len, and cap of a slice variable pointed to by |
|
| 31 |
-// the slice parameter. This helper should be used over other direct |
|
| 32 |
-// manipulation of reflect.SliceHeader to prevent misuse, namely, converting |
|
| 33 |
-// from reflect.SliceHeader to a Go slice type. |
|
| 34 |
-func unsafeSlice(slice, data unsafe.Pointer, len int) {
|
|
| 35 |
- s := (*reflect.SliceHeader)(slice) |
|
| 36 |
- s.Data = uintptr(data) |
|
| 37 |
- s.Cap = len |
|
| 38 |
- s.Len = len |
|
| 39 |
-} |
| ... | ... |
@@ -444,7 +444,7 @@ github.com/deckarep/golang-set/v2 |
| 444 | 444 |
# github.com/dimchansky/utfbom v1.1.1 |
| 445 | 445 |
## explicit |
| 446 | 446 |
github.com/dimchansky/utfbom |
| 447 |
-# github.com/distribution/reference v0.5.0 |
|
| 447 |
+# github.com/distribution/reference v0.6.0 |
|
| 448 | 448 |
## explicit; go 1.20 |
| 449 | 449 |
github.com/distribution/reference |
| 450 | 450 |
# github.com/docker/distribution v2.8.3+incompatible |
| ... | ... |
@@ -712,7 +712,7 @@ github.com/mitchellh/hashstructure/v2 |
| 712 | 712 |
# github.com/mitchellh/reflectwalk v1.0.2 |
| 713 | 713 |
## explicit |
| 714 | 714 |
github.com/mitchellh/reflectwalk |
| 715 |
-# github.com/moby/buildkit v0.14.0-rc2 |
|
| 715 |
+# github.com/moby/buildkit v0.14.0 |
|
| 716 | 716 |
## explicit; go 1.21 |
| 717 | 717 |
github.com/moby/buildkit/api/services/control |
| 718 | 718 |
github.com/moby/buildkit/api/types |
| ... | ... |
@@ -1145,8 +1145,8 @@ github.com/zmap/zlint/v3/lints/etsi |
| 1145 | 1145 |
github.com/zmap/zlint/v3/lints/mozilla |
| 1146 | 1146 |
github.com/zmap/zlint/v3/lints/rfc |
| 1147 | 1147 |
github.com/zmap/zlint/v3/util |
| 1148 |
-# go.etcd.io/bbolt v1.3.9 |
|
| 1149 |
-## explicit; go 1.17 |
|
| 1148 |
+# go.etcd.io/bbolt v1.3.10 |
|
| 1149 |
+## explicit; go 1.21 |
|
| 1150 | 1150 |
go.etcd.io/bbolt |
| 1151 | 1151 |
# go.etcd.io/etcd/client/pkg/v3 v3.5.6 |
| 1152 | 1152 |
## explicit; go 1.16 |