package app import ( "context" "fmt" "strings" "coopcloud.tech/abra/pkg/client/stack" "coopcloud.tech/abra/pkg/config" apiclient "github.com/docker/docker/client" ) // Get retrieves an app func Get(appName string) (config.App, error) { files, err := config.LoadAppFiles("") if err != nil { return config.App{}, err } app, err := config.GetApp(files, appName) if err != nil { return config.App{}, err } return app, nil } // deployedServiceSpec represents a deployed service of an app. type deployedServiceSpec struct { Name string Version string } // VersionSpec represents a deployed app and associated metadata. type VersionSpec map[string]deployedServiceSpec // DeployedVersions lists metadata (e.g. versions) for deployed func DeployedVersions(ctx context.Context, cl *apiclient.Client, app config.App) (VersionSpec, bool, error) { services, err := stack.GetStackServices(ctx, cl, app.StackName()) if err != nil { return VersionSpec{}, false, err } appSpec := make(VersionSpec) for _, service := range services { serviceName := ParseServiceName(service.Spec.Name) label := fmt.Sprintf("coop-cloud.%s.%s.version", app.StackName(), serviceName) if deployLabel, ok := service.Spec.Labels[label]; ok { version, _ := ParseVersionLabel(deployLabel) appSpec[serviceName] = deployedServiceSpec{Name: serviceName, Version: version} } } return appSpec, len(services) > 0, nil } // ParseVersionLabel parses a $VERSION-$DIGEST app service label. func ParseVersionLabel(label string) (string, string) { // versions may look like v4.2-abcd or v4.2-alpine-abcd idx := strings.LastIndex(label, "-") return label[:idx], label[idx+1:] } // ParseVersionName parses a $STACK_NAME_$SERVICE_NAME service label. func ParseServiceName(label string) string { idx := strings.LastIndex(label, "_") return label[idx+1:] }