Skip to content

Commit e70a597

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

2 files changed

Lines changed: 124 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: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ 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+
"github.com/containerd/nerdctl/v2/pkg/api/types"
3033
)
3134

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

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

0 commit comments

Comments
 (0)