feat(discovery): parse Compose-managed labels
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
package discovery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ComposeLabels captures the four Compose-managed labels we need
|
||||
// to drive a `docker compose pull`/`up -d` against the right stack.
|
||||
type ComposeLabels struct {
|
||||
Project string
|
||||
Service string
|
||||
WorkingDir string
|
||||
ConfigFiles []string
|
||||
}
|
||||
|
||||
const (
|
||||
labelProject = "com.docker.compose.project"
|
||||
labelService = "com.docker.compose.service"
|
||||
labelWorkingDir = "com.docker.compose.project.working_dir"
|
||||
labelConfigFiles = "com.docker.compose.project.config_files"
|
||||
)
|
||||
|
||||
// ParseComposeLabels extracts the Compose labels we need. Returns an
|
||||
// error naming the missing label if any required field is absent —
|
||||
// in practice this should only happen if the container was not
|
||||
// started by Compose.
|
||||
func ParseComposeLabels(labels map[string]string) (ComposeLabels, error) {
|
||||
get := func(key string) (string, error) {
|
||||
v, ok := labels[key]
|
||||
if !ok || v == "" {
|
||||
return "", fmt.Errorf("missing required label: %s", key)
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
project, err := get(labelProject)
|
||||
if err != nil {
|
||||
return ComposeLabels{}, err
|
||||
}
|
||||
service, err := get(labelService)
|
||||
if err != nil {
|
||||
return ComposeLabels{}, err
|
||||
}
|
||||
workingDir, err := get(labelWorkingDir)
|
||||
if err != nil {
|
||||
return ComposeLabels{}, err
|
||||
}
|
||||
configFilesRaw, err := get(labelConfigFiles)
|
||||
if err != nil {
|
||||
return ComposeLabels{}, err
|
||||
}
|
||||
|
||||
files := strings.Split(configFilesRaw, ",")
|
||||
for i, f := range files {
|
||||
files[i] = strings.TrimSpace(f)
|
||||
}
|
||||
|
||||
return ComposeLabels{
|
||||
Project: project,
|
||||
Service: service,
|
||||
WorkingDir: workingDir,
|
||||
ConfigFiles: files,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// HasOptIn reports whether the labels include the opt-in marker with
|
||||
// value "true" (exact, case-sensitive — anything else is excluded).
|
||||
func HasOptIn(labels map[string]string, key string) bool {
|
||||
return labels[key] == "true"
|
||||
}
|
||||
Reference in New Issue
Block a user