Merge pull request #10548 from cdoern/imgFeature

API images/create added missing parameters platform, message, repo
This commit is contained in:
OpenShift Merge Robot
2021-06-08 17:44:02 +02:00
committed by GitHub
3 changed files with 52 additions and 7 deletions

View File

@ -168,6 +168,8 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
query := struct { query := struct {
FromSrc string `schema:"fromSrc"` FromSrc string `schema:"fromSrc"`
Changes []string `schema:"changes"` Changes []string `schema:"changes"`
Message string `schema:"message"`
Repo string `shchema:"repo"`
}{ }{
// 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
} }
@ -184,14 +186,15 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to create tempfile")) utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to create tempfile"))
return return
} }
source = f.Name() source = f.Name()
if err := SaveFromBody(f, r); err != nil { if err := SaveFromBody(f, r); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file")) utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file"))
} }
} }
imageEngine := abi.ImageEngine{Libpod: runtime} imageEngine := abi.ImageEngine{Libpod: runtime}
report, err := imageEngine.Import(r.Context(), entities.ImageImportOptions{Source: source, Changes: query.Changes}) // TODO: add support for ImageImportOptions to take a platform parameter. Also import https://github.com/opencontainers/image-spec/tree/master/specs-go/v1 either here or within imageEngine.Import to get default platform
report, err := imageEngine.Import(r.Context(), entities.ImageImportOptions{Source: source, Changes: query.Changes, Message: query.Message, Reference: query.Repo})
if err != nil { if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to import tarball")) utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "unable to import tarball"))
return return
@ -224,10 +227,10 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
query := struct { query := struct {
FromImage string `schema:"fromImage"` FromImage string `schema:"fromImage"`
Tag string `schema:"tag"` Tag string `schema:"tag"`
Platform string `schema:"platform"`
}{ }{
// 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
} }
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return return
@ -250,12 +253,36 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
} }
defer auth.RemoveAuthfile(authfile) defer auth.RemoveAuthfile(authfile)
platformSpecs := strings.Split(query.Platform, "/") // split query into its parts
addOS := true // default assume true due to structure of if/else below
addArch := false
addVariant := false
if len(platformSpecs) > 1 { // if we have two arguments then we have os and arch
addArch = true
if len(platformSpecs) > 2 { // if we have 3 arguments then we have os arch and variant
addVariant = true
}
} else if len(platformSpecs) == 0 {
addOS = false
}
pullOptions := &libimage.PullOptions{} pullOptions := &libimage.PullOptions{}
pullOptions.AuthFilePath = authfile pullOptions.AuthFilePath = authfile
if authConf != nil { if authConf != nil {
pullOptions.Username = authConf.Username pullOptions.Username = authConf.Username
pullOptions.Password = authConf.Password pullOptions.Password = authConf.Password
pullOptions.IdentityToken = authConf.IdentityToken pullOptions.IdentityToken = authConf.IdentityToken
if addOS { // if the len is not 0
pullOptions.OS = platformSpecs[0]
if addArch {
pullOptions.Architecture = platformSpecs[1]
}
if addVariant {
pullOptions.Variant = platformSpecs[2]
}
}
} }
pullOptions.Writer = os.Stderr // allows for debugging on the server pullOptions.Writer = os.Stderr // allows for debugging on the server
@ -294,7 +321,6 @@ loop: // break out of for/select infinite loop
Error string `json:"error,omitempty"` Error string `json:"error,omitempty"`
Id string `json:"id,omitempty"` // nolint Id string `json:"id,omitempty"` // nolint
} }
select { select {
case e := <-progress: case e := <-progress:
switch e.Event { switch e.Event {

View File

@ -28,15 +28,28 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// - in: query // - in: query
// name: fromImage // name: fromImage
// type: string // type: string
// description: needs description // description: Name of the image to pull. The name may include a tag or digest. This parameter may only be used when pulling an image. The pull is cancelled if the HTTP connection is closed.
// - in: query // - in: query
// name: fromSrc // name: fromSrc
// type: string // type: string
// description: needs description // description: Source to import. The value may be a URL from which the image can be retrieved or - to read the image from the request body. This parameter may only be used when importing an image
// - in: query
// name: repo
// type: string
// description: Repository name given to an image when it is imported. The repo may include a tag. This parameter may only be used when importing an image.
// - in: query // - in: query
// name: tag // name: tag
// type: string // type: string
// description: needs description // description: Tag or digest. If empty when pulling an image, this causes all tags for the given image to be pulled.
// - in: query
// name: message
// type: string
// description: Set commit message for imported image.
// - in: query
// name: platform
// type: string
// description: Platform in the format os[/arch[/variant]]
// default: ""
// - in: header // - in: header
// name: X-Registry-Auth // name: X-Registry-Auth
// type: string // type: string
@ -45,6 +58,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// name: request // name: request
// schema: // schema:
// type: string // type: string
// format: binary
// description: Image content if fromSrc parameter was used // description: Image content if fromSrc parameter was used
// responses: // responses:
// 200: // 200:

View File

@ -86,6 +86,11 @@ class ImageTestCase(APITestCase):
self.assertTrue(keys["id"], "Expected to find id stanza") self.assertTrue(keys["id"], "Expected to find id stanza")
self.assertTrue(keys["images"], "Expected to find images stanza") self.assertTrue(keys["images"], "Expected to find images stanza")
self.assertTrue(keys["stream"], "Expected to find stream progress stanza's") self.assertTrue(keys["stream"], "Expected to find stream progress stanza's")
def test_create(self):
r = requests.post(self.podman_url + "/v1.40/images/create?fromImage=alpine&platform=linux/amd64/v8", timeout=15)
self.assertEqual(r.status_code, 200, r.text)
r = requests.post(self.podman_url + "/v1.40/images/create?fromSrc=-&repo=fedora&message=testing123", timeout=15)
self.assertEqual(r.status_code, 200, r.text)
def test_search_compat(self): def test_search_compat(self):
url = self.podman_url + "/v1.40/images/search" url = self.podman_url + "/v1.40/images/search"