Files
.gitea
cli
cmd
pkg
app
autocomplete
catalogue
client
compose
config
container
container.go
context
dns
formatter
git
integration
jsontable
limit
lint
recipe
secret
server
service
ssh
test
upstream
web
scripts
tests
.dockerignore
.drone.yml
.envrc.sample
.gitignore
.goreleaser.yml
AUTHORS.md
Dockerfile
LICENSE
Makefile
README.md
go.mod
go.sum
renovate.json
abra/pkg/container/container.go

71 lines
2.1 KiB
Go

package container
import (
"context"
"fmt"
"strings"
"coopcloud.tech/abra/pkg/formatter"
"github.com/AlecAivazis/survey/v2"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client"
"github.com/sirupsen/logrus"
)
// GetContainer retrieves a container. If noInput is false and the retrievd
// count of containers does not match 1, then a prompt is presented to let the
// user choose. A count of 0 is handled gracefully.
func GetContainer(c context.Context, cl *client.Client, filters filters.Args, noInput bool) (types.Container, error) {
containerOpts := types.ContainerListOptions{Filters: filters}
containers, err := cl.ContainerList(c, containerOpts)
if err != nil {
return types.Container{}, err
}
if len(containers) == 0 {
filter := filters.Get("name")[0]
return types.Container{}, fmt.Errorf("no containers matching the %v filter found?", filter)
}
if len(containers) != 1 {
var containersRaw []string
for _, container := range containers {
containerName := strings.Join(container.Names, " ")
trimmed := strings.TrimPrefix(containerName, "/")
created := formatter.HumanDuration(container.Created)
containersRaw = append(containersRaw, fmt.Sprintf("%s (created %v)", trimmed, created))
}
if noInput {
err := fmt.Errorf("expected 1 container but found %v: %s", len(containers), strings.Join(containersRaw, " "))
return types.Container{}, err
}
logrus.Warnf("ambiguous container list received, prompting for input")
var response string
prompt := &survey.Select{
Message: "which container are you looking for?",
Options: containersRaw,
}
if err := survey.AskOne(prompt, &response); err != nil {
return types.Container{}, err
}
chosenContainer := strings.TrimSpace(strings.Split(response, " ")[0])
for _, container := range containers {
containerName := strings.TrimSpace(strings.Join(container.Names, " "))
trimmed := strings.TrimPrefix(containerName, "/")
if trimmed == chosenContainer {
return container, nil
}
}
logrus.Panic("failed to match chosen container")
}
return containers[0], nil
}