Skip to content

Commit eca395d

Browse files
committed
Allow to skip manifest schema V2 push
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
1 parent 370ac4f commit eca395d

4 files changed

Lines changed: 88 additions & 18 deletions

File tree

daemon/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ type CommonConfig struct {
107107
LiveRestoreEnabled bool `json:"live-restore,omitempty"`
108108
BlockedRegistries []string `json:"block-registry,omitempty"`
109109
AdditionalRegistries []string `json:"add-registry,omitempty"`
110+
SkipSchemaV2Push bool `json:"skip-schema2-push"`
110111

111112
// ClusterStore is the storage backend used for the cluster information. It is used by both
112113
// multihost networking (to store networks and endpoints information) and by the node discovery
@@ -202,6 +203,7 @@ func (config *Config) InstallCommonFlags(flags *pflag.FlagSet) {
202203

203204
flags.Var(opts.NewListOptsRef(&config.BlockedRegistries, registry.ValidateIndexName), "block-registry", "Don't contact given registry")
204205
flags.Var(opts.NewListOptsRef(&config.AdditionalRegistries, registry.ValidateIndexName), "add-registry", "Registry to query before a public one")
206+
flags.BoolVar(&config.SkipSchemaV2Push, "skip-schema2-push", false, "override push behavior to push only schema1 manifests")
205207
}
206208

207209
// IsValueSet returns true if a configuration value

daemon/image_push.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func (daemon *Daemon) PushImage(ctx context.Context, image, tag string, metaHead
5454
LayerStore: distribution.NewLayerProviderFromStore(daemon.layerStore),
5555
TrustKey: daemon.trustKey,
5656
UploadManager: daemon.uploadManager,
57+
SkipSchemaV2: daemon.configStore.SkipSchemaV2Push,
5758
}
5859

5960
err = distribution.Push(ctx, ref, imagePushConfig)

distribution/push_v2.go

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -174,40 +174,55 @@ func (p *v2Pusher) pushV2Tag(ctx context.Context, ref reference.NamedTagged, id
174174
return err
175175
}
176176

177-
// Try schema2 first
178-
builder := schema2.NewManifestBuilder(p.repo.Blobs(ctx), p.config.ConfigMediaType, imgConfig)
179-
manifest, err := manifestFromBuilder(ctx, builder, descriptors)
180-
if err != nil {
181-
return err
182-
}
183-
184177
manSvc, err := p.repo.Manifests(ctx)
185178
if err != nil {
186179
return err
187180
}
188181

189-
putOptions := []distribution.ManifestServiceOption{distribution.WithTag(ref.Tag())}
190-
if _, err = manSvc.Put(ctx, manifest, putOptions...); err != nil {
191-
if runtime.GOOS == "windows" || p.config.TrustKey == nil || p.config.RequireSchema2 {
192-
logrus.Warnf("failed to upload schema2 manifest: %v", err)
193-
return err
194-
}
195-
196-
logrus.Warnf("failed to upload schema2 manifest: %v - falling back to schema1", err)
197-
182+
var (
183+
manifest distribution.Manifest
184+
putOptions = []distribution.ManifestServiceOption{distribution.WithTag(ref.Tag())}
185+
)
186+
if p.config.SkipSchemaV2 {
198187
manifestRef, err := distreference.WithTag(p.repo.Named(), ref.Tag())
199188
if err != nil {
200189
return err
201190
}
202-
builder = schema1.NewConfigManifestBuilder(p.repo.Blobs(ctx), p.config.TrustKey, manifestRef, imgConfig)
191+
builder := schema1.NewConfigManifestBuilder(p.repo.Blobs(ctx), p.config.TrustKey, manifestRef, imgConfig)
203192
manifest, err = manifestFromBuilder(ctx, builder, descriptors)
204193
if err != nil {
205194
return err
206195
}
207-
208196
if _, err = manSvc.Put(ctx, manifest, putOptions...); err != nil {
209197
return err
210198
}
199+
} else {
200+
builder := schema2.NewManifestBuilder(p.repo.Blobs(ctx), p.config.ConfigMediaType, imgConfig)
201+
manifest, err = manifestFromBuilder(ctx, builder, descriptors)
202+
if err != nil {
203+
return err
204+
}
205+
if _, err = manSvc.Put(ctx, manifest, putOptions...); err != nil {
206+
if runtime.GOOS == "windows" {
207+
logrus.Warnf("failed to upload schema2 manifest: %v", err)
208+
return err
209+
}
210+
211+
logrus.Warnf("failed to upload schema2 manifest: %v - falling back to schema1", err)
212+
213+
manifestRef, err := distreference.WithTag(p.repo.Named(), ref.Tag())
214+
if err != nil {
215+
return err
216+
}
217+
builder = schema1.NewConfigManifestBuilder(p.repo.Blobs(ctx), p.config.TrustKey, manifestRef, imgConfig)
218+
manifest, err = manifestFromBuilder(ctx, builder, descriptors)
219+
if err != nil {
220+
return err
221+
}
222+
if _, err = manSvc.Put(ctx, manifest, putOptions...); err != nil {
223+
return err
224+
}
225+
}
211226
}
212227

213228
var canonicalManifest []byte

integration-cli/docker_cli_push_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,3 +855,55 @@ func (s *DockerRegistriesSuite) TestPushNeedsAuth(c *check.C) {
855855
c.Fatalf("Wanted %s, got %s", expected, out)
856856
}
857857
}
858+
859+
func (s *DockerRegistrySuite) TestPushWithSkipSchema2(c *check.C) {
860+
c.Assert(s.d.StartWithBusybox("--skip-schema2-push=false"), check.IsNil)
861+
862+
repo := fmt.Sprintf("%s/runcom/busybox", s.reg.url)
863+
out, err := s.d.Cmd("tag", "busybox", repo)
864+
c.Assert(err, check.IsNil, check.Commentf(out))
865+
866+
out, err = s.d.Cmd("push", repo)
867+
c.Assert(err, check.IsNil, check.Commentf(out))
868+
869+
digest1 := reference.DigestRegexp.FindString(out)
870+
c.Assert(len(digest1), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest"))
871+
872+
out, err = s.d.Cmd("pull", repo+"@"+digest1)
873+
c.Assert(err, check.IsNil, check.Commentf(out))
874+
875+
out, err = s.d.Cmd("rmi", "-f", repo+"@"+digest1)
876+
c.Assert(err, check.IsNil, check.Commentf(out))
877+
878+
c.Assert(s.d.Restart("--skip-schema2-push=true"), check.IsNil)
879+
880+
out, err = s.d.Cmd("push", repo)
881+
c.Assert(err, check.IsNil, check.Commentf(out))
882+
883+
digest2 := reference.DigestRegexp.FindString(out)
884+
c.Assert(len(digest2), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest"))
885+
886+
out, err = s.d.Cmd("pull", repo+"@"+digest2)
887+
c.Assert(err, check.IsNil, check.Commentf(out))
888+
889+
out, err = s.d.Cmd("rmi", "-f", repo+"@"+digest2)
890+
c.Assert(err, check.IsNil, check.Commentf(out))
891+
892+
c.Assert(digest1, check.Not(checker.Equals), digest2)
893+
894+
c.Assert(s.d.Restart(), check.IsNil)
895+
896+
out, err = s.d.Cmd("push", repo)
897+
c.Assert(err, check.IsNil, check.Commentf(out))
898+
899+
digest3 := reference.DigestRegexp.FindString(out)
900+
c.Assert(len(digest3), checker.GreaterThan, 0, check.Commentf("no digest found for pushed manifest"))
901+
902+
out, err = s.d.Cmd("pull", repo+"@"+digest3)
903+
c.Assert(err, check.IsNil, check.Commentf(out))
904+
905+
out, err = s.d.Cmd("rmi", "-f", repo+"@"+digest3)
906+
c.Assert(err, check.IsNil, check.Commentf(out))
907+
908+
c.Assert(digest1, checker.Equals, digest3)
909+
}

0 commit comments

Comments
 (0)