Skip to content

Commit a408a0b

Browse files
committed
add inspect of image
1 parent 885b14e commit a408a0b

4 files changed

Lines changed: 72 additions & 25 deletions

File tree

images/cloudimg/cloudimg.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,23 @@ func (c *CloudImg) Pull(ctx context.Context, url string, tracker progress.Tracke
5151
return pull(ctx, c.conf, c.store, url, tracker)
5252
}
5353

54+
// Inspect returns the record for a single image. Returns (nil, nil) if not found.
55+
func (c *CloudImg) Inspect(ctx context.Context, id string) (result *types.Image, err error) {
56+
err = c.store.With(ctx, func(idx *imageIndex) error {
57+
refs := idx.LookupRefs(id)
58+
if len(refs) == 0 {
59+
return nil
60+
}
61+
result = images.EntryToImage(idx.Images[refs[0]], typ, c.imageSizer)
62+
return nil
63+
})
64+
return
65+
}
66+
5467
// List returns all locally stored cloud images.
5568
func (c *CloudImg) List(ctx context.Context) (result []*types.Image, err error) {
5669
err = c.store.With(ctx, func(idx *imageIndex) error {
57-
result = images.ListImages(idx.Images, typ, func(e *imageEntry) int64 {
58-
if info, err := os.Stat(c.conf.CloudimgBlobPath(e.ContentSum.Hex())); err == nil {
59-
return info.Size()
60-
}
61-
return 0
62-
})
70+
result = images.ListImages(idx.Images, typ, c.imageSizer)
6371
return nil
6472
})
6573
return
@@ -106,3 +114,10 @@ func (c *CloudImg) Config(ctx context.Context, vms []*types.VMConfig) (result []
106114
})
107115
return
108116
}
117+
118+
func (c *CloudImg) imageSizer(e *imageEntry) int64 {
119+
if info, err := os.Stat(c.conf.CloudimgBlobPath(e.ContentSum.Hex())); err == nil {
120+
return info.Size()
121+
}
122+
return 0
123+
}

images/images.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type Images interface {
1212
Type() string
1313

1414
Pull(context.Context, string, progress.Tracker) error
15+
Inspect(context.Context, string) (*types.Image, error)
1516
List(context.Context) ([]*types.Image, error)
1617
Delete(context.Context, []string) ([]string, error)
1718
RegisterGC(*gc.Orchestrator)

images/index.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,22 @@ func DeleteByID[E any](ctx context.Context, logPrefix string, images map[string]
112112
return deleted
113113
}
114114

115+
// EntryToImage converts a single index entry to *types.Image.
116+
// Cheaper than ListImages for single-entry lookups — no map or slice allocation.
117+
func EntryToImage[E Entry](entry *E, typ string, sizer func(*E) int64) *types.Image {
118+
if entry == nil {
119+
return nil
120+
}
121+
e := *entry
122+
return &types.Image{
123+
ID: e.EntryID(),
124+
Name: e.EntryRef(),
125+
Type: typ,
126+
Size: sizer(entry),
127+
CreatedAt: e.EntryCreatedAt(),
128+
}
129+
}
130+
115131
// ListImages iterates the index and builds a list of types.Image.
116132
// sizer is provided by each backend to compute per-entry disk usage.
117133
func ListImages[E Entry](images map[string]*E, typ string, sizer func(*E) int64) []*types.Image {

images/oci/oci.go

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,28 +54,23 @@ func (o *OCI) Pull(ctx context.Context, image string, tracker progress.Tracker)
5454
return pull(ctx, o.conf, o.store, image, tracker)
5555
}
5656

57+
// Inspect returns the record for a single image. Returns (nil, nil) if not found.
58+
func (o *OCI) Inspect(ctx context.Context, id string) (result *types.Image, err error) {
59+
err = o.store.With(ctx, func(idx *imageIndex) error {
60+
refs := idx.LookupRefs(id)
61+
if len(refs) == 0 {
62+
return nil
63+
}
64+
result = images.EntryToImage(idx.Images[refs[0]], typ, o.imageSizer)
65+
return nil
66+
})
67+
return
68+
}
69+
5770
// List returns all locally stored images.
5871
func (o *OCI) List(ctx context.Context) (result []*types.Image, err error) {
5972
err = o.store.With(ctx, func(idx *imageIndex) error {
60-
result = images.ListImages(idx.Images, typ, func(e *imageEntry) int64 {
61-
var total int64
62-
for _, layer := range e.Layers {
63-
if info, err := os.Stat(o.conf.BlobPath(layer.Digest.Hex())); err == nil {
64-
total += info.Size()
65-
}
66-
}
67-
if e.KernelLayer != "" {
68-
if info, err := os.Stat(o.conf.KernelPath(e.KernelLayer.Hex())); err == nil {
69-
total += info.Size()
70-
}
71-
}
72-
if e.InitrdLayer != "" {
73-
if info, err := os.Stat(o.conf.InitrdPath(e.InitrdLayer.Hex())); err == nil {
74-
total += info.Size()
75-
}
76-
}
77-
return total
78-
})
73+
result = images.ListImages(idx.Images, typ, o.imageSizer)
7974
return nil
8075
})
8176
return
@@ -136,3 +131,23 @@ func (o *OCI) Config(ctx context.Context, vms []*types.VMConfig) (result [][]*ty
136131
})
137132
return
138133
}
134+
135+
func (o *OCI) imageSizer(e *imageEntry) int64 {
136+
var total int64
137+
for _, layer := range e.Layers {
138+
if info, err := os.Stat(o.conf.BlobPath(layer.Digest.Hex())); err == nil {
139+
total += info.Size()
140+
}
141+
}
142+
if e.KernelLayer != "" {
143+
if info, err := os.Stat(o.conf.KernelPath(e.KernelLayer.Hex())); err == nil {
144+
total += info.Size()
145+
}
146+
}
147+
if e.InitrdLayer != "" {
148+
if info, err := os.Stat(o.conf.InitrdPath(e.InitrdLayer.Hex())); err == nil {
149+
total += info.Size()
150+
}
151+
}
152+
return total
153+
}

0 commit comments

Comments
 (0)