From 47254833034d587500769503a890167b8a1768c8 Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sat, 9 Dec 2023 16:46:13 +0100 Subject: [PATCH 01/10] feat(template): add support for passing all docker run arguments --- defaults/main.yml | 4 ++ molecule/default_vagrant/group_vars/all.yml | 11 +++++- molecule/default_vagrant/prepare.yml | 2 + templates/unit.j2 | 41 +++++++++++---------- 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 08691f6..99eb48c 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -5,6 +5,8 @@ docker_systemd_service_image: docker_systemd_service_container_env: {} docker_systemd_service_container_pull_image: true docker_systemd_service_container_pull_force_source: true +docker_systemd_service_flags: [] +#! TO REPLACE docker_systemd_service_container_labels: [] docker_systemd_service_container_cmd: [] docker_systemd_service_container_host_network: false @@ -20,6 +22,8 @@ docker_systemd_service_container_cap_drop: [] docker_systemd_service_container_devices: [] docker_systemd_service_container_privileged: false docker_systemd_service_container_args: "" +#! END TO REPLACE + docker_systemd_service_name: "{{ docker_systemd_service_container_name }}_container" docker_systemd_service_systemd_options: [] docker_systemd_service_enabled: true diff --git a/molecule/default_vagrant/group_vars/all.yml b/molecule/default_vagrant/group_vars/all.yml index a2f343b..f4a6cb9 100644 --- a/molecule/default_vagrant/group_vars/all.yml +++ b/molecule/default_vagrant/group_vars/all.yml @@ -1,11 +1,17 @@ --- -docker_systemd_service_container_name: "nginx" +docker_systemd_service_container_name: "ninx" docker_systemd_service_image: nginx docker_systemd_service_container_env: {} docker_systemd_service_container_pull_image: true docker_systemd_service_container_pull_force_source: false -docker_systemd_service_container_labels: [] +docker_systemd_service_flags: + - network: host + - volume: + - /root:/mnt/volume + - /var:/test:ro docker_systemd_service_container_cmd: [] +#! TO REPLACE +docker_systemd_service_container_labels: [] docker_systemd_service_container_host_network: false docker_systemd_service_container_network: "" docker_systemd_service_container_user: "" @@ -19,6 +25,7 @@ docker_systemd_service_container_cap_drop: [] docker_systemd_service_container_devices: [] docker_systemd_service_container_privileged: false docker_systemd_service_container_args: "" +#! END TO REPLACE docker_systemd_service_name: "{{ docker_systemd_service_container_name }}_container" docker_systemd_service_systemd_options: [] docker_systemd_service_enabled: true diff --git a/molecule/default_vagrant/prepare.yml b/molecule/default_vagrant/prepare.yml index af09212..06b4860 100644 --- a/molecule/default_vagrant/prepare.yml +++ b/molecule/default_vagrant/prepare.yml @@ -6,3 +6,5 @@ - name: "Install docker" ansible.builtin.include_role: name: ednxzu.install_docker + vars: + install_docker_python_packages: true diff --git a/templates/unit.j2 b/templates/unit.j2 index a20e2d2..01aa6f7 100644 --- a/templates/unit.j2 +++ b/templates/unit.j2 @@ -1,7 +1,22 @@ # {{ ansible_managed }} -{% macro params(name, vals) %} -{% for v in vals %}{{ name }} {{ v }} {% endfor %} +{%- macro create_docker_flags(flags) %} +{% for item in flags %} +{{ create_docker_flag(item) }} +{% endfor %} +{% endmacro -%} + +{%- macro create_docker_flag(item) %} +{% set key = item.keys() | first %} +{% set value = item[key] %} +{%- if value is string %} +--{{ key }} {{ value }} \ +{%- elif value is iterable and value is not string %} +{% for val in value %} +--{{ key }} {{ val }} \{% if not loop.last +%} +{% endif %}{% endfor %} +{% endif -%} {% endmacro %} + {% set service_systemd_options_keys = docker_systemd_service_systemd_options | selectattr("key") | map(attribute="key") | list %} [Unit] {% for key, value in docker_systemd_service_systemd_unit_options | dictsort %} @@ -12,30 +27,18 @@ {% for item in docker_systemd_service_systemd_options %} {{ item['key'] }}={{ item['value'] }} {% endfor %} -{% if docker_systemd_service_container_env is defined %} {% if not 'EnvironmentFile' in service_systemd_options_keys %} EnvironmentFile={{ docker_systemd_service_sysconf_dir }}/{{ docker_systemd_service_container_name }} {% endif %} -{% endif %} {% if not 'ExecStartPre' in service_systemd_options_keys %} ExecStartPre=-{{ docker_systemd_service_docker_path }} rm -f {{ docker_systemd_service_container_name }} {% endif %} {% if not 'ExecStart' in service_systemd_options_keys %} -{% if docker_systemd_service_container_env is defined %}ExecStart={{ docker_systemd_service_docker_path }} run --name {{ docker_systemd_service_container_name }} --rm --env-file {{ docker_systemd_service_sysconf_dir }}/{{ docker_systemd_service_container_name }} {% endif %}\ -{{ params('--volume', docker_systemd_service_container_volumes)~' \\'| trim }} -{% if docker_systemd_service_container_host_network == true %}--network host \{% else %}{{ params('--publish', docker_systemd_service_container_ports)~'\\'| trim }}{% endif +%} -{% if docker_systemd_service_container_network %}--network {{ docker_systemd_service_container_network }} {% endif %}\ -{% if docker_systemd_service_container_user %}--user {{ docker_systemd_service_container_user }} {% endif %}\ -{% if docker_systemd_service_container_hostname %}--hostname {{ docker_systemd_service_container_hostname }} {% endif %}\ -{{ params('--link', docker_systemd_service_container_links)~' \\'| trim }} -{{ params('--add-host', docker_systemd_service_container_hosts)~' \\'| trim }} -{{ params('--label', docker_systemd_service_container_labels)~' \\'| trim }} -{{ params('--cap-add', docker_systemd_service_container_cap_add)~' \\'| trim }} -{{ params('--cap-drop', docker_systemd_service_container_cap_drop)~' \\'| trim }} -{{ params('--device', docker_systemd_service_container_devices)~' \\'| trim }} -{% if docker_systemd_service_container_privileged == true %}--privileged {% endif %}\ -{{ docker_systemd_service_container_args~' \\'| trim}} -{{ docker_systemd_service_image -}}{{ ' ' if docker_systemd_service_container_cmd else '' }}{% if docker_systemd_service_container_cmd is string %}{{ docker_systemd_service_container_cmd | trim }}{% else %}{{ docker_systemd_service_container_cmd | join(' ') | trim }}{% endif %} +ExecStart={{ docker_systemd_service_docker_path }} run --name {{ docker_systemd_service_container_name }} \ +--rm \ +--env-file {{ docker_systemd_service_sysconf_dir }}/{{ docker_systemd_service_container_name }} \ +{{ create_docker_flags(docker_systemd_service_flags) -}} +{{- docker_systemd_service_image -}}{{ ' ' if docker_systemd_service_container_cmd else '' }}{% if docker_systemd_service_container_cmd is string %}{{ docker_systemd_service_container_cmd | trim }}{% else %}{{ docker_systemd_service_container_cmd | join(' ') | trim }}{% endif %} {% endif +%} {% if not 'ExecStop' in service_systemd_options_keys %} ExecStop={{ docker_systemd_service_docker_path }} stop {{ docker_systemd_service_container_name }} -- 2.45.2 From 84aac3e7163c51269e590d024b77e5d44c03797c Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sat, 9 Dec 2023 16:48:02 +0100 Subject: [PATCH 02/10] feat(readme): credits mhutter for original material --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d1538e6..7128ffa 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ docker_systemd_service ========= > This repository is only a mirror. Development and testing is done on a private gitea server. -This role lets you configure a docker container and run it as a systemd service on **debian-based** distributions. +This role lets you configure a docker container and run it as a systemd service on **debian-based** distributions. This role is heavily sourced from [mhutter.docker-systemd-service](https://github.com/mhutter/ansible-docker-systemd-service), but aims at providing some of the missing features of said role. Requirements ------------ -- 2.45.2 From 2c275b9f1c2172a40e9f836df2beb964adba1486 Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sat, 9 Dec 2023 17:47:35 +0100 Subject: [PATCH 03/10] feat(template): add support for simple string flags --- molecule/default_vagrant/group_vars/all.yml | 1 + templates/unit.j2 | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/molecule/default_vagrant/group_vars/all.yml b/molecule/default_vagrant/group_vars/all.yml index f4a6cb9..6f2f7f4 100644 --- a/molecule/default_vagrant/group_vars/all.yml +++ b/molecule/default_vagrant/group_vars/all.yml @@ -5,6 +5,7 @@ docker_systemd_service_container_env: {} docker_systemd_service_container_pull_image: true docker_systemd_service_container_pull_force_source: false docker_systemd_service_flags: + - privileged - network: host - volume: - /root:/mnt/volume diff --git a/templates/unit.j2 b/templates/unit.j2 index 01aa6f7..9b2a8fb 100644 --- a/templates/unit.j2 +++ b/templates/unit.j2 @@ -6,15 +6,19 @@ {% endmacro -%} {%- macro create_docker_flag(item) %} +{%- if item is mapping %} {% set key = item.keys() | first %} {% set value = item[key] %} {%- if value is string %} --{{ key }} {{ value }} \ -{%- elif value is iterable and value is not string %} +{%- elif value is iterable %} {% for val in value %} --{{ key }} {{ val }} \{% if not loop.last +%} {% endif %}{% endfor %} {% endif -%} +{%- elif item is string %} +--{{ item }} \ +{%- endif -%} {% endmacro %} {% set service_systemd_options_keys = docker_systemd_service_systemd_options | selectattr("key") | map(attribute="key") | list %} -- 2.45.2 From b46674110299367007168496890207b404641cd7 Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sat, 9 Dec 2023 18:20:54 +0100 Subject: [PATCH 04/10] feat(template): test the type of data against list to enable passing integers or strings or lists --- molecule/default_vagrant/group_vars/all.yml | 3 +++ templates/unit.j2 | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/molecule/default_vagrant/group_vars/all.yml b/molecule/default_vagrant/group_vars/all.yml index 6f2f7f4..d797bed 100644 --- a/molecule/default_vagrant/group_vars/all.yml +++ b/molecule/default_vagrant/group_vars/all.yml @@ -10,6 +10,9 @@ docker_systemd_service_flags: - volume: - /root:/mnt/volume - /var:/test:ro + - health-cmd: curl localhost:80 + - health-retries: 10 + docker_systemd_service_container_cmd: [] #! TO REPLACE docker_systemd_service_container_labels: [] diff --git a/templates/unit.j2 b/templates/unit.j2 index 9b2a8fb..f671ce4 100644 --- a/templates/unit.j2 +++ b/templates/unit.j2 @@ -9,13 +9,13 @@ {%- if item is mapping %} {% set key = item.keys() | first %} {% set value = item[key] %} -{%- if value is string %} ---{{ key }} {{ value }} \ -{%- elif value is iterable %} +{%- if value.__class__.__name__ == 'list' %} {% for val in value %} ---{{ key }} {{ val }} \{% if not loop.last +%} +--{{ key }} "{{ val }}" \{% if not loop.last +%} {% endif %}{% endfor %} -{% endif -%} +{%- else %} +--{{ key }} "{{ value }}" \ +{%- endif %} {%- elif item is string %} --{{ item }} \ {%- endif -%} -- 2.45.2 From 562fc0215e4d7d4d30d421dd84425937924eacc0 Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sat, 9 Dec 2023 18:36:25 +0100 Subject: [PATCH 05/10] feat(template): move flag formatting to filter_plugin --- filter_plugins/docker_filters.py | 26 +++++++++++++++++++++ molecule/default_vagrant/group_vars/all.yml | 3 +++ templates/unit.j2 | 26 ++------------------- 3 files changed, 31 insertions(+), 24 deletions(-) create mode 100644 filter_plugins/docker_filters.py diff --git a/filter_plugins/docker_filters.py b/filter_plugins/docker_filters.py new file mode 100644 index 0000000..6c163a8 --- /dev/null +++ b/filter_plugins/docker_filters.py @@ -0,0 +1,26 @@ +# filter_plugins/docker_filters.py + + +def create_docker_flags(flags): + return "\n".join([create_docker_flag(item) for item in flags]) + + +def create_docker_flag(item): + if isinstance(item, dict): + key = list(item.keys())[0] + value = item[key] + if isinstance(value, list): + return "\n".join(['--{} "{}" \\'.format(key, val) for val in value]) + else: + return '--{} "{}" \\'.format(key, value) + elif isinstance(item, str): + return "--{} \\".format(item) + else: + return "" + + +class FilterModule(object): + def filters(self): + return { + "create_docker_flags": create_docker_flags, + } diff --git a/molecule/default_vagrant/group_vars/all.yml b/molecule/default_vagrant/group_vars/all.yml index d797bed..b02a738 100644 --- a/molecule/default_vagrant/group_vars/all.yml +++ b/molecule/default_vagrant/group_vars/all.yml @@ -12,6 +12,9 @@ docker_systemd_service_flags: - /var:/test:ro - health-cmd: curl localhost:80 - health-retries: 10 + - cap-add: + - SYS_ADMIN + - dns: "8.8.8.8" docker_systemd_service_container_cmd: [] #! TO REPLACE diff --git a/templates/unit.j2 b/templates/unit.j2 index f671ce4..f75743a 100644 --- a/templates/unit.j2 +++ b/templates/unit.j2 @@ -1,26 +1,4 @@ # {{ ansible_managed }} -{%- macro create_docker_flags(flags) %} -{% for item in flags %} -{{ create_docker_flag(item) }} -{% endfor %} -{% endmacro -%} - -{%- macro create_docker_flag(item) %} -{%- if item is mapping %} -{% set key = item.keys() | first %} -{% set value = item[key] %} -{%- if value.__class__.__name__ == 'list' %} -{% for val in value %} ---{{ key }} "{{ val }}" \{% if not loop.last +%} -{% endif %}{% endfor %} -{%- else %} ---{{ key }} "{{ value }}" \ -{%- endif %} -{%- elif item is string %} ---{{ item }} \ -{%- endif -%} -{% endmacro %} - {% set service_systemd_options_keys = docker_systemd_service_systemd_options | selectattr("key") | map(attribute="key") | list %} [Unit] {% for key, value in docker_systemd_service_systemd_unit_options | dictsort %} @@ -41,8 +19,8 @@ ExecStartPre=-{{ docker_systemd_service_docker_path }} rm -f {{ docker_systemd_s ExecStart={{ docker_systemd_service_docker_path }} run --name {{ docker_systemd_service_container_name }} \ --rm \ --env-file {{ docker_systemd_service_sysconf_dir }}/{{ docker_systemd_service_container_name }} \ -{{ create_docker_flags(docker_systemd_service_flags) -}} -{{- docker_systemd_service_image -}}{{ ' ' if docker_systemd_service_container_cmd else '' }}{% if docker_systemd_service_container_cmd is string %}{{ docker_systemd_service_container_cmd | trim }}{% else %}{{ docker_systemd_service_container_cmd | join(' ') | trim }}{% endif %} +{{ docker_systemd_service_flags|create_docker_flags }} +{{ docker_systemd_service_image -}}{{ ' ' if docker_systemd_service_container_cmd else '' }}{% if docker_systemd_service_container_cmd is string %}{{ docker_systemd_service_container_cmd | trim }}{% else %}{{ docker_systemd_service_container_cmd | join(' ') | trim }}{% endif %} {% endif +%} {% if not 'ExecStop' in service_systemd_options_keys %} ExecStop={{ docker_systemd_service_docker_path }} stop {{ docker_systemd_service_container_name }} -- 2.45.2 From d15bce04dea78d45fed22ddbfbeb0df5885f31c7 Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sat, 9 Dec 2023 19:47:00 +0100 Subject: [PATCH 06/10] feat(readme): update documentation on variables --- README.md | 93 +++++---------------- molecule/default_vagrant/group_vars/all.yml | 7 +- 2 files changed, 23 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index 7128ffa..f08d6a6 100644 --- a/README.md +++ b/README.md @@ -39,79 +39,28 @@ docker_systemd_service_container_pull_force_source: true # by default, set to tr If `docker_systemd_service_container_pull_image: true`, whether the pull you be executed at every run. See [`docker_image.force_source`](https://docs.ansible.com/ansible/latest/collections/community/docker/docker_image_module.html#parameter-force_source) ```yaml -docker_systemd_service_container_labels: [] # by default, set to [] +docker_systemd_service_flags: [] # by default, set to [] ``` -A list of labels to add to the container. These should be strings of the form `some.label=value`. - -```yaml -docker_systemd_service_container_cmd: [] # by default, set to [] -``` -A list of container run command to apply. - -```yaml -docker_systemd_service_container_host_network: false # by default, set to false -``` -Whether the container should use the `network_mode: host`. - -```yaml -docker_systemd_service_container_network: "" # by default, set to "" -``` -If `docker_systemd_service_container_host_network: false`, you can define the network to use for the container. - -```yaml -docker_systemd_service_container_user: "" # by default, set to "" -``` -Define a user to use within the container. See [user settings](https://docs.docker.com/engine/reference/run/#user) - -```yaml -docker_systemd_service_container_hostname: "" # by default, set to "" -``` -The hostname to apply to the container. - -```yaml -docker_systemd_service_container_links: [] # by default, set to [] -``` -A list of `--links` arguments. - -```yaml -docker_systemd_service_container_ports: [] # by default, set to [] -``` -A list of ports to expose. Example: `:` - -```yaml -docker_systemd_service_container_hosts: [] # by default, set to [] -``` -A list of `--add-host` arguments. - -```yaml -docker_systemd_service_container_volumes: [] # by default, set to [] -``` -A list of volumes and their mount points. Example: `/path/on/host:/path/in/container` - -```yaml -docker_systemd_service_container_cap_add: [] # by default, set to [] -``` -A list of capabilities to add to the container. Example: `SYS_ADMIN`. - -```yaml -docker_systemd_service_container_cap_drop: [] # by default, set to [] -``` -A list of capabilities to remove from the container. - -```yaml -docker_systemd_service_container_devices: [] # by default, set to [] -``` -A list of devices to add to the container. - -```yaml -docker_systemd_service_container_privileged: false # by default, set to false -``` -Whether to run the container in privileged mode. See [runtime privilege](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities) - -```yaml -docker_systemd_service_container_args: "" # by default, set to "" -``` -Arbitrary list of arguments to the `docker run` command as a string. +This variable lets you pass whatever flags you need to the docker run command. It is a list, to which you can add multiple types of flags: + - ```yaml + - key: value + # will pass the flag --key "value" to the container. + Example: + - network: host + - ```yaml + - simple_key + # will pass the flag --simple_key to the container. + Example: + - privileged + - ```yaml + - key: + - value1 + - value2 + # will pass the flags --key "value1" --key "value2" to the container. + Example: + - volume: + - /path/on/host:/path/on/container + - /var/run/docker.sock:/var/run/docker.sock:ro ```yaml docker_systemd_service_name: "{{ docker_systemd_service_container_name }}_container" # by default, set to "{{ docker_systemd_service_container_name }}_container" diff --git a/molecule/default_vagrant/group_vars/all.yml b/molecule/default_vagrant/group_vars/all.yml index b02a738..b0f1b7f 100644 --- a/molecule/default_vagrant/group_vars/all.yml +++ b/molecule/default_vagrant/group_vars/all.yml @@ -5,16 +5,13 @@ docker_systemd_service_container_env: {} docker_systemd_service_container_pull_image: true docker_systemd_service_container_pull_force_source: false docker_systemd_service_flags: + - health-cmd: curl localhost:80 + - health-retries: 10 - privileged - network: host - volume: - /root:/mnt/volume - /var:/test:ro - - health-cmd: curl localhost:80 - - health-retries: 10 - - cap-add: - - SYS_ADMIN - - dns: "8.8.8.8" docker_systemd_service_container_cmd: [] #! TO REPLACE -- 2.45.2 From f813944d742a89546e830bc5fb0378e165dcfa44 Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sun, 10 Dec 2023 17:32:52 +0100 Subject: [PATCH 07/10] feat(tests): add testing for the default values on both docker and vagrant --- defaults/main.yml | 17 ------------ filter_plugins/docker_filters.py | 4 ++- molecule/default/group_vars/all.yml | 17 ++---------- molecule/default/verify.yml | 17 +++--------- molecule/default_vagrant/group_vars/all.yml | 30 +++------------------ molecule/default_vagrant/verify.yml | 17 +++--------- templates/unit.j2 | 5 ++-- 7 files changed, 17 insertions(+), 90 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index 99eb48c..f70688b 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -6,24 +6,7 @@ docker_systemd_service_container_env: {} docker_systemd_service_container_pull_image: true docker_systemd_service_container_pull_force_source: true docker_systemd_service_flags: [] -#! TO REPLACE -docker_systemd_service_container_labels: [] docker_systemd_service_container_cmd: [] -docker_systemd_service_container_host_network: false -docker_systemd_service_container_network: "" -docker_systemd_service_container_user: "" -docker_systemd_service_container_hostname: "" -docker_systemd_service_container_links: [] -docker_systemd_service_container_ports: [] -docker_systemd_service_container_hosts: [] -docker_systemd_service_container_volumes: [] -docker_systemd_service_container_cap_add: [] -docker_systemd_service_container_cap_drop: [] -docker_systemd_service_container_devices: [] -docker_systemd_service_container_privileged: false -docker_systemd_service_container_args: "" -#! END TO REPLACE - docker_systemd_service_name: "{{ docker_systemd_service_container_name }}_container" docker_systemd_service_systemd_options: [] docker_systemd_service_enabled: true diff --git a/filter_plugins/docker_filters.py b/filter_plugins/docker_filters.py index 6c163a8..ee7e669 100644 --- a/filter_plugins/docker_filters.py +++ b/filter_plugins/docker_filters.py @@ -2,7 +2,9 @@ def create_docker_flags(flags): - return "\n".join([create_docker_flag(item) for item in flags]) + if flags: + return "\n".join([create_docker_flag(item) for item in flags]) + return None def create_docker_flag(item): diff --git a/molecule/default/group_vars/all.yml b/molecule/default/group_vars/all.yml index c719622..1546e18 100644 --- a/molecule/default/group_vars/all.yml +++ b/molecule/default/group_vars/all.yml @@ -1,24 +1,11 @@ --- docker_systemd_service_container_name: "nginx" -docker_systemd_service_image: "nginx" +docker_systemd_service_image: nginx docker_systemd_service_container_env: {} docker_systemd_service_container_pull_image: false docker_systemd_service_container_pull_force_source: false -docker_systemd_service_container_labels: [] +docker_systemd_service_flags: [] docker_systemd_service_container_cmd: [] -docker_systemd_service_container_host_network: false -docker_systemd_service_container_network: "" -docker_systemd_service_container_user: "" -docker_systemd_service_container_hostname: "" -docker_systemd_service_container_links: [] -docker_systemd_service_container_ports: [] -docker_systemd_service_container_hosts: [] -docker_systemd_service_container_volumes: [] -docker_systemd_service_container_cap_add: [] -docker_systemd_service_container_cap_drop: [] -docker_systemd_service_container_devices: [] -docker_systemd_service_container_privileged: false -docker_systemd_service_container_args: "" docker_systemd_service_name: "{{ docker_systemd_service_container_name }}_container" docker_systemd_service_systemd_options: [] docker_systemd_service_enabled: true diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index 7845ff9..433b360 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -53,20 +53,9 @@ [Service] EnvironmentFile=/etc/default/nginx ExecStartPre=-/usr/bin/docker rm -f nginx - ExecStart=/usr/bin/docker run --name nginx --rm --env-file /etc/default/nginx \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ + ExecStart=/usr/bin/docker run --name nginx \ + --rm \ + --env-file /etc/default/nginx \ nginx ExecStop=/usr/bin/docker stop nginx SyslogIdentifier=nginx diff --git a/molecule/default_vagrant/group_vars/all.yml b/molecule/default_vagrant/group_vars/all.yml index b0f1b7f..359ff70 100644 --- a/molecule/default_vagrant/group_vars/all.yml +++ b/molecule/default_vagrant/group_vars/all.yml @@ -1,35 +1,11 @@ --- -docker_systemd_service_container_name: "ninx" +docker_systemd_service_container_name: "nginx" docker_systemd_service_image: nginx docker_systemd_service_container_env: {} docker_systemd_service_container_pull_image: true -docker_systemd_service_container_pull_force_source: false -docker_systemd_service_flags: - - health-cmd: curl localhost:80 - - health-retries: 10 - - privileged - - network: host - - volume: - - /root:/mnt/volume - - /var:/test:ro - +docker_systemd_service_container_pull_force_source: true +docker_systemd_service_flags: [] docker_systemd_service_container_cmd: [] -#! TO REPLACE -docker_systemd_service_container_labels: [] -docker_systemd_service_container_host_network: false -docker_systemd_service_container_network: "" -docker_systemd_service_container_user: "" -docker_systemd_service_container_hostname: "" -docker_systemd_service_container_links: [] -docker_systemd_service_container_ports: [] -docker_systemd_service_container_hosts: [] -docker_systemd_service_container_volumes: [] -docker_systemd_service_container_cap_add: [] -docker_systemd_service_container_cap_drop: [] -docker_systemd_service_container_devices: [] -docker_systemd_service_container_privileged: false -docker_systemd_service_container_args: "" -#! END TO REPLACE docker_systemd_service_name: "{{ docker_systemd_service_container_name }}_container" docker_systemd_service_systemd_options: [] docker_systemd_service_enabled: true diff --git a/molecule/default_vagrant/verify.yml b/molecule/default_vagrant/verify.yml index 293cc93..5e1cbce 100644 --- a/molecule/default_vagrant/verify.yml +++ b/molecule/default_vagrant/verify.yml @@ -53,20 +53,9 @@ [Service] EnvironmentFile=/etc/default/nginx ExecStartPre=-/usr/bin/docker rm -f nginx - ExecStart=/usr/bin/docker run --name nginx --rm --env-file /etc/default/nginx \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ + ExecStart=/usr/bin/docker run --name nginx \ + --rm \ + --env-file /etc/default/nginx \ nginx ExecStop=/usr/bin/docker stop nginx SyslogIdentifier=nginx diff --git a/templates/unit.j2 b/templates/unit.j2 index f75743a..3a0700c 100644 --- a/templates/unit.j2 +++ b/templates/unit.j2 @@ -16,11 +16,12 @@ EnvironmentFile={{ docker_systemd_service_sysconf_dir }}/{{ docker_systemd_servi ExecStartPre=-{{ docker_systemd_service_docker_path }} rm -f {{ docker_systemd_service_container_name }} {% endif %} {% if not 'ExecStart' in service_systemd_options_keys %} +{% set docker_flags = docker_systemd_service_flags | create_docker_flags %} ExecStart={{ docker_systemd_service_docker_path }} run --name {{ docker_systemd_service_container_name }} \ --rm \ --env-file {{ docker_systemd_service_sysconf_dir }}/{{ docker_systemd_service_container_name }} \ -{{ docker_systemd_service_flags|create_docker_flags }} -{{ docker_systemd_service_image -}}{{ ' ' if docker_systemd_service_container_cmd else '' }}{% if docker_systemd_service_container_cmd is string %}{{ docker_systemd_service_container_cmd | trim }}{% else %}{{ docker_systemd_service_container_cmd | join(' ') | trim }}{% endif %} +{{ docker_flags -}}{% if docker_flags +%} +{% endif %}{{ docker_systemd_service_image -}}{{ ' ' if docker_systemd_service_container_cmd else '' }}{% if docker_systemd_service_container_cmd is string %}{{ docker_systemd_service_container_cmd | trim }}{% else %}{{ docker_systemd_service_container_cmd | join(' ') | trim }}{% endif %} {% endif +%} {% if not 'ExecStop' in service_systemd_options_keys %} ExecStop={{ docker_systemd_service_docker_path }} stop {{ docker_systemd_service_container_name }} -- 2.45.2 From 9b6bf1684eb5ea479fafcafd47b297a79d17947f Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sun, 10 Dec 2023 18:25:43 +0100 Subject: [PATCH 08/10] feat(tests): added custom tests for both vagrant and docker --- molecule/default/requirements.yml | 1 - molecule/with_custom_flags/converge.yml | 8 ++ molecule/with_custom_flags/group_vars/all.yml | 19 +++++ molecule/with_custom_flags/molecule.yml | 37 ++++++++ molecule/with_custom_flags/requirements.yml | 5 ++ molecule/with_custom_flags/verify.yml | 84 +++++++++++++++++++ .../with_custom_flags_vagrant/converge.yml | 8 ++ .../group_vars/all.yml | 19 +++++ .../with_custom_flags_vagrant/molecule.yml | 35 ++++++++ .../with_custom_flags_vagrant/prepare.yml | 10 +++ .../requirements.yml | 6 ++ molecule/with_custom_flags_vagrant/verify.yml | 84 +++++++++++++++++++ 12 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 molecule/with_custom_flags/converge.yml create mode 100644 molecule/with_custom_flags/group_vars/all.yml create mode 100644 molecule/with_custom_flags/molecule.yml create mode 100644 molecule/with_custom_flags/requirements.yml create mode 100644 molecule/with_custom_flags/verify.yml create mode 100644 molecule/with_custom_flags_vagrant/converge.yml create mode 100644 molecule/with_custom_flags_vagrant/group_vars/all.yml create mode 100644 molecule/with_custom_flags_vagrant/molecule.yml create mode 100644 molecule/with_custom_flags_vagrant/prepare.yml create mode 100644 molecule/with_custom_flags_vagrant/requirements.yml create mode 100644 molecule/with_custom_flags_vagrant/verify.yml diff --git a/molecule/default/requirements.yml b/molecule/default/requirements.yml index 1316891..0a4a9fb 100644 --- a/molecule/default/requirements.yml +++ b/molecule/default/requirements.yml @@ -3,4 +3,3 @@ roles: - name: ednxzu.manage_repositories - name: ednxzu.manage_apt_packages - - name: ednxzu.install_docker diff --git a/molecule/with_custom_flags/converge.yml b/molecule/with_custom_flags/converge.yml new file mode 100644 index 0000000..1271eed --- /dev/null +++ b/molecule/with_custom_flags/converge.yml @@ -0,0 +1,8 @@ +--- +- name: Converge + hosts: all + become: true + tasks: + - name: "Include ednxzu.docker_systemd_service" + ansible.builtin.include_role: + name: "ednxzu.docker_systemd_service" diff --git a/molecule/with_custom_flags/group_vars/all.yml b/molecule/with_custom_flags/group_vars/all.yml new file mode 100644 index 0000000..11733c3 --- /dev/null +++ b/molecule/with_custom_flags/group_vars/all.yml @@ -0,0 +1,19 @@ +--- +docker_systemd_service_container_name: "nginx" +docker_systemd_service_image: nginx +docker_systemd_service_container_env: + TEST_ENV: test +docker_systemd_service_container_pull_image: false +docker_systemd_service_container_pull_force_source: false +docker_systemd_service_flags: + - privileged + - network: host + - cap-add: + - NET_ADMIN +docker_systemd_service_container_cmd: [] +docker_systemd_service_name: "{{ docker_systemd_service_container_name }}_container" +docker_systemd_service_systemd_options: [] +docker_systemd_service_enabled: true +docker_systemd_service_masked: false +docker_systemd_service_state: stopped +docker_systemd_service_restart: false diff --git a/molecule/with_custom_flags/molecule.yml b/molecule/with_custom_flags/molecule.yml new file mode 100644 index 0000000..ce39f56 --- /dev/null +++ b/molecule/with_custom_flags/molecule.yml @@ -0,0 +1,37 @@ +--- +dependency: + name: galaxy + options: + requirements-file: ./requirements.yml +driver: + name: docker +platforms: + - name: instance + image: geerlingguy/docker-${MOLECULE_TEST_OS}-ansible + command: "" + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup + cgroupns_mode: host + privileged: true + pre_build_image: true +provisioner: + name: ansible + config_options: + defaults: + remote_tmp: /tmp/.ansible +verifier: + name: ansible +scenario: + name: with_custom_flags + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy diff --git a/molecule/with_custom_flags/requirements.yml b/molecule/with_custom_flags/requirements.yml new file mode 100644 index 0000000..0a4a9fb --- /dev/null +++ b/molecule/with_custom_flags/requirements.yml @@ -0,0 +1,5 @@ +--- +# requirements file for molecule +roles: + - name: ednxzu.manage_repositories + - name: ednxzu.manage_apt_packages diff --git a/molecule/with_custom_flags/verify.yml b/molecule/with_custom_flags/verify.yml new file mode 100644 index 0000000..6e80eef --- /dev/null +++ b/molecule/with_custom_flags/verify.yml @@ -0,0 +1,84 @@ +--- +- name: Verify + hosts: all + gather_facts: true + become: true + tasks: + - name: "Test: file /etc/default/nginx" + block: + - name: "Stat file /etc/default/nginx" + ansible.builtin.stat: + path: "/etc/default/nginx" + register: stat_etc_default_nginx + + - name: "Slurp file /etc/default/nginx" + ansible.builtin.slurp: + src: "/etc/default/nginx" + register: slurp_etc_default_nginx + + - name: "Verify file /etc/default/nginx" + vars: + nginx_expected_env_file: | + TEST_ENV=test + ansible.builtin.assert: + that: + - stat_etc_default_nginx.stat.exists + - stat_etc_default_nginx.stat.isreg + - stat_etc_default_nginx.stat.pw_name == 'root' + - stat_etc_default_nginx.stat.gr_name == 'root' + - stat_etc_default_nginx.stat.mode == '0600' + - (slurp_etc_default_nginx.content|b64decode) == nginx_expected_env_file + + - name: "Test: service nginx_container" + block: + - name: "Get service nginx_container" + ansible.builtin.service_facts: + + - name: "Stat file /etc/systemd/system/nginx_container.service" + ansible.builtin.stat: + path: "/etc/systemd/system/nginx_container.service" + register: stat_etc_systemd_system_nginx_container_service + + - name: "Slurp file /etc/systemd/system/nginx_container.service" + ansible.builtin.slurp: + src: "/etc/systemd/system/nginx_container.service" + register: slurp_etc_systemd_system_nginx_container_service + + - name: "Verify service nginx_container" + vars: + nginx_expected_service_file: | + # Ansible managed: Do NOT edit this file manually! + [Unit] + After=docker.service + PartOf=docker.service + Requires=docker.service + + [Service] + EnvironmentFile=/etc/default/nginx + ExecStartPre=-/usr/bin/docker rm -f nginx + ExecStart=/usr/bin/docker run --name nginx \ + --rm \ + --env-file /etc/default/nginx \ + --privileged \ + --network "host" \ + --cap-add "NET_ADMIN" \ + nginx + ExecStop=/usr/bin/docker stop nginx + SyslogIdentifier=nginx + Restart=always + RestartSec=10s + + [Install] + WantedBy=docker.service + ansible.builtin.assert: + that: + - stat_etc_systemd_system_nginx_container_service.stat.exists + - stat_etc_systemd_system_nginx_container_service.stat.isreg + - stat_etc_systemd_system_nginx_container_service.stat.pw_name == 'root' + - stat_etc_systemd_system_nginx_container_service.stat.gr_name == 'root' + - stat_etc_systemd_system_nginx_container_service.stat.mode == '0644' + - (slurp_etc_systemd_system_nginx_container_service.content|b64decode) == nginx_expected_service_file + - ansible_facts.services['nginx_container.service'] is defined + - ansible_facts.services['nginx_container.service']['source'] == 'systemd' + - ansible_facts.services['nginx_container.service']['state'] == 'inactive' + - ansible_facts.services['nginx_container.service']['status'] == 'enabled' diff --git a/molecule/with_custom_flags_vagrant/converge.yml b/molecule/with_custom_flags_vagrant/converge.yml new file mode 100644 index 0000000..1271eed --- /dev/null +++ b/molecule/with_custom_flags_vagrant/converge.yml @@ -0,0 +1,8 @@ +--- +- name: Converge + hosts: all + become: true + tasks: + - name: "Include ednxzu.docker_systemd_service" + ansible.builtin.include_role: + name: "ednxzu.docker_systemd_service" diff --git a/molecule/with_custom_flags_vagrant/group_vars/all.yml b/molecule/with_custom_flags_vagrant/group_vars/all.yml new file mode 100644 index 0000000..0c8909c --- /dev/null +++ b/molecule/with_custom_flags_vagrant/group_vars/all.yml @@ -0,0 +1,19 @@ +--- +docker_systemd_service_container_name: "nginx" +docker_systemd_service_image: nginx +docker_systemd_service_container_env: + TEST_ENV: test +docker_systemd_service_container_pull_image: true +docker_systemd_service_container_pull_force_source: true +docker_systemd_service_flags: + - privileged + - network: host + - cap-add: + - NET_ADMIN +docker_systemd_service_container_cmd: [] +docker_systemd_service_name: "{{ docker_systemd_service_container_name }}_container" +docker_systemd_service_systemd_options: [] +docker_systemd_service_enabled: true +docker_systemd_service_masked: false +docker_systemd_service_state: started +docker_systemd_service_restart: true diff --git a/molecule/with_custom_flags_vagrant/molecule.yml b/molecule/with_custom_flags_vagrant/molecule.yml new file mode 100644 index 0000000..fe55051 --- /dev/null +++ b/molecule/with_custom_flags_vagrant/molecule.yml @@ -0,0 +1,35 @@ +--- +dependency: + name: galaxy + options: + requirements-file: ./requirements.yml +driver: + name: vagrant + provider: + name: libvirt +platforms: + - name: instance + box: generic/${MOLECULE_TEST_OS} + cpus: 4 + memory: 4096 +provisioner: + name: ansible + config_options: + defaults: + remote_tmp: /tmp/.ansible +verifier: + name: ansible +scenario: + name: with_custom_flags_vagrant + test_sequence: + - dependency + - cleanup + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - cleanup + - destroy diff --git a/molecule/with_custom_flags_vagrant/prepare.yml b/molecule/with_custom_flags_vagrant/prepare.yml new file mode 100644 index 0000000..06b4860 --- /dev/null +++ b/molecule/with_custom_flags_vagrant/prepare.yml @@ -0,0 +1,10 @@ +--- +- name: Prepare + hosts: all + become: true + tasks: + - name: "Install docker" + ansible.builtin.include_role: + name: ednxzu.install_docker + vars: + install_docker_python_packages: true diff --git a/molecule/with_custom_flags_vagrant/requirements.yml b/molecule/with_custom_flags_vagrant/requirements.yml new file mode 100644 index 0000000..1316891 --- /dev/null +++ b/molecule/with_custom_flags_vagrant/requirements.yml @@ -0,0 +1,6 @@ +--- +# requirements file for molecule +roles: + - name: ednxzu.manage_repositories + - name: ednxzu.manage_apt_packages + - name: ednxzu.install_docker diff --git a/molecule/with_custom_flags_vagrant/verify.yml b/molecule/with_custom_flags_vagrant/verify.yml new file mode 100644 index 0000000..d043f00 --- /dev/null +++ b/molecule/with_custom_flags_vagrant/verify.yml @@ -0,0 +1,84 @@ +--- +- name: Verify + hosts: all + gather_facts: true + become: true + tasks: + - name: "Test: file /etc/default/nginx" + block: + - name: "Stat file /etc/default/nginx" + ansible.builtin.stat: + path: "/etc/default/nginx" + register: stat_etc_default_nginx + + - name: "Slurp file /etc/default/nginx" + ansible.builtin.slurp: + src: "/etc/default/nginx" + register: slurp_etc_default_nginx + + - name: "Verify file /etc/default/nginx" + vars: + nginx_expected_env_file: | + TEST_ENV=test + ansible.builtin.assert: + that: + - stat_etc_default_nginx.stat.exists + - stat_etc_default_nginx.stat.isreg + - stat_etc_default_nginx.stat.pw_name == 'root' + - stat_etc_default_nginx.stat.gr_name == 'root' + - stat_etc_default_nginx.stat.mode == '0600' + - (slurp_etc_default_nginx.content|b64decode) == nginx_expected_env_file + + - name: "Test: service nginx_container" + block: + - name: "Get service nginx_container" + ansible.builtin.service_facts: + + - name: "Stat file /etc/systemd/system/nginx_container.service" + ansible.builtin.stat: + path: "/etc/systemd/system/nginx_container.service" + register: stat_etc_systemd_system_nginx_container_service + + - name: "Slurp file /etc/systemd/system/nginx_container.service" + ansible.builtin.slurp: + src: "/etc/systemd/system/nginx_container.service" + register: slurp_etc_systemd_system_nginx_container_service + + - name: "Verify service nginx_container" + vars: + nginx_expected_service_file: | + # Ansible managed: Do NOT edit this file manually! + [Unit] + After=docker.service + PartOf=docker.service + Requires=docker.service + + [Service] + EnvironmentFile=/etc/default/nginx + ExecStartPre=-/usr/bin/docker rm -f nginx + ExecStart=/usr/bin/docker run --name nginx \ + --rm \ + --env-file /etc/default/nginx \ + --privileged \ + --network "host" \ + --cap-add "NET_ADMIN" \ + nginx + ExecStop=/usr/bin/docker stop nginx + SyslogIdentifier=nginx + Restart=always + RestartSec=10s + + [Install] + WantedBy=docker.service + ansible.builtin.assert: + that: + - stat_etc_systemd_system_nginx_container_service.stat.exists + - stat_etc_systemd_system_nginx_container_service.stat.isreg + - stat_etc_systemd_system_nginx_container_service.stat.pw_name == 'root' + - stat_etc_systemd_system_nginx_container_service.stat.gr_name == 'root' + - stat_etc_systemd_system_nginx_container_service.stat.mode == '0644' + - (slurp_etc_systemd_system_nginx_container_service.content|b64decode) == nginx_expected_service_file + - ansible_facts.services['nginx_container.service'] is defined + - ansible_facts.services['nginx_container.service']['source'] == 'systemd' + - ansible_facts.services['nginx_container.service']['state'] == 'running' + - ansible_facts.services['nginx_container.service']['status'] == 'enabled' -- 2.45.2 From e25f838a8d75b2d9e187344173a8c1fcd4e396bd Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sun, 10 Dec 2023 18:26:53 +0100 Subject: [PATCH 09/10] feat(cicd): add unit testing jobs --- .gitea/workflows/test.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index fd2a722..77b20fa 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -22,3 +22,31 @@ jobs: - name: "YAML lint" run: yamllint . -f colored -c .yamllint working-directory: ${{ gitea.workspace }} + + molecule-test: + name: Molecule tests + runs-on: ubuntu-latest + needs: lint + container: + image: git.ednz.fr/container-factory/ansible-runner:act-latest + credentials: + username: ${{ secrets.ACTIONS_USER }} + password: ${{ secrets.ACTIONS_TOKEN }} + strategy: + matrix: + test_os: [debian11, debian12, ubuntu2004, ubuntu2204] + scenario: [default, with_custom_config] + env: + ANSIBLE_HOST_KEY_CHECKING: 'false' + ANSIBLE_FORCE_COLOR: 'true' + ANSIBLE_PYTHON_INTERPRETER: /usr/bin/python3 + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: "Molecule test" + run: molecule test -s ${{ matrix.scenario }} + shell: bash + working-directory: ${{ gitea.workspace }} + env: + MOLECULE_TEST_OS: ${{ matrix.test_os }} -- 2.45.2 From 4b1ea01f3b9dc987a084463dc258fc13b38d61ea Mon Sep 17 00:00:00 2001 From: Bertrand Lanson Date: Sun, 10 Dec 2023 18:50:18 +0100 Subject: [PATCH 10/10] fix: change test scenario names in CICD --- .gitea/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index 77b20fa..3a74d0a 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -35,7 +35,7 @@ jobs: strategy: matrix: test_os: [debian11, debian12, ubuntu2004, ubuntu2204] - scenario: [default, with_custom_config] + scenario: [default, with_custom_flags] env: ANSIBLE_HOST_KEY_CHECKING: 'false' ANSIBLE_FORCE_COLOR: 'true' -- 2.45.2