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
|
@ -51,6 +51,12 @@ var (
|
||||||
onlyContainers bool
|
onlyContainers bool
|
||||||
onlyImages 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{
|
var listCmd = &cobra.Command{
|
||||||
|
@ -123,35 +129,22 @@ func list(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainers() ([]toolboxContainer, error) {
|
func getContainers() ([]toolboxContainer, error) {
|
||||||
logrus.Debug("Fetching containers with label=com.github.containers.toolbox=true")
|
var err error
|
||||||
args := []string{"--all", "--filter", "label=com.github.containers.toolbox=true"}
|
var args []string
|
||||||
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 containers []map[string]interface{}
|
var containers []map[string]interface{}
|
||||||
if podman.CheckVersion("2.0.0") {
|
var toolboxContainers []toolboxContainer
|
||||||
containers = utils.JoinJSON("Id", containers_old, containers_new)
|
|
||||||
containers = utils.SortJSON(containers, "Names", true)
|
logrus.Debug("Fetching all containers")
|
||||||
} else {
|
args = []string{"--all", "--sort", "names"}
|
||||||
containers = utils.JoinJSON("ID", containers_old, containers_new)
|
containers, err = podman.GetContainers(args...)
|
||||||
containers = utils.SortJSON(containers, "Names", false)
|
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 {
|
for _, container := range containers {
|
||||||
var c toolboxContainer
|
var c toolboxContainer
|
||||||
|
var isToolboxContainer bool = false
|
||||||
|
|
||||||
containerJSON, err := json.Marshal(container)
|
containerJSON, err := json.Marshal(container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("failed to marshal container: %v", err)
|
logrus.Errorf("failed to marshal container: %v", err)
|
||||||
|
@ -163,8 +156,18 @@ func getContainers() ([]toolboxContainer, error) {
|
||||||
logrus.Errorf("failed to unmarshal container: %v", err)
|
logrus.Errorf("failed to unmarshal container: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for label := range toolboxLabels {
|
||||||
|
if _, ok := c.Labels[label]; ok {
|
||||||
|
isToolboxContainer = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isToolboxContainer {
|
||||||
toolboxContainers = append(toolboxContainers, c)
|
toolboxContainers = append(toolboxContainers, c)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return toolboxContainers, nil
|
return toolboxContainers, nil
|
||||||
}
|
}
|
||||||
|
@ -191,38 +194,22 @@ func listHelp(cmd *cobra.Command, args []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getImages() ([]toolboxImage, error) {
|
func getImages() ([]toolboxImage, error) {
|
||||||
logrus.Debug("Fetching images with label=com.github.containers.toolbox=true")
|
var err error
|
||||||
args := []string{"--filter", "label=com.github.containers.toolbox=true"}
|
var args []string
|
||||||
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 images []map[string]interface{}
|
var images []map[string]interface{}
|
||||||
if podman.CheckVersion("2.0.0") {
|
var toolboxImages []toolboxImage
|
||||||
images = utils.JoinJSON("Id", images_old, images_new)
|
|
||||||
images = utils.SortJSON(images, "Names", true)
|
logrus.Debug("Fetching all images")
|
||||||
} else if podman.CheckVersion("1.8.3") {
|
args = []string{"--sort", "repository"}
|
||||||
images = utils.JoinJSON("ID", images_old, images_new)
|
images, err = podman.GetImages(args...)
|
||||||
images = utils.SortJSON(images, "Names", true)
|
if err != nil {
|
||||||
} else {
|
return nil, fmt.Errorf("failed to get images: %w", err)
|
||||||
images = utils.JoinJSON("id", images_old, images_new)
|
|
||||||
images = utils.SortJSON(images, "names", true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 {
|
for _, image := range images {
|
||||||
var i toolboxImage
|
var i toolboxImage
|
||||||
|
var isToolboxImage bool = false
|
||||||
|
|
||||||
imageJSON, err := json.Marshal(image)
|
imageJSON, err := json.Marshal(image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("failed to marshal toolbox image: %v", err)
|
logrus.Errorf("failed to marshal toolbox image: %v", err)
|
||||||
|
@ -234,8 +221,18 @@ func getImages() ([]toolboxImage, error) {
|
||||||
logrus.Errorf("failed to unmarshal toolbox image: %v", err)
|
logrus.Errorf("failed to unmarshal toolbox image: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for label := range toolboxLabels {
|
||||||
|
if _, ok := i.Labels[label]; ok {
|
||||||
|
isToolboxImage = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isToolboxImage {
|
||||||
toolboxImages = append(toolboxImages, i)
|
toolboxImages = append(toolboxImages, i)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return toolboxImages, nil
|
return toolboxImages, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue