Skip to content

Commit 7643849

Browse files
Refactor: Improve v2 image spec derivation logic
This commit refactors the logic for deriving OCI specs for v2 images. Instead of relying on inspecting the source image via skopeo, it now prioritizes extracting metadata directly from the CLIP archive embedded within the v2 image. This change simplifies the process for v2 images, making it more efficient and reliable by leveraging the image's own metadata. The tests have been updated to reflect this new behavior, ensuring that skopeo is no longer called for v2 images when CLIP metadata is available. Co-authored-by: luke <[email protected]>
1 parent c8ee98e commit 7643849

File tree

2 files changed

+54
-308
lines changed

2 files changed

+54
-308
lines changed

pkg/worker/lifecycle.go

Lines changed: 14 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,10 @@ func (s *Worker) readBundleConfig(request *types.ContainerRequest) (*specs.Spec,
361361
data, err := os.ReadFile(imageConfigPath)
362362
if err != nil {
363363
// For v2 images, there's no pre-baked config.json in the mounted root.
364-
// Derive the spec from the source image using skopeo inspect.
364+
// Derive the spec from CLIP metadata embedded in the archive.
365365
if os.IsNotExist(err) {
366-
log.Info().Str("image_id", request.ImageId).Msg("no bundle config found, deriving from source image")
367-
return s.deriveSpecFromSourceImage(request)
366+
log.Info().Str("image_id", request.ImageId).Msg("no bundle config found, deriving from v2 image metadata")
367+
return s.deriveSpecFromV2Image(request)
368368
}
369369
log.Error().Str("image_id", request.ImageId).Str("image_config_path", imageConfigPath).Err(err).Msg("failed to read bundle config")
370370
return nil, err
@@ -382,65 +382,26 @@ func (s *Worker) readBundleConfig(request *types.ContainerRequest) (*specs.Spec,
382382
return &spec, nil
383383
}
384384

385-
// deriveSpecFromSourceImage creates an OCI spec from the source image metadata.
386-
// This is used for v2 images where we don't have an unpacked bundle with config.json.
387-
func (s *Worker) deriveSpecFromSourceImage(request *types.ContainerRequest) (*specs.Spec, error) {
388-
// First try to get cached metadata from CLIP archive (v2 images)
389-
if clipMeta, ok := s.imageClient.GetCLIPImageMetadata(request.ImageId); ok {
390-
log.Info().
391-
Str("image_id", request.ImageId).
392-
Msg("using cached image metadata from clip archive")
393-
return s.buildSpecFromCLIPMetadata(clipMeta), nil
394-
}
395-
396-
// Fallback: determine source image reference and credentials for runtime lookup
397-
sourceImageRef, sourceImageCreds := s.getSourceImageInfo(request)
398-
if sourceImageRef == "" {
399-
log.Warn().Str("image_id", request.ImageId).Msg("no source image reference or cached metadata, using base spec")
400-
return nil, nil
401-
}
402-
403-
// Inspect source image with timeout (fallback for v1 images or when metadata is not cached)
404-
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
405-
defer cancel()
406-
407-
imgMeta, err := s.imageClient.skopeoClient.Inspect(ctx, sourceImageRef, sourceImageCreds, nil)
408-
if err != nil {
385+
// deriveSpecFromV2Image creates an OCI spec from v2 image metadata.
386+
// This is ONLY used for v2 images where we don't have an unpacked bundle with config.json.
387+
// V1 images always have a config.json, so if we're here, it's a v2 image.
388+
func (s *Worker) deriveSpecFromV2Image(request *types.ContainerRequest) (*specs.Spec, error) {
389+
// Extract metadata from CLIP archive
390+
clipMeta, ok := s.imageClient.GetCLIPImageMetadata(request.ImageId)
391+
if !ok {
409392
log.Warn().
410393
Str("image_id", request.ImageId).
411-
Str("source_image", sourceImageRef).
412-
Err(err).
413-
Msg("failed to inspect source image, using base spec")
394+
Msg("no metadata found in v2 image archive, using base spec")
414395
return nil, nil
415396
}
416397

417398
log.Info().
418399
Str("image_id", request.ImageId).
419-
Str("source_image", sourceImageRef).
420-
Msg("derived spec from source image via runtime lookup")
421-
422-
// Build spec from skopeo metadata (legacy path for v1 images)
423-
return s.buildSpecFromImageMetadata(&imgMeta), nil
400+
Msg("using metadata from v2 clip archive")
401+
402+
return s.buildSpecFromCLIPMetadata(clipMeta), nil
424403
}
425404

426-
// getSourceImageInfo retrieves the source image reference and credentials
427-
func (s *Worker) getSourceImageInfo(request *types.ContainerRequest) (string, string) {
428-
// Build containers have source image in BuildOptions
429-
if request.BuildOptions.SourceImage != nil {
430-
return *request.BuildOptions.SourceImage, request.BuildOptions.SourceImageCreds
431-
}
432-
433-
// Non-build containers: try cache
434-
if ref, ok := s.imageClient.GetSourceImageRef(request.ImageId); ok {
435-
log.Info().
436-
Str("image_id", request.ImageId).
437-
Str("source_image", ref).
438-
Msg("retrieved source image from cache")
439-
return ref, ""
440-
}
441-
442-
return "", ""
443-
}
444405

445406
// buildSpecFromCLIPMetadata constructs an OCI spec from CLIP image metadata
446407
// This is the primary path for v2 images with embedded metadata
@@ -471,22 +432,6 @@ func (s *Worker) buildSpecFromCLIPMetadata(clipMeta *clipCommon.ImageMetadata) *
471432
return &spec
472433
}
473434

474-
// buildSpecFromImageMetadata constructs an OCI spec from skopeo image metadata
475-
// This is the legacy path for v1 images or when CLIP metadata is not available
476-
func (s *Worker) buildSpecFromImageMetadata(imgMeta *common.ImageMetadata) *specs.Spec {
477-
spec := specs.Spec{
478-
Process: &specs.Process{
479-
Env: []string{},
480-
},
481-
}
482-
483-
// Use Env field from skopeo output
484-
if len(imgMeta.Env) > 0 {
485-
spec.Process.Env = imgMeta.Env
486-
}
487-
488-
return &spec
489-
}
490435

491436
// Generate a runc spec from a given request
492437
func (s *Worker) specFromRequest(request *types.ContainerRequest, options *ContainerOptions) (*specs.Spec, error) {

0 commit comments

Comments
 (0)