github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/api/handlers/types.go (about) 1 package handlers 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "time" 8 9 "github.com/containers/image/v5/manifest" 10 libpodImage "github.com/containers/podman/v2/libpod/image" 11 "github.com/containers/podman/v2/pkg/domain/entities" 12 docker "github.com/docker/docker/api/types" 13 dockerContainer "github.com/docker/docker/api/types/container" 14 dockerNetwork "github.com/docker/docker/api/types/network" 15 "github.com/docker/go-connections/nat" 16 "github.com/pkg/errors" 17 ) 18 19 type AuthConfig struct { 20 docker.AuthConfig 21 } 22 23 type ImageInspect struct { 24 docker.ImageInspect 25 } 26 27 type ContainerConfig struct { 28 dockerContainer.Config 29 } 30 31 type LibpodImagesLoadReport struct { 32 ID string `json:"id"` 33 } 34 35 type LibpodImagesPullReport struct { 36 entities.ImagePullReport 37 } 38 39 // LibpodImagesRemoveReport is the return type for image removal via the rest 40 // api. 41 type LibpodImagesRemoveReport struct { 42 entities.ImageRemoveReport 43 // Image removal requires is to return data and an error. 44 Errors []string 45 } 46 47 type ContainersPruneReport struct { 48 docker.ContainersPruneReport 49 } 50 51 type LibpodContainersPruneReport struct { 52 ID string `json:"id"` 53 SpaceReclaimed int64 `json:"space"` 54 PruneError string `json:"error"` 55 } 56 57 type Info struct { 58 docker.Info 59 BuildahVersion string 60 CPURealtimePeriod bool 61 CPURealtimeRuntime bool 62 CgroupVersion string 63 Rootless bool 64 SwapFree int64 65 SwapTotal int64 66 Uptime string 67 } 68 69 type Container struct { 70 docker.Container 71 docker.ContainerCreateConfig 72 } 73 74 type DiskUsage struct { 75 docker.DiskUsage 76 } 77 78 type VolumesPruneReport struct { 79 docker.VolumesPruneReport 80 } 81 82 type ImagesPruneReport struct { 83 docker.ImagesPruneReport 84 } 85 86 type BuildCachePruneReport struct { 87 docker.BuildCachePruneReport 88 } 89 90 type NetworkPruneReport struct { 91 docker.NetworksPruneReport 92 } 93 94 type ConfigCreateResponse struct { 95 docker.ConfigCreateResponse 96 } 97 98 type PushResult struct { 99 docker.PushResult 100 } 101 102 type BuildResult struct { 103 docker.BuildResult 104 } 105 106 type ContainerWaitOKBody struct { 107 StatusCode int 108 Error struct { 109 Message string 110 } 111 } 112 113 // CreateContainerConfig used when compatible endpoint creates a container 114 type CreateContainerConfig struct { 115 Name string // container name 116 dockerContainer.Config // desired container configuration 117 HostConfig dockerContainer.HostConfig // host dependent configuration for container 118 NetworkingConfig dockerNetwork.NetworkingConfig // network configuration for container 119 } 120 121 // swagger:model IDResponse 122 type IDResponse struct { 123 // ID 124 ID string `json:"Id"` 125 } 126 127 type ContainerTopOKBody struct { 128 dockerContainer.ContainerTopOKBody 129 } 130 131 type PodTopOKBody struct { 132 dockerContainer.ContainerTopOKBody 133 } 134 135 // swagger:model PodCreateConfig 136 type PodCreateConfig struct { 137 Name string `json:"name"` 138 CGroupParent string `json:"cgroup-parent"` 139 Hostname string `json:"hostname"` 140 Infra bool `json:"infra"` 141 InfraCommand string `json:"infra-command"` 142 InfraImage string `json:"infra-image"` 143 Labels []string `json:"labels"` 144 Publish []string `json:"publish"` 145 Share string `json:"share"` 146 } 147 148 type HistoryResponse struct { 149 ID string `json:"Id"` 150 Created int64 `json:"Created"` 151 CreatedBy string `json:"CreatedBy"` 152 Tags []string `json:"Tags"` 153 Size int64 `json:"Size"` 154 Comment string `json:"Comment"` 155 } 156 157 type ImageLayer struct{} 158 159 type ImageTreeResponse struct { 160 ID string `json:"id"` 161 Tags []string `json:"tags"` 162 Size string `json:"size"` 163 Layers []ImageLayer `json:"layers"` 164 } 165 166 type ExecCreateConfig struct { 167 docker.ExecConfig 168 } 169 170 type ExecCreateResponse struct { 171 docker.IDResponse 172 } 173 174 type ExecStartConfig struct { 175 Detach bool `json:"Detach"` 176 Tty bool `json:"Tty"` 177 } 178 179 func ImageToImageSummary(l *libpodImage.Image) (*entities.ImageSummary, error) { 180 containers, err := l.Containers() 181 if err != nil { 182 return nil, errors.Wrapf(err, "failed to obtain Containers for image %s", l.ID()) 183 } 184 containerCount := len(containers) 185 186 // FIXME: GetParent() panics 187 // parent, err := l.GetParent(context.TODO()) 188 // if err != nil { 189 // return nil, errors.Wrapf(err, "failed to obtain ParentID for image %s", l.ID()) 190 // } 191 192 labels, err := l.Labels(context.TODO()) 193 if err != nil { 194 return nil, errors.Wrapf(err, "failed to obtain Labels for image %s", l.ID()) 195 } 196 197 size, err := l.Size(context.TODO()) 198 if err != nil { 199 return nil, errors.Wrapf(err, "failed to obtain Size for image %s", l.ID()) 200 } 201 202 repoTags, err := l.RepoTags() 203 if err != nil { 204 return nil, errors.Wrapf(err, "failed to obtain RepoTags for image %s", l.ID()) 205 } 206 207 digests := make([]string, len(l.Digests())) 208 for i, d := range l.Digests() { 209 digests[i] = string(d) 210 } 211 212 is := entities.ImageSummary{ 213 ID: l.ID(), 214 ParentId: l.Parent, 215 RepoTags: repoTags, 216 Created: l.Created().Unix(), 217 Size: int64(*size), 218 SharedSize: 0, 219 VirtualSize: l.VirtualSize, 220 Labels: labels, 221 Containers: containerCount, 222 ReadOnly: l.IsReadOnly(), 223 Dangling: l.Dangling(), 224 Names: l.Names(), 225 Digest: string(l.Digest()), 226 Digests: digests, 227 ConfigDigest: string(l.ConfigDigest), 228 History: l.NamesHistory(), 229 } 230 return &is, nil 231 } 232 233 func ImageDataToImageInspect(ctx context.Context, l *libpodImage.Image) (*ImageInspect, error) { 234 info, err := l.Inspect(context.Background()) 235 if err != nil { 236 return nil, err 237 } 238 ports, err := portsToPortSet(info.Config.ExposedPorts) 239 if err != nil { 240 return nil, err 241 } 242 243 // TODO the rest of these still need wiring! 244 config := dockerContainer.Config{ 245 // Hostname: "", 246 // Domainname: "", 247 User: info.User, 248 // AttachStdin: false, 249 // AttachStdout: false, 250 // AttachStderr: false, 251 ExposedPorts: ports, 252 // Tty: false, 253 // OpenStdin: false, 254 // StdinOnce: false, 255 Env: info.Config.Env, 256 Cmd: info.Config.Cmd, 257 // Healthcheck: l.ImageData.HealthCheck, 258 // ArgsEscaped: false, 259 // Image: "", 260 Volumes: info.Config.Volumes, 261 WorkingDir: info.Config.WorkingDir, 262 Entrypoint: info.Config.Entrypoint, 263 // NetworkDisabled: false, 264 // MacAddress: "", 265 // OnBuild: info.Config.OnBuild, 266 Labels: info.Labels, 267 StopSignal: info.Config.StopSignal, 268 // StopTimeout: nil, 269 // Shell: nil, 270 } 271 ic, err := l.ToImageRef(ctx) 272 if err != nil { 273 return nil, err 274 } 275 276 rootfs := docker.RootFS{} 277 if info.RootFS != nil { 278 rootfs.Type = info.RootFS.Type 279 rootfs.Layers = make([]string, 0, len(info.RootFS.Layers)) 280 for _, layer := range info.RootFS.Layers { 281 rootfs.Layers = append(rootfs.Layers, string(layer)) 282 } 283 } 284 dockerImageInspect := docker.ImageInspect{ 285 Architecture: l.Architecture, 286 Author: l.Author, 287 Comment: info.Comment, 288 Config: &config, 289 Created: l.Created().Format(time.RFC3339Nano), 290 DockerVersion: info.Version, 291 GraphDriver: docker.GraphDriverData{}, 292 ID: fmt.Sprintf("sha256:%s", l.ID()), 293 Metadata: docker.ImageMetadata{}, 294 Os: l.Os, 295 OsVersion: l.Version, 296 Parent: l.Parent, 297 RepoDigests: info.RepoDigests, 298 RepoTags: info.RepoTags, 299 RootFS: rootfs, 300 Size: info.Size, 301 Variant: "", 302 VirtualSize: info.VirtualSize, 303 } 304 bi := ic.ConfigInfo() 305 // For docker images, we need to get the Container id and config 306 // and populate the image with it. 307 if bi.MediaType == manifest.DockerV2Schema2ConfigMediaType { 308 d := manifest.Schema2Image{} 309 b, err := ic.ConfigBlob(ctx) 310 if err != nil { 311 return nil, err 312 } 313 if err := json.Unmarshal(b, &d); err != nil { 314 return nil, err 315 } 316 // populate the Container id into the image 317 dockerImageInspect.Container = d.Container 318 containerConfig := dockerContainer.Config{} 319 configBytes, err := json.Marshal(d.ContainerConfig) 320 if err != nil { 321 return nil, err 322 } 323 if err := json.Unmarshal(configBytes, &containerConfig); err != nil { 324 return nil, err 325 } 326 // populate the Container config in the image 327 dockerImageInspect.ContainerConfig = &containerConfig 328 // populate parent 329 dockerImageInspect.Parent = d.Parent.String() 330 } 331 return &ImageInspect{dockerImageInspect}, nil 332 333 } 334 335 // portsToPortSet converts libpods exposed ports to dockers structs 336 func portsToPortSet(input map[string]struct{}) (nat.PortSet, error) { 337 ports := make(nat.PortSet) 338 for k := range input { 339 proto, port := nat.SplitProtoPort(k) 340 switch proto { 341 // See the OCI image spec for details: 342 // https://github.com/opencontainers/image-spec/blob/e562b04403929d582d449ae5386ff79dd7961a11/config.md#properties 343 case "tcp", "": 344 p, err := nat.NewPort("tcp", port) 345 if err != nil { 346 return nil, errors.Wrapf(err, "unable to create tcp port from %s", k) 347 } 348 ports[p] = struct{}{} 349 case "udp": 350 p, err := nat.NewPort("udp", port) 351 if err != nil { 352 return nil, errors.Wrapf(err, "unable to create tcp port from %s", k) 353 } 354 ports[p] = struct{}{} 355 default: 356 return nil, errors.Errorf("invalid port proto %q in %q", proto, k) 357 } 358 } 359 return ports, nil 360 }