Skip to content

Instantly share code, notes, and snippets.

@troyready
Last active March 9, 2021 00:06
Show Gist options
  • Save troyready/9779eb8b4be32325fd5566e4994202f9 to your computer and use it in GitHub Desktop.
Save troyready/9779eb8b4be32325fd5566e4994202f9 to your computer and use it in GitHub Desktop.
podman patches for debian bullseye (f4ece018 for images_push & #9589 for login)
diff -Naur libpod-3.0.1+dfsg1/pkg/api/handlers/compat/auth.go libpod-3.0.1+dfsg1-patched/pkg/api/handlers/compat/auth.go
--- libpod-3.0.1+dfsg1/pkg/api/handlers/compat/auth.go 1969-12-31 16:00:00.000000000 -0800
+++ libpod-3.0.1+dfsg1-patched/pkg/api/handlers/compat/auth.go 2021-03-08 15:59:36.566483940 -0800
@@ -0,0 +1,51 @@
+package compat
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "strings"
+
+ DockerClient "github.com/containers/image/v5/docker"
+ "github.com/containers/image/v5/types"
+ "github.com/containers/podman/v2/pkg/api/handlers/utils"
+ "github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/registries"
+ docker "github.com/docker/docker/api/types"
+ "github.com/pkg/errors"
+)
+
+func Auth(w http.ResponseWriter, r *http.Request) {
+ var authConfig docker.AuthConfig
+ err := json.NewDecoder(r.Body).Decode(&authConfig)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to parse request"))
+ return
+ }
+
+ skipTLS := types.NewOptionalBool(false)
+ if strings.HasPrefix(authConfig.ServerAddress, "http://localhost/") || strings.HasPrefix(authConfig.ServerAddress, "http://localhost:") {
+ // support for local testing
+ skipTLS = types.NewOptionalBool(true)
+ }
+
+ fmt.Println("Authenticating with existing credentials...")
+ sysCtx := types.SystemContext{
+ AuthFilePath: "",
+ DockerCertPath: "",
+ DockerInsecureSkipTLSVerify: skipTLS,
+ SystemRegistriesConfPath: registries.SystemRegistriesConfPath(),
+ }
+ if err := DockerClient.CheckAuth(context.Background(), &sysCtx, authConfig.Username, authConfig.Password, authConfig.ServerAddress); err == nil {
+ utils.WriteResponse(w, http.StatusOK, entities.AuthReport{
+ IdentityToken: "",
+ Status: "Login Succeeded",
+ })
+ } else {
+ utils.WriteResponse(w, http.StatusBadRequest, entities.AuthReport{
+ IdentityToken: "",
+ Status: "login attempt to " + authConfig.ServerAddress + " failed with status: " + err.Error(),
+ })
+ }
+}
diff -Naur libpod-3.0.1+dfsg1/pkg/api/handlers/compat/images_push.go libpod-3.0.1+dfsg1-patched/pkg/api/handlers/compat/images_push.go
--- libpod-3.0.1+dfsg1/pkg/api/handlers/compat/images_push.go 2021-02-18 12:15:25.000000000 -0800
+++ libpod-3.0.1+dfsg1-patched/pkg/api/handlers/compat/images_push.go 2021-03-08 15:57:30.898060892 -0800
@@ -1,10 +1,12 @@
package compat
import (
- "context"
+ "fmt"
+ "io/ioutil"
"net/http"
"strings"
+ "github.com/containers/image/v5/types"
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/auth"
@@ -19,6 +21,14 @@
func PushImage(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
runtime := r.Context().Value("runtime").(*libpod.Runtime)
+
+ digestFile, err := ioutil.TempFile("", "digest.txt")
+ if err != nil {
+ utils.Error(w, "unable to create digest tempfile", http.StatusInternalServerError, errors.Wrap(err, "unable to create tempfile"))
+ return
+ }
+ defer digestFile.Close()
+
// Now use the ABI implementation to prevent us from having duplicate
// code.
imageEngine := abi.ImageEngine{Libpod: runtime}
@@ -27,8 +37,9 @@
All bool `schema:"all"`
Compress bool `schema:"compress"`
Destination string `schema:"destination"`
- Tag string `schema:"tag"`
+ Format string `schema:"format"`
TLSVerify bool `schema:"tlsVerify"`
+ Tag string `schema:"tag"`
}{
// This is where you can override the golang default value for one of fields
TLSVerify: true,
@@ -64,13 +75,26 @@
password = authconf.Password
}
options := entities.ImagePushOptions{
- All: query.All,
- Authfile: authfile,
- Compress: query.Compress,
- Username: username,
- Password: password,
+ All: query.All,
+ Authfile: authfile,
+ Compress: query.Compress,
+ Format: query.Format,
+ Password: password,
+ Username: username,
+ DigestFile: digestFile.Name(),
+ }
+ if _, found := r.URL.Query()["tlsVerify"]; found {
+ options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
+ }
+
+ var destination string
+ if _, found := r.URL.Query()["destination"]; found {
+ destination = query.Destination
+ } else {
+ destination = imageName
}
- if err := imageEngine.Push(context.Background(), imageName, query.Destination, options); err != nil {
+
+ if err := imageEngine.Push(r.Context(), imageName, destination, options); err != nil {
if errors.Cause(err) != storage.ErrImageUnknown {
utils.ImageNotFound(w, imageName, errors.Wrapf(err, "failed to find image %s", imageName))
return
@@ -80,5 +104,21 @@
return
}
- utils.WriteResponse(w, http.StatusOK, "")
+ digestBytes, err := ioutil.ReadAll(digestFile)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to read digest tmp file"))
+ return
+ }
+
+ tag := query.Tag
+ if tag == "" {
+ tag = "latest"
+ }
+ respData := struct {
+ Status string `json:"status"`
+ }{
+ Status: fmt.Sprintf("%s: digest: %s size: null", tag, string(digestBytes)),
+ }
+
+ utils.WriteJSON(w, http.StatusOK, &respData)
}
diff -Naur libpod-3.0.1+dfsg1/pkg/api/server/register_auth.go libpod-3.0.1+dfsg1-patched/pkg/api/server/register_auth.go
--- libpod-3.0.1+dfsg1/pkg/api/server/register_auth.go 2021-02-18 12:15:25.000000000 -0800
+++ libpod-3.0.1+dfsg1-patched/pkg/api/server/register_auth.go 2021-03-08 16:00:28.598658408 -0800
@@ -1,13 +1,33 @@
package server
import (
+ "net/http"
+
"github.com/containers/podman/v2/pkg/api/handlers/compat"
"github.com/gorilla/mux"
)
func (s *APIServer) registerAuthHandlers(r *mux.Router) error {
- r.Handle(VersionedPath("/auth"), s.APIHandler(compat.UnsupportedHandler))
+ // swagger:operation POST /auth compat auth
+ // ---
+ // summary: Check auth configuration
+ // tags:
+ // - system (compat)
+ // produces:
+ // - application/json
+ // parameters:
+ // - in: body
+ // name: authConfig
+ // description: Authentication to check
+ // schema:
+ // $ref: "#/definitions/AuthConfig"
+ // responses:
+ // 200:
+ // $ref: "#/responses/SystemAuthResponse"
+ // 500:
+ // $ref: "#/responses/InternalError"
+ r.Handle(VersionedPath("/auth"), s.APIHandler(compat.Auth)).Methods(http.MethodPost)
// Added non version path to URI to support docker non versioned paths
- r.Handle("/auth", s.APIHandler(compat.UnsupportedHandler))
+ r.Handle("/auth", s.APIHandler(compat.Auth)).Methods(http.MethodPost)
return nil
}
diff -Naur libpod-3.0.1+dfsg1/pkg/api/server/swagger.go libpod-3.0.1+dfsg1-patched/pkg/api/server/swagger.go
--- libpod-3.0.1+dfsg1/pkg/api/server/swagger.go 2021-02-18 12:15:25.000000000 -0800
+++ libpod-3.0.1+dfsg1-patched/pkg/api/server/swagger.go 2021-03-08 16:00:57.622755571 -0800
@@ -226,3 +226,12 @@
entities.SystemPruneReport
}
}
+
+// Auth response
+// swagger:response SystemAuthResponse
+type swagSystemAuthResponse struct {
+ // in:body
+ Body struct {
+ entities.AuthReport
+ }
+}
diff -Naur libpod-3.0.1+dfsg1/pkg/domain/entities/system.go libpod-3.0.1+dfsg1-patched/pkg/domain/entities/system.go
--- libpod-3.0.1+dfsg1/pkg/domain/entities/system.go 2021-02-18 12:15:25.000000000 -0800
+++ libpod-3.0.1+dfsg1-patched/pkg/domain/entities/system.go 2021-03-08 16:01:26.586852426 -0800
@@ -107,3 +107,14 @@
type ListRegistriesReport struct {
Registries []string
}
+
+// swagger:model AuthConfig
+type AuthConfig struct {
+ types.AuthConfig
+}
+
+// AuthReport describes the response for authentication check
+type AuthReport struct {
+ IdentityToken string
+ Status string
+}
diff -Naur libpod-3.0.1+dfsg1/test/apiv2/rest_api/test_rest_v2_0_0.py libpod-3.0.1+dfsg1-patched/test/apiv2/rest_api/test_rest_v2_0_0.py
--- libpod-3.0.1+dfsg1/test/apiv2/rest_api/test_rest_v2_0_0.py 2021-02-18 12:15:25.000000000 -0800
+++ libpod-3.0.1+dfsg1-patched/test/apiv2/rest_api/test_rest_v2_0_0.py 2021-03-08 16:02:10.879000353 -0800
@@ -513,16 +513,18 @@
self.assertIn(name, payload["VolumesDeleted"])
self.assertGreater(payload["SpaceReclaimed"], 0)
- def test_auth_compat(self):
- r = requests.post(
- PODMAN_URL + "/v1.40/auth",
- json={
- "username": "bozo",
- "password": "wedontneednopasswords",
- "serveraddress": "https://localhost/v1.40/",
- },
- )
- self.assertEqual(r.status_code, 404, r.content)
+ # TBD: how to test auth endpoint (which in turn requires a docker registry to connect to)
+ # def test_auth_compat(self):
+ # r = requests.post(
+ # PODMAN_URL + "/v1.40/auth",
+ # json={
+ # "username": "bozo",
+ # "password": "wedontneednopasswords",
+ # "serveraddress": "https://localhost/v1.40/",
+ # },
+ # )
+ # self.assertEqual(r.status_code, 404, r.content)
+
def test_version(self):
r = requests.get(PODMAN_URL + "/v1.40/version")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment