package app import ( "context" "fmt" "strings" "coopcloud.tech/abra/pkg/config" "coopcloud.tech/abra/pkg/upstream/stack" apiclient "github.com/docker/docker/client" "github.com/sirupsen/logrus" ) // 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 } logrus.Debugf("retrieved '%s' for '%s'", app, appName) 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} } } deployed := len(services) > 0 if deployed { logrus.Debugf("detected %s as deployed versions of %s", appSpec, app.Name) } else { logrus.Debugf("detected %s as not deployed", app.Name) } 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, "-") version := label[:idx] digest := label[idx+1:] logrus.Debugf("parsed %s as version from %s", version, label) logrus.Debugf("parsed %s as digest from %s", digest, label) return version, digest } // ParseServiceName parses a $STACK_NAME_$SERVICE_NAME service label. func ParseServiceName(label string) string { idx := strings.LastIndex(label, "_") serviceName := label[idx+1:] logrus.Debugf("parsed %s as service name from %s", serviceName, label) return serviceName }