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

adding support for docker stack config #510

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,6 @@ dmypy.json
.pyre/
docs/generated_sources
docs/site

# pycharm or other jetbrains ide
.idea/
27 changes: 27 additions & 0 deletions python_on_whales/components/stack/cli_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
from pathlib import Path
from typing import Any, Dict, List, Optional, Union

import yaml

import python_on_whales.components.service.cli_wrapper
import python_on_whales.components.task.cli_wrapper
from python_on_whales.client_config import DockerCLICaller
from python_on_whales.components.compose.models import ComposeConfig
from python_on_whales.utils import ValidPath, read_env_files, run, to_list


Expand Down Expand Up @@ -92,6 +95,30 @@ def deploy(
run(full_cmd, capture_stdout=False, env=env)
return Stack(self.client_config, name)

def config(
self,
compose_files: Union[ValidPath, List[ValidPath]],
env_files: Optional[List[ValidPath]] = None,
variables: Optional[Dict[str, str]] = None,
thosil marked this conversation as resolved.
Show resolved Hide resolved
return_json: bool = False,
) -> Union[ComposeConfig, Dict[str, Any]]:
env_files = [] if env_files is None else env_files
variables = {} if variables is None else variables

full_cmd = self.docker_cmd + ["stack", "config"]
thosil marked this conversation as resolved.
Show resolved Hide resolved
full_cmd.add_args_list("--compose-file", compose_files)

env = read_env_files([Path(x) for x in env_files])
env.update(variables)

result = yaml.safe_load(
run(full_cmd, capture_stdout=True, return_stderr=False, env=env)
)

if return_json:
return result
return ComposeConfig(**result)

def list(self) -> List[Stack]:
"""Returns a list of `python_on_whales.Stack`

Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ requests
tqdm
typer>=0.4.1
typing_extensions
pyyaml >= 6.0.1
thosil marked this conversation as resolved.
Show resolved Hide resolved
78 changes: 77 additions & 1 deletion tests/python_on_whales/components/test_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest

from python_on_whales import docker
from python_on_whales.exceptions import NotASwarmManager
from python_on_whales.exceptions import DockerException, NotASwarmManager
from python_on_whales.utils import PROJECT_ROOT


Expand Down Expand Up @@ -122,3 +122,79 @@ def test_services_not_swarm_manager():
docker.stack.services("dodo")

assert "not a swarm manager" in str(e.value).lower()


def test_stack_config_missing_compose_file():
with pytest.raises(DockerException) as e:
docker.stack.config(compose_files=[])

assert "Please specify a Compose file (with --compose-file)" in str(e.value)


def test_stack_config():
config = docker.stack.config(
[PROJECT_ROOT / "tests/python_on_whales/components/test-stack-file.yml"],
)

assert "app" in config.services
assert config.services["app"].image == "swarmpit/swarmpit:latest"


def test_stack_config_return_json():
config = docker.stack.config(
[PROJECT_ROOT / "tests/python_on_whales/components/test-stack-file.yml"],
return_json=True,
)

assert "app" in config["services"]
assert config["services"]["app"]["image"] == "swarmpit/swarmpit:latest"


def test_stack_config_variables():
config = docker.stack.config(
[PROJECT_ROOT / "tests/python_on_whales/components/test-stack-file.yml"],
variables={"SOME_VARIABLE": "hello-world"},
)

agent_service = config.services["agent"]
expected = "hello-world"
assert agent_service.environment["SOME_OTHER_VARIABLE"] == expected


def test_stack_config_variables_return_json():
config = docker.stack.config(
[PROJECT_ROOT / "tests/python_on_whales/components/test-stack-file.yml"],
variables={"SOME_VARIABLE": "hello-world"},
return_json=True,
)

agent_service = config["services"]["agent"]
expected = "hello-world"
assert agent_service["environment"]["SOME_OTHER_VARIABLE"] == expected


def test_stack_config_envfiles(tmp_path: Path):
env_file = tmp_path / "some.env"
env_file.write_text('SOME_VARIABLE="--tls=true" # some var \n # some comment')
config = docker.stack.config(
[PROJECT_ROOT / "tests/python_on_whales/components/test-stack-file.yml"],
env_files=[env_file],
)

agent_service = config.services["agent"]
expected = '"--tls=true"'
assert agent_service.environment["SOME_OTHER_VARIABLE"] == expected


def test_stack_config_envfiles_return_json(tmp_path: Path):
env_file = tmp_path / "some.env"
env_file.write_text('SOME_VARIABLE="--tls=true" # some var \n # some comment')
config = docker.stack.config(
[PROJECT_ROOT / "tests/python_on_whales/components/test-stack-file.yml"],
env_files=[env_file],
return_json=True,
)

agent_service = config["services"]["agent"]
expected = '"--tls=true"'
assert agent_service["environment"]["SOME_OTHER_VARIABLE"] == expected
Loading