Skip to content

Commit e09bb34

Browse files
committed
Propagate container image size lookup errors
1 parent 3a9fc91 commit e09bb34

13 files changed

Lines changed: 72 additions & 40 deletions

File tree

enterprise/server/remote_execution/container/container.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ type CommandContainer interface {
469469
// ImageSizeBytes returns the estimated on-disk size of the pulled
470470
// container image in bytes. Should be called after PullImage.
471471
// Returns 0 if unknown or not applicable.
472-
ImageSizeBytes(ctx context.Context) int64
472+
ImageSizeBytes(ctx context.Context) (int64, error)
473473
}
474474

475475
// StatsRecorder is an optional interface implemented by a [CommandContainer]
@@ -723,7 +723,7 @@ func (t *TracedCommandContainer) IsolationType() string {
723723
return t.Delegate.IsolationType()
724724
}
725725

726-
func (t *TracedCommandContainer) ImageSizeBytes(ctx context.Context) int64 {
726+
func (t *TracedCommandContainer) ImageSizeBytes(ctx context.Context) (int64, error) {
727727
return t.Delegate.ImageSizeBytes(ctx)
728728
}
729729

enterprise/server/remote_execution/container/container_test.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ type FakeContainer struct {
2828
RequiredPullCredentials oci.Credentials
2929
PullCount int
3030
pullDelay time.Duration
31+
imageSizeBytes int64
32+
imageSizeErr error
3133
}
3234

3335
func (c *FakeContainer) IsolationType() string {
@@ -62,7 +64,9 @@ func (c *FakeContainer) Unpause(ctx context.Context) error { return nil }
6264
func (c *FakeContainer) Stats(context.Context) (*repb.UsageStats, error) {
6365
return &repb.UsageStats{}, nil
6466
}
65-
func (c *FakeContainer) ImageSizeBytes(context.Context) int64 { return 0 }
67+
func (c *FakeContainer) ImageSizeBytes(context.Context) (int64, error) {
68+
return c.imageSizeBytes, c.imageSizeErr
69+
}
6670

6771
func userCtx(t *testing.T, ta *testauth.TestAuthenticator, userID string) context.Context {
6872
ctx, err := ta.WithAuthenticatedUser(context.Background(), userID)
@@ -421,10 +425,12 @@ func TestUsageStats_Timeseries(t *testing.T) {
421425
assert.Equal(t, []int64{0, 500, 400}, memKBSamples, "memory kb samples")
422426
}
423427

424-
func TestTracedCommandContainer_ImageSizeBytes(t *testing.T) {
425-
delegate := &FakeContainer{}
428+
func TestTracedCommandContainer_ImageSizeBytes_Error(t *testing.T) {
429+
delegate := &FakeContainer{imageSizeErr: status.InternalError("image inspect failed")}
426430
traced := container.NewTracedCommandContainer(delegate)
427-
assert.Equal(t, int64(0), traced.ImageSizeBytes(context.Background()))
431+
_, err := traced.ImageSizeBytes(context.Background())
432+
require.Error(t, err)
433+
assert.Contains(t, err.Error(), "image inspect failed")
428434
}
429435

430436
func makePSI(someTotal, fullTotal int64) *repb.PSI {

enterprise/server/remote_execution/containers/bare/bare.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,4 @@ func (c *bareCommandContainer) Stats(ctx context.Context) (*repb.UsageStats, err
193193
return nil, nil
194194
}
195195

196-
func (c *bareCommandContainer) ImageSizeBytes(ctx context.Context) int64 { return 0 }
196+
func (c *bareCommandContainer) ImageSizeBytes(ctx context.Context) (int64, error) { return 0, nil }

enterprise/server/remote_execution/containers/docker/docker.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,12 @@ func (c *dockerCommandContainer) IsolationType() string {
202202
return "docker"
203203
}
204204

205-
func (c *dockerCommandContainer) ImageSizeBytes(ctx context.Context) int64 {
205+
func (c *dockerCommandContainer) ImageSizeBytes(ctx context.Context) (int64, error) {
206206
ii, err := c.client.ImageInspect(ctx, c.image, dockerclient.ImageInspectWithRawResponse(nil))
207207
if err != nil {
208-
return 0
208+
return 0, err
209209
}
210-
return ii.Size
210+
return ii.Size, nil
211211
}
212212

213213
func (r *dockerCommandContainer) Run(ctx context.Context, command *repb.Command, workDir string, creds oci.Credentials) *interfaces.CommandResult {

enterprise/server/remote_execution/containers/firecracker/firecracker.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,19 +2100,22 @@ func (c *FirecrackerContainer) IsolationType() string {
21002100
return "firecracker"
21012101
}
21022102

2103-
func (c *FirecrackerContainer) ImageSizeBytes(ctx context.Context) int64 {
2103+
func (c *FirecrackerContainer) ImageSizeBytes(ctx context.Context) (int64, error) {
21042104
if !c.pulled {
2105-
return 0
2105+
return 0, nil
21062106
}
21072107
imagePath, err := ociconv.CachedDiskImagePath(ctx, c.executorConfig.CacheRoot, c.containerImage)
2108-
if err != nil || imagePath == "" {
2109-
return 0
2108+
if err != nil {
2109+
return 0, err
2110+
}
2111+
if imagePath == "" {
2112+
return 0, nil
21102113
}
21112114
info, err := os.Stat(imagePath)
21122115
if err != nil {
2113-
return 0
2116+
return 0, err
21142117
}
2115-
return info.Size()
2118+
return info.Size(), nil
21162119
}
21172120

21182121
// Run the given command within the container and remove the container after

enterprise/server/remote_execution/containers/ociruntime/ociruntime.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -629,15 +629,15 @@ func (c *ociContainer) IsolationType() string {
629629
return "oci" // TODO: make const in platform.go
630630
}
631631

632-
func (c *ociContainer) ImageSizeBytes(ctx context.Context) int64 {
632+
func (c *ociContainer) ImageSizeBytes(ctx context.Context) (int64, error) {
633633
if c.lockedImage == nil {
634-
return 0
634+
return 0, nil
635635
}
636636
var total int64
637637
for _, layer := range c.lockedImage.Layers {
638638
total += layer.EstimatedDiskUsageBytes
639639
}
640-
return total
640+
return total, nil
641641
}
642642

643643
func (c *ociContainer) IsImageCached(ctx context.Context) (bool, error) {

enterprise/server/remote_execution/containers/podman/podman.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -368,17 +368,20 @@ func (c *podmanCommandContainer) IsolationType() string {
368368
return "podman"
369369
}
370370

371-
func (c *podmanCommandContainer) ImageSizeBytes(ctx context.Context) int64 {
371+
func (c *podmanCommandContainer) ImageSizeBytes(ctx context.Context) (int64, error) {
372372
stdout := &bytes.Buffer{}
373373
res := c.runPodman(ctx, "image", &interfaces.Stdio{Stdout: stdout}, "inspect", c.image, "--format", "{{.Size}}")
374-
if res.Error != nil || res.ExitCode != 0 {
375-
return 0
374+
if res.Error != nil {
375+
return 0, res.Error
376+
}
377+
if res.ExitCode != 0 {
378+
return 0, status.UnknownErrorf("podman image inspect exited with code %d", res.ExitCode)
376379
}
377380
size, err := strconv.ParseInt(strings.TrimSpace(stdout.String()), 10, 64)
378381
if err != nil {
379-
return 0
382+
return 0, status.WrapError(err, "parse podman image size")
380383
}
381-
return size
384+
return size, nil
382385
}
383386

384387
func (c *podmanCommandContainer) Run(ctx context.Context, command *repb.Command, workDir string, creds oci.Credentials) *interfaces.CommandResult {

enterprise/server/remote_execution/containers/sandbox/sandbox.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,4 +348,4 @@ func (c *sandbox) Unpause(ctx context.Context) error {
348348
func (c *sandbox) Stats(ctx context.Context) (*repb.UsageStats, error) {
349349
return nil, nil
350350
}
351-
func (c *sandbox) ImageSizeBytes(ctx context.Context) int64 { return 0 }
351+
func (c *sandbox) ImageSizeBytes(ctx context.Context) (int64, error) { return 0, nil }

enterprise/server/remote_execution/executor/executor.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,11 @@ func (s *Executor) ExecuteTaskAndStreamResults(ctx context.Context, st *repb.Sch
329329
}
330330

331331
// Record container image metadata after pulling.
332-
auxMetadata.ContainerImageRef, auxMetadata.ContainerImageSizeBytes = r.ContainerImageInfo(ctx)
332+
var imageSizeErr error
333+
auxMetadata.ContainerImageRef, auxMetadata.ContainerImageSizeBytes, imageSizeErr = r.ContainerImageInfo(ctx)
334+
if imageSizeErr != nil {
335+
log.CtxWarningf(ctx, "Failed to get container image size: %s", imageSizeErr)
336+
}
333337

334338
md.InputFetchStartTimestamp = timestamppb.New(s.env.GetClock().Now())
335339

enterprise/server/remote_execution/executor/executor_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,8 +570,8 @@ type imageSizingContainer struct {
570570
imageSize int64
571571
}
572572

573-
func (c *imageSizingContainer) ImageSizeBytes(ctx context.Context) int64 {
574-
return c.imageSize
573+
func (c *imageSizingContainer) ImageSizeBytes(ctx context.Context) (int64, error) {
574+
return c.imageSize, nil
575575
}
576576

577577
type imageSizingContainerProvider struct {

0 commit comments

Comments
 (0)