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 }