| package containerd | |
| import ( | |
| "github.com/docker/docker/api/types/container" | |
| "github.com/docker/docker/dockerversion" | |
| "github.com/docker/docker/image" | |
| "github.com/docker/docker/layer" | |
| "github.com/docker/go-connections/nat" | |
| imagespec "github.com/moby/docker-image-spec/specs-go/v1" | |
| "github.com/opencontainers/go-digest" | |
| ocispec "github.com/opencontainers/image-spec/specs-go/v1" | |
| ) | |
| // dockerOciImageToDockerImagePartial creates an image.Image from the imagespec.DockerOCIImage | |
| // It doesn't set: | |
| // - V1Image.ContainerConfig | |
| // - V1Image.Container | |
| // - Details | |
| func dockerOciImageToDockerImagePartial(id image.ID, img imagespec.DockerOCIImage) *image.Image { | |
| v1Image := image.V1Image{ | |
| DockerVersion: dockerversion.Version, | |
| Config: dockerOCIImageConfigToContainerConfig(img.Config), | |
| Architecture: img.Platform.Architecture, | |
| Variant: img.Platform.Variant, | |
| OS: img.Platform.OS, | |
| Author: img.Author, | |
| Created: img.Created, | |
| } | |
| rootFS := &image.RootFS{ | |
| Type: img.RootFS.Type, | |
| } | |
| for _, diffId := range img.RootFS.DiffIDs { | |
| rootFS.DiffIDs = append(rootFS.DiffIDs, layer.DiffID(diffId)) | |
| } | |
| out := image.NewImage(id) | |
| out.V1Image = v1Image | |
| out.RootFS = rootFS | |
| out.History = img.History | |
| out.OSFeatures = img.OSFeatures | |
| out.OSVersion = img.OSVersion | |
| return out | |
| } | |
| func dockerImageToDockerOCIImage(img image.Image) imagespec.DockerOCIImage { | |
| rootfs := ocispec.RootFS{ | |
| Type: img.RootFS.Type, | |
| DiffIDs: []digest.Digest{}, | |
| } | |
| for _, diffId := range img.RootFS.DiffIDs { | |
| rootfs.DiffIDs = append(rootfs.DiffIDs, digest.Digest(diffId)) | |
| } | |
| return imagespec.DockerOCIImage{ | |
| Image: ocispec.Image{ | |
| Created: img.Created, | |
| Author: img.Author, | |
| Platform: ocispec.Platform{ | |
| Architecture: img.Architecture, | |
| Variant: img.Variant, | |
| OS: img.OS, | |
| OSVersion: img.OSVersion, | |
| OSFeatures: img.OSFeatures, | |
| }, | |
| RootFS: rootfs, | |
| History: img.History, | |
| }, | |
| Config: containerConfigToDockerOCIImageConfig(img.Config), | |
| } | |
| } | |
| func containerConfigToDockerOCIImageConfig(cfg *container.Config) imagespec.DockerOCIImageConfig { | |
| var ociCfg ocispec.ImageConfig | |
| var ext imagespec.DockerOCIImageConfigExt | |
| if cfg != nil { | |
| ociCfg = ocispec.ImageConfig{ | |
| User: cfg.User, | |
| Env: cfg.Env, | |
| Entrypoint: cfg.Entrypoint, | |
| Cmd: cfg.Cmd, | |
| Volumes: cfg.Volumes, | |
| WorkingDir: cfg.WorkingDir, | |
| Labels: cfg.Labels, | |
| StopSignal: cfg.StopSignal, | |
| ArgsEscaped: cfg.ArgsEscaped, //nolint:staticcheck // Ignore SA1019. Need to keep it in image. | |
| } | |
| if len(cfg.ExposedPorts) > 0 { | |
| ociCfg.ExposedPorts = map[string]struct{}{} | |
| for k, v := range cfg.ExposedPorts { | |
| ociCfg.ExposedPorts[string(k)] = v | |
| } | |
| } | |
| ext.Healthcheck = cfg.Healthcheck | |
| ext.OnBuild = cfg.OnBuild | |
| ext.Shell = cfg.Shell | |
| } | |
| return imagespec.DockerOCIImageConfig{ | |
| ImageConfig: ociCfg, | |
| DockerOCIImageConfigExt: ext, | |
| } | |
| } | |
| func dockerOCIImageConfigToContainerConfig(cfg imagespec.DockerOCIImageConfig) *container.Config { | |
| exposedPorts := make(nat.PortSet, len(cfg.ExposedPorts)) | |
| for k, v := range cfg.ExposedPorts { | |
| exposedPorts[nat.Port(k)] = v | |
| } | |
| return &container.Config{ | |
| Entrypoint: cfg.Entrypoint, | |
| Env: cfg.Env, | |
| Cmd: cfg.Cmd, | |
| User: cfg.User, | |
| WorkingDir: cfg.WorkingDir, | |
| ExposedPorts: exposedPorts, | |
| Volumes: cfg.Volumes, | |
| Labels: cfg.Labels, | |
| ArgsEscaped: cfg.ArgsEscaped, //nolint:staticcheck // Ignore SA1019. Need to keep it in image. | |
| StopSignal: cfg.StopSignal, | |
| Healthcheck: cfg.Healthcheck, | |
| OnBuild: cfg.OnBuild, | |
| Shell: cfg.Shell, | |
| } | |
| } |