cmd/list, pkg/podman: Don't unmarshal the 'podman images' JSON twice

This builds on top of commit e772207831.

Currently, the JSON from 'podman images --format json' gets unmarshalled
into a []map[string]interface{} in podman.GetImages, where the maps in
the slice represent images.  Each map is then marshalled back into JSON
and then again unmarshalled into a toolboxImage type.

This is wasteful.  The toolboxImage type already implements the
json.Unmarshaler interface [1], since commit e772207831.  Hence,
the entire JSON from 'podman images --format json' can be directly
unmarshalled into a slice of toolboxImages without involving the
[]map[string]interface{}.

A subsequent commit will move the toolboxImage type into the podman
package to more tightly encapsulate the unmarshalling of the JSON.  So,
as an intermediate step in that direction, the podman.GetImages function
has been temporarily changed to return the entire JSON.

[1] https://pkg.go.dev/encoding/json#Unmarshaler

https://github.com/containers/toolbox/pull/1190
This commit is contained in:
Debarshi Ray 2022-12-06 00:25:23 +01:00
parent aeb5d8ec1a
commit 2486e25601
2 changed files with 14 additions and 28 deletions

View file

@ -190,32 +190,24 @@ func listHelp(cmd *cobra.Command, args []string) {
func getImages() ([]toolboxImage, error) {
logrus.Debug("Fetching all images")
args := []string{"--sort", "repository"}
images, err := podman.GetImages(args...)
data, err := podman.GetImagesJSON(args...)
if err != nil {
logrus.Debugf("Fetching all images failed: %s", err)
return nil, errors.New("failed to get images")
}
var images []toolboxImage
if err := json.Unmarshal(data, &images); err != nil {
logrus.Debugf("Fetching all images failed: %s", err)
return nil, errors.New("failed to get images")
}
var toolboxImages []toolboxImage
for _, image := range images {
var i toolboxImage
imageJSON, err := json.Marshal(image)
if err != nil {
logrus.Errorf("failed to marshal toolbox image: %v", err)
continue
}
err = i.UnmarshalJSON(imageJSON)
if err != nil {
logrus.Errorf("failed to unmarshal toolbox image: %v", err)
continue
}
for label := range toolboxLabels {
if _, ok := i.Labels[label]; ok {
toolboxImages = append(toolboxImages, i)
if _, ok := image.Labels[label]; ok {
toolboxImages = append(toolboxImages, image)
break
}
}

View file

@ -95,14 +95,14 @@ func GetContainers(args ...string) ([]map[string]interface{}, error) {
return containers, nil
}
// GetImages is a wrapper function around `podman images --format json` command.
// GetImagesJSON is a wrapper function around `podman images --format json` command.
//
// Parameter args accepts an array of strings to be passed to the wrapped command (eg. ["-a", "--filter", "123"]).
//
// Returned value is a slice of dynamically unmarshalled json, so it needs to be treated properly.
// Returned value is the JSON representing the images.
//
// If a problem happens during execution, first argument is nil and second argument holds the error message.
func GetImages(args ...string) ([]map[string]interface{}, error) {
func GetImagesJSON(args ...string) ([]byte, error) {
var stdout bytes.Buffer
logLevelString := LogLevel.String()
@ -111,14 +111,8 @@ func GetImages(args ...string) ([]map[string]interface{}, error) {
return nil, err
}
output := stdout.Bytes()
var images []map[string]interface{}
if err := json.Unmarshal(output, &images); err != nil {
return nil, err
}
return images, nil
data := stdout.Bytes()
return data, nil
}
// GetVersion returns version of Podman in a string