Merge pull request #19781 from mtrmac/api-handlers-types-no-impl

Remove a dependency on libimage from pkg/api/handlers
This commit is contained in:
OpenShift Merge Robot
2023-08-29 09:56:32 +02:00
committed by GitHub
2 changed files with 99 additions and 100 deletions

View File

@ -1,12 +1,14 @@
package compat
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"os"
"strings"
"time"
"github.com/containers/buildah"
"github.com/containers/common/libimage"
@ -24,7 +26,10 @@ import (
"github.com/containers/podman/v4/pkg/util"
"github.com/containers/storage"
"github.com/docker/distribution/registry/api/errcode"
docker "github.com/docker/docker/api/types"
dockerContainer "github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/go-connections/nat"
"github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus"
)
@ -418,7 +423,7 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
utils.Error(w, http.StatusNotFound, fmt.Errorf("failed to find image %s: %s", name, errMsg))
return
}
inspect, err := handlers.ImageDataToImageInspect(r.Context(), newImage)
inspect, err := imageDataToImageInspect(r.Context(), newImage)
if err != nil {
utils.Error(w, http.StatusInternalServerError, fmt.Errorf("failed to convert ImageData to ImageInspect '%s': %w", name, err))
return
@ -426,6 +431,99 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, inspect)
}
func imageDataToImageInspect(ctx context.Context, l *libimage.Image) (*handlers.ImageInspect, error) {
options := &libimage.InspectOptions{WithParent: true, WithSize: true}
info, err := l.Inspect(ctx, options)
if err != nil {
return nil, err
}
ports, err := portsToPortSet(info.Config.ExposedPorts)
if err != nil {
return nil, err
}
// TODO: many fields in Config still need wiring
config := dockerContainer.Config{
User: info.User,
ExposedPorts: ports,
Env: info.Config.Env,
Cmd: info.Config.Cmd,
Volumes: info.Config.Volumes,
WorkingDir: info.Config.WorkingDir,
Entrypoint: info.Config.Entrypoint,
Labels: info.Labels,
StopSignal: info.Config.StopSignal,
}
rootfs := docker.RootFS{}
if info.RootFS != nil {
rootfs.Type = info.RootFS.Type
rootfs.Layers = make([]string, 0, len(info.RootFS.Layers))
for _, layer := range info.RootFS.Layers {
rootfs.Layers = append(rootfs.Layers, string(layer))
}
}
graphDriver := docker.GraphDriverData{
Name: info.GraphDriver.Name,
Data: info.GraphDriver.Data,
}
// Add in basic ContainerConfig to satisfy docker-compose
cc := new(dockerContainer.Config)
cc.Hostname = info.ID[0:11] // short ID is the hostname
cc.Volumes = info.Config.Volumes
dockerImageInspect := docker.ImageInspect{
Architecture: info.Architecture,
Author: info.Author,
Comment: info.Comment,
Config: &config,
ContainerConfig: cc,
Created: l.Created().Format(time.RFC3339Nano),
DockerVersion: info.Version,
GraphDriver: graphDriver,
ID: "sha256:" + l.ID(),
Metadata: docker.ImageMetadata{},
Os: info.Os,
OsVersion: info.Version,
Parent: info.Parent,
RepoDigests: info.RepoDigests,
RepoTags: info.RepoTags,
RootFS: rootfs,
Size: info.Size,
Variant: "",
VirtualSize: info.VirtualSize,
}
return &handlers.ImageInspect{ImageInspect: dockerImageInspect}, nil
}
// portsToPortSet converts libpod's exposed ports to docker's structs
func portsToPortSet(input map[string]struct{}) (nat.PortSet, error) {
ports := make(nat.PortSet)
for k := range input {
proto, port := nat.SplitProtoPort(k)
switch proto {
// See the OCI image spec for details:
// https://github.com/opencontainers/image-spec/blob/e562b04403929d582d449ae5386ff79dd7961a11/config.md#properties
case "tcp", "":
p, err := nat.NewPort("tcp", port)
if err != nil {
return nil, fmt.Errorf("unable to create tcp port from %s: %w", k, err)
}
ports[p] = struct{}{}
case "udp":
p, err := nat.NewPort("udp", port)
if err != nil {
return nil, fmt.Errorf("unable to create tcp port from %s: %w", k, err)
}
ports[p] = struct{}{}
default:
return nil, fmt.Errorf("invalid port proto %q in %q", proto, k)
}
}
return ports, nil
}
func GetImages(w http.ResponseWriter, r *http.Request) {
decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)

View File

@ -1,16 +1,10 @@
package handlers
import (
"context"
"fmt"
"time"
"github.com/containers/common/libimage"
"github.com/containers/podman/v4/pkg/domain/entities"
docker "github.com/docker/docker/api/types"
dockerContainer "github.com/docker/docker/api/types/container"
dockerNetwork "github.com/docker/docker/api/types/network"
"github.com/docker/go-connections/nat"
"github.com/opencontainers/runtime-spec/specs-go"
)
@ -167,96 +161,3 @@ type ExecStartConfig struct {
Height uint16 `json:"h"`
Width uint16 `json:"w"`
}
func ImageDataToImageInspect(ctx context.Context, l *libimage.Image) (*ImageInspect, error) {
options := &libimage.InspectOptions{WithParent: true, WithSize: true}
info, err := l.Inspect(ctx, options)
if err != nil {
return nil, err
}
ports, err := portsToPortSet(info.Config.ExposedPorts)
if err != nil {
return nil, err
}
// TODO: many fields in Config still need wiring
config := dockerContainer.Config{
User: info.User,
ExposedPorts: ports,
Env: info.Config.Env,
Cmd: info.Config.Cmd,
Volumes: info.Config.Volumes,
WorkingDir: info.Config.WorkingDir,
Entrypoint: info.Config.Entrypoint,
Labels: info.Labels,
StopSignal: info.Config.StopSignal,
}
rootfs := docker.RootFS{}
if info.RootFS != nil {
rootfs.Type = info.RootFS.Type
rootfs.Layers = make([]string, 0, len(info.RootFS.Layers))
for _, layer := range info.RootFS.Layers {
rootfs.Layers = append(rootfs.Layers, string(layer))
}
}
graphDriver := docker.GraphDriverData{
Name: info.GraphDriver.Name,
Data: info.GraphDriver.Data,
}
// Add in basic ContainerConfig to satisfy docker-compose
cc := new(dockerContainer.Config)
cc.Hostname = info.ID[0:11] // short ID is the hostname
cc.Volumes = info.Config.Volumes
dockerImageInspect := docker.ImageInspect{
Architecture: info.Architecture,
Author: info.Author,
Comment: info.Comment,
Config: &config,
ContainerConfig: cc,
Created: l.Created().Format(time.RFC3339Nano),
DockerVersion: info.Version,
GraphDriver: graphDriver,
ID: "sha256:" + l.ID(),
Metadata: docker.ImageMetadata{},
Os: info.Os,
OsVersion: info.Version,
Parent: info.Parent,
RepoDigests: info.RepoDigests,
RepoTags: info.RepoTags,
RootFS: rootfs,
Size: info.Size,
Variant: "",
VirtualSize: info.VirtualSize,
}
return &ImageInspect{dockerImageInspect}, nil
}
// portsToPortSet converts libpod's exposed ports to docker's structs
func portsToPortSet(input map[string]struct{}) (nat.PortSet, error) {
ports := make(nat.PortSet)
for k := range input {
proto, port := nat.SplitProtoPort(k)
switch proto {
// See the OCI image spec for details:
// https://github.com/opencontainers/image-spec/blob/e562b04403929d582d449ae5386ff79dd7961a11/config.md#properties
case "tcp", "":
p, err := nat.NewPort("tcp", port)
if err != nil {
return nil, fmt.Errorf("unable to create tcp port from %s: %w", k, err)
}
ports[p] = struct{}{}
case "udp":
p, err := nat.NewPort("udp", port)
if err != nil {
return nil, fmt.Errorf("unable to create tcp port from %s: %w", k, err)
}
ports[p] = struct{}{}
default:
return nil, fmt.Errorf("invalid port proto %q in %q", proto, k)
}
}
return ports, nil
}