forked from toolshed/abra
.gitea
cli
cmd
pkg
app
autocomplete
client
compose
config
container
container.go
context
dns
formatter
git
integration
limit
lint
recipe
secret
server
service
ssh
upstream
web
scripts
tests
.drone.yml
.e2e.env.sample
.envrc.sample
.gitignore
.goreleaser.yml
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 prompt is true 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, prompt 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 !prompt {
|
|
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
|
|
}
|