Skip to content

Commit 680f950

Browse files
committed
fix: fix load image failed
Signed-off-by: ningmingxiao <ning.mingxiao@zte.com.cn>
1 parent 0b388bb commit 680f950

2 files changed

Lines changed: 125 additions & 21 deletions

File tree

pkg/imgutil/load/load.go

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -84,32 +84,13 @@ func FromArchive(ctx context.Context, client *containerd.Client, options types.I
8484
storeOpts = append(storeOpts, transferimage.WithUnpack(platUnpack, options.GOptions.Snapshotter))
8585
storeOpts = append(storeOpts, transferimage.WithDigestRef("import", true, true))
8686

87-
var loadedImages []images.Image
88-
pf, done := transferutil.ProgressHandler(ctx, options.Stdout)
89-
87+
pf, done, loadedImages := transferutil.ProgressHandlerLoadImage(ctx, client, beforeSet, options)
9088
err = client.Transfer(ctx,
9189
tarchive.NewImageImportStream(options.Stdin, ""),
9290
transferimage.NewStore("", storeOpts...),
93-
transfer.WithProgress(func(p transfer.Progress) {
94-
if p.Event == "saved" {
95-
if img, err := imageService.Get(ctx, p.Name); err == nil {
96-
if !beforeSet[img.Name] {
97-
loadedImages = append(loadedImages, img)
98-
}
99-
}
100-
}
101-
pf(p)
102-
}),
91+
transfer.WithProgress(pf),
10392
)
104-
10593
done()
106-
107-
if !options.Quiet {
108-
for _, img := range loadedImages {
109-
fmt.Fprintf(options.Stdout, "Loaded image: %s\n", img.Name)
110-
}
111-
}
112-
11394
return loadedImages, err
11495
}
11596

pkg/transferutil/progress.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ import (
2525

2626
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
2727

28+
containerd "github.com/containerd/containerd/v2/client"
29+
"github.com/containerd/containerd/v2/core/images"
2830
"github.com/containerd/containerd/v2/core/transfer"
2931
"github.com/containerd/containerd/v2/pkg/progress"
32+
33+
"github.com/containerd/nerdctl/v2/pkg/api/types"
3034
)
3135

3236
// From https://github.com/containerd/containerd/blob/v2.2.0-rc.0/cmd/ctr/commands/image/pull.go#L240-L473
@@ -156,6 +160,125 @@ func ProgressHandler(ctx context.Context, out io.Writer) (transfer.ProgressFunc,
156160
return progressFn, done
157161
}
158162

163+
func ProgressHandlerLoadImage(ctx context.Context, client *containerd.Client, beforeSet map[string]bool, options types.ImageLoadOptions) (transfer.ProgressFunc, func(), []images.Image) {
164+
ctx, cancel := context.WithCancel(ctx)
165+
var (
166+
fw = progress.NewWriter(options.Stdout)
167+
start = time.Now()
168+
statuses = map[string]*progressNode{}
169+
roots = []*progressNode{}
170+
pc = make(chan transfer.Progress, 5)
171+
status string
172+
closeC = make(chan struct{})
173+
loadedImages []images.Image
174+
imagesDisplay []string
175+
)
176+
progressFn := func(p transfer.Progress) {
177+
select {
178+
case pc <- p:
179+
case <-ctx.Done():
180+
}
181+
}
182+
183+
done := func() {
184+
cancel()
185+
<-closeC
186+
if !options.Quiet {
187+
for _, img := range imagesDisplay {
188+
fmt.Fprintf(options.Stdout, "Loaded image: %s\n", img)
189+
}
190+
}
191+
}
192+
193+
go func() {
194+
defer close(closeC)
195+
for {
196+
select {
197+
case p := <-pc:
198+
if p.Name == "" {
199+
status = p.Event
200+
continue
201+
}
202+
if p.Event == "saved" {
203+
if img, err := client.ImageService().Get(ctx, p.Name); err == nil {
204+
if !beforeSet[img.Name] {
205+
loadedImages = append(loadedImages, img)
206+
}
207+
imagesDisplay = append(imagesDisplay, img.Name)
208+
}
209+
}
210+
if node, ok := statuses[p.Name]; !ok {
211+
node = &progressNode{
212+
Progress: p,
213+
root: true,
214+
}
215+
if len(p.Parents) == 0 {
216+
roots = append(roots, node)
217+
} else {
218+
var parents []string
219+
for _, parent := range p.Parents {
220+
pStatus, ok := statuses[parent]
221+
if ok {
222+
parents = append(parents, parent)
223+
pStatus.children = append(pStatus.children, node)
224+
node.root = false
225+
}
226+
}
227+
node.Progress.Parents = parents
228+
if node.root {
229+
roots = append(roots, node)
230+
}
231+
}
232+
statuses[p.Name] = node
233+
} else {
234+
if len(node.Progress.Parents) != len(p.Parents) {
235+
var parents []string
236+
var removeRoot bool
237+
for _, parent := range p.Parents {
238+
pStatus, ok := statuses[parent]
239+
if ok {
240+
parents = append(parents, parent)
241+
var found bool
242+
for _, child := range pStatus.children {
243+
if child.Progress.Name == p.Name {
244+
found = true
245+
break
246+
}
247+
}
248+
if !found {
249+
pStatus.children = append(pStatus.children, node)
250+
}
251+
if node.root {
252+
removeRoot = true
253+
}
254+
node.root = false
255+
}
256+
}
257+
p.Parents = parents
258+
// Check if needs to remove from root
259+
if removeRoot {
260+
for i := range roots {
261+
if roots[i] == node {
262+
roots = append(roots[:i], roots[i+1:]...)
263+
break
264+
}
265+
}
266+
}
267+
}
268+
node.Progress = p
269+
}
270+
271+
displayHierarchy(fw, status, roots, start)
272+
fw.Flush()
273+
274+
case <-ctx.Done():
275+
return
276+
}
277+
}
278+
}()
279+
return progressFn, done, loadedImages
280+
}
281+
159282
func displayHierarchy(w io.Writer, status string, roots []*progressNode, start time.Time) {
160283
total := displayNode(w, "", roots)
161284
for _, r := range roots {

0 commit comments

Comments
 (0)