forked from toolshed/abra
.gitea
cli
cmd
pkg
app
autocomplete
catalogue
client
compose
config
container
context
dns
formatter
git
integration
jsontable
limit
lint
recipe
runtime
secret
server
service
service.go
ssh
test
upstream
web
scripts
tests
.dockerignore
.drone.yml
.e2e.env.sample
.envrc.sample
.gitignore
.goreleaser.yml
AUTHORS.md
Dockerfile
LICENSE
Makefile
README.md
go.mod
go.sum
renovate.json
79 lines
2.4 KiB
Go
79 lines
2.4 KiB
Go
package service
|
|
|
|
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/api/types/swarm"
|
|
"github.com/docker/docker/client"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// GetService retrieves a service container. If prompt is true and the retrievd
|
|
// count of service containers does not match 1, then a prompt is presented to
|
|
// let the user choose. A count of 0 is handled gracefully.
|
|
func GetService(c context.Context, cl *client.Client, filters filters.Args, prompt bool) (swarm.Service, error) {
|
|
serviceOpts := types.ServiceListOptions{Filters: filters}
|
|
services, err := cl.ServiceList(c, serviceOpts)
|
|
if err != nil {
|
|
return swarm.Service{}, err
|
|
}
|
|
|
|
if len(services) == 0 {
|
|
filter := filters.Get("name")[0]
|
|
return swarm.Service{}, fmt.Errorf("no services matching the %v filter found?", filter)
|
|
}
|
|
|
|
if len(services) != 1 {
|
|
var servicesRaw []string
|
|
for _, service := range services {
|
|
serviceName := service.Spec.Name
|
|
created := formatter.HumanDuration(service.CreatedAt.Unix())
|
|
servicesRaw = append(servicesRaw, fmt.Sprintf("%s (created %v)", serviceName, created))
|
|
}
|
|
|
|
if !prompt {
|
|
err := fmt.Errorf("expected 1 service but found %v: %s", len(services), strings.Join(servicesRaw, " "))
|
|
return swarm.Service{}, err
|
|
}
|
|
|
|
logrus.Warnf("ambiguous service list received, prompting for input")
|
|
|
|
var response string
|
|
prompt := &survey.Select{
|
|
Message: "which service are you looking for?",
|
|
Options: servicesRaw,
|
|
}
|
|
|
|
if err := survey.AskOne(prompt, &response); err != nil {
|
|
return swarm.Service{}, err
|
|
}
|
|
|
|
chosenService := strings.TrimSpace(strings.Split(response, " ")[0])
|
|
for _, service := range services {
|
|
serviceName := strings.ToLower(service.Spec.Name)
|
|
if serviceName == chosenService {
|
|
return service, nil
|
|
}
|
|
}
|
|
|
|
logrus.Panic("failed to match chosen service")
|
|
}
|
|
|
|
return services[0], nil
|
|
}
|
|
|
|
// ContainerToServiceName converts a container name to a service name.
|
|
func ContainerToServiceName(containerNames []string, stackName string) string {
|
|
containerName := strings.Join(containerNames, "")
|
|
trimmed := strings.TrimPrefix(containerName, "/")
|
|
stackNameServiceName := strings.Split(trimmed, ".")[0]
|
|
splitter := fmt.Sprintf("%s_", stackName)
|
|
return strings.Split(stackNameServiceName, splitter)[1]
|
|
}
|