From e12a487e6a8ba290a43fc4f5ac1e5b3cd661679d Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 18 Apr 2022 22:54:00 +0200 Subject: [PATCH] Add EE support, support GHA in current_container_facts (#336) * Try adding EE support. * Use GHA instead of AZP for EE tests. * Update changelog fragment, extend tests. * Disable current_container_facts test. * Increase verbosity. * 2.9 compatibility. * Use docker instead of podman for building EE and running tests in it. * Output some more information (helpful for debugging). * Fix GHA handling for current_container_facts. * Try to fix permissions. --- .github/workflows/ee.yml | 114 ++++++++++++++++++ changelogs/fragments/336-ee.yml | 3 + meta/ee-bindep.txt | 0 meta/ee-requirements.txt | 2 + meta/execution-environment.yml | 5 + plugins/modules/current_container_facts.py | 15 ++- tests/ee/all.yml | 15 +++ .../current_container_facts/tasks/main.yml | 28 +++++ tests/ee/roles/docker_compose/tasks/main.yml | 34 ++++++ tests/ee/roles/docker_plain/tasks/main.yml | 28 +++++ tests/ee/roles/docker_stack/tasks/main.yml | 2 + tests/sanity/ignore-2.10.txt | 1 + tests/sanity/ignore-2.11.txt | 1 + tests/sanity/ignore-2.12.txt | 1 + tests/utils/shippable/shippable.sh | 2 +- 15 files changed, 246 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/ee.yml create mode 100644 changelogs/fragments/336-ee.yml create mode 100644 meta/ee-bindep.txt create mode 100644 meta/ee-requirements.txt create mode 100644 meta/execution-environment.yml create mode 100644 tests/ee/all.yml create mode 100644 tests/ee/roles/current_container_facts/tasks/main.yml create mode 100644 tests/ee/roles/docker_compose/tasks/main.yml create mode 100644 tests/ee/roles/docker_plain/tasks/main.yml create mode 100644 tests/ee/roles/docker_stack/tasks/main.yml diff --git a/.github/workflows/ee.yml b/.github/workflows/ee.yml new file mode 100644 index 00000000..8ad9838d --- /dev/null +++ b/.github/workflows/ee.yml @@ -0,0 +1,114 @@ +--- +name: execution environment +on: + # Run CI against all pushes (direct commits, also merged PRs), Pull Requests + push: + branches: + - main + - stable-* + pull_request: + # Run CI once per day (at 04:30 UTC) + # This ensures that even if there haven't been commits that we are still testing against latest version of ansible-builder + schedule: + - cron: '30 4 * * *' + +env: + NAMESPACE: community + COLLECTION_NAME: docker + +jobs: + build: + name: Build and test EE (Ⓐ${{ matrix.runner_tag }}) + strategy: + matrix: + runner_tag: + - devel + - stable-2.12-latest + - stable-2.11-latest + - stable-2.9-latest + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v3 + with: + path: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }} + + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: '3.10' + + - name: Install ansible-builder and ansible-navigator + run: pip install ansible-builder ansible-navigator + + - name: Verify requirements + run: ansible-builder introspect --sanitize . + + - name: Make sure galaxy.yml has version entry + run: >- + python -c + 'import yaml ; + f = open("galaxy.yml", "rb") ; + data = yaml.safe_load(f) ; + f.close() ; + data["version"] = data.get("version") or "0.0.1" ; + f = open("galaxy.yml", "wb") ; + f.write(yaml.dump(data).encode("utf-8")) ; + f.close() ; + ' + working-directory: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }} + + - name: Build collection + run: | + ansible-galaxy collection build --output-path ../../../ + working-directory: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }} + + - name: Create files for building execution environment + run: | + COLLECTION_FILENAME="$(ls "${{ env.NAMESPACE }}-${{ env.COLLECTION_NAME }}"-*.tar.gz)" + + # EE config + cat > execution-environment.yml < requirements.yml < + ansible-navigator run + --mode stdout + --pull-policy never + --set-environment-variable ANSIBLE_PRIVATE_ROLE_VARS=true + --container-engine docker + --container-options=-v --container-options=/var/run/docker.sock:/var/run/docker.sock + --execution-environment-image test-ee:latest + -v + all.yml + working-directory: ansible_collections/${{ env.NAMESPACE }}/${{ env.COLLECTION_NAME }}/tests/ee diff --git a/changelogs/fragments/336-ee.yml b/changelogs/fragments/336-ee.yml new file mode 100644 index 00000000..9f05681e --- /dev/null +++ b/changelogs/fragments/336-ee.yml @@ -0,0 +1,3 @@ +minor_changes: + - "Prepare collection for inclusion in an Execution Environment by declaring its dependencies. The ``docker_stack*`` modules are not supported (https://github.com/ansible-collections/community.docker/pull/336)." + - "current_container_facts - add detection for GitHub Actions (https://github.com/ansible-collections/community.docker/pull/336)." diff --git a/meta/ee-bindep.txt b/meta/ee-bindep.txt new file mode 100644 index 00000000..e69de29b diff --git a/meta/ee-requirements.txt b/meta/ee-requirements.txt new file mode 100644 index 00000000..52fdd017 --- /dev/null +++ b/meta/ee-requirements.txt @@ -0,0 +1,2 @@ +docker +docker-compose diff --git a/meta/execution-environment.yml b/meta/execution-environment.yml new file mode 100644 index 00000000..525b5ceb --- /dev/null +++ b/meta/execution-environment.yml @@ -0,0 +1,5 @@ +--- +version: 1 +dependencies: + python: meta/ee-requirements.txt + system: meta/ee-bindep.txt diff --git a/plugins/modules/current_container_facts.py b/plugins/modules/current_container_facts.py index 926c6ee4..fd9cf754 100644 --- a/plugins/modules/current_container_facts.py +++ b/plugins/modules/current_container_facts.py @@ -50,12 +50,15 @@ ansible_facts: description: - The detected container environment. - Contains an empty string if no container was detected. - - Otherwise, will be one of C(docker) or C(azure_pipelines). + - Otherwise, will be one of C(docker), C(azure_pipelines), or C(github_actions). + - C(github_actions) is supported since community.docker 2.4.0. returned: always type: str - # choices: - # - docker - # - azure_pipelines + choices: + - '' + - docker + - azure_pipelines + - github_actions ''' import os @@ -89,6 +92,10 @@ def main(): container_id = cgroup_name container_type = 'azure_pipelines' + if cgroup_path == '/actions_job': + container_id = cgroup_name + container_type = 'github_actions' + module.exit_json(ansible_facts=dict( ansible_module_running_in_container=container_id != '', ansible_module_container_id=container_id, diff --git a/tests/ee/all.yml b/tests/ee/all.yml new file mode 100644 index 00000000..bf0659e5 --- /dev/null +++ b/tests/ee/all.yml @@ -0,0 +1,15 @@ +- hosts: localhost + vars: + docker_test_image_alpine: quay.io/ansible/docker-test-containers:alpine3.8 + tasks: + - name: Find all roles + find: + paths: + - "{{ (playbook_dir | default('.')) ~ '/roles' }}" + file_type: directory + depth: 1 + register: result + - name: Include all roles + include_role: + name: "{{ item }}" + loop: "{{ result.files | map(attribute='path') | map('regex_replace', '.*/', '') | sort }}" diff --git a/tests/ee/roles/current_container_facts/tasks/main.yml b/tests/ee/roles/current_container_facts/tasks/main.yml new file mode 100644 index 00000000..30158497 --- /dev/null +++ b/tests/ee/roles/current_container_facts/tasks/main.yml @@ -0,0 +1,28 @@ +--- +- name: Retrieve information on current container + community.docker.current_container_facts: + register: result + +# The following two tasks are useful if we ever have to debug why this fails. + +- name: Print all Ansible facts + debug: + var: ansible_facts + +- name: Read some files + slurp: + src: "{{ item }}" + loop: + - /proc/self/cpuset + - /proc/1/cgroup + - /proc/1/environ + +- name: Print facts returned by module + debug: + var: result.ansible_facts + +- name: Validate results + assert: + that: + - ansible_module_running_in_container + - ansible_module_container_type != '' diff --git a/tests/ee/roles/docker_compose/tasks/main.yml b/tests/ee/roles/docker_compose/tasks/main.yml new file mode 100644 index 00000000..3da18a41 --- /dev/null +++ b/tests/ee/roles/docker_compose/tasks/main.yml @@ -0,0 +1,34 @@ +--- +# Create random name prefix (for containers, networks, ...) +- name: Create random container name prefix + set_fact: + cname_prefix: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}" + +- name: Create project and container names + set_fact: + pname: "{{ cname_prefix }}" + cname: "{{ cname_prefix }}-hi" + +- name: Define service + set_fact: + test_service: | + version: '3' + services: + {{ cname }}: + image: "{{ docker_test_image_alpine }}" + command: '/bin/sh -c "sleep 10m"' + stop_grace_period: 1s + +- name: Present + community.docker.docker_compose: + project_name: "{{ pname }}" + state: present + remove_orphans: true + definition: "{{ test_service | from_yaml }}" + +- name: Absent + community.docker.docker_compose: + project_name: "{{ pname }}" + state: absent + remove_orphans: true + definition: "{{ test_service | from_yaml }}" diff --git a/tests/ee/roles/docker_plain/tasks/main.yml b/tests/ee/roles/docker_plain/tasks/main.yml new file mode 100644 index 00000000..25c1a02b --- /dev/null +++ b/tests/ee/roles/docker_plain/tasks/main.yml @@ -0,0 +1,28 @@ +--- +# Create random name prefix (for containers, networks, ...) +- name: Create random container name prefix + set_fact: + cname_prefix: "{{ 'ansible-docker-test-%0x' % ((2**32) | random) }}" + +- name: Make sure image is absent + community.docker.docker_image: + name: "{{ docker_test_image_alpine }}" + state: absent + +- name: Make sure image is pulled + community.docker.docker_image: + name: "{{ docker_test_image_alpine }}" + source: pull + +- name: Start container + community.docker.docker_container: + name: "{{ cname_prefix }}-1" + image: "{{ docker_test_image_alpine }}" + state: started + +- name: Remove container + community.docker.docker_container: + name: "{{ cname_prefix }}-1" + state: absent + stop_timeout: 1 + force_kill: yes diff --git a/tests/ee/roles/docker_stack/tasks/main.yml b/tests/ee/roles/docker_stack/tasks/main.yml new file mode 100644 index 00000000..44b6295c --- /dev/null +++ b/tests/ee/roles/docker_stack/tasks/main.yml @@ -0,0 +1,2 @@ +--- +# Currently the docker_stack* modules are not supported in the EE since we'd need to install the Docker CLI client diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index 8cdc50bd..fc12c304 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -4,4 +4,5 @@ .azure-pipelines/scripts/publish-codecov.py compile-3.5!skip # Uses Python 3.6+ syntax .azure-pipelines/scripts/publish-codecov.py future-import-boilerplate .azure-pipelines/scripts/publish-codecov.py metaclass-boilerplate +plugins/modules/current_container_facts.py validate-modules:return-syntax-error plugins/modules/docker_container.py use-argspec-type-path # uses colon-separated paths, can't use type=path diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 8cdc50bd..fc12c304 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -4,4 +4,5 @@ .azure-pipelines/scripts/publish-codecov.py compile-3.5!skip # Uses Python 3.6+ syntax .azure-pipelines/scripts/publish-codecov.py future-import-boilerplate .azure-pipelines/scripts/publish-codecov.py metaclass-boilerplate +plugins/modules/current_container_facts.py validate-modules:return-syntax-error plugins/modules/docker_container.py use-argspec-type-path # uses colon-separated paths, can't use type=path diff --git a/tests/sanity/ignore-2.12.txt b/tests/sanity/ignore-2.12.txt index 878e3796..9be213a0 100644 --- a/tests/sanity/ignore-2.12.txt +++ b/tests/sanity/ignore-2.12.txt @@ -1,2 +1,3 @@ .azure-pipelines/scripts/publish-codecov.py replace-urlopen +plugins/modules/current_container_facts.py validate-modules:return-syntax-error plugins/modules/docker_container.py use-argspec-type-path # uses colon-separated paths, can't use type=path diff --git a/tests/utils/shippable/shippable.sh b/tests/utils/shippable/shippable.sh index 6e5588ab..1e5d5006 100755 --- a/tests/utils/shippable/shippable.sh +++ b/tests/utils/shippable/shippable.sh @@ -15,7 +15,7 @@ function join { } # Ensure we can write other collections to this dir -sudo chown "$(whoami)" "${PWD}/../../" +sudo chown -R "$(whoami)" "${PWD}/../../../" test="$(join / "${args[@]:1}")"