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

use compose-go to load and parse compose files #4863

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

glours
Copy link

@glours glours commented Feb 8, 2024

- What I did
Use compose-go to parse, interpolate and merge Compose configurations.
As this library, under active maintenance and development by the Compose team, is up to date with the recent evolutions of the Compose Specification it will remove the potential divergence between the 2 code base, make the maintenance and evolution easier for everyone.
As a side effect, it would remove the necessity of using the version attribute. It disturbs users, the official Docker message is: "You don't need the version attribute anymore in your Compose files" and the CLI continue to introduce new versions of compose v3 file format

- How I did it
Import the compose-go library, removed the duplicated code for structs, keep only the specific checks done on forbidden, unsupported and deprecated properties on the parsing part.
Remove the interpolation and merging functions and let compose-go doing the job
Add the specific mapping for x-cluster-spec extension attribut to match the ClusterVolumeSpec struct
Remove all the duplicated tests already done on the compose-go side

- How to verify it
Run tests
Use average Compose configurations and check we're still producing the same output than the current version

- Description for the changelog

Use compose-go to manage Compose configuration files

- A picture of a cute animal (not mandatory but encouraged)

image

@codecov-commenter
Copy link

codecov-commenter commented Feb 8, 2024

Codecov Report

Merging #4863 (6abad62) into master (c986d09) will decrease coverage by 1.23%.
Report is 16 commits behind head on master.
The diff coverage is 65.74%.

❗ Current head 6abad62 differs from pull request most recent head 21487c5. Consider uploading reports for the commit 21487c5 to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4863      +/-   ##
==========================================
- Coverage   61.31%   60.09%   -1.23%     
==========================================
  Files         287      283       -4     
  Lines       20058    19131     -927     
==========================================
- Hits        12298    11496     -802     
+ Misses       6867     6782      -85     
+ Partials      893      853      -40     

@Radiergummi
Copy link

You have NO idea how much this improves my job. Merci beaucoup 🫶

@Leopere
Copy link

Leopere commented Feb 14, 2024

You have NO idea how much this improves my job. Merci beaucoup 🫶

Silver plates Yeah no this is pretty wonderful if/when it get's accepted.

@glours glours force-pushed the use-compose-go branch 2 times, most recently from 21487c5 to aa63cb7 Compare February 16, 2024 14:35
Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
neersighted added a commit to neersighted/docker-cli that referenced this pull request Mar 22, 2024
Go's `net` package [will unlink][1] for us, as long as we used listen to
create the Unix socket.

Go will even skip the unlink when the socket appears to be abstract
(start with a NUL, represented by an @), though we must be cautious to
only create sockets with an abstract address on platforms that actually
support it -- this caused [several][2] [bugs][3] before.

  [1]: https://pkg.go.dev/net#UnixListener.SetUnlinkOnClose
  [2]: docker#4783
  [3]: docker#4863

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
neersighted added a commit to neersighted/docker-cli that referenced this pull request Mar 22, 2024
Go's `net` package [will unlink][1] for us, as long as we used Listen &
friends to create the Unix socket.

Go will even skip the unlink when the socket appears to be abstract
(starts with a NUL, represented by an @), though we must be cautious to
only create sockets with an abstract address on platforms that actually
support it -- this caused [several][2] [bugs][3] before.

  [1]: https://pkg.go.dev/net#UnixListener.SetUnlinkOnClose
  [2]: docker#4783
  [3]: docker#4863

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
neersighted added a commit to neersighted/docker-cli that referenced this pull request Mar 22, 2024
Go's `net` package [will unlink][1] for us, as long as we used Listen &
friends to create the Unix socket.

Go will even skip the unlink when the socket appears to be abstract
(starts with a NUL, represented by an @), though we must be cautious to
only create sockets with an abstract address on platforms that actually
support it -- this caused [several][2] [bugs][3] before.

  [1]: https://pkg.go.dev/net#UnixListener.SetUnlinkOnClose
  [2]: docker#4783
  [3]: docker#4863

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
Copy link
Member

@Benehiko Benehiko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have all the context of the impact these changes will bring but I thought that giving a code review might help push this forward :)


specLoader "github.com/compose-spec/compose-go/v2/loader"
compose "github.com/compose-spec/compose-go/v2/types"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: keep it consistent with the other import names. Either stick with compose or composetypes.

var o []string

if spec == nil {
return nil, nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this is an internal function I don't think we should return a nil error and nil value here.

Suggested change
return nil, nil
return nil, errors.New("spec is nil")

Comment on lines +434 to +439
for hostName, hostIPs := range extraHosts {
for _, hostIP := range hostIPs {
hosts = append(hosts, hostIP+" "+hostName)
}
}
slices.Sort(hosts)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"IP-address hostname(s)". The original order of mappings is preserved.

Since this function mentions it keeps the order of hosts, I'm a bit skeptical of this change. Wouldn't sorting the slice here potentially change the original order of the hosts? How do we know if the host mappings were sorted in the first place?

If we do intend to break the original contract, we should then also update the comments on the function to match the new behavior of the function.

Comment on lines +51 to +55
r := reflect.ValueOf(service)
for property, value := range types.UnsupportedProperties {
f := reflect.Indirect(r).FieldByName(property)
if f.IsValid() && !f.IsZero() && !slices.Contains(unsupported, value) {
unsupported = append(unsupported, value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm always a bit skeptical of using reflect. Although the previous solution also seemed quite messy, I'm not sure if this one is better with reflect. A simple if type check might do:

if ok, f := service.(map[string]any); !ok {
  return errors.New("not supported")
}

Comment on lines +80 to 86
r := reflect.ValueOf(service)
for property, pair := range propertyMap {
f := reflect.Indirect(r).FieldByName(property)
if f.IsValid() && !f.IsZero() {
output[pair.Key()] = pair.Value()
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm here also not sure if reflect is a good approach.

Comment on lines +52 to +57
for _, f := range configFiles.ConfigFiles {
if f.Filename != "" {
dir = filepath.Base(f.Filename)
break
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to iterate over the config files here? I don't know much about this part of the code, but would like to know what problem it solves. For example, In which cases would the filename be empty?

rige1 pushed a commit to rige1/cli that referenced this pull request Apr 16, 2024
Go's `net` package [will unlink][1] for us, as long as we used Listen &
friends to create the Unix socket.

Go will even skip the unlink when the socket appears to be abstract
(starts with a NUL, represented by an @), though we must be cautious to
only create sockets with an abstract address on platforms that actually
support it -- this caused [several][2] [bugs][3] before.

  [1]: https://pkg.go.dev/net#UnixListener.SetUnlinkOnClose
  [2]: docker/cli#4783
  [3]: docker/cli#4863

Signed-off-by: Bjorn Neergaard <bjorn.neergaard@docker.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants