Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reading a Compose file results in undefined Labels #9808

Closed
paroque28 opened this issue Sep 5, 2022 · 7 comments
Closed

Reading a Compose file results in undefined Labels #9808

paroque28 opened this issue Sep 5, 2022 · 7 comments
Assignees

Comments

@paroque28
Copy link
Contributor

Description

Steps to reproduce the issue:

  1. git clone https://github.com/paroque28/compose-test
  2. cd compose-test
  3. pkg/compose-test/main.go

Describe the results you received:
If I comment the following lines of code:

if project.Services[i].CustomLabels == nil {
			project.Services[i].CustomLabels = map[string]string{
				api.ProjectLabel: project.Name,
			}
		}

I get the following error:

panic: assignment to entry in nil map

goroutine 1 [running]:
main.readComposeFile({0x1274cf9, 0x12})
        /home/pablo/compose-test/pkg/compose-test/main.go:57 +0x49a
main.StartProject({0x1274cf9, 0x12})
        /home/pablo/compose-test/pkg/compose-test/main.go:78 +0x1a5
main.main()
        /home/pablo/compose-test/pkg/compose-test/main.go:102 +0x29
exit status 2

Describe the results you expected:
Not an error, an initialized custom labels string map

Additional information you deem important (e.g. issue happens only occasionally):

Output of docker compose version:
github.com/docker/compose/v2 v2.10.2

(paste your output here)

Output of docker info:

(paste your output here)

Additional environment details:

Related to:

#9579

And:
docker/roadmap#387

@paroque28
Copy link
Contributor Author

My question is, how do you expect users to parse Docker-compose files? I might be using the wrong method

@paroque28
Copy link
Contributor Author

@RiskyFeryansyahP
Copy link
Contributor

My question is, how do you expect users to parse Docker-compose files? I might be using the wrong method

I think your method is already right, even in the compose code itself it needs to initialize for the CustomLabel part. the code is like this:

for i, s := range project.Services {
		s.CustomLabels = map[string]string{
			api.ProjectLabel:     project.Name,
			api.ServiceLabel:     s.Name,
			api.VersionLabel:     api.ComposeVersion,
			api.WorkingDirLabel:  project.WorkingDir,
			api.ConfigFilesLabel: strings.Join(project.ComposeFiles, ","),
			api.OneoffLabel:      "False", // default, will be overridden by `run` command
		}
		if ef != "" {
			s.CustomLabels[api.EnvironmentFileLabel] = ef
		}
		project.Services[i] = s
	}

@milas
Copy link
Contributor

milas commented Sep 6, 2022

Your code looks good to me given the behavior right now - that is the correct method to load projects 🙂

You're definitely not the first one to be tripped up by this, and we've discussed making some improvements here before, so I created compose-spec/compose-go#305 (the loading is actually handled by compose-spec/compose-go).

I'm closing this issue, but please feel free to add your thoughts/input on the linked issue!

@milas milas closed this as not planned Won't fix, can't repro, duplicate, stale Sep 6, 2022
@glours
Copy link
Contributor

glours commented Sep 6, 2022

Same as this previous PR, you should use the AddLabel function to safetly add a new label

@paroque28
Copy link
Contributor Author

Thank you guys, I was just curious if there was another way already :)

And yes @glours, forgot to use the AddLabel method, thanks for the reminder.

@hmb
Copy link

hmb commented Jun 8, 2024

For anyone new to this (like myself), when using the Add method the result has to be assigned to the CustomLabels field, otherwise it won't work if that is nil at start. It could be done in a fluent way:

	for serviceName, serviceConfig := range project.Services {
		serviceConfig.CustomLabels =
			serviceConfig.CustomLabels.
				Add(api.ProjectLabel, project.Name).
				Add(api.ServiceLabel, serviceConfig.Name).
				Add(api.VersionLabel, api.ComposeVersion).
				Add(api.WorkingDirLabel, project.WorkingDir).
				Add(api.ConfigFilesLabel, strings.Join(project.ComposeFiles, ",")).
				Add(api.OneoffLabel, "False")
		project.Services[serviceName] = serviceConfig
	}

The reason for this can be found in the code of Add, which simply returns a new Labels instance in case l is nil:

func (l Labels) Add(key, value string) Labels {
	if l == nil {
		l = Labels{}
	}
	l[key] = value
	return l
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants