diff --git a/cli/config_test.go b/cli/config_test.go index d93e99dc6..7110583db 100644 --- a/cli/config_test.go +++ b/cli/config_test.go @@ -92,7 +92,7 @@ func (s *SuiteConfig) TestLabelsConfig(c *C) { { Labels: map[string]map[string]string{ "some": map[string]string{ - requiredLabel: "true", + requiredLabelName: "true", "label2": "2", }, }, @@ -102,7 +102,7 @@ func (s *SuiteConfig) TestLabelsConfig(c *C) { { Labels: map[string]map[string]string{ "some": map[string]string{ - requiredLabel: "false", + requiredLabelName: "false", labelPrefix + "." + jobLocal + ".job1.schedule": "everyday! yey!", }, }, @@ -112,7 +112,7 @@ func (s *SuiteConfig) TestLabelsConfig(c *C) { { Labels: map[string]map[string]string{ "some": map[string]string{ - requiredLabel: "true", + requiredLabelName: "true", labelPrefix + "." + jobLocal + ".job1.schedule": "everyday! yey!", labelPrefix + "." + jobLocal + ".job1.command": "rm -rf *test*", labelPrefix + "." + jobLocal + ".job2.schedule": "everynanosecond! yey!", @@ -125,8 +125,8 @@ func (s *SuiteConfig) TestLabelsConfig(c *C) { { Labels: map[string]map[string]string{ "some": map[string]string{ - requiredLabel: "true", - serviceLabel: "true", + requiredLabelName: "true", + serviceLabelName: "true", labelPrefix + "." + jobLocal + ".job1.schedule": "schedule1", labelPrefix + "." + jobLocal + ".job1.command": "command1", labelPrefix + "." + jobRun + ".job2.schedule": "schedule2", @@ -135,7 +135,7 @@ func (s *SuiteConfig) TestLabelsConfig(c *C) { labelPrefix + "." + jobServiceRun + ".job3.command": "command3", }, "other": map[string]string{ - requiredLabel: "true", + requiredLabelName: "true", labelPrefix + "." + jobLocal + ".job4.schedule": "schedule4", labelPrefix + "." + jobLocal + ".job4.command": "command4", labelPrefix + "." + jobRun + ".job5.schedule": "schedule5", @@ -169,13 +169,13 @@ func (s *SuiteConfig) TestLabelsConfig(c *C) { { Labels: map[string]map[string]string{ "some": map[string]string{ - requiredLabel: "true", - serviceLabel: "true", + requiredLabelName: "true", + serviceLabelName: "true", labelPrefix + "." + jobExec + ".job1.schedule": "schedule1", labelPrefix + "." + jobExec + ".job1.command": "command1", }, "other": map[string]string{ - requiredLabel: "true", + requiredLabelName: "true", labelPrefix + "." + jobExec + ".job2.schedule": "schedule2", labelPrefix + "." + jobExec + ".job2.command": "command2", }, @@ -200,8 +200,8 @@ func (s *SuiteConfig) TestLabelsConfig(c *C) { { Labels: map[string]map[string]string{ "some": map[string]string{ - requiredLabel: "true", - serviceLabel: "true", + requiredLabelName: "true", + serviceLabelName: "true", labelPrefix + "." + jobExec + ".job1.schedule": "schedule1", labelPrefix + "." + jobExec + ".job1.command": "command1", labelPrefix + "." + jobExec + ".job1.no-overlap": "true", @@ -222,8 +222,8 @@ func (s *SuiteConfig) TestLabelsConfig(c *C) { { Labels: map[string]map[string]string{ "some": { - requiredLabel: "true", - serviceLabel: "true", + requiredLabelName: "true", + serviceLabelName: "true", labelPrefix + "." + jobRun + ".job1.schedule": "schedule1", labelPrefix + "." + jobRun + ".job1.command": "command1", labelPrefix + "." + jobRun + ".job1.volume": "/test/tmp:/test/tmp:ro", diff --git a/cli/docker-labels.go b/cli/docker-labels.go index df2e93356..697e35232 100644 --- a/cli/docker-labels.go +++ b/cli/docker-labels.go @@ -2,7 +2,7 @@ package cli import ( "encoding/json" - "errors" + "fmt" "strings" "time" @@ -13,9 +13,9 @@ import ( const ( labelPrefix = "ofelia" - requiredLabel = labelPrefix + ".enabled" - requiredLabelFilter = requiredLabel + "=true" - serviceLabel = labelPrefix + ".service" + requiredLabelName = labelPrefix + ".enabled" + requiredLabelFilter = requiredLabelName + "=true" + serviceLabelName = labelPrefix + ".service" ) func getLabels(d *docker.Client) (map[string]map[string]string, error) { @@ -36,7 +36,7 @@ func getLabels(d *docker.Client) (map[string]map[string]string, error) { } if len(conts) == 0 { - return nil, errors.New("Couldn't find containers with label 'ofelia.enabled=true'") + return nil, fmt.Errorf("couldn't find containers with label '%s'", requiredLabelFilter) } var labels = make(map[string]map[string]string) @@ -45,7 +45,7 @@ func getLabels(d *docker.Client) (map[string]map[string]string, error) { if len(c.Names) > 0 && len(c.Labels) > 0 { name := strings.TrimPrefix(c.Names[0], "/") for k := range c.Labels { - // remove all not relevant labels + // Remove all irrelevant labels if !strings.HasPrefix(k, labelPrefix) { delete(c.Labels, k) continue @@ -66,56 +66,61 @@ func (c *Config) buildFromDockerLabels(labels map[string]map[string]string) erro serviceJobs := make(map[string]map[string]interface{}) globalConfigs := make(map[string]interface{}) - for c, l := range labels { - isServiceContainer := func() bool { - for k, v := range l { - if k == serviceLabel { - return v == "true" - } - } - return false - }() - - for k, v := range l { - parts := strings.Split(k, ".") - if len(parts) < 4 { - if isServiceContainer { - globalConfigs[parts[1]] = v + jobTypes := map[string]map[string]map[string]interface{}{ + jobExec: execJobs, + jobLocal: localJobs, + jobRun: runJobs, + jobServiceRun: serviceJobs, + } + + for containerName, containerLabels := range labels { + serviceLabelValue, hasServiceLabel := containerLabels[serviceLabelName] + isServiceContainer := hasServiceLabel && serviceLabelValue == "true" + + for labelName, labelValue := range containerLabels { + selectors := strings.Split(labelName, ".") + + // Handle short labels + if len(selectors) < 4 { + if len(selectors) > 1 && isServiceContainer { + // Always ignore the third selector of short labels + // TODO: Add warning + globalConfigs[selectors[1]] = labelValue } + // Always ignore incomplete labels continue } - jobType, jobName, jopParam := parts[1], parts[2], parts[3] - switch { - case jobType == jobExec: // only job exec can be provided on the non-service container - if _, ok := execJobs[jobName]; !ok { + // The first selector, corresponding to the prefix, is always ignored + jobType, jobName, jobParam := selectors[1], selectors[2], selectors[3] + + // Only job exec can be provided on the non-service container + if jobType == jobExec { + if _, hasJob := execJobs[jobName]; !hasJob { execJobs[jobName] = make(map[string]interface{}) } - setJobParam(execJobs[jobName], jopParam, v) - // since this label was placed not on the service container + setJobParam(execJobs[jobName], jobParam, labelValue) + // Since this label was placed not on the service container // this means we need to `exec` command in this container if !isServiceContainer { - execJobs[jobName]["container"] = c + execJobs[jobName]["container"] = containerName } - case jobType == jobLocal && isServiceContainer: - if _, ok := localJobs[jobName]; !ok { - localJobs[jobName] = make(map[string]interface{}) - } - setJobParam(localJobs[jobName], jopParam, v) - case jobType == jobServiceRun && isServiceContainer: - if _, ok := serviceJobs[jobName]; !ok { - serviceJobs[jobName] = make(map[string]interface{}) - } - setJobParam(serviceJobs[jobName], jopParam, v) - case jobType == jobRun && isServiceContainer: - if _, ok := runJobs[jobName]; !ok { - runJobs[jobName] = make(map[string]interface{}) + + continue + } + + // Handle remaining job types + if isServiceContainer { + if jobMap, hasJobMap := jobTypes[jobType]; hasJobMap { + if _, hasJob := jobMap[jobName]; !hasJob { + jobMap[jobName] = make(map[string]interface{}) + } + setJobParam(jobMap[jobName], jobParam, labelValue) + } else { + // TODO: Warn about unknown parameter } - setJobParam(runJobs[jobName], jopParam, v) - default: - // TODO: warn about unknown parameter } } }