diff options
Diffstat (limited to 'pkg/api')
32 files changed, 369 insertions, 119 deletions
diff --git a/pkg/api/handlers/compat/auth.go b/pkg/api/handlers/compat/auth.go index 37d2b784d..ee478b9e3 100644 --- a/pkg/api/handlers/compat/auth.go +++ b/pkg/api/handlers/compat/auth.go @@ -1,7 +1,6 @@ package compat import ( - "context" "encoding/json" "errors" "fmt" @@ -44,7 +43,7 @@ func Auth(w http.ResponseWriter, r *http.Request) { fmt.Println("Authenticating with existing credentials...") registry := stripAddressOfScheme(authConfig.ServerAddress) - if err := DockerClient.CheckAuth(context.Background(), sysCtx, authConfig.Username, authConfig.Password, registry); err == nil { + if err := DockerClient.CheckAuth(r.Context(), sysCtx, authConfig.Username, authConfig.Password, registry); err == nil { utils.WriteResponse(w, http.StatusOK, entities.AuthReport{ IdentityToken: "", Status: "Login Succeeded", diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go index ae063dc9f..61d6fc86d 100644 --- a/pkg/api/handlers/compat/containers.go +++ b/pkg/api/handlers/compat/containers.go @@ -407,7 +407,7 @@ func convertSecondaryIPPrefixLen(input *define.InspectNetworkSettings, output *t } func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON, error) { - _, imageName := l.Image() + imageID, imageName := l.Image() inspect, err := l.Inspect(sz) if err != nil { return nil, err @@ -467,6 +467,7 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON, if err := json.Unmarshal(h, &hc); err != nil { return nil, err } + sort.Strings(hc.Binds) // k8s-file == json-file if hc.LogConfig.Type == define.KubernetesLogging { @@ -487,7 +488,7 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON, Path: inspect.Path, Args: inspect.Args, State: &state, - Image: imageName, + Image: "sha256:" + imageID, ResolvConfPath: inspect.ResolvConfPath, HostnamePath: inspect.HostnamePath, HostsPath: inspect.HostsPath, diff --git a/pkg/api/handlers/compat/containers_attach.go b/pkg/api/handlers/compat/containers_attach.go index e804e628a..c37dc09af 100644 --- a/pkg/api/handlers/compat/containers_attach.go +++ b/pkg/api/handlers/compat/containers_attach.go @@ -86,7 +86,7 @@ func AttachContainer(w http.ResponseWriter, r *http.Request) { // For Docker compatibility, we need to re-initialize containers in these states. if state == define.ContainerStateConfigured || state == define.ContainerStateExited || state == define.ContainerStateStopped { if err := ctr.Init(r.Context(), ctr.PodID() != ""); err != nil { - utils.Error(w, http.StatusConflict, fmt.Errorf("error preparing container %s for attach: %w", ctr.ID(), err)) + utils.Error(w, http.StatusConflict, fmt.Errorf("preparing container %s for attach: %w", ctr.ID(), err)) return } } else if !(state == define.ContainerStateCreated || state == define.ContainerStateRunning) { diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 9fff8b4c8..a86b0b0d5 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -64,7 +64,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { imageName, err := utils.NormalizeToDockerHub(r, body.Config.Image) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } body.Config.Image = imageName @@ -76,7 +76,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { return } - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error looking up image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("looking up image: %w", err)) return } @@ -408,6 +408,7 @@ func cliOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.C Systemd: "true", // podman default TmpFS: parsedTmp, TTY: cc.Config.Tty, + EnvMerge: cc.EnvMerge, UnsetEnv: cc.UnsetEnv, UnsetEnvAll: cc.UnsetEnvAll, User: cc.Config.User, @@ -479,7 +480,7 @@ func cliOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.C } if err := os.MkdirAll(vol, 0o755); err != nil { if !os.IsExist(err) { - return nil, nil, fmt.Errorf("error making volume mountpoint for volume %s: %w", vol, err) + return nil, nil, fmt.Errorf("making volume mountpoint for volume %s: %w", vol, err) } } } diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go index c115b4181..519661675 100644 --- a/pkg/api/handlers/compat/containers_stats.go +++ b/pkg/api/handlers/compat/containers_stats.go @@ -11,6 +11,7 @@ import ( "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/api/handlers/utils" api "github.com/containers/podman/v4/pkg/api/types" + "github.com/containers/storage/pkg/system" docker "github.com/docker/docker/api/types" "github.com/gorilla/schema" runccgroups "github.com/opencontainers/runc/libcontainer/cgroups" @@ -139,6 +140,16 @@ streamLabel: // A label to flatten the scope memoryLimit = uint64(*cfg.Spec.Linux.Resources.Memory.Limit) } + memInfo, err := system.ReadMemInfo() + if err != nil { + logrus.Errorf("Unable to get cgroup stats: %v", err) + return + } + // cap the memory limit to the available memory. + if memInfo.MemTotal > 0 && memoryLimit > uint64(memInfo.MemTotal) { + memoryLimit = uint64(memInfo.MemTotal) + } + systemUsage, _ := cgroups.GetSystemCPUUsage() s := StatsJSON{ Stats: Stats{ @@ -177,7 +188,7 @@ streamLabel: // A label to flatten the scope PreCPUStats: preCPUStats, MemoryStats: docker.MemoryStats{ Usage: cgroupStat.MemoryStats.Usage.Usage, - MaxUsage: cgroupStat.MemoryStats.Usage.Limit, + MaxUsage: cgroupStat.MemoryStats.Usage.MaxUsage, Stats: nil, Failcnt: 0, Limit: memoryLimit, diff --git a/pkg/api/handlers/compat/events.go b/pkg/api/handlers/compat/events.go index 18fb35966..105404a0d 100644 --- a/pkg/api/handlers/compat/events.go +++ b/pkg/api/handlers/compat/events.go @@ -89,6 +89,12 @@ func GetEvents(w http.ResponseWriter, r *http.Request) { } e := entities.ConvertToEntitiesEvent(*evt) + // Some events differ between Libpod and Docker endpoints. + // Handle these differences for Docker-compat. + if !utils.IsLibpodRequest(r) && e.Type == "image" && e.Status == "remove" { + e.Status = "delete" + e.Action = "delete" + } if !utils.IsLibpodRequest(r) && e.Status == "died" { e.Status = "die" e.Action = "die" diff --git a/pkg/api/handlers/compat/exec.go b/pkg/api/handlers/compat/exec.go index 1b4dead8b..17f199a8b 100644 --- a/pkg/api/handlers/compat/exec.go +++ b/pkg/api/handlers/compat/exec.go @@ -26,7 +26,7 @@ func ExecCreateHandler(w http.ResponseWriter, r *http.Request) { input := new(handlers.ExecCreateConfig) if err := json.NewDecoder(r.Body).Decode(&input); err != nil { - utils.InternalServerError(w, fmt.Errorf("error decoding request body as JSON: %w", err)) + utils.InternalServerError(w, fmt.Errorf("decoding request body as JSON: %w", err)) return } @@ -114,7 +114,7 @@ func ExecInspectHandler(w http.ResponseWriter, r *http.Request) { session, err := sessionCtr.ExecSession(sessionID) if err != nil { - utils.InternalServerError(w, fmt.Errorf("error retrieving exec session %s from container %s: %w", sessionID, sessionCtr.ID(), err)) + utils.InternalServerError(w, fmt.Errorf("retrieving exec session %s from container %s: %w", sessionID, sessionCtr.ID(), err)) return } @@ -174,7 +174,7 @@ func ExecStartHandler(w http.ResponseWriter, r *http.Request) { } logErr := func(e error) { - logrus.Error(fmt.Errorf("error attaching to container %s exec session %s: %w", sessionCtr.ID(), sessionID, e)) + logrus.Error(fmt.Errorf("attaching to container %s exec session %s: %w", sessionCtr.ID(), sessionID, e)) } var size *resize.TerminalSize diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 39bd165d6..0493c6ffb 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -59,7 +59,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) { name := utils.GetName(r) possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, name) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } @@ -155,7 +155,7 @@ func CommitContainer(w http.ResponseWriter, r *http.Request) { destImage = fmt.Sprintf("%s:%s", query.Repo, query.Tag) possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, destImage) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } destImage = possiblyNormalizedName @@ -209,7 +209,7 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) { if query.Repo != "" { possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, reference) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } reference = possiblyNormalizedName @@ -272,7 +272,7 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, mergeNameAndTagOrDigest(query.FromImage, query.Tag)) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } @@ -390,7 +390,7 @@ func GetImage(w http.ResponseWriter, r *http.Request) { name := utils.GetName(r) possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, name) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } @@ -541,7 +541,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) { for i, img := range query.Names { possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, img) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } images[i] = possiblyNormalizedName diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index 15cfc824e..4035b4315 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -17,6 +17,7 @@ import ( "github.com/containers/buildah" buildahDefine "github.com/containers/buildah/define" "github.com/containers/buildah/pkg/parse" + "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/types" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/pkg/api/handlers/utils" @@ -78,6 +79,8 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { AppArmor string `schema:"apparmor"` BuildArgs string `schema:"buildargs"` CacheFrom string `schema:"cachefrom"` + CacheTo string `schema:"cacheto"` + CacheTTL string `schema:"cachettl"` CgroupParent string `schema:"cgroupparent"` Compression uint64 `schema:"compression"` ConfigureNetwork string `schema:"networkmode"` @@ -98,6 +101,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { ForceRm bool `schema:"forcerm"` From string `schema:"from"` HTTPProxy bool `schema:"httpproxy"` + IDMappingOptions string `schema:"idmappingoptions"` IdentityLabel bool `schema:"identitylabel"` Ignore bool `schema:"ignore"` Isolation string `schema:"isolation"` @@ -339,7 +343,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { if len(tags) > 0 { possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, tags[0]) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } output = possiblyNormalizedName @@ -372,7 +376,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { for i := 1; i < len(tags); i++ { possiblyNormalizedTag, err := utils.NormalizeToDockerHub(r, tags[i]) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } additionalTags = append(additionalTags, possiblyNormalizedTag) @@ -386,6 +390,39 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { } } + var idMappingOptions buildahDefine.IDMappingOptions + if _, found := r.URL.Query()["idmappingoptions"]; found { + if err := json.Unmarshal([]byte(query.IDMappingOptions), &idMappingOptions); err != nil { + utils.BadRequest(w, "idmappingoptions", query.IDMappingOptions, err) + return + } + } + + var cacheFrom reference.Named + if _, found := r.URL.Query()["cachefrom"]; found { + cacheFrom, err = parse.RepoNameToNamedReference(query.CacheFrom) + if err != nil { + utils.BadRequest(w, "cacheFrom", query.CacheFrom, err) + return + } + } + var cacheTo reference.Named + if _, found := r.URL.Query()["cacheto"]; found { + cacheTo, err = parse.RepoNameToNamedReference(query.CacheTo) + if err != nil { + utils.BadRequest(w, "cacheto", query.CacheTo, err) + return + } + } + var cacheTTL time.Duration + if _, found := r.URL.Query()["cachettl"]; found { + cacheTTL, err = time.ParseDuration(query.CacheTTL) + if err != nil { + utils.BadRequest(w, "cachettl", query.CacheTTL, err) + return + } + } + var buildArgs = map[string]string{} if _, found := r.URL.Query()["buildargs"]; found { if err := json.Unmarshal([]byte(query.BuildArgs), &buildArgs); err != nil { @@ -541,7 +578,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { if fromImage != "" { possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, fromImage) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } fromImage = possiblyNormalizedName @@ -578,6 +615,9 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { AdditionalTags: additionalTags, Annotations: annotations, CPPFlags: cppflags, + CacheFrom: cacheFrom, + CacheTo: cacheTo, + CacheTTL: cacheTTL, Args: buildArgs, AllPlatforms: query.AllPlatforms, CommonBuildOpts: &buildah.CommonBuildOptions{ @@ -613,6 +653,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Excludes: excludes, ForceRmIntermediateCtrs: query.ForceRm, From: fromImage, + IDMappingOptions: &idMappingOptions, IgnoreUnrecognizedInstructions: query.Ignore, Isolation: isolation, Jobs: &jobs, @@ -663,7 +704,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { success bool ) - runCtx, cancel := context.WithCancel(context.Background()) + runCtx, cancel := context.WithCancel(r.Context()) go func() { defer cancel() imageID, _, err = runtime.Build(r.Context(), buildOptions, containerFiles...) diff --git a/pkg/api/handlers/compat/images_history.go b/pkg/api/handlers/compat/images_history.go index ebb5acdd9..1b83d274a 100644 --- a/pkg/api/handlers/compat/images_history.go +++ b/pkg/api/handlers/compat/images_history.go @@ -16,7 +16,7 @@ func HistoryImage(w http.ResponseWriter, r *http.Request) { possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, name) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } diff --git a/pkg/api/handlers/compat/images_push.go b/pkg/api/handlers/compat/images_push.go index f29808124..a1173de0b 100644 --- a/pkg/api/handlers/compat/images_push.go +++ b/pkg/api/handlers/compat/images_push.go @@ -69,7 +69,7 @@ func PushImage(w http.ResponseWriter, r *http.Request) { possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, imageName) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } imageName = possiblyNormalizedName diff --git a/pkg/api/handlers/compat/images_remove.go b/pkg/api/handlers/compat/images_remove.go index b59bfd0b1..71d6a644f 100644 --- a/pkg/api/handlers/compat/images_remove.go +++ b/pkg/api/handlers/compat/images_remove.go @@ -37,7 +37,7 @@ func RemoveImage(w http.ResponseWriter, r *http.Request) { name := utils.GetName(r) possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, name) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } diff --git a/pkg/api/handlers/compat/images_tag.go b/pkg/api/handlers/compat/images_tag.go index a1da7a4b9..e9f6dedd0 100644 --- a/pkg/api/handlers/compat/images_tag.go +++ b/pkg/api/handlers/compat/images_tag.go @@ -17,7 +17,7 @@ func TagImage(w http.ResponseWriter, r *http.Request) { name := utils.GetName(r) possiblyNormalizedName, err := utils.NormalizeToDockerHub(r, name) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } @@ -42,7 +42,7 @@ func TagImage(w http.ResponseWriter, r *http.Request) { possiblyNormalizedTag, err := utils.NormalizeToDockerHub(r, tagName) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error normalizing image: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("normalizing image: %w", err)) return } diff --git a/pkg/api/handlers/compat/info.go b/pkg/api/handlers/compat/info.go index d82513284..60bbd40fe 100644 --- a/pkg/api/handlers/compat/info.go +++ b/pkg/api/handlers/compat/info.go @@ -2,7 +2,6 @@ package compat import ( "fmt" - "io/ioutil" "net/http" "os" goRuntime "runtime" @@ -198,7 +197,7 @@ func getRuntimes(configInfo *config.Config) map[string]docker.Runtime { func getFdCount() (count int) { count = -1 - if entries, err := ioutil.ReadDir("/proc/self/fd"); err == nil { + if entries, err := os.ReadDir("/proc/self/fd"); err == nil { count = len(entries) } return diff --git a/pkg/api/handlers/compat/system.go b/pkg/api/handlers/compat/system.go index 97bc9eac2..23f116d16 100644 --- a/pkg/api/handlers/compat/system.go +++ b/pkg/api/handlers/compat/system.go @@ -76,7 +76,7 @@ func GetDiskUsage(w http.ResponseWriter, r *http.Request) { Scope: "local", Status: nil, UsageData: &docker.VolumeUsageData{ - RefCount: 1, + RefCount: int64(o.Links), Size: o.Size, }, } diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go index 5d85d4009..a76e3d988 100644 --- a/pkg/api/handlers/libpod/containers.go +++ b/pkg/api/handlers/libpod/containers.go @@ -1,6 +1,7 @@ package libpod import ( + "encoding/json" "errors" "fmt" "io/ioutil" @@ -10,6 +11,7 @@ import ( "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" + "github.com/containers/podman/v4/pkg/api/handlers" "github.com/containers/podman/v4/pkg/api/handlers/compat" "github.com/containers/podman/v4/pkg/api/handlers/utils" api "github.com/containers/podman/v4/pkg/api/types" @@ -17,6 +19,7 @@ import ( "github.com/containers/podman/v4/pkg/domain/infra/abi" "github.com/containers/podman/v4/pkg/util" "github.com/gorilla/schema" + "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" ) @@ -263,16 +266,16 @@ func Checkpoint(w http.ResponseWriter, r *http.Request) { utils.InternalServerError(w, err) return } + if len(reports) != 1 { + utils.InternalServerError(w, fmt.Errorf("expected 1 restore report but got %d", len(reports))) + return + } + if reports[0].Err != nil { + utils.InternalServerError(w, reports[0].Err) + return + } if !query.Export { - if len(reports) != 1 { - utils.InternalServerError(w, fmt.Errorf("expected 1 restore report but got %d", len(reports))) - return - } - if reports[0].Err != nil { - utils.InternalServerError(w, reports[0].Err) - return - } utils.WriteResponse(w, http.StatusOK, reports[0]) return } @@ -391,6 +394,28 @@ func InitContainer(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusNoContent, "") } +func UpdateContainer(w http.ResponseWriter, r *http.Request) { + name := utils.GetName(r) + runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) + ctr, err := runtime.LookupContainer(name) + if err != nil { + utils.ContainerNotFound(w, name, err) + return + } + + options := &handlers.UpdateEntities{Resources: &specs.LinuxResources{}} + if err := json.NewDecoder(r.Body).Decode(&options.Resources); err != nil { + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("decode(): %w", err)) + return + } + err = ctr.Update(options.Resources) + if err != nil { + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusCreated, ctr.ID()) +} + func ShouldRestart(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) // Now use the ABI implementation to prevent us from having duplicate diff --git a/pkg/api/handlers/libpod/containers_create.go b/pkg/api/handlers/libpod/containers_create.go index 1307c267a..429f45f91 100644 --- a/pkg/api/handlers/libpod/containers_create.go +++ b/pkg/api/handlers/libpod/containers_create.go @@ -1,7 +1,6 @@ package libpod import ( - "context" "encoding/json" "fmt" "net/http" @@ -63,12 +62,12 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { utils.InternalServerError(w, err) return } - rtSpec, spec, opts, err := generate.MakeContainer(context.Background(), runtime, &sg, false, nil) + rtSpec, spec, opts, err := generate.MakeContainer(r.Context(), runtime, &sg, false, nil) if err != nil { utils.InternalServerError(w, err) return } - ctr, err := generate.ExecuteCreate(context.Background(), runtime, rtSpec, spec, false, opts...) + ctr, err := generate.ExecuteCreate(r.Context(), runtime, rtSpec, spec, false, opts...) if err != nil { utils.InternalServerError(w, err) return diff --git a/pkg/api/handlers/libpod/generate.go b/pkg/api/handlers/libpod/generate.go index 48c4c59e1..9b38829ad 100644 --- a/pkg/api/handlers/libpod/generate.go +++ b/pkg/api/handlers/libpod/generate.go @@ -17,20 +17,21 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) query := struct { - Name bool `schema:"useName"` - New bool `schema:"new"` - NoHeader bool `schema:"noHeader"` - TemplateUnitFile bool `schema:"templateUnitFile"` - RestartPolicy *string `schema:"restartPolicy"` - RestartSec uint `schema:"restartSec"` - StopTimeout uint `schema:"stopTimeout"` - StartTimeout uint `schema:"startTimeout"` - ContainerPrefix *string `schema:"containerPrefix"` - PodPrefix *string `schema:"podPrefix"` - Separator *string `schema:"separator"` - Wants []string `schema:"wants"` - After []string `schema:"after"` - Requires []string `schema:"requires"` + Name bool `schema:"useName"` + New bool `schema:"new"` + NoHeader bool `schema:"noHeader"` + TemplateUnitFile bool `schema:"templateUnitFile"` + RestartPolicy *string `schema:"restartPolicy"` + RestartSec uint `schema:"restartSec"` + StopTimeout uint `schema:"stopTimeout"` + StartTimeout uint `schema:"startTimeout"` + ContainerPrefix *string `schema:"containerPrefix"` + PodPrefix *string `schema:"podPrefix"` + Separator *string `schema:"separator"` + Wants []string `schema:"wants"` + After []string `schema:"after"` + Requires []string `schema:"requires"` + AdditionalEnvVariables []string `schema:"additionalEnvVariables"` }{ StartTimeout: 0, StopTimeout: util.DefaultContainerConfig().Engine.StopTimeout, @@ -58,25 +59,26 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) { containerEngine := abi.ContainerEngine{Libpod: runtime} options := entities.GenerateSystemdOptions{ - Name: query.Name, - New: query.New, - NoHeader: query.NoHeader, - TemplateUnitFile: query.TemplateUnitFile, - RestartPolicy: query.RestartPolicy, - StartTimeout: &query.StartTimeout, - StopTimeout: &query.StopTimeout, - ContainerPrefix: ContainerPrefix, - PodPrefix: PodPrefix, - Separator: Separator, - RestartSec: &query.RestartSec, - Wants: query.Wants, - After: query.After, - Requires: query.Requires, + Name: query.Name, + New: query.New, + NoHeader: query.NoHeader, + TemplateUnitFile: query.TemplateUnitFile, + RestartPolicy: query.RestartPolicy, + StartTimeout: &query.StartTimeout, + StopTimeout: &query.StopTimeout, + ContainerPrefix: ContainerPrefix, + PodPrefix: PodPrefix, + Separator: Separator, + RestartSec: &query.RestartSec, + Wants: query.Wants, + After: query.After, + Requires: query.Requires, + AdditionalEnvVariables: query.AdditionalEnvVariables, } report, err := containerEngine.GenerateSystemd(r.Context(), utils.GetName(r), options) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error generating systemd units: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("generating systemd units: %w", err)) return } @@ -102,7 +104,7 @@ func GenerateKube(w http.ResponseWriter, r *http.Request) { options := entities.GenerateKubeOptions{Service: query.Service} report, err := containerEngine.GenerateKube(r.Context(), query.Names, options) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error generating YAML: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("generating YAML: %w", err)) return } diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index 67943ecf1..82c1971cd 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -12,6 +12,7 @@ import ( "github.com/containers/buildah" "github.com/containers/common/libimage" + "github.com/containers/common/pkg/ssh" "github.com/containers/image/v5/manifest" "github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod/define" @@ -547,6 +548,7 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) { Ignore bool `schema:"ignore"` LookupManifest bool `schema:"lookupManifest"` Images []string `schema:"images"` + NoPrune bool `schema:"noprune"` }{} if err := decoder.Decode(&query, r.URL.Query()); err != nil { @@ -554,7 +556,7 @@ func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) { return } - opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force, Ignore: query.Ignore, LookupManifest: query.LookupManifest} + opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force, Ignore: query.Ignore, LookupManifest: query.LookupManifest, NoPrune: query.NoPrune} imageEngine := abi.ImageEngine{Libpod: runtime} rmReport, rmErrors := imageEngine.Remove(r.Context(), query.Images, opts) strErrs := errorhandling.ErrorsToStrings(rmErrors) @@ -617,7 +619,7 @@ func ImageScp(w http.ResponseWriter, r *http.Request) { sourceArg := utils.GetName(r) - rep, source, dest, _, err := domainUtils.ExecuteTransfer(sourceArg, query.Destination, []string{}, query.Quiet) + rep, source, dest, _, err := domainUtils.ExecuteTransfer(sourceArg, query.Destination, []string{}, query.Quiet, ssh.GolangMode) if err != nil { utils.Error(w, http.StatusInternalServerError, err) return diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go index 7e24ae5ac..57b2e3a78 100644 --- a/pkg/api/handlers/libpod/images_pull.go +++ b/pkg/api/handlers/libpod/images_pull.go @@ -82,17 +82,32 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) { pullOptions.IdentityToken = authConf.IdentityToken } - writer := channel.NewWriter(make(chan []byte)) - defer writer.Close() - - pullOptions.Writer = writer - pullPolicy, err := config.ParsePullPolicy(query.PullPolicy) if err != nil { utils.Error(w, http.StatusBadRequest, err) return } + // Let's keep thing simple when running in quiet mode and pull directly. + if query.Quiet { + images, err := runtime.LibimageRuntime().Pull(r.Context(), query.Reference, pullPolicy, pullOptions) + var report entities.ImagePullReport + if err != nil { + report.Error = err.Error() + } + for _, image := range images { + report.Images = append(report.Images, image.ID()) + // Pull last ID from list and publish in 'id' stanza. This maintains previous API contract + report.ID = image.ID() + } + utils.WriteResponse(w, http.StatusOK, report) + return + } + + writer := channel.NewWriter(make(chan []byte)) + defer writer.Close() + pullOptions.Writer = writer + var pulledImages []*libimage.Image var pullError error runCtx, cancel := context.WithCancel(r.Context()) @@ -118,10 +133,8 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) { select { case s := <-writer.Chan(): report.Stream = string(s) - if !query.Quiet { - if err := enc.Encode(report); err != nil { - logrus.Warnf("Failed to encode json: %v", err) - } + if err := enc.Encode(report); err != nil { + logrus.Warnf("Failed to encode json: %v", err) } flush() case <-runCtx.Done(): diff --git a/pkg/api/handlers/libpod/images_push.go b/pkg/api/handlers/libpod/images_push.go index e931fd2f9..4102f23de 100644 --- a/pkg/api/handlers/libpod/images_push.go +++ b/pkg/api/handlers/libpod/images_push.go @@ -90,8 +90,8 @@ func PushImage(w http.ResponseWriter, r *http.Request) { // Let's keep thing simple when running in quiet mode and push directly. if query.Quiet { - if err := imageEngine.Push(context.Background(), source, destination, options); err != nil { - utils.Error(w, http.StatusBadRequest, fmt.Errorf("error pushing image %q: %w", destination, err)) + if err := imageEngine.Push(r.Context(), source, destination, options); err != nil { + utils.Error(w, http.StatusBadRequest, fmt.Errorf("pushing image %q: %w", destination, err)) return } utils.WriteResponse(w, http.StatusOK, "") diff --git a/pkg/api/handlers/libpod/kube.go b/pkg/api/handlers/libpod/kube.go index 6cad58795..2a61d1723 100644 --- a/pkg/api/handlers/libpod/kube.go +++ b/pkg/api/handlers/libpod/kube.go @@ -103,7 +103,7 @@ func KubePlay(w http.ResponseWriter, r *http.Request) { report, err := containerEngine.PlayKube(r.Context(), r.Body, options) _ = r.Body.Close() if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error playing YAML file: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("playing YAML file: %w", err)) return } utils.WriteResponse(w, http.StatusOK, report) @@ -116,8 +116,12 @@ func KubePlayDown(w http.ResponseWriter, r *http.Request) { report, err := containerEngine.PlayKubeDown(r.Context(), r.Body, *options) _ = r.Body.Close() if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error tearing down YAML file: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("tearing down YAML file: %w", err)) return } utils.WriteResponse(w, http.StatusOK, report) } + +func KubeGenerate(w http.ResponseWriter, r *http.Request) { + GenerateKube(w, r) +} diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go index 2d6223e4e..d5af72a61 100644 --- a/pkg/api/handlers/libpod/manifests.go +++ b/pkg/api/handlers/libpod/manifests.go @@ -19,12 +19,14 @@ import ( "github.com/containers/podman/v4/pkg/api/handlers/utils" api "github.com/containers/podman/v4/pkg/api/types" "github.com/containers/podman/v4/pkg/auth" + "github.com/containers/podman/v4/pkg/channel" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/domain/infra/abi" "github.com/containers/podman/v4/pkg/errorhandling" "github.com/gorilla/mux" "github.com/gorilla/schema" "github.com/opencontainers/go-digest" + "github.com/sirupsen/logrus" ) func ManifestCreate(w http.ResponseWriter, r *http.Request) { @@ -34,6 +36,7 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) { Name string `schema:"name"` Images []string `schema:"images"` All bool `schema:"all"` + Amend bool `schema:"amend"` }{ // Add defaults here once needed. } @@ -68,7 +71,7 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) { imageEngine := abi.ImageEngine{Libpod: runtime} - createOptions := entities.ManifestCreateOptions{All: query.All} + createOptions := entities.ManifestCreateOptions{All: query.All, Amend: query.Amend} manID, err := imageEngine.ManifestCreate(r.Context(), query.Name, query.Images, createOptions) if err != nil { utils.InternalServerError(w, err) @@ -290,9 +293,9 @@ func ManifestPushV3(w http.ResponseWriter, r *http.Request) { options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify) } imageEngine := abi.ImageEngine{Libpod: runtime} - digest, err := imageEngine.ManifestPush(context.Background(), source, query.Destination, options) + digest, err := imageEngine.ManifestPush(r.Context(), source, query.Destination, options) if err != nil { - utils.Error(w, http.StatusBadRequest, fmt.Errorf("error pushing image %q: %w", query.Destination, err)) + utils.Error(w, http.StatusBadRequest, fmt.Errorf("pushing image %q: %w", query.Destination, err)) return } utils.WriteResponse(w, http.StatusOK, entities.IDResponse{ID: digest}) @@ -311,9 +314,13 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) { Format string `schema:"format"` RemoveSignatures bool `schema:"removeSignatures"` TLSVerify bool `schema:"tlsVerify"` + Quiet bool `schema:"quiet"` }{ // Add defaults here once needed. TLSVerify: true, + // #15210: older versions did not sent *any* data, so we need + // to be quiet by default to remain backwards compatible + Quiet: true, } if err := decoder.Decode(&query, r.URL.Query()); err != nil { utils.Error(w, http.StatusBadRequest, @@ -344,6 +351,7 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) { CompressionFormat: query.CompressionFormat, Format: query.Format, Password: password, + Quiet: true, RemoveSignatures: query.RemoveSignatures, Username: username, } @@ -356,12 +364,67 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) { imageEngine := abi.ImageEngine{Libpod: runtime} source := utils.GetName(r) - digest, err := imageEngine.ManifestPush(context.Background(), source, destination, options) - if err != nil { - utils.Error(w, http.StatusBadRequest, fmt.Errorf("error pushing image %q: %w", destination, err)) + + // Let's keep thing simple when running in quiet mode and push directly. + if query.Quiet { + digest, err := imageEngine.ManifestPush(r.Context(), source, destination, options) + if err != nil { + utils.Error(w, http.StatusBadRequest, fmt.Errorf("pushing image %q: %w", destination, err)) + return + } + utils.WriteResponse(w, http.StatusOK, entities.ManifestPushReport{ID: digest}) return } - utils.WriteResponse(w, http.StatusOK, entities.IDResponse{ID: digest}) + + writer := channel.NewWriter(make(chan []byte)) + defer writer.Close() + options.Writer = writer + + pushCtx, pushCancel := context.WithCancel(r.Context()) + var digest string + var pushError error + go func() { + defer pushCancel() + digest, pushError = imageEngine.ManifestPush(pushCtx, source, destination, options) + }() + + flush := func() { + if flusher, ok := w.(http.Flusher); ok { + flusher.Flush() + } + } + + w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/json") + flush() + + enc := json.NewEncoder(w) + enc.SetEscapeHTML(true) + for { + var report entities.ManifestPushReport + select { + case s := <-writer.Chan(): + report.Stream = string(s) + if err := enc.Encode(report); err != nil { + logrus.Warnf("Failed to encode json: %v", err) + } + flush() + case <-pushCtx.Done(): + if pushError != nil { + report.Error = pushError.Error() + } else { + report.ID = digest + } + if err := enc.Encode(report); err != nil { + logrus.Warnf("Failed to encode json: %v", err) + } + flush() + return + case <-r.Context().Done(): + // Client has closed connection + return + } + } } // ManifestModify efficiently updates the named manifest list diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go index 8b1d456ec..c39b9ee2f 100644 --- a/pkg/api/handlers/libpod/pods.go +++ b/pkg/api/handlers/libpod/pods.go @@ -51,7 +51,7 @@ func PodCreate(w http.ResponseWriter, r *http.Request) { } err = specgenutil.FillOutSpecGen(psg.InfraContainerSpec, &infraOptions, []string{}) // necessary for default values in many cases (userns, idmappings) if err != nil { - utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error filling out specgen: %w", err)) + utils.Error(w, http.StatusInternalServerError, fmt.Errorf("filling out specgen: %w", err)) return } out, err := json.Marshal(psg) // marshal our spec so the matching options can be unmarshaled into infra @@ -178,7 +178,7 @@ func PodStop(w http.ResponseWriter, r *http.Request) { report := entities.PodStopReport{Id: pod.ID()} for id, err := range responses { - report.Errs = append(report.Errs, fmt.Errorf("error stopping container %s: %w", id, err)) + report.Errs = append(report.Errs, fmt.Errorf("stopping container %s: %w", id, err)) } code := http.StatusOK @@ -214,7 +214,7 @@ func PodStart(w http.ResponseWriter, r *http.Request) { report := entities.PodStartReport{Id: pod.ID()} for id, err := range responses { - report.Errs = append(report.Errs, fmt.Errorf("%v: %w", "error starting container "+id, err)) + report.Errs = append(report.Errs, fmt.Errorf("%v: %w", "starting container "+id, err)) } code := http.StatusOK @@ -270,7 +270,7 @@ func PodRestart(w http.ResponseWriter, r *http.Request) { report := entities.PodRestartReport{Id: pod.ID()} for id, err := range responses { - report.Errs = append(report.Errs, fmt.Errorf("error restarting container %s: %w", id, err)) + report.Errs = append(report.Errs, fmt.Errorf("restarting container %s: %w", id, err)) } code := http.StatusOK @@ -321,7 +321,7 @@ func PodPause(w http.ResponseWriter, r *http.Request) { report := entities.PodPauseReport{Id: pod.ID()} for id, v := range responses { - report.Errs = append(report.Errs, fmt.Errorf("error pausing container %s: %w", id, v)) + report.Errs = append(report.Errs, fmt.Errorf("pausing container %s: %w", id, v)) } code := http.StatusOK @@ -347,7 +347,7 @@ func PodUnpause(w http.ResponseWriter, r *http.Request) { report := entities.PodUnpauseReport{Id: pod.ID()} for id, v := range responses { - report.Errs = append(report.Errs, fmt.Errorf("error unpausing container %s: %w", id, v)) + report.Errs = append(report.Errs, fmt.Errorf("unpausing container %s: %w", id, v)) } code := http.StatusOK diff --git a/pkg/api/handlers/swagger/responses.go b/pkg/api/handlers/swagger/responses.go index 5731f8edd..3de9b06e9 100644 --- a/pkg/api/handlers/swagger/responses.go +++ b/pkg/api/handlers/swagger/responses.go @@ -71,7 +71,7 @@ type imagesRemoveResponseLibpod struct { // PlayKube response // swagger:response -type kubePlayResponseLibpod struct { +type playKubeResponseLibpod struct { // in:body Body entities.PlayKubeReport } @@ -313,6 +313,11 @@ type containerCreateResponse struct { Body entities.ContainerCreateResponse } +type containerUpdateResponse struct { + // in:body + ID string +} + // Wait container // swagger:response type containerWaitResponse struct { diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go index b533e131c..bb416d9f4 100644 --- a/pkg/api/handlers/types.go +++ b/pkg/api/handlers/types.go @@ -11,6 +11,7 @@ import ( 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" ) type AuthConfig struct { @@ -64,6 +65,12 @@ type LibpodContainersRmReport struct { RmError string `json:"Err,omitempty"` } +// UpdateEntities used to wrap the oci resource spec in a swagger model +// swagger:model +type UpdateEntities struct { + Resources *specs.LinuxResources +} + type Info struct { docker.Info BuildahVersion string @@ -127,6 +134,7 @@ type CreateContainerConfig struct { dockerContainer.Config // desired container configuration HostConfig dockerContainer.HostConfig // host dependent configuration for container NetworkingConfig dockerNetwork.NetworkingConfig // network configuration for container + EnvMerge []string // preprocess env variables from image before injecting into containers UnsetEnv []string // unset specified default environment variables UnsetEnvAll bool // unset all default environment variables } @@ -162,7 +170,7 @@ type ExecStartConfig struct { func ImageDataToImageInspect(ctx context.Context, l *libimage.Image) (*ImageInspect, error) { options := &libimage.InspectOptions{WithParent: true, WithSize: true} - info, err := l.Inspect(context.Background(), options) + info, err := l.Inspect(ctx, options) if err != nil { return nil, err } diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index b319fc14a..311eecd17 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -11,9 +11,9 @@ import ( func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // swagger:operation POST /containers/create compat ContainerCreate // --- - // summary: Create a container // tags: // - containers (compat) + // summary: Create a container // produces: // - application/json // parameters: @@ -212,7 +212,6 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // - in: query // name: signal // type: string - // default: TERM // description: signal to be sent to container // default: SIGKILL // produces: @@ -678,9 +677,9 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // swagger:operation POST /libpod/containers/create libpod ContainerCreateLibpod // --- - // summary: Create a container // tags: // - containers + // summary: Create a container // produces: // - application/json // parameters: @@ -689,6 +688,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // description: attributes for creating a container // schema: // $ref: "#/definitions/SpecGenerator" + // required: true // responses: // 201: // $ref: "#/responses/containerCreateResponse" @@ -722,6 +722,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // type: boolean // description: Include namespace information // default: false + // - in: query // name: pod // type: boolean // default: false @@ -896,7 +897,7 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // - in: query // name: signal // type: string - // default: TERM + // default: SIGKILL // description: signal to be sent to container, either by integer or SIG_ name // produces: // - application/json @@ -1290,11 +1291,6 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // required: true // description: the name or ID of the container // - in: query - // name: all - // type: boolean - // default: false - // description: Stop all containers - // - in: query // name: timeout // type: integer // default: 10 @@ -1625,5 +1621,33 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // 500: // $ref: "#/responses/internalError" r.HandleFunc(VersionedPath("/libpod/containers/{name}/rename"), s.APIHandler(compat.RenameContainer)).Methods(http.MethodPost) + // swagger:operation POST /libpod/containers/{name}/update libpod ContainerUpdateLibpod + // --- + // tags: + // - containers + // summary: Update an existing containers cgroup configuration + // description: Update an existing containers cgroup configuration. + // parameters: + // - in: path + // name: name + // type: string + // required: true + // description: Full or partial ID or full name of the container to update + // - in: body + // name: resources + // description: attributes for updating the container + // schema: + // $ref: "#/definitions/UpdateEntities" + // produces: + // - application/json + // responses: + // responses: + // 201: + // $ref: "#/responses/containerUpdateResponse" + // 404: + // $ref: "#/responses/containerNotFound" + // 500: + // $ref: "#/responses/internalError" + r.HandleFunc(VersionedPath("/libpod/containers/{name}/update"), s.APIHandler(libpod.UpdateContainer)).Methods(http.MethodPost) return nil } diff --git a/pkg/api/server/register_generate.go b/pkg/api/server/register_generate.go index 82fbe3d09..ac2818db0 100644 --- a/pkg/api/server/register_generate.go +++ b/pkg/api/server/register_generate.go @@ -93,6 +93,13 @@ func (s *APIServer) registerGenerateHandlers(r *mux.Router) error { // type: string // default: [] // description: Systemd Requires list for the container or pods. + // - in: query + // name: additionalEnvVariables + // type: array + // items: + // type: string + // default: [] + // description: Set environment variables to the systemd unit files. // produces: // - application/json // responses: diff --git a/pkg/api/server/register_kube.go b/pkg/api/server/register_kube.go index 6ae9e8123..0c3cd1d04 100644 --- a/pkg/api/server/register_kube.go +++ b/pkg/api/server/register_kube.go @@ -8,7 +8,7 @@ import ( ) func (s *APIServer) registerKubeHandlers(r *mux.Router) error { - // swagger:operation POST /libpod/kube/play libpod KubePlayLibpod + // swagger:operation POST /libpod/play/kube libpod PlayKubeLibpod // --- // tags: // - containers @@ -57,12 +57,12 @@ func (s *APIServer) registerKubeHandlers(r *mux.Router) error { // - application/json // responses: // 200: - // $ref: "#/responses/kubePlayResponseLibpod" + // $ref: "#/responses/playKubeResponseLibpod" // 500: // $ref: "#/responses/internalError" - r.HandleFunc(VersionedPath("/libpod/kube/play"), s.APIHandler(libpod.KubePlay)).Methods(http.MethodPost) r.HandleFunc(VersionedPath("/libpod/play/kube"), s.APIHandler(libpod.PlayKube)).Methods(http.MethodPost) - // swagger:operation DELETE /libpod/kube/play libpod KubePlayDownLibpod + r.HandleFunc(VersionedPath("/libpod/kube/play"), s.APIHandler(libpod.KubePlay)).Methods(http.MethodPost) + // swagger:operation DELETE /libpod/play/kube libpod PlayKubeDownLibpod // --- // tags: // - containers @@ -73,10 +73,43 @@ func (s *APIServer) registerKubeHandlers(r *mux.Router) error { // - application/json // responses: // 200: - // $ref: "#/responses/kubePlayResponseLibpod" + // $ref: "#/responses/playKubeResponseLibpod" // 500: // $ref: "#/responses/internalError" - r.HandleFunc(VersionedPath("/libpod/kube/play"), s.APIHandler(libpod.KubePlayDown)).Methods(http.MethodDelete) r.HandleFunc(VersionedPath("/libpod/play/kube"), s.APIHandler(libpod.PlayKubeDown)).Methods(http.MethodDelete) + r.HandleFunc(VersionedPath("/libpod/kube/play"), s.APIHandler(libpod.KubePlayDown)).Methods(http.MethodDelete) + // swagger:operation GET /libpod/generate/kube libpod GenerateKubeLibpod + // --- + // tags: + // - containers + // - pods + // summary: Generate a Kubernetes YAML file. + // description: Generate Kubernetes YAML based on a pod or container. + // parameters: + // - in: query + // name: names + // type: array + // items: + // type: string + // required: true + // description: Name or ID of the container or pod. + // - in: query + // name: service + // type: boolean + // default: false + // description: Generate YAML for a Kubernetes service object. + // produces: + // - text/vnd.yaml + // - application/json + // responses: + // 200: + // description: Kubernetes YAML file describing pod + // schema: + // type: string + // format: binary + // 500: + // $ref: "#/responses/internalError" + r.HandleFunc(VersionedPath("/libpod/generate/kube"), s.APIHandler(libpod.GenerateKube)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/libpod/kube/generate"), s.APIHandler(libpod.KubeGenerate)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_manifest.go b/pkg/api/server/register_manifest.go index 19b507047..7a55eaefe 100644 --- a/pkg/api/server/register_manifest.go +++ b/pkg/api/server/register_manifest.go @@ -75,6 +75,11 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error { // type: boolean // default: true // description: Require HTTPS and verify signatures when contacting registries. + // - in: query + // name: quiet + // description: "silences extra stream data on push" + // type: boolean + // default: true // responses: // 200: // schema: @@ -112,6 +117,10 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error { // name: all // type: boolean // description: add all contents if given list + // - in: query + // name: amend + // type: boolean + // description: modify an existing list if one with the desired name already exists // - in: body // name: options // description: options for new manifest diff --git a/pkg/api/server/register_secrets.go b/pkg/api/server/register_secrets.go index f4608baa6..8918ad238 100644 --- a/pkg/api/server/register_secrets.go +++ b/pkg/api/server/register_secrets.go @@ -54,7 +54,6 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error { // - `id=[id]` Matches for full or partial ID. // produces: // - application/json - // parameters: // responses: // '200': // "$ref": "#/responses/SecretListResponse" @@ -128,7 +127,6 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error { // - `id=[id]` Matches for full or partial ID. // produces: // - application/json - // parameters: // responses: // '200': // "$ref": "#/responses/SecretListCompatResponse" diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index a6d8b5e4c..39423dabe 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -126,11 +126,11 @@ func newServer(runtime *libpod.Runtime, listener net.Listener, opts entities.Ser server.registerHealthCheckHandlers, server.registerImagesHandlers, server.registerInfoHandlers, - server.registerKubeHandlers, server.registerManifestHandlers, server.registerMonitorHandlers, server.registerNetworkHandlers, server.registerPingHandlers, + server.registerKubeHandlers, server.registerPluginsHandlers, server.registerPodsHandlers, server.registerSecretHandlers, |