From 687ac7f615d7bb5294c5d35aabe45567e53b1fbe Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Wed, 17 Feb 2021 18:58:20 +0000 Subject: [PATCH] weldr/compose/ostree: introduce URL parameter For now this is simply used to resolve the parent commit, in case one is not provided. In the future it will be used by new image types to actually pull content from. This extends the weldr API, so that future work does not have to modify that. The logic we now implement for the ostree commit image types is: If the URL is provided, but the parent commit is not. The parent commit is taken to be the current HEAD of the ostree repo at the given url, with the given (or default) ref. This only provides a small optional convenience, but we will soon introduce image types where the URL of the repository is required. This commit still needs testing. Signed-off-by: Tom Gundersen --- internal/weldr/api.go | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/internal/weldr/api.go b/internal/weldr/api.go index a8da9eabe..dd17dfcab 100644 --- a/internal/weldr/api.go +++ b/internal/weldr/api.go @@ -4,6 +4,7 @@ import ( "archive/tar" "bytes" "crypto/rand" + "encoding/hex" "encoding/json" errors_package "errors" "fmt" @@ -1798,6 +1799,36 @@ func (api *API) blueprintsTagHandler(writer http.ResponseWriter, request *http.R statusResponseOK(writer) } +func ostreeResolveRef(location, ref string) (string, error) { + u, err := url.Parse(location) + if err != nil { + return "", err + } + u, err = u.Parse("refs/heads/") + if err != nil { + return "", err + } + u, err = u.Parse(ref) + if err != nil { + return "", err + } + resp, err := http.Get(u.String()) + if err != nil { + return "", err + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + parent := strings.TrimSpace(string(body)) + // Check that this is at least a hex string. + _, err = hex.DecodeString(parent) + if err != nil { + return "", err + } + return parent, nil +} + // Schedule new compose by first translating the appropriate blueprint into a pipeline and then // pushing it into the channel for waiting builds. func (api *API) composeHandler(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { @@ -1806,6 +1837,7 @@ func (api *API) composeHandler(writer http.ResponseWriter, request *http.Request } type OSTreeRequest struct { + URL string `json:"url"` Ref string `json:"ref"` Parent string `json:"parent"` } @@ -1883,6 +1915,31 @@ func (api *API) composeHandler(writer http.ResponseWriter, request *http.Request return } + // Fetch parent ostree commit from ref + url if commit is not + // provided. The parameter name "parent" is perhaps slightly misleading + // as it represent whatever commit sha the image type requires, not + // strictly speaking just the parent commit. + if cr.OSTree.Ref != "" && cr.OSTree.URL != "" { + if cr.OSTree.Parent != "" { + errors := responseError{ + ID: "OSTreeOptionsError", + Msg: "Supply at most one of Parent and URL", + } + statusResponseError(writer, http.StatusBadRequest, errors) + return + } + parent, err := ostreeResolveRef(cr.OSTree.URL, cr.OSTree.Ref) + if err != nil { + errors := responseError{ + ID: "OSTreeCommitError", + Msg: err.Error(), + } + statusResponseError(writer, http.StatusBadRequest, errors) + return + } + cr.OSTree.Parent = parent + } + packages, buildPackages, err := api.depsolveBlueprint(bp, imageType) if err != nil { errors := responseError{