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

[FEATURE] Multi service docker support #99

Open
wants to merge 45 commits into
base: develop
Choose a base branch
from

Conversation

jakeberesford-palmetto
Copy link
Collaborator

@jakeberesford-palmetto jakeberesford-palmetto commented May 16, 2023

Pull request checklist

Before submitting your PR, please review the following checklist:

  • Consider adding a unit test if your PR resolves an issue.
  • All new and existing tests pass locally (palm test)
  • Lint (palm lint) has passed locally and any fixes were made for failures
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)

Breaking changes

  • Check if this pull request introduces a breaking change

What does this implement/fix? Explain your changes.

Adds support for projects with multiple services in docker-compose.
Palm was originally built for very simple applications with a single 'primary' service. This has worked well for our needs, but doesn't allow folks to use palm for more complex projects.

Does this close any currently open issues?

#16

Any other comments?

I also added some new utilities to support this functionality:

  • choice prompt: easily create a 'choose from list' interface for any CLI command.
  • environment.get_plugin allows you to get a plugin by name, useful if a plugin provides a method for re-use
  • docker details: info about the docker-compose file is now available via environment.palm

Housekeeping:

  • Removed palm scaffold config - this was replaced by palm init long ago and is unused.

Note: This is still a WIP. I need to add tests and docs for all of this. Opening the PR now to get feedback on the functionality from users.

Testing instructions

To test this functionality, you will need a codebase with multiple docker services in your compose file.

  1. Pull this branch and install palm from source with python3 -m pip install .
  2. palm init to set your repo up for using palm if you haven't already done so.
  3. Add the multi_service plugin to your repo's .palm/config.yaml it should look like this:
plugins:
  - multi_service
  1. palm to see available commands, you should see a section for 'Multi Service' with up/down/logs/exec - try them out!
  2. Try writing a custom palm command to execute something useful in one (or more) of your containers
  3. Try to break it!

Don't forget to re-install palm from pypi after you're done testing! pip install -U palm

Where has this been tested?

Operating System: MacOS

Platform: Python 3.9

@jakeberesford-palmetto jakeberesford-palmetto changed the title [WIP] [FEATURE] Multi service docker support [FEATURE] Multi service docker support May 26, 2023
Copy link
Contributor

@norton120 norton120 left a comment

Choose a reason for hiding this comment

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

few nitts but great addition!

@@ -108,6 +108,22 @@ is provided via the palm context. If you want to use ``run_in_docker`` in your
own command, ensure you use the ``@click.pass_obj`` decorator for your command,
then use ``environment.run_in_docker(command)``.

Note that in multi-service applications, ``run_in_docker`` will run proxy your command
Copy link
Contributor

Choose a reason for hiding this comment

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

future iteration, should we have it say things like that with maybe an --plan flag? that instead of running the command, it describes in detail what the command would do?

@@ -90,6 +90,7 @@ def format_commands(self, ctx, formatter) -> None:
plugin_name = self.plugin_manager.plugin_command_dict.get(
subcommand
)
plugin_name = plugin_name.replace("_", " ")
Copy link
Contributor

Choose a reason for hiding this comment

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

❤️ this has bit me before trying to be smarter than the service

Returns:
str: The name of the running service
"""
cmd = 'docker ps -a --filter name={service} --format {{{{.Names}}}}'.format(
Copy link
Contributor

Choose a reason for hiding this comment

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

eventually it'd be nice to move to dockerpy, but at the same time it looks like Docker is (terrifyingly enough) slowing down support for dockerpy - so shelling may stay the safest option long-run

click.secho(
"This command is only available in multi-service repos", fg="red"
)
raise Exception("exec_in_docker only available in multi-service repos")
Copy link
Contributor

Choose a reason for hiding this comment

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

nitt - should it link you to the docs on how to enable multiservice? lots of editors like vscode will give you an easy cmd+ to open the link from the response in the browser

@@ -122,7 +166,27 @@ def plugin_config(self, plugin_name: str) -> Optional[BaseModel]:
Optional[BaseModel]: The config for the plugin, or None if the plugin
is not found or does not have a config
"""
plugin = self.plugin_manager.plugins.get(plugin_name)
plugin = self.get_plugin(plugin_name)
Copy link
Contributor

Choose a reason for hiding this comment

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

way nicer interface here 💥


def __init__(
self,
message: str = "No running services found, start your services with `palm up` and try again",
Copy link
Contributor

Choose a reason for hiding this comment

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

slick

def cli(environment, flags: tuple):
"""Bring up all services"""
# This sucks. Don't commit this.
flags = [f"-{flag}" if len(flag) == 1 else f"--{flag}" for flag in flags]
Copy link
Contributor

Choose a reason for hiding this comment

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

can you just do [f"--{flag}" for flag in flags] and let it join the single element?


@click.command("up")
@click.option(
"--no-detach", "-nd", is_flag=True, help="Run containers in the background."
Copy link
Contributor

Choose a reason for hiding this comment

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

should the help be "don't run containers in the background?"

from collections import OrderedDict


def choice_prompt(prompt: str, options: List[str]) -> str:
Copy link
Contributor

Choose a reason for hiding this comment

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

this is cool

- Add new multi-service plugin
- Add detection of multi-service docker setup
- Add container selection to run_in_docker
Adds new UI to allow users to select from a list
This will be used to get a list of services to support multi-service projects, but may be extended in the future to provide additional information about the docker configuration
- default to showing last 50 log lines
Allows users to exec arbitrary commands in any running container.
Create shared abstraction for choice prompt, this is useful in many contexts, not only environment.
This could be useful for other features and provides
a consistent way to access the compose yml
…want.

- Get a list of service names
- Check to make sure some services are running
- Make exec_in_docker work as expected
@jakeberesford-palmetto jakeberesford-palmetto force-pushed the feature/multi-service-docker-support branch from 5bb0b99 to 0462082 Compare November 9, 2023 20:28
@jakeberesford-palmetto jakeberesford-palmetto requested a review from a team as a code owner November 9, 2023 20:28
@jakeberesford-palmetto jakeberesford-palmetto requested review from emilypastewka, murphymoulds, david-jy-kim and a user and removed request for a team November 9, 2023 20:28
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.

2 participants