--- - name: Validate required runner settings ansible.builtin.assert: that: - windows_gitea_runner_instance_url | length > 0 - windows_gitea_runner_registration_token | length > 0 - windows_gitea_runner_runners | length > 0 fail_msg: >- windows_gitea_runner_instance_url, windows_gitea_runner_registration_token, and at least one windows_gitea_runner_runners entry are required. tags: - always - name: Build effective runner matrix ansible.builtin.set_fact: __windows_gitea_runner_effective_runners: "{{ windows_gitea_runner_runners }}" tags: - always - name: Validate runner execution modes ansible.builtin.assert: that: - >- ( windows_gitea_runner_runner.mode | default(windows_gitea_runner_default_mode) ) in ['linux_podman', 'windows_mcr'] fail_msg: >- Unsupported runner mode for {{ windows_gitea_runner_runner.name | default(windows_gitea_runner_runner.profile | default('runner')) }}. Supported modes: linux_podman, windows_mcr. loop: "{{ __windows_gitea_runner_effective_runners }}" loop_control: loop_var: windows_gitea_runner_runner tags: - always - name: Resolve runner mode flags ansible.builtin.set_fact: __windows_gitea_runner_modes: >- {{ __windows_gitea_runner_effective_runners | map(attribute='mode', default=windows_gitea_runner_default_mode) | list }} tags: - always - name: Set runner mode booleans ansible.builtin.set_fact: __windows_gitea_runner_has_linux_runners: >- {{ 'linux_podman' in __windows_gitea_runner_modes }} __windows_gitea_runner_has_windows_runners: >- {{ 'windows_mcr' in __windows_gitea_runner_modes }} tags: - always - name: Ensure Podman auto-start service is running ansible.windows.win_service: name: "{{ windows_gitea_runner_podman_service_name }}" start_mode: auto state: started become: true become_method: ansible.builtin.runas become_user: SYSTEM when: __windows_gitea_runner_has_linux_runners tags: - roles::windows_gitea_runner::linux - name: Wait until Podman machine is ready ansible.windows.win_shell: | $ErrorActionPreference = "Stop" $ready = $false for ($i = 0; $i -lt 90; $i++) { $null = & "{{ windows_gitea_runner_podman_install_dir }}\podman.exe" info --format json 2>$null if ($LASTEXITCODE -eq 0) { $ready = $true break } Start-Sleep -Seconds 2 } if (-not $ready) { Write-Error "Podman machine {{ windows_gitea_runner_podman_machine_name }} did not become ready" exit 1 } become: true become_method: ansible.builtin.runas become_user: "{{ windows_gitea_runner_podman_service_user }}" changed_when: false when: __windows_gitea_runner_has_linux_runners tags: - roles::windows_gitea_runner::linux - name: Ensure Docker service is running for Windows runners ansible.windows.win_service: name: docker start_mode: auto state: started become: true become_method: ansible.builtin.runas become_user: SYSTEM when: __windows_gitea_runner_has_windows_runners tags: - roles::windows_gitea_runner::windows - name: Resolve Windows docker runtime user ansible.builtin.set_fact: __windows_gitea_runner_windows_runtime_user: >- {{ windows_gitea_runner_windows_runtime_user | default(windows_gitea_runner_podman_service_user, true) | default(ansible_user | default(''), true) }} __windows_gitea_runner_windows_become_user: >- {{ windows_gitea_runner_windows_become_user | default(__windows_gitea_runner_windows_runtime_user, true) | default('SYSTEM', true) }} when: __windows_gitea_runner_has_windows_runners tags: - roles::windows_gitea_runner::windows - name: Check docker-users local group availability ansible.windows.win_shell: | $group = Get-LocalGroup -Name 'docker-users' -ErrorAction SilentlyContinue if ($null -ne $group) { Write-Output "__EXISTS__" exit 0 } Write-Output "__MISSING__" exit 0 become: true become_method: ansible.builtin.runas become_user: SYSTEM register: __windows_gitea_runner_docker_users_group changed_when: false when: - __windows_gitea_runner_has_windows_runners - __windows_gitea_runner_windows_runtime_user | length > 0 tags: - roles::windows_gitea_runner::windows - name: Add runtime user to docker-users group ansible.windows.win_group_membership: name: docker-users members: - >- {{ __windows_gitea_runner_windows_runtime_user if ('\\' in __windows_gitea_runner_windows_runtime_user) else '.\\' ~ __windows_gitea_runner_windows_runtime_user }} state: present become: true become_method: ansible.builtin.runas become_user: SYSTEM when: - __windows_gitea_runner_has_windows_runners - __windows_gitea_runner_windows_runtime_user | length > 0 - "'__EXISTS__' in (__windows_gitea_runner_docker_users_group.stdout | default(''))" tags: - roles::windows_gitea_runner::windows - name: Ensure Windows base build directory exists ansible.windows.win_file: path: "{{ windows_gitea_runner_windows_base_build_dir }}" state: directory when: __windows_gitea_runner_has_windows_runners tags: - roles::windows_gitea_runner::windows - name: Copy Windows base Dockerfile to build context ansible.windows.win_copy: src: >- {{ windows_gitea_runner_windows_dockerfile_source_root ~ '/' ~ windows_gitea_runner_windows_base_dockerfile_src }} dest: "{{ windows_gitea_runner_windows_base_build_dir }}\\Dockerfile" when: __windows_gitea_runner_has_windows_runners tags: - roles::windows_gitea_runner::windows - name: Copy Windows base entrypoint script to build context ansible.windows.win_copy: src: >- {{ windows_gitea_runner_windows_dockerfile_source_root ~ '/' ~ windows_gitea_runner_windows_base_entrypoint_script_src }} dest: >- {{ windows_gitea_runner_windows_base_build_dir ~ '\\' ~ windows_gitea_runner_windows_base_entrypoint_script_src }} when: __windows_gitea_runner_has_windows_runners tags: - roles::windows_gitea_runner::windows - name: Read current Windows base image hash label ansible.windows.win_shell: | $ErrorActionPreference = "Stop" $docker = "{{ windows_gitea_runner_windows_runtime_bin }}" $image = "{{ windows_gitea_runner_windows_base_image }}" if (Get-Variable -Name PSNativeCommandUseErrorActionPreference -ErrorAction SilentlyContinue) { $PSNativeCommandUseErrorActionPreference = $false } $ErrorActionPreference = "Continue" $raw = & $docker image inspect $image 2>$null $inspectExit = $LASTEXITCODE $ErrorActionPreference = "Stop" if ($inspectExit -ne 0 -or [string]::IsNullOrWhiteSpace($raw)) { Write-Output "__MISSING__" exit 0 } $obj = $raw | ConvertFrom-Json if ($obj -is [System.Array]) { $obj = $obj[0] } $labels = $obj.Config.Labels if ($null -eq $labels) { Write-Output "__UNLABELED__" exit 0 } $key = "{{ windows_gitea_runner_windows_base_image_hash_label }}" $current = $labels.$key if ([string]::IsNullOrWhiteSpace($current)) { Write-Output "__UNLABELED__" exit 0 } Write-Output $current.Trim() become: true become_method: ansible.builtin.runas become_user: "{{ __windows_gitea_runner_windows_become_user }}" register: __windows_gitea_runner_current_windows_base_image_hash changed_when: false when: __windows_gitea_runner_has_windows_runners tags: - roles::windows_gitea_runner::windows - name: Read desired Windows base Dockerfile checksum ansible.builtin.set_fact: __windows_gitea_runner_windows_base_dockerfile_checksum: >- {{ ( lookup( 'file', windows_gitea_runner_windows_dockerfile_source_root ~ '/' ~ windows_gitea_runner_windows_base_dockerfile_src ) ~ '\n' ~ lookup( 'file', windows_gitea_runner_windows_dockerfile_source_root ~ '/' ~ windows_gitea_runner_windows_base_entrypoint_script_src ) ) | hash('sha1') }} when: __windows_gitea_runner_has_windows_runners tags: - roles::windows_gitea_runner::windows - name: Determine if Windows base image needs rebuild ansible.builtin.set_fact: __windows_gitea_runner_needs_windows_base_image_rebuild: >- {{ (__windows_gitea_runner_current_windows_base_image_hash.stdout | trim) != (__windows_gitea_runner_windows_base_dockerfile_checksum | trim) }} when: __windows_gitea_runner_has_windows_runners tags: - roles::windows_gitea_runner::windows - name: Rebuild Windows base image when Dockerfile changed ansible.windows.win_shell: | $ErrorActionPreference = "Stop" $docker = "{{ windows_gitea_runner_windows_runtime_bin }}" $baseHash = "{{ __windows_gitea_runner_windows_base_dockerfile_checksum }}" $baseLabel = "{{ windows_gitea_runner_windows_base_image_hash_label }}=$baseHash" & $docker build ` --label "$baseLabel" ` --tag "{{ windows_gitea_runner_windows_base_image }}" ` --file "{{ windows_gitea_runner_windows_base_build_dir }}\Dockerfile" ` "{{ windows_gitea_runner_windows_base_build_dir }}" if ($LASTEXITCODE -ne 0) { exit 1 } Write-Output "__BUILT__" become: true become_method: ansible.builtin.runas become_user: "{{ __windows_gitea_runner_windows_become_user }}" register: __windows_gitea_runner_windows_base_build changed_when: "'__BUILT__' in __windows_gitea_runner_windows_base_build.stdout" when: - __windows_gitea_runner_has_windows_runners - __windows_gitea_runner_needs_windows_base_image_rebuild tags: - roles::windows_gitea_runner::windows - name: Ensure base build directory exists ansible.windows.win_file: path: "{{ windows_gitea_runner_base_build_dir }}" state: directory when: __windows_gitea_runner_has_linux_runners tags: - roles::windows_gitea_runner::linux - name: Copy base Dockerfile to build context ansible.windows.win_copy: src: "{{ windows_gitea_runner_dockerfile_source_root }}/{{ windows_gitea_runner_base_dockerfile_src }}" dest: "{{ windows_gitea_runner_base_build_dir }}\\Dockerfile" when: __windows_gitea_runner_has_linux_runners tags: - roles::windows_gitea_runner::linux - name: Grant podman service user access to base build directory ansible.windows.win_acl: path: "{{ windows_gitea_runner_base_build_dir }}" user: ".\\{{ windows_gitea_runner_podman_service_user }}" rights: FullControl type: allow state: present inherit: ContainerInherit, ObjectInherit propagation: None become: true become_method: ansible.builtin.runas become_user: SYSTEM when: __windows_gitea_runner_has_linux_runners tags: - roles::windows_gitea_runner::linux - name: Read current base image hash label ansible.windows.win_shell: | $ErrorActionPreference = "Stop" $podman = "{{ windows_gitea_runner_podman_install_dir }}\podman.exe" $image = "{{ windows_gitea_runner_base_image }}" $null = & $podman image exists $image 2>$null if ($LASTEXITCODE -ne 0) { Write-Output "__MISSING__" exit 0 } $raw = & $podman image inspect $image --format json 2>$null if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($raw)) { Write-Output "__MISSING__" exit 0 } $obj = $raw | ConvertFrom-Json if ($obj -is [System.Array]) { $obj = $obj[0] } $labels = $obj.Config.Labels if ($null -eq $labels) { Write-Output "__UNLABELED__" exit 0 } $key = "{{ windows_gitea_runner_base_image_hash_label }}" $current = $labels.$key if ([string]::IsNullOrWhiteSpace($current)) { Write-Output "__UNLABELED__" exit 0 } Write-Output $current.Trim() become: true become_method: ansible.builtin.runas become_user: "{{ windows_gitea_runner_podman_service_user }}" register: __windows_gitea_runner_current_base_image_hash changed_when: false when: __windows_gitea_runner_has_linux_runners tags: - roles::windows_gitea_runner::linux - name: Read desired base Dockerfile checksum ansible.builtin.set_fact: __windows_gitea_runner_base_dockerfile_checksum: >- {{ lookup( 'file', windows_gitea_runner_dockerfile_source_root ~ '/' ~ windows_gitea_runner_base_dockerfile_src ) | hash('sha1') }} when: __windows_gitea_runner_has_linux_runners tags: - roles::windows_gitea_runner::linux - name: Determine if base image needs rebuild ansible.builtin.set_fact: __windows_gitea_runner_needs_base_image_rebuild: >- {{ (__windows_gitea_runner_current_base_image_hash.stdout | trim) != (__windows_gitea_runner_base_dockerfile_checksum | trim) }} when: __windows_gitea_runner_has_linux_runners tags: - roles::windows_gitea_runner::linux - name: Rebuild base image when Dockerfile changed ansible.windows.win_shell: | $ErrorActionPreference = "Stop" $podman = "{{ windows_gitea_runner_podman_install_dir }}\podman.exe" & $podman build ` --label "{{ windows_gitea_runner_base_image_hash_label }}={{ __windows_gitea_runner_base_dockerfile_checksum }}" ` --tag "{{ windows_gitea_runner_base_image }}" ` --file "{{ windows_gitea_runner_base_build_dir }}\\Dockerfile" ` "{{ windows_gitea_runner_base_build_dir }}" if ($LASTEXITCODE -ne 0) { exit 1 } Write-Output "__BUILT__" become: true become_method: ansible.builtin.runas become_user: "{{ windows_gitea_runner_podman_service_user }}" register: __windows_gitea_runner_base_build changed_when: "'__BUILT__' in __windows_gitea_runner_base_build.stdout" when: - __windows_gitea_runner_has_linux_runners - __windows_gitea_runner_needs_base_image_rebuild tags: - roles::windows_gitea_runner::linux - name: Reconcile Linux Podman runners ansible.builtin.include_tasks: runner.yml args: apply: tags: - roles::windows_gitea_runner::linux loop: "{{ __windows_gitea_runner_effective_runners }}" loop_control: loop_var: windows_gitea_runner_runner label: >- {{ windows_gitea_runner_runner.name | default(windows_gitea_runner_runner.profile) }} when: >- ( windows_gitea_runner_runner.mode | default(windows_gitea_runner_default_mode) ) == 'linux_podman' tags: - roles::windows_gitea_runner::linux - name: Reconcile Windows Mirantis runners ansible.builtin.include_tasks: runner_windows.yml args: apply: tags: - roles::windows_gitea_runner::windows loop: "{{ __windows_gitea_runner_effective_runners }}" loop_control: loop_var: windows_gitea_runner_runner label: >- {{ windows_gitea_runner_runner.name | default(windows_gitea_runner_runner.profile) }} when: >- ( windows_gitea_runner_runner.mode | default(windows_gitea_runner_default_mode) ) == 'windows_mcr' tags: - roles::windows_gitea_runner::windows