Skip to content

Commit 6ad8a46

Browse files
authored
Merge pull request #8491 from dmcgowan/transfer-service-backports
[release/1.7] Transfer service backports
2 parents e39c5c4 + 35e86f9 commit 6ad8a46

2 files changed

Lines changed: 95 additions & 30 deletions

File tree

pkg/transfer/local/transfer.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,19 @@ type localTransferService struct {
4646
}
4747

4848
func NewTransferService(lm leases.Manager, cs content.Store, is images.Store, tc *TransferConfig) transfer.Transferrer {
49-
return &localTransferService{
50-
leases: lm,
51-
content: cs,
52-
images: is,
53-
limiterU: semaphore.NewWeighted(int64(tc.MaxConcurrentUploadedLayers)),
54-
limiterD: semaphore.NewWeighted(int64(tc.MaxConcurrentDownloads)),
55-
config: *tc,
49+
ts := &localTransferService{
50+
leases: lm,
51+
content: cs,
52+
images: is,
53+
config: *tc,
5654
}
55+
if tc.MaxConcurrentUploadedLayers > 0 {
56+
ts.limiterU = semaphore.NewWeighted(int64(tc.MaxConcurrentUploadedLayers))
57+
}
58+
if tc.MaxConcurrentDownloads > 0 {
59+
ts.limiterD = semaphore.NewWeighted(int64(tc.MaxConcurrentDownloads))
60+
}
61+
return ts
5762
}
5863

5964
func (ts *localTransferService) Transfer(ctx context.Context, src interface{}, dest interface{}, opts ...transfer.Opt) error {

plugins/transfer/plugin.go

Lines changed: 83 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ import (
2020
"fmt"
2121

2222
"github.com/containerd/containerd"
23+
"github.com/containerd/containerd/diff"
24+
"github.com/containerd/containerd/errdefs"
2325
"github.com/containerd/containerd/leases"
26+
"github.com/containerd/containerd/log"
2427
"github.com/containerd/containerd/metadata"
2528
"github.com/containerd/containerd/pkg/transfer/local"
2629
"github.com/containerd/containerd/pkg/unpack"
@@ -30,6 +33,7 @@ import (
3033
// Load packages with type registrations
3134
_ "github.com/containerd/containerd/pkg/transfer/archive"
3235
_ "github.com/containerd/containerd/pkg/transfer/image"
36+
_ "github.com/containerd/containerd/pkg/transfer/registry"
3337
)
3438

3539
// Register local transfer service plugin
@@ -40,6 +44,7 @@ func init() {
4044
Requires: []plugin.Type{
4145
plugin.LeasePlugin,
4246
plugin.MetadataPlugin,
47+
plugin.DiffPlugin,
4348
},
4449
Config: defaultConfig(),
4550
InitFn: func(ic *plugin.InitContext) (interface{}, error) {
@@ -56,54 +61,109 @@ func init() {
5661

5762
// Set configuration based on default or user input
5863
var lc local.TransferConfig
59-
lc.MaxConcurrentDownloads = config.maxConcurrentDownloads
60-
lc.MaxConcurrentUploadedLayers = config.maxConcurrentUploadedLayers
61-
for _, uc := range config.unpackConfiguration {
62-
p, err := platforms.Parse(uc.platform)
64+
lc.MaxConcurrentDownloads = config.MaxConcurrentDownloads
65+
lc.MaxConcurrentUploadedLayers = config.MaxConcurrentUploadedLayers
66+
for _, uc := range config.UnpackConfiguration {
67+
p, err := platforms.Parse(uc.Platform)
6368
if err != nil {
64-
return nil, fmt.Errorf("%s: platform configuration %v invalid", plugin.TransferPlugin, uc.platform)
69+
return nil, fmt.Errorf("%s: platform configuration %v invalid", plugin.TransferPlugin, uc.Platform)
70+
}
71+
72+
sn := ms.Snapshotter(uc.Snapshotter)
73+
if sn == nil {
74+
return nil, fmt.Errorf("snapshotter %q not found: %w", uc.Snapshotter, errdefs.ErrNotFound)
75+
}
76+
77+
diffPlugins, err := ic.GetByType(plugin.DiffPlugin)
78+
if err != nil {
79+
return nil, fmt.Errorf("error loading diff plugins: %w", err)
80+
}
81+
var applier diff.Applier
82+
target := platforms.OnlyStrict(p)
83+
if uc.Differ != "" {
84+
plugin, ok := diffPlugins[uc.Differ]
85+
if !ok {
86+
return nil, fmt.Errorf("diff plugin %q: %w", uc.Differ, errdefs.ErrNotFound)
87+
}
88+
inst, err := plugin.Instance()
89+
if err != nil {
90+
return nil, fmt.Errorf("failed to get instance for diff plugin %q: %w", uc.Differ, err)
91+
}
92+
applier = inst.(diff.Applier)
93+
} else {
94+
for name, plugin := range diffPlugins {
95+
var matched bool
96+
for _, p := range plugin.Meta.Platforms {
97+
if target.Match(p) {
98+
matched = true
99+
}
100+
}
101+
if !matched {
102+
continue
103+
}
104+
if applier != nil {
105+
log.G(ic.Context).Warnf("multiple differs match for platform, set `differ` option to choose, skipping %q", name)
106+
continue
107+
}
108+
inst, err := plugin.Instance()
109+
if err != nil {
110+
return nil, fmt.Errorf("failed to get instance for diff plugin %q: %w", name, err)
111+
}
112+
applier = inst.(diff.Applier)
113+
}
114+
}
115+
if applier == nil {
116+
return nil, fmt.Errorf("no matching diff plugins: %w", errdefs.ErrNotFound)
65117
}
66118

67119
up := unpack.Platform{
68-
Platform: platforms.OnlyStrict(p),
69-
SnapshotterKey: uc.snapshotter,
120+
Platform: target,
121+
SnapshotterKey: uc.Snapshotter,
122+
Snapshotter: sn,
123+
Applier: applier,
70124
}
71125
lc.UnpackPlatforms = append(lc.UnpackPlatforms, up)
72126
}
73-
lc.RegistryConfigPath = config.registryConfigPath
127+
lc.RegistryConfigPath = config.RegistryConfigPath
74128

75129
return local.NewTransferService(l.(leases.Manager), ms.ContentStore(), metadata.NewImageStore(ms), &lc), nil
76130
},
77131
})
78132
}
79133

80134
type transferConfig struct {
81-
// maxConcurrentDownloads is the max concurrent content downloads for pull.
82-
maxConcurrentDownloads int `toml:"max_concurrent_downloads"`
135+
// MaxConcurrentDownloads is the max concurrent content downloads for pull.
136+
MaxConcurrentDownloads int `toml:"max_concurrent_downloads"`
83137

84-
// maxConcurrentUploadedLayers is the max concurrent uploads for push
85-
maxConcurrentUploadedLayers int `toml:"max_concurrent_uploaded_layers"`
138+
// MaxConcurrentUploadedLayers is the max concurrent uploads for push
139+
MaxConcurrentUploadedLayers int `toml:"max_concurrent_uploaded_layers"`
86140

87-
// unpackConfiguration is used to read config from toml
88-
unpackConfiguration []unpackConfiguration `toml:"unpack_config"`
141+
// UnpackConfiguration is used to read config from toml
142+
UnpackConfiguration []unpackConfiguration `toml:"unpack_config"`
89143

90-
// registryConfigPath is a path to the root directory containing registry-specific configurations
91-
registryConfigPath string `toml:"config_path"`
144+
// RegistryConfigPath is a path to the root directory containing registry-specific configurations
145+
RegistryConfigPath string `toml:"config_path"`
92146
}
93147

94148
type unpackConfiguration struct {
95-
platform string
96-
snapshotter string
149+
// Platform is the target unpack platform to match
150+
Platform string `toml:"platform"`
151+
152+
// Snapshotter is the snapshotter to use to unpack
153+
Snapshotter string `toml:"snapshotter"`
154+
155+
// Differ is the diff plugin to be used for apply
156+
Differ string `toml:"differ"`
97157
}
98158

99159
func defaultConfig() *transferConfig {
100160
return &transferConfig{
101-
maxConcurrentDownloads: 3,
102-
maxConcurrentUploadedLayers: 3,
103-
unpackConfiguration: []unpackConfiguration{
161+
MaxConcurrentDownloads: 3,
162+
MaxConcurrentUploadedLayers: 3,
163+
UnpackConfiguration: []unpackConfiguration{
104164
{
105-
platform: platforms.Format(platforms.DefaultSpec()),
106-
snapshotter: containerd.DefaultSnapshotter,
165+
Platform: platforms.Format(platforms.DefaultSpec()),
166+
Snapshotter: containerd.DefaultSnapshotter,
107167
},
108168
},
109169
}

0 commit comments

Comments
 (0)