github.com/moby/docker@v26.1.3+incompatible/daemon/containerd/imagespec.go (about)

     1  package containerd
     2  
     3  import (
     4  	"github.com/docker/docker/api/types/container"
     5  	"github.com/docker/docker/dockerversion"
     6  	"github.com/docker/docker/image"
     7  	"github.com/docker/docker/layer"
     8  	"github.com/docker/go-connections/nat"
     9  	imagespec "github.com/moby/docker-image-spec/specs-go/v1"
    10  	"github.com/opencontainers/go-digest"
    11  	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
    12  )
    13  
    14  // dockerOciImageToDockerImagePartial creates an image.Image from the imagespec.DockerOCIImage
    15  // It doesn't set:
    16  // - V1Image.ContainerConfig
    17  // - V1Image.Container
    18  // - Details
    19  func dockerOciImageToDockerImagePartial(id image.ID, img imagespec.DockerOCIImage) *image.Image {
    20  	v1Image := image.V1Image{
    21  		DockerVersion: dockerversion.Version,
    22  		Config:        dockerOCIImageConfigToContainerConfig(img.Config),
    23  		Architecture:  img.Platform.Architecture,
    24  		Variant:       img.Platform.Variant,
    25  		OS:            img.Platform.OS,
    26  		Author:        img.Author,
    27  		Created:       img.Created,
    28  	}
    29  
    30  	rootFS := &image.RootFS{
    31  		Type: img.RootFS.Type,
    32  	}
    33  	for _, diffId := range img.RootFS.DiffIDs {
    34  		rootFS.DiffIDs = append(rootFS.DiffIDs, layer.DiffID(diffId))
    35  	}
    36  
    37  	out := image.NewImage(id)
    38  	out.V1Image = v1Image
    39  	out.RootFS = rootFS
    40  	out.History = img.History
    41  	out.OSFeatures = img.OSFeatures
    42  	out.OSVersion = img.OSVersion
    43  	return out
    44  }
    45  
    46  func dockerImageToDockerOCIImage(img image.Image) imagespec.DockerOCIImage {
    47  	rootfs := ocispec.RootFS{
    48  		Type:    img.RootFS.Type,
    49  		DiffIDs: []digest.Digest{},
    50  	}
    51  	for _, diffId := range img.RootFS.DiffIDs {
    52  		rootfs.DiffIDs = append(rootfs.DiffIDs, digest.Digest(diffId))
    53  	}
    54  
    55  	return imagespec.DockerOCIImage{
    56  		Image: ocispec.Image{
    57  			Created: img.Created,
    58  			Author:  img.Author,
    59  			Platform: ocispec.Platform{
    60  				Architecture: img.Architecture,
    61  				Variant:      img.Variant,
    62  				OS:           img.OS,
    63  				OSVersion:    img.OSVersion,
    64  				OSFeatures:   img.OSFeatures,
    65  			},
    66  			RootFS:  rootfs,
    67  			History: img.History,
    68  		},
    69  		Config: containerConfigToDockerOCIImageConfig(img.Config),
    70  	}
    71  }
    72  
    73  func containerConfigToDockerOCIImageConfig(cfg *container.Config) imagespec.DockerOCIImageConfig {
    74  	var ociCfg ocispec.ImageConfig
    75  	var ext imagespec.DockerOCIImageConfigExt
    76  
    77  	if cfg != nil {
    78  		ociCfg = ocispec.ImageConfig{
    79  			User:        cfg.User,
    80  			Env:         cfg.Env,
    81  			Entrypoint:  cfg.Entrypoint,
    82  			Cmd:         cfg.Cmd,
    83  			Volumes:     cfg.Volumes,
    84  			WorkingDir:  cfg.WorkingDir,
    85  			Labels:      cfg.Labels,
    86  			StopSignal:  cfg.StopSignal,
    87  			ArgsEscaped: cfg.ArgsEscaped, //nolint:staticcheck // Ignore SA1019. Need to keep it in image.
    88  		}
    89  
    90  		if len(cfg.ExposedPorts) > 0 {
    91  			ociCfg.ExposedPorts = map[string]struct{}{}
    92  			for k, v := range cfg.ExposedPorts {
    93  				ociCfg.ExposedPorts[string(k)] = v
    94  			}
    95  		}
    96  		ext.Healthcheck = cfg.Healthcheck
    97  		ext.OnBuild = cfg.OnBuild
    98  		ext.Shell = cfg.Shell
    99  	}
   100  
   101  	return imagespec.DockerOCIImageConfig{
   102  		ImageConfig:             ociCfg,
   103  		DockerOCIImageConfigExt: ext,
   104  	}
   105  }
   106  
   107  func dockerOCIImageConfigToContainerConfig(cfg imagespec.DockerOCIImageConfig) *container.Config {
   108  	exposedPorts := make(nat.PortSet, len(cfg.ExposedPorts))
   109  	for k, v := range cfg.ExposedPorts {
   110  		exposedPorts[nat.Port(k)] = v
   111  	}
   112  
   113  	return &container.Config{
   114  		Entrypoint:   cfg.Entrypoint,
   115  		Env:          cfg.Env,
   116  		Cmd:          cfg.Cmd,
   117  		User:         cfg.User,
   118  		WorkingDir:   cfg.WorkingDir,
   119  		ExposedPorts: exposedPorts,
   120  		Volumes:      cfg.Volumes,
   121  		Labels:       cfg.Labels,
   122  		ArgsEscaped:  cfg.ArgsEscaped, //nolint:staticcheck // Ignore SA1019. Need to keep it in image.
   123  		StopSignal:   cfg.StopSignal,
   124  		Healthcheck:  cfg.Healthcheck,
   125  		OnBuild:      cfg.OnBuild,
   126  		Shell:        cfg.Shell,
   127  	}
   128  }