cmd/list: Filter images/containers using labels
Instead of executing 'podman ps|images' several times in a row, call them only once and get output with all images/containers. Then, filter out the JSON using labels and keep images/containers only with matching labels. This simplifies the code significantly and cuts down the execution time of 'toolbox list'. The speed gain is noticeable: - the system has 5 images and 10 containers Before patch: ~1.45s After patch: ~0.85s
This commit is contained in:
parent
49460ebc56
commit
2369da5d31
1 changed files with 50 additions and 53 deletions
103
src/cmd/list.go
103
src/cmd/list.go
|
@ -51,6 +51,12 @@ var (
|
|||
onlyContainers bool
|
||||
onlyImages bool
|
||||
}
|
||||
|
||||
// toolboxLabels holds labels used by containers/images that mark them as compatible with Toolbox
|
||||
toolboxLabels = map[string]string{
|
||||
"com.github.debarshiray.toolbox": "true",
|
||||
"com.github.containers.toolbox": "true",
|
||||
}
|
||||
)
|
||||
|
||||
var listCmd = &cobra.Command{
|
||||
|
@ -123,35 +129,22 @@ func list(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
func getContainers() ([]toolboxContainer, error) {
|
||||
logrus.Debug("Fetching containers with label=com.github.containers.toolbox=true")
|
||||
args := []string{"--all", "--filter", "label=com.github.containers.toolbox=true"}
|
||||
containers_old, err := podman.GetContainers(args...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list containers with label=com.github.containers.toolbox=true: %w", err)
|
||||
}
|
||||
|
||||
logrus.Debug("Fetching containers with label=com.github.debarshiray.toolbox=true")
|
||||
args = []string{"--all", "--filter", "label=com.github.debarshiray.toolbox=true"}
|
||||
containers_new, err := podman.GetContainers(args...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list containers with label=com.github.debarshiray.toolbox=true: %w", err)
|
||||
}
|
||||
|
||||
var err error
|
||||
var args []string
|
||||
var containers []map[string]interface{}
|
||||
if podman.CheckVersion("2.0.0") {
|
||||
containers = utils.JoinJSON("Id", containers_old, containers_new)
|
||||
containers = utils.SortJSON(containers, "Names", true)
|
||||
} else {
|
||||
containers = utils.JoinJSON("ID", containers_old, containers_new)
|
||||
containers = utils.SortJSON(containers, "Names", false)
|
||||
var toolboxContainers []toolboxContainer
|
||||
|
||||
logrus.Debug("Fetching all containers")
|
||||
args = []string{"--all", "--sort", "names"}
|
||||
containers, err = podman.GetContainers(args...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get containers: %w", err)
|
||||
}
|
||||
|
||||
// This section is a temporary solution that is here to prevent a major
|
||||
// redesign of the way how toolbox containers are fetched.
|
||||
// Remove this in Toolbox v0.2.0
|
||||
var toolboxContainers []toolboxContainer
|
||||
for _, container := range containers {
|
||||
var c toolboxContainer
|
||||
var isToolboxContainer bool = false
|
||||
|
||||
containerJSON, err := json.Marshal(container)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to marshal container: %v", err)
|
||||
|
@ -163,7 +156,17 @@ func getContainers() ([]toolboxContainer, error) {
|
|||
logrus.Errorf("failed to unmarshal container: %v", err)
|
||||
continue
|
||||
}
|
||||
toolboxContainers = append(toolboxContainers, c)
|
||||
|
||||
for label := range toolboxLabels {
|
||||
if _, ok := c.Labels[label]; ok {
|
||||
isToolboxContainer = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if isToolboxContainer {
|
||||
toolboxContainers = append(toolboxContainers, c)
|
||||
}
|
||||
}
|
||||
|
||||
return toolboxContainers, nil
|
||||
|
@ -191,38 +194,22 @@ func listHelp(cmd *cobra.Command, args []string) {
|
|||
}
|
||||
|
||||
func getImages() ([]toolboxImage, error) {
|
||||
logrus.Debug("Fetching images with label=com.github.containers.toolbox=true")
|
||||
args := []string{"--filter", "label=com.github.containers.toolbox=true"}
|
||||
images_old, err := podman.GetImages(args...)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to list images with label=com.github.containers.toolbox=true")
|
||||
}
|
||||
|
||||
logrus.Debug("Fetching images with label=com.github.debarshiray.toolbox=true")
|
||||
args = []string{"--filter", "label=com.github.debarshiray.toolbox=true"}
|
||||
images_new, err := podman.GetImages(args...)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to list images with com.github.debarshiray.toolbox=true")
|
||||
}
|
||||
|
||||
var err error
|
||||
var args []string
|
||||
var images []map[string]interface{}
|
||||
if podman.CheckVersion("2.0.0") {
|
||||
images = utils.JoinJSON("Id", images_old, images_new)
|
||||
images = utils.SortJSON(images, "Names", true)
|
||||
} else if podman.CheckVersion("1.8.3") {
|
||||
images = utils.JoinJSON("ID", images_old, images_new)
|
||||
images = utils.SortJSON(images, "Names", true)
|
||||
} else {
|
||||
images = utils.JoinJSON("id", images_old, images_new)
|
||||
images = utils.SortJSON(images, "names", true)
|
||||
var toolboxImages []toolboxImage
|
||||
|
||||
logrus.Debug("Fetching all images")
|
||||
args = []string{"--sort", "repository"}
|
||||
images, err = podman.GetImages(args...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get images: %w", err)
|
||||
}
|
||||
|
||||
// This section is a temporary solution that is here to prevent a major
|
||||
// redesign of the way how toolbox images are fetched.
|
||||
// Remove this in Toolbox v0.2.0
|
||||
var toolboxImages []toolboxImage
|
||||
for _, image := range images {
|
||||
var i toolboxImage
|
||||
var isToolboxImage bool = false
|
||||
|
||||
imageJSON, err := json.Marshal(image)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to marshal toolbox image: %v", err)
|
||||
|
@ -234,7 +221,17 @@ func getImages() ([]toolboxImage, error) {
|
|||
logrus.Errorf("failed to unmarshal toolbox image: %v", err)
|
||||
continue
|
||||
}
|
||||
toolboxImages = append(toolboxImages, i)
|
||||
|
||||
for label := range toolboxLabels {
|
||||
if _, ok := i.Labels[label]; ok {
|
||||
isToolboxImage = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if isToolboxImage {
|
||||
toolboxImages = append(toolboxImages, i)
|
||||
}
|
||||
}
|
||||
|
||||
return toolboxImages, nil
|
||||
|
|
Loading…
Reference in a new issue