mirror of
https://github.com/containers/podman.git
synced 2025-12-12 01:38:04 +08:00
Add GET /quadlets/{name}/file
Fixes: https://issues.redhat.com/browse/RUN-3716 Signed-off-by: Nicola Sella <nsella@redhat.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/containers/podman/v6/pkg/domain/entities"
|
"github.com/containers/podman/v6/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v6/pkg/domain/infra/abi"
|
"github.com/containers/podman/v6/pkg/domain/infra/abi"
|
||||||
"github.com/containers/podman/v6/pkg/util"
|
"github.com/containers/podman/v6/pkg/util"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ListQuadlets(w http.ResponseWriter, r *http.Request) {
|
func ListQuadlets(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -35,3 +36,23 @@ func ListQuadlets(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
utils.WriteResponse(w, http.StatusOK, quadlets)
|
utils.WriteResponse(w, http.StatusOK, quadlets)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetQuadletPrint(w http.ResponseWriter, r *http.Request) {
|
||||||
|
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
|
||||||
|
name := utils.GetName(r)
|
||||||
|
|
||||||
|
containerEngine := abi.ContainerEngine{Libpod: runtime}
|
||||||
|
|
||||||
|
quadletContents, err := containerEngine.QuadletPrint(r.Context(), name)
|
||||||
|
if err != nil {
|
||||||
|
utils.Error(w, http.StatusNotFound, fmt.Errorf("no such quadlet: %s: %w", name, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "text/plain")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
if _, err := w.Write([]byte(quadletContents)); err != nil {
|
||||||
|
logrus.Errorf("Failed to write quadlet contents: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -79,6 +79,13 @@ type podNotFound struct {
|
|||||||
Body errorhandling.ErrorModel
|
Body errorhandling.ErrorModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No such quadlet
|
||||||
|
// swagger:response
|
||||||
|
type quadletNotFound struct {
|
||||||
|
// in:body
|
||||||
|
Body errorhandling.ErrorModel
|
||||||
|
}
|
||||||
|
|
||||||
// No such manifest
|
// No such manifest
|
||||||
// swagger:response
|
// swagger:response
|
||||||
type manifestNotFound struct {
|
type manifestNotFound struct {
|
||||||
|
|||||||
@@ -527,3 +527,10 @@ type quadletListResponse struct {
|
|||||||
// in:body
|
// in:body
|
||||||
Body []entities.ListQuadlet
|
Body []entities.ListQuadlet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quadlet file
|
||||||
|
// swagger:response
|
||||||
|
type quadletFileResponse struct {
|
||||||
|
// in:body
|
||||||
|
Body string
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,5 +32,27 @@ func (s *APIServer) registerQuadletHandlers(r *mux.Router) error {
|
|||||||
// 500:
|
// 500:
|
||||||
// $ref: "#/responses/internalError"
|
// $ref: "#/responses/internalError"
|
||||||
r.HandleFunc(VersionedPath("/libpod/quadlets/json"), s.APIHandler(libpod.ListQuadlets)).Methods(http.MethodGet)
|
r.HandleFunc(VersionedPath("/libpod/quadlets/json"), s.APIHandler(libpod.ListQuadlets)).Methods(http.MethodGet)
|
||||||
|
// swagger:operation GET /libpod/quadlets/{name}/file libpod QuadletFileLibpod
|
||||||
|
// ---
|
||||||
|
// tags:
|
||||||
|
// - quadlets
|
||||||
|
// summary: Get quadlet file
|
||||||
|
// description: Get the contents of a Quadlet, displaying the file including all comments
|
||||||
|
// produces:
|
||||||
|
// - text/plain
|
||||||
|
// parameters:
|
||||||
|
// - in: path
|
||||||
|
// name: name
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// description: the name of the quadlet with extension (e.g., "myapp.container")
|
||||||
|
// responses:
|
||||||
|
// 200:
|
||||||
|
// $ref: "#/responses/quadletFileResponse"
|
||||||
|
// 404:
|
||||||
|
// $ref: "#/responses/quadletNotFound"
|
||||||
|
// 500:
|
||||||
|
// $ref: "#/responses/internalError"
|
||||||
|
r.HandleFunc(VersionedPath("/libpod/quadlets/{name}/file"), s.APIHandler(libpod.GetQuadletPrint)).Methods(http.MethodGet)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,60 @@
|
|||||||
# NOTE: Once podman-remote quadlet support is added we can enable the podman quadlet tests in
|
# NOTE: Once podman-remote quadlet support is added we can enable the podman quadlet tests in
|
||||||
# test/system/253-podman-quadlet.bats which should cover it in more detail then.
|
# test/system/253-podman-quadlet.bats which should cover it in more detail then.
|
||||||
|
|
||||||
## list volume
|
## Test list endpoint
|
||||||
t GET libpod/quadlets/json 200
|
t GET libpod/quadlets/json 200
|
||||||
|
|
||||||
# Example with filter applied (uncomment once needed)
|
# Test 404 for non-existent quadlet
|
||||||
# t GET libpod/quadlets/json?filters='{"name":["name.*"]}' 200
|
t GET libpod/quadlets/nonexistent.container 404
|
||||||
|
|
||||||
|
# Install a quadlet with a unique name
|
||||||
|
quadlet_name=quadlet-test-$(cat /proc/sys/kernel/random/uuid)
|
||||||
|
|
||||||
|
quadlet_container_name="$quadlet_name.container"
|
||||||
|
quadlet_build_name="$quadlet_name.build"
|
||||||
|
|
||||||
|
TMPDIR=$(mktemp -d podman-apiv2-test.quadlet.XXXXXXXX)
|
||||||
|
|
||||||
|
quadlet_container_file_content=$(cat << EOF
|
||||||
|
[Container]
|
||||||
|
Image=$IMAGE
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
quadlet_build_file_content=$(cat << EOF
|
||||||
|
[Build]
|
||||||
|
ImageTag=localhost/$quadlet_name
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "$quadlet_container_file_content" > $TMPDIR/$quadlet_container_name
|
||||||
|
echo "$quadlet_build_file_content" > $TMPDIR/$quadlet_build_name
|
||||||
|
|
||||||
|
# this should ensure the .config/containers/systemd directory is created
|
||||||
|
podman quadlet install $TMPDIR/$quadlet_container_name
|
||||||
|
podman quadlet install $TMPDIR/$quadlet_build_name
|
||||||
|
|
||||||
|
filter_param=$(printf '{"name":["%s"]}' "$quadlet_name")
|
||||||
|
t GET "libpod/quadlets/json?filters=$filter_param" 200 \
|
||||||
|
length=2 \
|
||||||
|
.[0].Name="$quadlet_build_name" \
|
||||||
|
.[1].Name="$quadlet_container_name"
|
||||||
|
|
||||||
|
filter_param=$(printf '{"name":["%s"]}' "$quadlet_container_name")
|
||||||
|
t GET "libpod/quadlets/json?filters=$filter_param" 200 \
|
||||||
|
length=1 \
|
||||||
|
.[0].Name="$quadlet_container_name"
|
||||||
|
|
||||||
|
t GET "libpod/quadlets/$quadlet_name/file" 404
|
||||||
|
|
||||||
|
t GET "libpod/quadlets/$quadlet_container_name/file" 200
|
||||||
|
is "$output" "$quadlet_container_file_content"
|
||||||
|
|
||||||
|
t GET "libpod/quadlets/$quadlet_build_name/file" 200
|
||||||
|
is "$output" "$quadlet_build_file_content"
|
||||||
|
|
||||||
|
podman quadlet rm $quadlet_container_name
|
||||||
|
podman quadlet rm $quadlet_build_name
|
||||||
|
rm -rf $TMPDIR
|
||||||
|
|
||||||
# vim: filetype=sh
|
# vim: filetype=sh
|
||||||
|
|||||||
Reference in New Issue
Block a user