forked from toolshed/abra
.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
71 lines
2.1 KiB
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
|
|
}
|