mirror of https://github.com/containers/podman.git
Add Compat API for Update
The Docker endpoint here is kind of a nightmare - accepts a full Resources block, including a large number of scary things like devices. But it only documents (and seems to use) a small subset of those. This implements support for that subset. We can always extend things to implement more later if we have a need. Signed-off-by: Matt Heon <mheon@redhat.com>
This commit is contained in:
parent
be3f075402
commit
ddea30e40e
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/docker/go-units"
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -661,3 +662,123 @@ func RenameContainer(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
utils.WriteResponse(w, http.StatusNoContent, nil)
|
||||
}
|
||||
|
||||
func UpdateContainer(w http.ResponseWriter, r *http.Request) {
|
||||
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
|
||||
name := utils.GetName(r)
|
||||
|
||||
ctr, err := runtime.LookupContainer(name)
|
||||
if err != nil {
|
||||
utils.ContainerNotFound(w, name, err)
|
||||
return
|
||||
}
|
||||
|
||||
options := new(container.UpdateConfig)
|
||||
if err := json.NewDecoder(r.Body).Decode(options); err != nil {
|
||||
utils.Error(w, http.StatusInternalServerError, fmt.Errorf("decoding request body: %w", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Only handle the bits of update that Docker uses as examples.
|
||||
// For example, the update API claims to be able to update devices for
|
||||
// existing containers... Which I am very dubious about.
|
||||
// Ignore bits like that unless someone asks us for them.
|
||||
|
||||
// We're going to be editing this, so we have to deep-copy to not affect
|
||||
// the container's own resources
|
||||
resources := new(spec.LinuxResources)
|
||||
oldResources := ctr.LinuxResources()
|
||||
if oldResources != nil {
|
||||
if err := libpod.JSONDeepCopy(oldResources, resources); err != nil {
|
||||
utils.Error(w, http.StatusInternalServerError, fmt.Errorf("copying old resource limits: %w", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// CPU limits
|
||||
cpu := resources.CPU
|
||||
if cpu == nil {
|
||||
cpu = new(spec.LinuxCPU)
|
||||
}
|
||||
useCPU := false
|
||||
if options.CPUShares != 0 {
|
||||
shares := uint64(options.CPUShares)
|
||||
cpu.Shares = &shares
|
||||
useCPU = true
|
||||
}
|
||||
if options.CPUPeriod != 0 {
|
||||
period := uint64(options.CPUPeriod)
|
||||
cpu.Period = &period
|
||||
useCPU = true
|
||||
}
|
||||
if options.CPUQuota != 0 {
|
||||
cpu.Quota = &options.CPUQuota
|
||||
useCPU = true
|
||||
}
|
||||
if options.CPURealtimeRuntime != 0 {
|
||||
cpu.RealtimeRuntime = &options.CPURealtimeRuntime
|
||||
useCPU = true
|
||||
}
|
||||
if options.CPURealtimePeriod != 0 {
|
||||
period := uint64(options.CPURealtimePeriod)
|
||||
cpu.RealtimePeriod = &period
|
||||
useCPU = true
|
||||
}
|
||||
if options.CpusetCpus != "" {
|
||||
cpu.Cpus = options.CpusetCpus
|
||||
useCPU = true
|
||||
}
|
||||
if options.CpusetMems != "" {
|
||||
cpu.Mems = options.CpusetMems
|
||||
useCPU = true
|
||||
}
|
||||
if useCPU {
|
||||
resources.CPU = cpu
|
||||
}
|
||||
|
||||
// Memory limits
|
||||
mem := resources.Memory
|
||||
if mem == nil {
|
||||
mem = new(spec.LinuxMemory)
|
||||
}
|
||||
useMem := false
|
||||
if options.Memory != 0 {
|
||||
mem.Limit = &options.Memory
|
||||
useMem = true
|
||||
}
|
||||
if options.MemorySwap != 0 {
|
||||
mem.Swap = &options.MemorySwap
|
||||
useMem = true
|
||||
}
|
||||
if options.MemoryReservation != 0 {
|
||||
mem.Reservation = &options.MemoryReservation
|
||||
useMem = true
|
||||
}
|
||||
if useMem {
|
||||
resources.Memory = mem
|
||||
}
|
||||
|
||||
// PIDs limit
|
||||
if options.PidsLimit != nil {
|
||||
if resources.Pids == nil {
|
||||
resources.Pids = new(spec.LinuxPids)
|
||||
}
|
||||
resources.Pids.Limit = *options.PidsLimit
|
||||
}
|
||||
|
||||
// Blkio Weight
|
||||
if options.BlkioWeight != 0 {
|
||||
if resources.BlockIO == nil {
|
||||
resources.BlockIO = new(spec.LinuxBlockIO)
|
||||
}
|
||||
resources.BlockIO.Weight = &options.BlkioWeight
|
||||
}
|
||||
|
||||
if err := ctr.Update(resources); err != nil {
|
||||
utils.Error(w, http.StatusInternalServerError, fmt.Errorf("updating resources: %w", err))
|
||||
return
|
||||
}
|
||||
|
||||
responseStruct := container.ContainerUpdateOKBody{}
|
||||
utils.WriteResponse(w, http.StatusOK, responseStruct)
|
||||
}
|
||||
|
|
|
@ -675,6 +675,34 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
|
|||
// $ref: "#/responses/internalError"
|
||||
r.HandleFunc(VersionedPath("/containers/{name}/rename"), s.APIHandler(compat.RenameContainer)).Methods(http.MethodPost)
|
||||
r.HandleFunc("/containers/{name}/rename", s.APIHandler(compat.RenameContainer)).Methods(http.MethodPost)
|
||||
// swagger:operation POST /containers/{name}/update compat ContainerUpdate
|
||||
// ---
|
||||
// tags:
|
||||
// - containers (compat)
|
||||
// summary: Update configuration of an existing container
|
||||
// description: Change configuration settings for an existing container without requiring recreation.
|
||||
// parameters:
|
||||
// - in: path
|
||||
// name: name
|
||||
// type: string
|
||||
// required: true
|
||||
// description: Full or partial ID or full name of the container to rename
|
||||
// - in: body
|
||||
// name: resources
|
||||
// description: attributes for updating the container
|
||||
// schema:
|
||||
// $ref: "#/definitions/UpdateConfig"
|
||||
// produces:
|
||||
// - application/json
|
||||
// responses:
|
||||
// 200:
|
||||
// description: no error
|
||||
// 404:
|
||||
// $ref: "#/responses/containerNotFound"
|
||||
// 500:
|
||||
// $ref: "#/responses/internalError"
|
||||
r.HandleFunc(VersionedPath("/containers/{name}/update"), s.APIHandler(compat.UpdateContainer)).Methods(http.MethodPost)
|
||||
r.HandleFunc("/containers/{name}/update", s.APIHandler(compat.UpdateContainer)).Methods(http.MethodPost)
|
||||
|
||||
/*
|
||||
libpod endpoints
|
||||
|
|
|
@ -730,6 +730,12 @@ if root; then
|
|||
eid=$(jq -r '.Id' <<<"$output")
|
||||
t POST exec/$eid/start 200 $cpu_weight_expect
|
||||
|
||||
# Now use the compat API
|
||||
echo '{ "Memory": 536870912 }' >${TMPD}/compatupdate.json
|
||||
t POST containers/updateCtr/update ${TMPD}/compatupdate.json 200
|
||||
t GET libpod/containers/updateCtr/json 200 \
|
||||
.HostConfig.Memory=536870912
|
||||
|
||||
podman rm -f updateCtr
|
||||
fi
|
||||
|
||||
|
|
|
@ -284,7 +284,7 @@ var _ = Describe("Podman update", func() {
|
|||
Expect(inspect4.OutputToString()).To(Equal("536870912"))
|
||||
|
||||
exec4 := podmanTest.Podman([]string{"exec", testCtr, "cat", "/sys/fs/cgroup/memory.max"})
|
||||
exec3.WaitWithDefaultTimeout()
|
||||
exec4.WaitWithDefaultTimeout()
|
||||
Expect(exec4).Should(ExitCleanly())
|
||||
Expect(exec4.OutputToString()).Should(ContainSubstring("536870912"))
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue