Skip to content

Implement service profiles#7930

Merged
aiordache merged 1 commit into
docker:masterfrom
acran:profiles
Dec 2, 2020
Merged

Implement service profiles#7930
aiordache merged 1 commit into
docker:masterfrom
acran:profiles

Conversation

@acran

@acran acran commented Nov 15, 2020

Copy link
Copy Markdown

Implement profiles as introduced in compose-spec/compose-spec#110

This is a first draft and probably needs some more discussion. Things I'm not quite sure about yet which may need further discussion:

How to specify profiles to enable

  • by parameter: I implemented the --profile flag for the main command, multiple profiles may be passed
    • use another flag name?
    • move the flag to the affected subcommands only (see below)?
  • by environment: I used COMPOSE_PROFILE with : as separator for multiple profiles
    • use another variable name?
    • use another separator(s)?
    • make the separator configurable?
  • merging profiles: to be consistent with how other array options are handled already the profiles of a service from multiple configuration files are just added together
    • there is no way to remove profiles from a service or unset the profiles option all together with override configurations. Should there be?

Affected commands

The main logic is implemented in Project.get_services() which was already used in the code paths for and therefor add profiles support to:

  • build
  • create
  • up
  • start
  • pull
  • push

The following functions use Project.containers() instead which is unchanged and therefor ignore profiles:

  • stop
  • down
    • using remove_stopped which already used Project.containers()
    • using remove_images which I changed to ignore profiles to be consistent with the rest
  • pause
  • unpause
  • kill

I couldn't quite decide if the latter commands should be consider profiles, too, because the behavior expected by the user would most probably not consider them, most notably with docker-compose down:

Executing docker-compose down the user expects that all defined services will be removed. But services assigned to specific profiles only could be missed here when docker-compose down is called without enabling those profiles.
Then those services would need to be considered orphans. But this would be inconsistent with notion of orphans since those services are actually defined in the configuration, just not enabled.
On the other hand docker-compose --profile foo down might suggest that services with the foo profile only would be removed, but actually the spec would require all services without profiles and services with the foo profile.

That's why I thought it to be most consistent/intuitive for docker-compose down and the other commands to just ignore profiles and act on all defined services (and because changing the logic of Project.containers() would require the refactoring/verification of a whole lot more code paths and tests).

Tests

Using the example docker-compose.yml from compose-spec/compose-spec#110 I implemented a test case for each of the examples in the spec as well as an extra test case for merging profiles from multiple configuration files.
Are there more tests needed here?

Small disclaimer: Since I'm neither familiar with the code base nor python even, please don't hold back with any feedback on the coding style/formatting/performance :)

Resolves #7919, #1896, #6742, #7539

@acran acran left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I comment on some code lines which probably require some attention

Comment thread compose/cli/command.py Outdated
Comment thread compose/project.py
'active profiles. '
'You may fix this by adding a common profile to '
'"{dep_name}" and "{service_name}".'
.format(dep_name=dep.name, service_name=service.name)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Is this a suitable error message making it clear to the user what went wrong, why and how to fix it?

Comment thread compose/project.py

def remove_images(self, remove_image_type):
for service in self.get_services():
for service in self.services:

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The call to self.get_services was actually unnecessary before, since without any parameters it would just return self.services.
But now it would filter services by enabled profiles, so this was changed so remove_images and thus down would act on all defined services.

Comment thread compose/project.py

def restart(self, service_names=None, **options):
# filter service_names by enabled profiles
service_names = [s.name for s in self.get_services(service_names)]

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

restart should consider the enabled profiles so to not start services disabled by profile with docker-compose restart

@aiordache

Copy link
Copy Markdown
Contributor

@acran Can you rebase please?

@acran

acran commented Dec 1, 2020

Copy link
Copy Markdown
Author

@aiordache yes, done

@aiordache aiordache left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you! SGTM

@aiordache aiordache added this to the 1.28.0 milestone Dec 1, 2020

@ulyssessouza ulyssessouza left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM in general, just missing changes

Comment thread compose/cli/command.py Outdated
Comment thread compose/project.py Outdated
Comment thread compose/project.py Outdated
Comment thread compose/project.py
Comment thread compose/project.py Outdated
Comment thread compose/cli/command.py
Implement profiles as introduced in compose-spec/compose-spec#110
fixes docker#7919
closes docker#1896
closes docker#6742
closes docker#7539

Signed-off-by: Roman Anasal <[email protected]>
@acran

acran commented Dec 2, 2020

Copy link
Copy Markdown
Author

I updated the PR again with the feedback from @ulyssessouza. For this I did a little refactoring and created service.enabled_for_profiles() to make the code a bit more readable.

@ulyssessouza
ulyssessouza self-requested a review December 2, 2020 12:42

@ulyssessouza ulyssessouza left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

Thanks @acran !

@aiordache
aiordache marked this pull request as ready for review December 2, 2020 18:56
@aiordache
aiordache requested a review from ndeloof as a code owner December 2, 2020 18:56
@aiordache
aiordache merged commit 5e3708e into docker:master Dec 2, 2020
acran added a commit to acran/docker.github.io that referenced this pull request Dec 3, 2020
Adds docs for the new service profiles feature introduced
in docker/compose#7930
acran added a commit to acran/docker.github.io that referenced this pull request Jan 25, 2021
Adds docs for the new service profiles feature introduced
in docker/compose#7930

Co-authored-by: Chris Crone <[email protected]>
acran added a commit to acran/docker.github.io that referenced this pull request Jan 25, 2021
Adds docs for the new service profiles feature introduced
in docker/compose#7930

Co-authored-by: Chris Crone <[email protected]>
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.

Implement service profiles in Compose

4 participants