fix longname handling for bindings

the api needs to account for image input where the image is encoded as a fqd image name.

Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
Brent Baude
2020-01-30 12:40:19 -06:00
parent 36af2833f9
commit f1eaccedfa
20 changed files with 148 additions and 79 deletions

View File

@ -115,6 +115,7 @@ func runREST(r *libpod.Runtime, uri string, timeout time.Duration) error {
if err != nil {
return errors.Wrapf(err, "unable to create socket %s", uri)
}
defer l.Close()
server, err := api.NewServerWithSettings(r, timeout, &l)
if err != nil {
return err

View File

@ -29,7 +29,7 @@ func StopContainer(w http.ResponseWriter, r *http.Request) {
return
}
name := getName(r)
name := utils.GetName(r)
con, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)
@ -67,7 +67,7 @@ func UnpauseContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
// /{version}/containers/(name)/unpause
name := getName(r)
name := utils.GetName(r)
con, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)
@ -88,7 +88,7 @@ func PauseContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
// /{version}/containers/(name)/pause
name := getName(r)
name := utils.GetName(r)
con, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)
@ -121,7 +121,7 @@ func StartContainer(w http.ResponseWriter, r *http.Request) {
return
}
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := getName(r)
name := utils.GetName(r)
con, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)
@ -159,7 +159,7 @@ func RestartContainer(w http.ResponseWriter, r *http.Request) {
return
}
name := getName(r)
name := utils.GetName(r)
con, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)

View File

@ -77,7 +77,7 @@ func AttachContainer(w http.ResponseWriter, r *http.Request) {
return
}
name := getName(r)
name := utils.GetName(r)
ctr, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)
@ -138,7 +138,7 @@ func ResizeContainer(w http.ResponseWriter, r *http.Request) {
return
}
name := getName(r)
name := utils.GetName(r)
ctr, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)

View File

@ -6,7 +6,6 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/gorilla/mux"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
@ -30,7 +29,7 @@ func TopContainer(w http.ResponseWriter, r *http.Request) {
return
}
name := mux.Vars(r)["name"]
name := utils.GetName(r)
c, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)

View File

@ -99,7 +99,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
func GetContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
ctnr, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)
@ -174,7 +174,7 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
return
}
name := mux.Vars(r)["name"]
name := utils.GetName(r)
ctnr, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)

View File

@ -11,7 +11,6 @@ import (
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/containers/libpod/pkg/cgroups"
docker "github.com/docker/docker/api/types"
"github.com/gorilla/mux"
"github.com/gorilla/schema"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -36,7 +35,7 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
return
}
name := mux.Vars(r)["name"]
name := utils.GetName(r)
ctnr, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)

View File

@ -16,7 +16,6 @@ import (
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/containers/libpod/pkg/util"
"github.com/docker/docker/api/types"
"github.com/gorilla/mux"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
@ -26,7 +25,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
// 500 server
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
utils.ImageNotFound(w, name, errors.Wrapf(err, "Failed to find image %s", name))
@ -285,7 +284,7 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
// 200 no error
// 404 no such
// 500 internal
name := mux.Vars(r)["name"]
name := utils.GetName(r)
newImage, err := handlers.GetImage(r, name)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "Failed to find image %s", name))

View File

@ -4,26 +4,17 @@ import (
"net/http"
"github.com/containers/libpod/libpod"
"github.com/gorilla/mux"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
// Convenience routines to reduce boiler plate in handlers
func getVar(r *http.Request, k string) string {
return mux.Vars(r)[k]
}
// func hasVar(r *http.Request, k string) bool {
// _, found := mux.Vars(r)[k]
// return found
// }
func getName(r *http.Request) string {
return getVar(r, "name")
}
func decodeQuery(r *http.Request, i interface{}) error {
decoder := r.Context().Value("decoder").(*schema.Decoder)

View File

@ -17,7 +17,7 @@ import (
func HistoryImage(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
var allHistory []HistoryResponse
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
@ -49,7 +49,7 @@ func TagImage(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
// /v1.xx/images/(name)/tag
name := mux.Vars(r)["name"]
name := utils.GetName(r)
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
utils.ImageNotFound(w, name, errors.Wrapf(err, "Failed to find image %s", name))
@ -92,7 +92,7 @@ func RemoveImage(w http.ResponseWriter, r *http.Request) {
utils.UnSupportedParameter("noprune")
}
}
name := mux.Vars(r)["name"]
name := utils.GetName(r)
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
utils.ImageNotFound(w, name, errors.Wrapf(err, "Failed to find image %s", name))

View File

@ -9,7 +9,6 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/gorilla/mux"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
@ -20,7 +19,7 @@ func StopContainer(w http.ResponseWriter, r *http.Request) {
func ContainerExists(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
_, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)
@ -105,7 +104,7 @@ func GetContainer(w http.ResponseWriter, r *http.Request) {
return
}
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
container, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)
@ -147,7 +146,7 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
func UnmountContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
conn, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)
@ -163,7 +162,7 @@ func UnmountContainer(w http.ResponseWriter, r *http.Request) {
}
func MountContainer(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
conn, err := runtime.LookupContainer(name)
if err != nil {
utils.ContainerNotFound(w, name, err)

View File

@ -5,15 +5,11 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/gorilla/mux"
)
func RunHealthCheck(w http.ResponseWriter, r *http.Request) {
// 200 ok
// 404 no such
// 500 internal
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
status, err := runtime.HealthCheck(name)
if err != nil {
if status == libpod.HealthCheckContainerNotFound {

View File

@ -11,7 +11,6 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/gorilla/mux"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
@ -28,11 +27,8 @@ import (
// create
func ImageExists(w http.ResponseWriter, r *http.Request) {
// 200 ok
// 404 no such
// 500 internal
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
_, err := runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
@ -45,7 +41,7 @@ func ImageExists(w http.ResponseWriter, r *http.Request) {
func ImageTree(w http.ResponseWriter, r *http.Request) {
// tree is a bit of a mess ... logic is in adapter and therefore not callable from here. needs rework
// name := mux.Vars(r)["name"]
// name := utils.GetName(r)
// _, layerInfoMap, _, err := s.Runtime.Tree(name)
// if err != nil {
// Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "Failed to find image information for %q", name))
@ -57,7 +53,7 @@ func ImageTree(w http.ResponseWriter, r *http.Request) {
}
func GetImage(w http.ResponseWriter, r *http.Request) {
name := mux.Vars(r)["name"]
name := utils.GetName(r)
newImage, err := handlers.GetImage(r, name)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "Failed to find image %s", name))
@ -160,7 +156,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to close tempfile"))
return
}
name := mux.Vars(r)["name"]
name := utils.GetName(r)
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
utils.ImageNotFound(w, name, err)

View File

@ -0,0 +1,85 @@
package libpod
import (
"net/http"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/containers/libpod/pkg/network"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
func CreateNetwork(w http.ResponseWriter, r *http.Request) {}
func ListNetworks(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
config, err := runtime.GetConfig()
if err != nil {
utils.InternalServerError(w, err)
return
}
configDir := config.CNIConfigDir
if len(configDir) < 1 {
configDir = network.CNIConfigDir
}
networks, err := network.LoadCNIConfsFromDir(configDir)
if err != nil {
utils.InternalServerError(w, err)
return
}
utils.WriteResponse(w, http.StatusOK, networks)
}
func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
// 200 ok
// 404 no such
// 500 internal
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
Force bool `schema:"force"`
}{
// override any golang type defaults
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
return
}
name := utils.GetName(r)
if err := network.RemoveNetwork(name); err != nil {
// If the network cannot be found, we return a 404.
if errors.Cause(err) == network.ErrNetworkNotFound {
utils.Error(w, "Something went wrong", http.StatusNotFound, err)
return
}
utils.InternalServerError(w, err)
return
}
utils.WriteResponse(w, http.StatusOK, "")
}
func InspectNetwork(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
Force bool `schema:"force"`
}{
// override any golang type defaults
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
return
}
name := utils.GetName(r)
n, err := network.InspectNetwork(name)
if err != nil {
// If the network cannot be found, we return a 404.
if errors.Cause(err) == network.ErrNetworkNotFound {
utils.Error(w, "Something went wrong", http.StatusNotFound, err)
return
}
utils.InternalServerError(w, err)
return
}
utils.WriteResponse(w, http.StatusOK, n)
}

View File

@ -19,8 +19,6 @@ import (
)
func PodCreate(w http.ResponseWriter, r *http.Request) {
// 200 ok
// 500 internal
var (
runtime = r.Context().Value("runtime").(*libpod.Runtime)
options []libpod.PodCreateOption
@ -141,7 +139,7 @@ func Pods(w http.ResponseWriter, r *http.Request) {
func PodInspect(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
if err != nil {
utils.PodNotFound(w, name, err)
@ -156,10 +154,6 @@ func PodInspect(w http.ResponseWriter, r *http.Request) {
}
func PodStop(w http.ResponseWriter, r *http.Request) {
// 200
// 304 not modified
// 404 no such
// 500 internal
var (
stopError error
runtime = r.Context().Value("runtime").(*libpod.Runtime)
@ -177,7 +171,7 @@ func PodStop(w http.ResponseWriter, r *http.Request) {
return
}
allContainersStopped := true
name := mux.Vars(r)["name"]
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
if err != nil {
utils.PodNotFound(w, name, err)
@ -224,7 +218,7 @@ func PodStop(w http.ResponseWriter, r *http.Request) {
func PodStart(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
allContainersRunning := true
name := mux.Vars(r)["name"]
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
if err != nil {
utils.PodNotFound(w, name, err)
@ -278,7 +272,7 @@ func PodDelete(w http.ResponseWriter, r *http.Request) {
errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
return
}
name := mux.Vars(r)["name"]
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
if err != nil {
utils.PodNotFound(w, name, err)
@ -293,7 +287,7 @@ func PodDelete(w http.ResponseWriter, r *http.Request) {
func PodRestart(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
if err != nil {
utils.PodNotFound(w, name, err)
@ -321,7 +315,7 @@ func PodPrune(w http.ResponseWriter, r *http.Request) {
func PodPause(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
if err != nil {
utils.PodNotFound(w, name, err)
@ -336,11 +330,8 @@ func PodPause(w http.ResponseWriter, r *http.Request) {
}
func PodUnpause(w http.ResponseWriter, r *http.Request) {
// 200 ok
// 404 no such
// 500 internal
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
if err != nil {
utils.PodNotFound(w, name, err)
@ -379,7 +370,7 @@ func PodKill(w http.ResponseWriter, r *http.Request) {
if err != nil {
utils.InternalServerError(w, errors.Wrapf(err, "unable to parse signal value"))
}
name := mux.Vars(r)["name"]
name := utils.GetName(r)
pod, err := runtime.LookupPod(name)
if err != nil {
utils.PodNotFound(w, name, err)
@ -412,7 +403,7 @@ func PodKill(w http.ResponseWriter, r *http.Request) {
func PodExists(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
_, err := runtime.LookupPod(name)
if err != nil {
utils.PodNotFound(w, name, err)

View File

@ -8,15 +8,12 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/api/handlers"
"github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/gorilla/mux"
"github.com/gorilla/schema"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
func CreateVolume(w http.ResponseWriter, r *http.Request) {
// 200 ok
// 500 internal
var (
volumeOptions []libpod.VolumeCreateOption
runtime = r.Context().Value("runtime").(*libpod.Runtime)
@ -66,7 +63,7 @@ func InspectVolume(w http.ResponseWriter, r *http.Request) {
var (
runtime = r.Context().Value("runtime").(*libpod.Runtime)
)
name := mux.Vars(r)["name"]
name := utils.GetName(r)
vol, err := runtime.GetVolume(name)
if err != nil {
utils.VolumeNotFound(w, name, err)
@ -132,7 +129,7 @@ func RemoveVolume(w http.ResponseWriter, r *http.Request) {
errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
return
}
name := mux.Vars(r)["name"]
name := utils.GetName(r)
vol, err := runtime.LookupVolume(name)
if err != nil {
utils.VolumeNotFound(w, name, err)

View File

@ -9,7 +9,6 @@ import (
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/gorilla/mux"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
@ -26,7 +25,7 @@ func KillContainer(w http.ResponseWriter, r *http.Request) (*libpod.Container, e
Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
return nil, err
}
name := mux.Vars(r)["name"]
name := GetName(r)
con, err := runtime.LookupContainer(name)
if err != nil {
ContainerNotFound(w, name, err)
@ -54,7 +53,7 @@ func KillContainer(w http.ResponseWriter, r *http.Request) (*libpod.Container, e
func RemoveContainer(w http.ResponseWriter, r *http.Request, force, vols bool) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
name := mux.Vars(r)["name"]
name := GetName(r)
con, err := runtime.LookupContainer(name)
if err != nil {
ContainerNotFound(w, name, err)
@ -87,7 +86,7 @@ func WaitContainer(w http.ResponseWriter, r *http.Request) (int32, error) {
UnSupportedParameter("condition")
}
name := mux.Vars(r)["name"]
name := GetName(r)
con, err := runtime.LookupContainer(name)
if err != nil {
ContainerNotFound(w, name, err)

View File

@ -3,11 +3,14 @@ package utils
import (
"encoding/json"
"fmt"
"github.com/pkg/errors"
"io"
"net/http"
"net/url"
"os"
"strings"
"github.com/gorilla/mux"
"github.com/sirupsen/logrus"
)
@ -59,3 +62,18 @@ func FilterMapToString(filters map[string][]string) (string, error) {
}
return string(f), nil
}
func getVar(r *http.Request, k string) string {
val := mux.Vars(r)[k]
safeVal, err := url.PathUnescape(val)
if err != nil {
logrus.Error(errors.Wrapf(err, "failed to unescape mux key %s, value %s", k, val))
return val
}
return safeVal
}
// GetName extracts the name from the mux
func GetName(r *http.Request) string {
return getVar(r, "name")
}

View File

@ -63,8 +63,7 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
listener = &listeners[0]
}
router := mux.NewRouter()
router := mux.NewRouter().UseEncodedPath()
server := APIServer{
Server: http.Server{
Handler: router,

View File

@ -116,7 +116,7 @@ func (c *Connection) DoRequest(httpBody io.Reader, httpMethod, endpoint string,
safePathValues := make([]interface{}, len(pathValues))
// Make sure path values are http url safe
for i, pv := range pathValues {
safePathValues[i] = url.QueryEscape(pv)
safePathValues[i] = url.PathEscape(pv)
}
// Lets eventually use URL for this which might lead to safer
// usage

View File

@ -67,10 +67,10 @@ var _ = Describe("Podman images", func() {
// Inspect with partial ID
_, err = images.GetImage(connText, data.ID[0:12], nil)
Expect(err).To(BeNil())
// Inspect by ID
//Inspect by long name should work, it doesnt (yet) i think it needs to be html escaped
//_, err = images.GetImage(connText, alpine, nil)
//Expect(err).To(BeNil())
_, err = images.GetImage(connText, alpine, nil)
Expect(err).To(BeNil())
})
It("remove image", func() {
// Remove invalid image should be a 404