Files
.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
abra/pkg/service/service.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]
}