WIP
This commit is contained in:
parent
2feabd9c23
commit
244cb48f91
28 changed files with 328 additions and 118 deletions
README.mdgalaxy.ymlpyproject.toml
plugins
lookup
module_utils
common.py
label
service
common.pycustom.pydocker_in_docker.pydocker_socket_proxy.pydocker_volume_backupper.pymariadb.pypostgres.pyredis.py
spec.pymodules
roles
test.json
|
@ -1 +1 @@
|
|||
# Ansible Collection - snailed.ez_compose
|
||||
# Ansible Collection - snailed.ez_docker
|
||||
|
|
14
galaxy.yml
14
galaxy.yml
|
@ -1,6 +1,6 @@
|
|||
namespace: snailed
|
||||
|
||||
name: ez_compose
|
||||
name: ez_docker
|
||||
|
||||
version: 1.0.0
|
||||
|
||||
|
@ -15,18 +15,18 @@ license:
|
|||
- MIT
|
||||
|
||||
tags:
|
||||
- linux
|
||||
- infrastructure
|
||||
- docker
|
||||
- compose
|
||||
- docker_compose
|
||||
|
||||
dependencies: {}
|
||||
|
||||
repository: http://git.snaile.de/snailed/ez_compose
|
||||
repository: http://git.snaile.de/snailed/ez_docker
|
||||
|
||||
documentation: http://git.snaile.de/snailed/ez_compose/src/branch/main/docs
|
||||
documentation: http://git.snaile.de/snailed/ez_docker/src/branch/main/docs
|
||||
|
||||
homepage: http://git.snaile.de/snailed/ez_compose
|
||||
homepage: http://git.snaile.de/snailed/ez_docker
|
||||
|
||||
issues: http://git.snaile.de/snailed/ez_compose/issues
|
||||
issues: http://git.snaile.de/snailed/ez_docker/issues
|
||||
|
||||
build_ignore: []
|
||||
|
|
73
plugins/lookup/container_names.py
Normal file
73
plugins/lookup/container_names.py
Normal file
|
@ -0,0 +1,73 @@
|
|||
# Copyright: (c) 2025, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
# ruff: noqa: E402,ANN001,ANN003,ANN201
|
||||
# pyright: basic
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
name: container_names
|
||||
version_added: 1.0.0
|
||||
short_description: Discover container names from ez_docker projects
|
||||
description:
|
||||
- This module is needed by ez_cp to find the names of containers to copy files into.
|
||||
- It takes a project definition and returns a dict of name/container_name key/value pairs.
|
||||
author:
|
||||
- "Luca Bilke (@ssnailed)"
|
||||
options:
|
||||
_terms:
|
||||
description:
|
||||
- "name: definition dict of project to search in"
|
||||
type: list
|
||||
elements: dict
|
||||
required: true
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Discover container names in projects
|
||||
ansible.builtin.set_fact:
|
||||
containers: "{{ lookup('snailed.ez_docker.container_names', ez_docker_projects) }}"
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
_list:
|
||||
description:
|
||||
- List of discovered services in items format
|
||||
- [{key: name, value: container_name}, ...]
|
||||
type: list
|
||||
"""
|
||||
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
ret = []
|
||||
for term in terms:
|
||||
project_name = term.key
|
||||
project = term.value
|
||||
|
||||
for service_name, service in project.items():
|
||||
if not (overwrite := service.get("overwrite")):
|
||||
overwrite = service.get("definition")
|
||||
|
||||
if overwrite and (container_name := overwrite.get("container_name")):
|
||||
ret.append(
|
||||
{
|
||||
"key": service_name,
|
||||
"value": container_name,
|
||||
}
|
||||
)
|
||||
continue
|
||||
|
||||
ret.append(
|
||||
{
|
||||
"key": service_name,
|
||||
"value": f"{project_name}_{service_name}",
|
||||
}
|
||||
)
|
||||
|
||||
return ret
|
74
plugins/lookup/slurp.py
Normal file
74
plugins/lookup/slurp.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
# Copyright: (c) 2025, Luca Bilke <luca@bil.ke>
|
||||
# MIT License (see LICENSE)
|
||||
# ruff: noqa: E402,ANN001,ANN003,ANN201
|
||||
# pyright: basic
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: slurp
|
||||
version_added: 1.0.0
|
||||
short_description: Lookup version of the slurp module
|
||||
description:
|
||||
- Instead of running the slurp module against local host, I wrote this module
|
||||
author:
|
||||
- "Luca Bilke (@ssnailed)"
|
||||
options:
|
||||
_terms:
|
||||
description: path(s) of files to read
|
||||
required: True
|
||||
seealso:
|
||||
- ref: playbook_task_paths
|
||||
description: Search paths used for relative files.
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
- ansible.builtin.debug:
|
||||
msg: "{{ lookup('snailed.ez_docker.slurp', '/etc/foo.txt') | b64decode }}"
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
_list:
|
||||
description:
|
||||
- content of file(s)
|
||||
type: list
|
||||
elements: str
|
||||
"""
|
||||
|
||||
import base64
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleLookupError, AnsibleOptionsError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
def run(self, terms, variables=None, **kwargs):
|
||||
ret = []
|
||||
self.set_options(var_options=variables, direct=kwargs)
|
||||
|
||||
for term in terms:
|
||||
display.debug(f"File lookup term: {term}")
|
||||
|
||||
try:
|
||||
lookupfile = self.find_file_in_search_path(
|
||||
variables, "files", term, ignore_missing=True,
|
||||
)
|
||||
display.vvvv(f"File lookup using {lookupfile} as file")
|
||||
|
||||
if lookupfile:
|
||||
b_contents, _ = self._loader._get_file_contents(lookupfile) # noqa: SLF001 # pyright: ignore[reportOptionalMemberAccess]
|
||||
contents = base64.b64encode(b_contents)
|
||||
ret.append(contents)
|
||||
else:
|
||||
msg = "file not found, use -vvvvv to see paths searched"
|
||||
raise AnsibleOptionsError(msg)
|
||||
|
||||
except AnsibleError as e:
|
||||
msg = f"The 'file' lookup had an issue accessing the file '{term}'"
|
||||
raise AnsibleLookupError(msg, orig_exc=e) # noqa: B904
|
||||
|
||||
return ret
|
|
@ -9,7 +9,7 @@ from pathlib import Path
|
|||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
import yaml
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import Result, State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import Result, State
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible.module_utils.basic import AnsibleModule # pyright: ignore[reportMissingTypeStubs]
|
||||
|
|
|
@ -5,13 +5,13 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING, Any, Callable
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import (
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.common import (
|
||||
clean_none,
|
||||
recursive_update,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
|
||||
BASE_ARGS: dict[str, Any] = {}
|
||||
|
|
|
@ -6,7 +6,7 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"stop": {"type": "bool", "default": True},
|
||||
|
|
|
@ -6,7 +6,7 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"proxy_type": {"type": "str", "default": "http"},
|
||||
|
|
|
@ -6,7 +6,7 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"name": {"type": "str"},
|
||||
|
|
|
@ -6,7 +6,7 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"proxy_type": {"type": "str", "default": "http"},
|
||||
|
|
|
@ -7,13 +7,13 @@ import copy
|
|||
from dataclasses import replace
|
||||
from typing import TYPE_CHECKING, Any, Callable
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import (
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.common import (
|
||||
clean_none,
|
||||
recursive_update,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
BASE_ARGS: dict[str, Any] = {
|
||||
"name": {"type": "str"},
|
||||
|
|
|
@ -5,11 +5,11 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils import label, spec
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.common import clean_none
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils import label, spec
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.common import clean_none
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import (
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import (
|
||||
State,
|
||||
)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
EXTRA_ARGS = {}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"read_only": {"type": "bool", "default": True},
|
||||
|
|
|
@ -6,7 +6,7 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"archive": {"type": "path"},
|
||||
|
|
|
@ -7,7 +7,7 @@ import shlex
|
|||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"backup": {"type": "bool", "default": True},
|
||||
|
|
|
@ -7,7 +7,7 @@ import shlex
|
|||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
EXTRA_ARGS = {
|
||||
"backup": {"type": "bool", "default": True},
|
||||
|
|
|
@ -6,7 +6,7 @@ from __future__ import annotations
|
|||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils.models import State
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils.models import State
|
||||
|
||||
EXTRA_ARGS = {}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, Any
|
|||
if TYPE_CHECKING:
|
||||
from types import ModuleType
|
||||
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils import (
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils import (
|
||||
label,
|
||||
service,
|
||||
)
|
||||
|
|
|
@ -9,6 +9,7 @@ from dataclasses import asdict
|
|||
|
||||
# TODO: break this down per module
|
||||
# TODO: generate this by reassembling
|
||||
# TODO: add note about not setting container_name or host_name in defaults
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: compose
|
||||
|
@ -456,7 +457,7 @@ options:
|
|||
from importlib.util import find_spec
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule # pyright: ignore[reportMissingTypeStubs]
|
||||
from ansible_collections.snailed.ez_compose.plugins.module_utils import (
|
||||
from ansible_collections.snailed.ez_docker.plugins.module_utils import (
|
||||
common,
|
||||
service,
|
||||
spec,
|
||||
|
@ -473,7 +474,7 @@ def main() -> None:
|
|||
},
|
||||
"project_dir": {
|
||||
"type": "path",
|
||||
"default": "/var/lib/ez_compose",
|
||||
"default": "/var/lib/ez_docker",
|
||||
},
|
||||
"settings": spec.settings_spec(),
|
||||
"services": spec.service_argument_spec(),
|
||||
|
|
|
@ -14,18 +14,13 @@ ignore = [
|
|||
"COM812",
|
||||
"D100",
|
||||
"D101",
|
||||
"D102",
|
||||
"D103",
|
||||
"D104",
|
||||
"D203",
|
||||
"D213",
|
||||
]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"tests/units/**" = [
|
||||
"S101",
|
||||
"PT009",
|
||||
]
|
||||
|
||||
[tool.ruff.format]
|
||||
line-ending = "lf"
|
||||
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
---
|
||||
- name: Login in to registries
|
||||
community.docker.docker_login:
|
||||
registry_url: "{{ item.registry }}"
|
||||
username: "{{ item.username }}"
|
||||
password: "{{ item.password }}"
|
||||
loop: "{{ compose_registry_logins }}"
|
||||
no_log: true
|
||||
when: >-
|
||||
ez_compose_state | default(None) == "present"
|
||||
and ez_compose_registry_logins is defined
|
||||
and ez_compose_registry_logins
|
||||
|
||||
- name: Ensure shared networks exist
|
||||
community.docker.docker_network:
|
||||
name: "{{ item.name }}"
|
||||
attachable: "{{ item.attachable | default(omit) }}"
|
||||
connected: "{{ item.connected | default(omit) }}"
|
||||
driver: "{{ item.driver | default(omit) }}"
|
||||
driver_options: "{{ item.driver_options | default(omit) }}"
|
||||
enable_ipv6: "{{ item.enable_ipv6 | default(omit) }}"
|
||||
force: "{{ item.force | default(omit) }}"
|
||||
ipam_config: "{{ item.ipam_config | default(omit) }}"
|
||||
ipam_driver: "{{ item.ipam_driver | default(omit) }}"
|
||||
labels: "{{ item.labels | default(omit) }}"
|
||||
scope: "{{ item.scope | default(omit) }}"
|
||||
state: "{{ item.state | default(omit) }}"
|
||||
loop: "{{ ez_compose_shared_networks }}"
|
||||
when: >-
|
||||
ez_compose_state | default(None) == "present"
|
||||
and ez_compose_shared_networks is defined
|
||||
and ez_compose_shared_networks
|
||||
|
||||
- name: Ensure shared volumes exist
|
||||
community.docker.docker_network:
|
||||
name: "{{ item.name }}"
|
||||
driver: "{{ item.driver | default(omit) }}"
|
||||
driver_options: "{{ item.driver_options | default(omit) }}"
|
||||
labels: "{{ item.labels | default(omit) }}"
|
||||
recreate: "{{ item.recreate | default(omit) }}"
|
||||
state: "{{ item.state | default(omit) }}"
|
||||
loop: "{{ ez_compose_shared_volumes }}"
|
||||
when: >-
|
||||
ez_compose_state | default(None) == "present"
|
||||
and ez_compose_shared_volumes is defined
|
||||
and ez_compose_shared_volumes
|
||||
|
||||
- name: Discover project definitions
|
||||
ansible.builtin.set_fact:
|
||||
ez_compose_projects: >-
|
||||
{{
|
||||
hostvars[inventory_hostname]
|
||||
| dict2items
|
||||
| selectattr(
|
||||
'key', 'in', (
|
||||
hostvars[inventory_hostname].keys()
|
||||
| select('match', '^ez_compose_project_')
|
||||
)
|
||||
)
|
||||
}}
|
||||
when: >-
|
||||
ez_compose_projects is not defined
|
||||
or not ez_compose_projects
|
||||
|
||||
- name: Import project tasks
|
||||
ansible.builtin.include_tasks: project.yml
|
||||
when: >-
|
||||
[project.key | split('_') | last, 'compose-all'] | intersect(ansible_run_tags) | length > 0
|
||||
and not
|
||||
[project.key | split('_') | last, 'compose-all'] | intersect(ansible_skip_tags) | length > 0
|
||||
loop: "{{ ez_compose_projects }}"
|
||||
loop_control:
|
||||
loop_var: project
|
||||
# no_log: true
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
- name: "project | Write compose file: {{ project.name }}"
|
||||
snailed.ez_compose.compose:
|
||||
name: "{{ project.key | split('_') | last }}"
|
||||
services: "{{ project.value }}"
|
||||
settings: "{{ ez_compose_settings }}"
|
||||
project_dir: "{{ ez_compose_project_dir }}"
|
49
roles/ez_docker/default/main.yml
Normal file
49
roles/ez_docker/default/main.yml
Normal file
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
# Registries to log in to with community.docker.docker_login
|
||||
ez_docker_registry_logins: []
|
||||
# - username: "example"
|
||||
# password: "example"
|
||||
# registry_url: "example.registry.url"
|
||||
|
||||
# A list of docker compose network definitions to create with
|
||||
# community.docker.docker_network and mark as external in projects
|
||||
ez_docker_shared_networks: []
|
||||
# - name: "shared_network"
|
||||
|
||||
# A list of docker compose volume definitions to create with
|
||||
# community.docker.docker_volume and mark as external in projects
|
||||
ez_docker_shared_volumes: []
|
||||
# - name: "shared_volume"
|
||||
|
||||
# Directory to put compose projects into
|
||||
ez_docker_project_dir: "/var/lib/ez_compose"
|
||||
|
||||
# Settings for the module
|
||||
ez_docker_settings:
|
||||
default_definition: {}
|
||||
# environment:
|
||||
# TZ: "Europe/Berlin"
|
||||
label_default_args: {}
|
||||
# traefik_router:
|
||||
# certresolver: "letsencrypt"
|
||||
# entrypoints: ["web-secure"]
|
||||
service_default_definitions: {}
|
||||
# docker_volume_backupper:
|
||||
# image: "offen/docker-volume-backup:v2.43.0"
|
||||
# environment:
|
||||
# BACKUP_CRON_EXPRESSION: "0 6 * * *"
|
||||
# BACKUP_RETENTION_DAYS: "7"
|
||||
service_default_args: {}
|
||||
# docker_volume_backupper:
|
||||
# archive: "/tank/docker-backups"
|
||||
#
|
||||
ez_cp_controller_files_root: "{{ playbook_dir }}/files/ez_cp/{{ inventory_hostname }}"
|
||||
ez_cp_controller_templates_root: "{{ playbook_dir }}/templates/ez_cp/{{ inventory_hostname }}"
|
||||
|
||||
# To copy into a non-running container we need the UID/GID for the files
|
||||
# TODO: implement this
|
||||
ez_cp_service_owners: {}
|
||||
# project_name:
|
||||
# service_name:
|
||||
# uid: 1000
|
||||
# gid: 1000
|
38
roles/ez_docker/tasks/main.yml
Normal file
38
roles/ez_docker/tasks/main.yml
Normal file
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
- name: Discover project definitions
|
||||
ansible.builtin.set_fact:
|
||||
ez_docker_projects: >-
|
||||
{{
|
||||
hostvars[inventory_hostname]
|
||||
| dict2items
|
||||
| selectattr(
|
||||
'key', 'in', (
|
||||
hostvars[inventory_hostname].keys()
|
||||
| select('match', '^ez_docker_project_')
|
||||
)
|
||||
)
|
||||
}}
|
||||
when: not ez_docker_projects
|
||||
|
||||
- name: Login in to registries
|
||||
community.docker.docker_login: "{{ item }}" # noqa: args[module]
|
||||
loop: "{{ ez_docker_registry_logins }}"
|
||||
no_log: true
|
||||
when: ez_docker_registry_logins
|
||||
|
||||
- name: Ensure shared networks exist # noqa: args[module]
|
||||
community.docker.docker_network: "{{ item }}"
|
||||
loop: "{{ ez_docker_shared_networks }}"
|
||||
when: ez_docker_shared_networks
|
||||
|
||||
- name: Ensure shared volumes exist # noqa: args[module]
|
||||
community.docker.docker_volume: "{{ item }}"
|
||||
loop: "{{ ez_docker_shared_volumes }}"
|
||||
when: ez_docker_shared_volumes
|
||||
|
||||
- name: Import per-project tasks
|
||||
ansible.builtin.include_tasks: project.yml
|
||||
loop: "{{ ez_docker_projects }}"
|
||||
loop_control:
|
||||
loop_var: project_definition
|
||||
no_log: true
|
27
roles/ez_docker/tasks/project.yml
Normal file
27
roles/ez_docker/tasks/project.yml
Normal file
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
- name: "project | Write compose files: {{ project_definition.key }}"
|
||||
snailed.ez_docker.compose:
|
||||
name: "{{ project_definition.key | split('_') | last }}"
|
||||
services: "{{ project_definition.value }}"
|
||||
settings: "{{ ez_docker_settings }}"
|
||||
project_dir: "{{ ez_docker_project_dir }}"
|
||||
no_log: true
|
||||
|
||||
- name: "project | Start project: {{ project.name }}"
|
||||
community.docker.docker_compose_v2:
|
||||
pull: missing
|
||||
project_src: "{{ ez_docker_project_dir }}/{{ project_definition.key }}"
|
||||
state: "present"
|
||||
|
||||
- name: "project | Import per-service tasks: {{ project_definition.key }}"
|
||||
ansible.builtin.include_tasks: service.yml
|
||||
with_snailed.ez_docker.container_names: "{{ project_definition }}"
|
||||
loop_control:
|
||||
loop_var: service
|
||||
|
||||
- name: "project | Restart docker projects: {{ project_definition.key }}"
|
||||
community.docker.docker_compose_v2:
|
||||
services: services_changed
|
||||
project_src: "{{ ez_docker_project_dir }}/{{ project_definition.key }}"
|
||||
state: "restarted"
|
||||
when: services_changed
|
34
roles/ez_docker/tasks/service.yml
Normal file
34
roles/ez_docker/tasks/service.yml
Normal file
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
- name: "service | Copy files into container: {{ service.key }}"
|
||||
community.docker.docker_container_copy_into:
|
||||
container: "{{ service.value }}"
|
||||
container_path: "/{{ item.path }}"
|
||||
content: >-
|
||||
{{ snailed.ez_docker.slurp(
|
||||
ez_cp_controller_files_root ~ "/" ~ project.key ~ "/" ~ service.key ~ "/" ~ item.path
|
||||
) }}
|
||||
content_is_b64: true
|
||||
mode: "{{ item.mode | int(base=8) }}"
|
||||
when: item.state == "file"
|
||||
with_community.general.filetree:
|
||||
- "{{ ez_cp_controller_files_root }}/{{ project.key }}/{{ service.key }}"
|
||||
register: copy
|
||||
|
||||
- name: "service | Template files into container: {{ service.key }}"
|
||||
community.docker.docker_container_copy_into:
|
||||
container: "{{ service.value }}"
|
||||
container_path: "/{{ item.path }}"
|
||||
content: >-
|
||||
{{ ansible.builtin.template(
|
||||
ez_cp_controller_templates_root ~ "/" ~ project.key ~ "/" ~ service.key ~ "/" ~ item.path,
|
||||
convert_data=false
|
||||
) }}
|
||||
mode: "{{ item.mode | int(base=8) }}"
|
||||
when: item.state == "file"
|
||||
with_community.general.filetree:
|
||||
- "{{ ez_cp_controller_templates_root }}/{{ project.key }}/{{ service.key }}"
|
||||
register: template
|
||||
|
||||
- name: "service | Register file changes: {{ service.key }}"
|
||||
ansible.builtin.set_fact:
|
||||
services_changed: "{{ services_changed | default([]) + [service.key] }}"
|
|
@ -23,7 +23,6 @@
|
|||
"label_helpers": {
|
||||
"docker_volume_backupper": {},
|
||||
"traefik_router": {
|
||||
"entrypoints": ["web-secure"],
|
||||
"rule": "Host(`taskwarrior-sync.snailed.de`)"
|
||||
}
|
||||
},
|
||||
|
@ -44,7 +43,8 @@
|
|||
},
|
||||
"label_default_args": {
|
||||
"traefik_router": {
|
||||
"certresolver": "letsencrypt"
|
||||
"certresolver": "letsencrypt",
|
||||
"entrypoints": ["web-secure"]
|
||||
}
|
||||
},
|
||||
"service_default_args": {
|
||||
|
|
Loading…
Add table
Reference in a new issue