fix: Docker API compatible bool deserialization

In Docker anything but "", "0", "no", "false", "none" (ignoring case) is considered to be true.

Signed-off-by: Matej Vasek <mvasek@redhat.com>
This commit is contained in:
Matej Vasek
2023-08-10 23:47:09 +02:00
parent 4cb2d48ca4
commit f33b01b731
27 changed files with 82 additions and 52 deletions

View File

@ -8,11 +8,10 @@ import (
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/api/handlers/utils" "github.com/containers/podman/v4/pkg/api/handlers/utils"
api "github.com/containers/podman/v4/pkg/api/types" api "github.com/containers/podman/v4/pkg/api/types"
"github.com/gorilla/schema"
) )
func Changes(w http.ResponseWriter, r *http.Request) { func Changes(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
query := struct { query := struct {

View File

@ -27,12 +27,11 @@ import (
"github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/network"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
"github.com/docker/go-units" "github.com/docker/go-units"
"github.com/gorilla/schema"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
func RemoveContainer(w http.ResponseWriter, r *http.Request) { func RemoveContainer(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
query := struct { query := struct {
Force bool `schema:"force"` Force bool `schema:"force"`
Ignore bool `schema:"ignore"` Ignore bool `schema:"ignore"`
@ -99,7 +98,7 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
func ListContainers(w http.ResponseWriter, r *http.Request) { func ListContainers(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
query := struct { query := struct {
All bool `schema:"all"` All bool `schema:"all"`
Limit int `schema:"limit"` Limit int `schema:"limit"`
@ -179,7 +178,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
func GetContainer(w http.ResponseWriter, r *http.Request) { func GetContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
query := struct { query := struct {
Size bool `schema:"size"` Size bool `schema:"size"`
}{ }{
@ -208,7 +207,7 @@ func GetContainer(w http.ResponseWriter, r *http.Request) {
func KillContainer(w http.ResponseWriter, r *http.Request) { func KillContainer(w http.ResponseWriter, r *http.Request) {
// /{version}/containers/(name)/kill // /{version}/containers/(name)/kill
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
query := struct { query := struct {
Signal string `schema:"signal"` Signal string `schema:"signal"`
}{ }{
@ -627,7 +626,7 @@ func formatCapabilities(slice []string) {
func RenameContainer(w http.ResponseWriter, r *http.Request) { func RenameContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
name := utils.GetName(r) name := utils.GetName(r)
query := struct { query := struct {

View File

@ -21,7 +21,7 @@ import (
) )
func Archive(w http.ResponseWriter, r *http.Request) { func Archive(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
switch r.Method { switch r.Method {

View File

@ -10,13 +10,12 @@ import (
"github.com/containers/podman/v4/pkg/api/handlers/utils" "github.com/containers/podman/v4/pkg/api/handlers/utils"
"github.com/containers/podman/v4/pkg/api/server/idle" "github.com/containers/podman/v4/pkg/api/server/idle"
api "github.com/containers/podman/v4/pkg/api/types" api "github.com/containers/podman/v4/pkg/api/types"
"github.com/gorilla/schema"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
func AttachContainer(w http.ResponseWriter, r *http.Request) { func AttachContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
query := struct { query := struct {
DetachKeys string `schema:"detachKeys"` DetachKeys string `schema:"detachKeys"`

View File

@ -28,12 +28,11 @@ import (
"github.com/containers/podman/v4/pkg/specgenutil" "github.com/containers/podman/v4/pkg/specgenutil"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/mount"
"github.com/gorilla/schema"
) )
func CreateContainer(w http.ResponseWriter, r *http.Request) { func CreateContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
query := struct { query := struct {
Name string `schema:"name"` Name string `schema:"name"`
Platform string `schema:"platform"` Platform string `schema:"platform"`

View File

@ -15,12 +15,11 @@ import (
"github.com/containers/podman/v4/pkg/api/handlers/utils" "github.com/containers/podman/v4/pkg/api/handlers/utils"
api "github.com/containers/podman/v4/pkg/api/types" api "github.com/containers/podman/v4/pkg/api/types"
"github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/pkg/util"
"github.com/gorilla/schema"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
func LogsFromContainer(w http.ResponseWriter, r *http.Request) { func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
query := struct { query := struct {

View File

@ -11,12 +11,11 @@ import (
api "github.com/containers/podman/v4/pkg/api/types" api "github.com/containers/podman/v4/pkg/api/types"
"github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/domain/infra/abi" "github.com/containers/podman/v4/pkg/domain/infra/abi"
"github.com/gorilla/schema"
) )
func RestartContainer(w http.ResponseWriter, r *http.Request) { func RestartContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
// Now use the ABI implementation to prevent us from having duplicate // Now use the ABI implementation to prevent us from having duplicate
// code. // code.
containerEngine := abi.ContainerEngine{Libpod: runtime} containerEngine := abi.ContainerEngine{Libpod: runtime}

View File

@ -9,11 +9,10 @@ import (
"github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/api/handlers/utils" "github.com/containers/podman/v4/pkg/api/handlers/utils"
"github.com/gorilla/schema"
) )
func StartContainer(w http.ResponseWriter, r *http.Request) { func StartContainer(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
query := struct { query := struct {
DetachKeys string `schema:"detachKeys"` DetachKeys string `schema:"detachKeys"`
}{ }{

View File

@ -13,7 +13,6 @@ import (
api "github.com/containers/podman/v4/pkg/api/types" api "github.com/containers/podman/v4/pkg/api/types"
"github.com/containers/storage/pkg/system" "github.com/containers/storage/pkg/system"
docker "github.com/docker/docker/api/types" docker "github.com/docker/docker/api/types"
"github.com/gorilla/schema"
runccgroups "github.com/opencontainers/runc/libcontainer/cgroups" runccgroups "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -22,7 +21,7 @@ const DefaultStatsPeriod = 5 * time.Second
func StatsContainer(w http.ResponseWriter, r *http.Request) { func StatsContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
query := struct { query := struct {
Stream bool `schema:"stream"` Stream bool `schema:"stream"`

View File

@ -12,12 +12,11 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/domain/infra/abi" "github.com/containers/podman/v4/pkg/domain/infra/abi"
"github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/pkg/util"
"github.com/gorilla/schema"
) )
func StopContainer(w http.ResponseWriter, r *http.Request) { func StopContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
// Now use the ABI implementation to prevent us from having duplicate // Now use the ABI implementation to prevent us from having duplicate
// code. // code.
containerEngine := abi.ContainerEngine{Libpod: runtime} containerEngine := abi.ContainerEngine{Libpod: runtime}

View File

@ -11,13 +11,12 @@ import (
"github.com/containers/podman/v4/pkg/api/handlers" "github.com/containers/podman/v4/pkg/api/handlers"
"github.com/containers/podman/v4/pkg/api/handlers/utils" "github.com/containers/podman/v4/pkg/api/handlers/utils"
api "github.com/containers/podman/v4/pkg/api/types" api "github.com/containers/podman/v4/pkg/api/types"
"github.com/gorilla/schema"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
func TopContainer(w http.ResponseWriter, r *http.Request) { func TopContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
psArgs := "-ef" psArgs := "-ef"
if utils.IsLibpodRequest(r) { if utils.IsLibpodRequest(r) {

View File

@ -10,7 +10,6 @@ import (
api "github.com/containers/podman/v4/pkg/api/types" api "github.com/containers/podman/v4/pkg/api/types"
"github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/pkg/util"
"github.com/gorilla/schema"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -19,7 +18,7 @@ import (
func GetEvents(w http.ResponseWriter, r *http.Request) { func GetEvents(w http.ResponseWriter, r *http.Request) {
var ( var (
fromStart bool fromStart bool
decoder = r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder = utils.GetDecoder(r)
runtime = r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime = r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
json = jsoniter.ConfigCompatibleWithStandardLibrary // FIXME: this should happen on the package level json = jsoniter.ConfigCompatibleWithStandardLibrary // FIXME: this should happen on the package level
) )

View File

@ -25,7 +25,6 @@ import (
"github.com/containers/storage" "github.com/containers/storage"
"github.com/docker/distribution/registry/api/errcode" "github.com/docker/distribution/registry/api/errcode"
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
"github.com/gorilla/schema"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -95,7 +94,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
} }
func CommitContainer(w http.ResponseWriter, r *http.Request) { func CommitContainer(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
query := struct { query := struct {
@ -174,7 +173,7 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
// 200 no error // 200 no error
// 404 repo does not exist or no read access // 404 repo does not exist or no read access
// 500 internal // 500 internal
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
query := struct { query := struct {
@ -258,7 +257,7 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
// 200 no error // 200 no error
// 404 repo does not exist or no read access // 404 repo does not exist or no read access
// 500 internal // 500 internal
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
query := struct { query := struct {
@ -428,7 +427,7 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
} }
func GetImages(w http.ResponseWriter, r *http.Request) { func GetImages(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
query := struct { query := struct {
All bool All bool
@ -489,7 +488,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) {
} }
func LoadImages(w http.ResponseWriter, r *http.Request) { func LoadImages(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
query := struct { query := struct {
@ -547,7 +546,7 @@ func LoadImages(w http.ResponseWriter, r *http.Request) {
func ExportImages(w http.ResponseWriter, r *http.Request) { func ExportImages(w http.ResponseWriter, r *http.Request) {
// 200 OK // 200 OK
// 500 Error // 500 Error
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
query := struct { query := struct {

View File

@ -27,7 +27,6 @@ import (
"github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/pkg/util"
"github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/archive"
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
"github.com/gorilla/schema"
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -151,7 +150,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
SkipUnusedStages: true, SkipUnusedStages: true,
} }
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, err) utils.Error(w, http.StatusBadRequest, err)
return return

View File

@ -16,13 +16,12 @@ import (
"github.com/containers/podman/v4/pkg/domain/infra/abi" "github.com/containers/podman/v4/pkg/domain/infra/abi"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
"github.com/gorilla/schema"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
// PushImage is the handler for the compat http endpoint for pushing images. // PushImage is the handler for the compat http endpoint for pushing images.
func PushImage(w http.ResponseWriter, r *http.Request) { func PushImage(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
// Now use the ABI implementation to prevent us from having duplicate // Now use the ABI implementation to prevent us from having duplicate

View File

@ -11,11 +11,10 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/domain/infra/abi" "github.com/containers/podman/v4/pkg/domain/infra/abi"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/gorilla/schema"
) )
func RemoveImage(w http.ResponseWriter, r *http.Request) { func RemoveImage(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
query := struct { query := struct {

View File

@ -12,12 +12,11 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/domain/infra/abi" "github.com/containers/podman/v4/pkg/domain/infra/abi"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/gorilla/schema"
) )
func SearchImages(w http.ResponseWriter, r *http.Request) { func SearchImages(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
query := struct { query := struct {
Term string `json:"term"` Term string `json:"term"`
Limit int `json:"limit"` Limit int `json:"limit"`

View File

@ -19,7 +19,6 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
dockerNetwork "github.com/docker/docker/api/types/network" dockerNetwork "github.com/docker/docker/api/types/network"
"github.com/gorilla/schema"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -41,7 +40,7 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
}{ }{
scope: "local", scope: "local",
} }
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err)) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
@ -315,7 +314,7 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
// This is where you can override the golang default value for one of fields // This is where you can override the golang default value for one of fields
} }
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err)) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return

View File

@ -12,12 +12,11 @@ import (
"github.com/containers/podman/v4/pkg/api/handlers/utils" "github.com/containers/podman/v4/pkg/api/handlers/utils"
api "github.com/containers/podman/v4/pkg/api/types" api "github.com/containers/podman/v4/pkg/api/types"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/gorilla/schema"
) )
func ResizeTTY(w http.ResponseWriter, r *http.Request) { func ResizeTTY(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
// /containers/{id}/resize // /containers/{id}/resize
query := struct { query := struct {

View File

@ -15,7 +15,6 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/domain/infra/abi" "github.com/containers/podman/v4/pkg/domain/infra/abi"
"github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/pkg/util"
"github.com/gorilla/schema"
) )
func ListSecrets(w http.ResponseWriter, r *http.Request) { func ListSecrets(w http.ResponseWriter, r *http.Request) {
@ -52,7 +51,7 @@ func ListSecrets(w http.ResponseWriter, r *http.Request) {
} }
func InspectSecret(w http.ResponseWriter, r *http.Request) { func InspectSecret(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder := utils.GetDecoder(r)
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
name := utils.GetName(r) name := utils.GetName(r)
names := []string{name} names := []string{name}

View File

@ -19,7 +19,6 @@ import (
"github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/pkg/util"
docker_api_types "github.com/docker/docker/api/types" docker_api_types "github.com/docker/docker/api/types"
docker_api_types_volume "github.com/docker/docker/api/types/volume" docker_api_types_volume "github.com/docker/docker/api/types/volume"
"github.com/gorilla/schema"
) )
func ListVolumes(w http.ResponseWriter, r *http.Request) { func ListVolumes(w http.ResponseWriter, r *http.Request) {
@ -85,7 +84,7 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
var ( var (
volumeOptions []libpod.VolumeCreateOption volumeOptions []libpod.VolumeCreateOption
runtime = r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime = r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder = r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder = utils.GetDecoder(r)
) )
/* No query string data*/ /* No query string data*/
query := struct{}{} query := struct{}{}
@ -213,7 +212,7 @@ func InspectVolume(w http.ResponseWriter, r *http.Request) {
func RemoveVolume(w http.ResponseWriter, r *http.Request) { func RemoveVolume(w http.ResponseWriter, r *http.Request) {
var ( var (
runtime = r.Context().Value(api.RuntimeKey).(*libpod.Runtime) runtime = r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder = r.Context().Value(api.DecoderKey).(*schema.Decoder) decoder = utils.GetDecoder(r)
) )
query := struct { query := struct {
Force bool `schema:"force"` Force bool `schema:"force"`

View File

@ -3,6 +3,7 @@ package handlers
import ( import (
"encoding/json" "encoding/json"
"reflect" "reflect"
"strings"
"syscall" "syscall"
"time" "time"
@ -28,6 +29,18 @@ func NewAPIDecoder() *schema.Decoder {
return d return d
} }
func NewCompatAPIDecoder() *schema.Decoder {
dec := NewAPIDecoder()
// mimic behaviour of github.com/docker/docker/api/server/httputils.BoolValue()
dec.RegisterConverter(true, func(s string) reflect.Value {
s = strings.ToLower(strings.TrimSpace(s))
return reflect.ValueOf(!(s == "" || s == "0" || s == "no" || s == "false" || s == "none"))
})
return dec
}
// On client: // On client:
// //
// v := map[string][]string{ // v := map[string][]string{

View File

@ -13,8 +13,11 @@ import (
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
"github.com/containers/podman/v4/version" "github.com/containers/podman/v4/version"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/gorilla/schema"
jsoniter "github.com/json-iterator/go" jsoniter "github.com/json-iterator/go"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
api "github.com/containers/podman/v4/pkg/api/types"
) )
var ( var (
@ -188,3 +191,10 @@ func GetVar(r *http.Request, k string) string {
func GetName(r *http.Request) string { func GetName(r *http.Request) string {
return GetVar(r, "name") return GetVar(r, "name")
} }
func GetDecoder(r *http.Request) *schema.Decoder {
if IsLibpodRequest(r) {
return r.Context().Value(api.DecoderKey).(*schema.Decoder)
}
return r.Context().Value(api.CompatDecoderKey).(*schema.Decoder)
}

View File

@ -90,6 +90,7 @@ func newServer(runtime *libpod.Runtime, listener net.Listener, opts entities.Ser
server.BaseContext = func(l net.Listener) context.Context { server.BaseContext = func(l net.Listener) context.Context {
ctx := context.WithValue(context.Background(), types.DecoderKey, handlers.NewAPIDecoder()) ctx := context.WithValue(context.Background(), types.DecoderKey, handlers.NewAPIDecoder())
ctx = context.WithValue(ctx, types.CompatDecoderKey, handlers.NewCompatAPIDecoder())
ctx = context.WithValue(ctx, types.RuntimeKey, runtime) ctx = context.WithValue(ctx, types.RuntimeKey, runtime)
ctx = context.WithValue(ctx, types.IdleTrackerKey, tracker) ctx = context.WithValue(ctx, types.IdleTrackerKey, tracker)
return ctx return ctx

View File

@ -7,4 +7,5 @@ const (
RuntimeKey RuntimeKey
IdleTrackerKey IdleTrackerKey
ConnKey ConnKey
CompatDecoderKey
) )

View File

@ -234,6 +234,11 @@ t POST "build?dockerfile=containerfile" $CONTAINERFILE_TAR application/json 200
response_headers=$(cat "$WORKDIR/curl.headers.out") response_headers=$(cat "$WORKDIR/curl.headers.out")
like "$response_headers" ".*application/json.*" "header does not contain application/json" like "$response_headers" ".*application/json.*" "header does not contain application/json"
# Build api response header must contain Content-type: application/json
t POST "build?dockerfile=containerfile&pull=1" $CONTAINERFILE_TAR application/json 200
response_headers=$(cat "$WORKDIR/curl.headers.out")
like "$response_headers" ".*application/json.*" "header does not contain application/json"
# PR #12091: output from compat API must now include {"aux":{"ID":"sha..."}} # PR #12091: output from compat API must now include {"aux":{"ID":"sha..."}}
t POST "build?dockerfile=containerfile" $CONTAINERFILE_TAR 200 \ t POST "build?dockerfile=containerfile" $CONTAINERFILE_TAR 200 \
'.aux|select(has("ID")).ID~^sha256:[0-9a-f]\{64\}$' '.aux|select(has("ID")).ID~^sha256:[0-9a-f]\{64\}$'

View File

@ -239,6 +239,26 @@ class TestContainers(common.DockerTestCase):
ret, _ = ctr.exec_run(["stat", "/workspace/scratch/test"]) ret, _ = ctr.exec_run(["stat", "/workspace/scratch/test"])
self.assertEqual(ret, 0, "Working directory created if it doesn't exist") self.assertEqual(ret, 0, "Working directory created if it doesn't exist")
def test_build_pull(self):
dockerfile = (
b"FROM quay.io/libpod/alpine:latest\n"
b"USER 1000:1000\n"
)
img: Image
img, logs = self.docker.images.build(fileobj=io.BytesIO(dockerfile), quiet=False, pull=True)
has_tried_pull = False
for e in logs:
if "stream" in e and "trying to pull" in e["stream"].lower():
has_tried_pull = True
self.assertTrue(has_tried_pull, "the build process has not tried to pull the base image")
img, logs = self.docker.images.build(fileobj=io.BytesIO(dockerfile), quiet=False, pull=False)
has_tried_pull = False
for e in logs:
if "stream" in e and "trying to pull" in e["stream"].lower():
has_tried_pull = True
self.assertFalse(has_tried_pull, "the build process has tried tried to pull the base image")
def test_mount_rw_by_default(self): def test_mount_rw_by_default(self):
ctr: Optional[Container] = None ctr: Optional[Container] = None
vol: Optional[Volume] = None vol: Optional[Volume] = None