Skip to content

Commit 7429a76

Browse files
committed
Use describably interfaces
Replace use of foreign sources with descriptors and describable Signed-off-by: Derek McGowan <[email protected]> (github: dmcgowan)
1 parent 05bd043 commit 7429a76

16 files changed

Lines changed: 103 additions & 101 deletions

distribution/pull_v2.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ type v2LayerDescriptor struct {
133133
V2MetadataService *metadata.V2MetadataService
134134
tmpFile *os.File
135135
verifier digest.Verifier
136-
foreignSrc *distribution.Descriptor
136+
src distribution.Descriptor
137137
}
138138

139139
func (ld *v2LayerDescriptor) Key() string {
@@ -511,14 +511,7 @@ func (p *v2Puller) pullSchema2(ctx context.Context, ref reference.Named, mfst *s
511511
repo: p.repo,
512512
repoInfo: p.repoInfo,
513513
V2MetadataService: p.V2MetadataService,
514-
}
515-
516-
if d.MediaType == schema2.MediaTypeForeignLayer && len(d.URLs) > 0 {
517-
if !layer.ForeignSourceSupported() {
518-
return "", "", errors.New("foreign layers are not supported on this OS")
519-
}
520-
521-
layerDescriptor.foreignSrc = &d
514+
src: d,
522515
}
523516

524517
descriptors = append(descriptors, layerDescriptor)

distribution/pull_v2_windows.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import (
1111
"github.com/docker/distribution"
1212
"github.com/docker/distribution/context"
1313
"github.com/docker/distribution/manifest/schema1"
14+
"github.com/docker/distribution/manifest/schema2"
1415
"github.com/docker/distribution/registry/client/transport"
1516
"github.com/docker/docker/image"
16-
"github.com/docker/docker/layer"
1717
)
1818

1919
func detectBaseLayer(is image.Store, m *schema1.Manifest, rootFS *image.RootFS) error {
@@ -35,10 +35,13 @@ func detectBaseLayer(is image.Store, m *schema1.Manifest, rootFS *image.RootFS)
3535
return fmt.Errorf("Invalid base layer %q", v1img.Parent)
3636
}
3737

38-
var _ layer.ForeignSourcer = &v2LayerDescriptor{}
38+
var _ distribution.Describable = &v2LayerDescriptor{}
3939

40-
func (ld *v2LayerDescriptor) ForeignSource() *distribution.Descriptor {
41-
return ld.foreignSrc
40+
func (ld *v2LayerDescriptor) Descriptor() distribution.Descriptor {
41+
if ld.src.MediaType == schema2.MediaTypeForeignLayer && len(ld.src.URLs) > 0 {
42+
return ld.src
43+
}
44+
return distribution.Descriptor{}
4245
}
4346

4447
func (ld *v2LayerDescriptor) open(ctx context.Context) (distribution.ReadSeekCloser, error) {

distribution/push_v2.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,10 @@ func (pd *v2PushDescriptor) DiffID() layer.DiffID {
240240
}
241241

242242
func (pd *v2PushDescriptor) Upload(ctx context.Context, progressOutput progress.Output) (distribution.Descriptor, error) {
243-
if fs, ok := pd.layer.(layer.ForeignSourcer); ok {
244-
if d := fs.ForeignSource(); d != nil {
243+
if fs, ok := pd.layer.(distribution.Describable); ok {
244+
if d := fs.Descriptor(); len(d.URLs) > 0 {
245245
progress.Update(progressOutput, pd.ID(), "Skipped foreign layer")
246-
return *d, nil
246+
return d, nil
247247
}
248248
}
249249

distribution/xfer/download.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -319,11 +319,15 @@ func (ldm *LayerDownloadManager) makeDownloadFunc(descriptor DownloadDescriptor,
319319
return
320320
}
321321

322-
var src *distribution.Descriptor
323-
if fs, ok := descriptor.(layer.ForeignSourcer); ok {
324-
src = fs.ForeignSource()
322+
var src distribution.Descriptor
323+
if fs, ok := descriptor.(distribution.Describable); ok {
324+
src = fs.Descriptor()
325+
}
326+
if ds, ok := d.layerStore.(layer.DescribableStore); ok {
327+
d.layer, err = ds.RegisterWithDescriptor(inflatedLayerData, parentLayer, src)
328+
} else {
329+
d.layer, err = d.layerStore.Register(inflatedLayerData, parentLayer)
325330
}
326-
d.layer, err = d.layerStore.RegisterForeign(inflatedLayerData, parentLayer, src)
327331
if err != nil {
328332
select {
329333
case <-d.Transfer.Context().Done():
@@ -414,11 +418,15 @@ func (ldm *LayerDownloadManager) makeDownloadFuncFromDownload(descriptor Downloa
414418
}
415419
defer layerReader.Close()
416420

417-
var src *distribution.Descriptor
418-
if fs, ok := l.(layer.ForeignSourcer); ok {
419-
src = fs.ForeignSource()
421+
var src distribution.Descriptor
422+
if fs, ok := l.(distribution.Describable); ok {
423+
src = fs.Descriptor()
424+
}
425+
if ds, ok := d.layerStore.(layer.DescribableStore); ok {
426+
d.layer, err = ds.RegisterWithDescriptor(layerReader, parentLayer, src)
427+
} else {
428+
d.layer, err = d.layerStore.Register(layerReader, parentLayer)
420429
}
421-
d.layer, err = d.layerStore.RegisterForeign(layerReader, parentLayer, src)
422430
if err != nil {
423431
d.err = fmt.Errorf("failed to register layer: %v", err)
424432
return

distribution/xfer/download_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ func createChainIDFromParent(parent layer.ChainID, dgsts ...layer.DiffID) layer.
7272
}
7373

7474
func (ls *mockLayerStore) Register(reader io.Reader, parentID layer.ChainID) (layer.Layer, error) {
75-
return ls.RegisterForeign(reader, parentID, nil)
75+
return ls.RegisterWithDescriptor(reader, parentID, distribution.Descriptor{})
7676
}
7777

78-
func (ls *mockLayerStore) RegisterForeign(reader io.Reader, parentID layer.ChainID, _ *distribution.Descriptor) (layer.Layer, error) {
78+
func (ls *mockLayerStore) RegisterWithDescriptor(reader io.Reader, parentID layer.ChainID, _ distribution.Descriptor) (layer.Layer, error) {
7979
var (
8080
parent layer.Layer
8181
err error

image/tarexport/load.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool)
6464
var parentLinks []parentLink
6565

6666
for _, m := range manifest {
67-
if m.LayerSources != nil && !layer.ForeignSourceSupported() {
68-
return fmt.Errorf("invalid manifest, foreign layers not supported on this operating system")
69-
}
70-
7167
configPath, err := safePath(tmpDir, m.Config)
7268
if err != nil {
7369
return err
@@ -156,7 +152,7 @@ func (l *tarexporter) setParentID(id, parentID image.ID) error {
156152
return l.is.SetParent(id, parentID)
157153
}
158154

159-
func (l *tarexporter) loadLayer(filename string, rootFS image.RootFS, id string, foreignSrc *distribution.Descriptor, progressOutput progress.Output) (layer.Layer, error) {
155+
func (l *tarexporter) loadLayer(filename string, rootFS image.RootFS, id string, foreignSrc distribution.Descriptor, progressOutput progress.Output) (layer.Layer, error) {
160156
rawTar, err := os.Open(filename)
161157
if err != nil {
162158
logrus.Debugf("Error reading embedded tar: %v", err)
@@ -179,9 +175,17 @@ func (l *tarexporter) loadLayer(filename string, rootFS image.RootFS, id string,
179175

180176
progressReader := progress.NewProgressReader(inflatedLayerData, progressOutput, fileInfo.Size(), stringid.TruncateID(id), "Loading layer")
181177

182-
return l.ls.RegisterForeign(progressReader, rootFS.ChainID(), foreignSrc)
178+
if ds, ok := l.ls.(layer.DescribableStore); ok {
179+
return ds.RegisterWithDescriptor(progressReader, rootFS.ChainID(), foreignSrc)
180+
}
181+
return l.ls.Register(progressReader, rootFS.ChainID())
182+
183+
}
184+
185+
if ds, ok := l.ls.(layer.DescribableStore); ok {
186+
return ds.RegisterWithDescriptor(inflatedLayerData, rootFS.ChainID(), foreignSrc)
183187
}
184-
return l.ls.RegisterForeign(inflatedLayerData, rootFS.ChainID(), foreignSrc)
188+
return l.ls.Register(inflatedLayerData, rootFS.ChainID())
185189
}
186190

187191
func (l *tarexporter) setLoadedTag(ref reference.NamedTagged, imgID image.ID, outStream io.Writer) error {
@@ -303,7 +307,7 @@ func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[str
303307
if err != nil {
304308
return err
305309
}
306-
newLayer, err := l.loadLayer(layerPath, *rootFS, oldID, nil, progressOutput)
310+
newLayer, err := l.loadLayer(layerPath, *rootFS, oldID, distribution.Descriptor{}, progressOutput)
307311
if err != nil {
308312
return err
309313
}

image/tarexport/save.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ func (s *saveSession) save(outStream io.Writer) error {
216216
return nil
217217
}
218218

219-
func (s *saveSession) saveImage(id image.ID) (map[layer.DiffID]*distribution.Descriptor, error) {
219+
func (s *saveSession) saveImage(id image.ID) (map[layer.DiffID]distribution.Descriptor, error) {
220220
img, err := s.is.Get(id)
221221
if err != nil {
222222
return nil, err
@@ -228,7 +228,7 @@ func (s *saveSession) saveImage(id image.ID) (map[layer.DiffID]*distribution.Des
228228

229229
var parent digest.Digest
230230
var layers []string
231-
var foreignSrcs map[layer.DiffID]*distribution.Descriptor
231+
var foreignSrcs map[layer.DiffID]distribution.Descriptor
232232
for i := range img.RootFS.DiffIDs {
233233
v1Img := image.V1Image{}
234234
if i == len(img.RootFS.DiffIDs)-1 {
@@ -252,9 +252,9 @@ func (s *saveSession) saveImage(id image.ID) (map[layer.DiffID]*distribution.Des
252252
}
253253
layers = append(layers, v1Img.ID)
254254
parent = v1ID
255-
if src != nil {
255+
if src.Digest != "" {
256256
if foreignSrcs == nil {
257-
foreignSrcs = make(map[layer.DiffID]*distribution.Descriptor)
257+
foreignSrcs = make(map[layer.DiffID]distribution.Descriptor)
258258
}
259259
foreignSrcs[img.RootFS.DiffIDs[i]] = src
260260
}
@@ -272,65 +272,65 @@ func (s *saveSession) saveImage(id image.ID) (map[layer.DiffID]*distribution.Des
272272
return foreignSrcs, nil
273273
}
274274

275-
func (s *saveSession) saveLayer(id layer.ChainID, legacyImg image.V1Image, createdTime time.Time) (*distribution.Descriptor, error) {
275+
func (s *saveSession) saveLayer(id layer.ChainID, legacyImg image.V1Image, createdTime time.Time) (distribution.Descriptor, error) {
276276
if _, exists := s.savedLayers[legacyImg.ID]; exists {
277-
return nil, nil
277+
return distribution.Descriptor{}, nil
278278
}
279279

280280
outDir := filepath.Join(s.outDir, legacyImg.ID)
281281
if err := os.Mkdir(outDir, 0755); err != nil {
282-
return nil, err
282+
return distribution.Descriptor{}, err
283283
}
284284

285285
// todo: why is this version file here?
286286
if err := ioutil.WriteFile(filepath.Join(outDir, legacyVersionFileName), []byte("1.0"), 0644); err != nil {
287-
return nil, err
287+
return distribution.Descriptor{}, err
288288
}
289289

290290
imageConfig, err := json.Marshal(legacyImg)
291291
if err != nil {
292-
return nil, err
292+
return distribution.Descriptor{}, err
293293
}
294294

295295
if err := ioutil.WriteFile(filepath.Join(outDir, legacyConfigFileName), imageConfig, 0644); err != nil {
296-
return nil, err
296+
return distribution.Descriptor{}, err
297297
}
298298

299299
// serialize filesystem
300300
tarFile, err := os.Create(filepath.Join(outDir, legacyLayerFileName))
301301
if err != nil {
302-
return nil, err
302+
return distribution.Descriptor{}, err
303303
}
304304
defer tarFile.Close()
305305

306306
l, err := s.ls.Get(id)
307307
if err != nil {
308-
return nil, err
308+
return distribution.Descriptor{}, err
309309
}
310310
defer layer.ReleaseAndLog(s.ls, l)
311311

312312
arch, err := l.TarStream()
313313
if err != nil {
314-
return nil, err
314+
return distribution.Descriptor{}, err
315315
}
316316
defer arch.Close()
317317

318318
if _, err := io.Copy(tarFile, arch); err != nil {
319-
return nil, err
319+
return distribution.Descriptor{}, err
320320
}
321321

322322
for _, fname := range []string{"", legacyVersionFileName, legacyConfigFileName, legacyLayerFileName} {
323323
// todo: maybe save layer created timestamp?
324324
if err := system.Chtimes(filepath.Join(outDir, fname), createdTime, createdTime); err != nil {
325-
return nil, err
325+
return distribution.Descriptor{}, err
326326
}
327327
}
328328

329329
s.savedLayers[legacyImg.ID] = struct{}{}
330330

331-
var src *distribution.Descriptor
332-
if fs, ok := l.(layer.ForeignSourcer); ok {
333-
src = fs.ForeignSource()
331+
var src distribution.Descriptor
332+
if fs, ok := l.(distribution.Describable); ok {
333+
src = fs.Descriptor()
334334
}
335335
return src, nil
336336
}

image/tarexport/tarexport.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ type manifestItem struct {
1919
Config string
2020
RepoTags []string
2121
Layers []string
22-
Parent image.ID `json:",omitempty"`
23-
LayerSources map[layer.DiffID]*distribution.Descriptor `json:",omitempty"`
22+
Parent image.ID `json:",omitempty"`
23+
LayerSources map[layer.DiffID]distribution.Descriptor `json:",omitempty"`
2424
}
2525

2626
type tarexporter struct {

layer/filestore.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ var (
2626
// digest.SHA384, // Currently not used
2727
// digest.SHA512, // Currently not used
2828
}
29-
30-
// ErrNoForeignSource is returned when no foreign source is set for a layer.
31-
ErrNoForeignSource = errors.New("layer does not have a foreign source")
3229
)
3330

3431
type fileMetadataStore struct {
@@ -103,7 +100,7 @@ func (fm *fileMetadataTransaction) SetCacheID(cacheID string) error {
103100
return ioutil.WriteFile(filepath.Join(fm.root, "cache-id"), []byte(cacheID), 0644)
104101
}
105102

106-
func (fm *fileMetadataTransaction) SetForeignSource(ref distribution.Descriptor) error {
103+
func (fm *fileMetadataTransaction) SetDescriptor(ref distribution.Descriptor) error {
107104
jsonRef, err := json.Marshal(ref)
108105
if err != nil {
109106
return err
@@ -204,11 +201,12 @@ func (fms *fileMetadataStore) GetCacheID(layer ChainID) (string, error) {
204201
return content, nil
205202
}
206203

207-
func (fms *fileMetadataStore) GetForeignSource(layer ChainID) (distribution.Descriptor, error) {
204+
func (fms *fileMetadataStore) GetDescriptor(layer ChainID) (distribution.Descriptor, error) {
208205
content, err := ioutil.ReadFile(fms.getLayerFilename(layer, "descriptor.json"))
209206
if err != nil {
210207
if os.IsNotExist(err) {
211-
return distribution.Descriptor{}, ErrNoForeignSource
208+
// only return empty descriptor to represent what is stored
209+
return distribution.Descriptor{}, nil
212210
}
213211
return distribution.Descriptor{}, err
214212
}

layer/layer.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,6 @@ type Layer interface {
108108
Metadata() (map[string]string, error)
109109
}
110110

111-
// ForeignSourcer is an interface used to describe the source of layers
112-
// and objects representing layers, when the source is a foreign URL.
113-
type ForeignSourcer interface {
114-
// ForeignSource returns the descriptor for this layer if it is
115-
// a foreign layer, or nil for ordinary layers.
116-
ForeignSource() *distribution.Descriptor
117-
}
118-
119111
// RWLayer represents a layer which is
120112
// read and writable
121113
type RWLayer interface {
@@ -177,7 +169,6 @@ type MountInit func(root string) error
177169
// read-only and read-write layers.
178170
type Store interface {
179171
Register(io.Reader, ChainID) (Layer, error)
180-
RegisterForeign(io.Reader, ChainID, *distribution.Descriptor) (Layer, error)
181172
Get(ChainID) (Layer, error)
182173
Release(Layer) ([]Metadata, error)
183174

@@ -192,14 +183,20 @@ type Store interface {
192183
DriverName() string
193184
}
194185

186+
// DescribableStore represents a layer store capable of storing
187+
// descriptors for layers.
188+
type DescribableStore interface {
189+
RegisterWithDescriptor(io.Reader, ChainID, distribution.Descriptor) (Layer, error)
190+
}
191+
195192
// MetadataTransaction represents functions for setting layer metadata
196193
// with a single transaction.
197194
type MetadataTransaction interface {
198195
SetSize(int64) error
199196
SetParent(parent ChainID) error
200197
SetDiffID(DiffID) error
201198
SetCacheID(string) error
202-
SetForeignSource(distribution.Descriptor) error
199+
SetDescriptor(distribution.Descriptor) error
203200
TarSplitWriter(compressInput bool) (io.WriteCloser, error)
204201

205202
Commit(ChainID) error
@@ -219,7 +216,7 @@ type MetadataStore interface {
219216
GetParent(ChainID) (ChainID, error)
220217
GetDiffID(ChainID) (DiffID, error)
221218
GetCacheID(ChainID) (string, error)
222-
GetForeignSource(ChainID) (distribution.Descriptor, error)
219+
GetDescriptor(ChainID) (distribution.Descriptor, error)
223220
TarSplitReader(ChainID) (io.ReadCloser, error)
224221

225222
SetMountID(string, string) error

0 commit comments

Comments
 (0)