
Because buildset registries may be used by jobs that finish before other jobs are finished using the buildset registry we must be careful not to expose the registry credentials in the jobs that finish sooner. Otherwise logs for the earlier job runs could potentially be used to poison the registry for later jobs. This is likely currently incomplete. Other Zuulians should look over it carefully to ensure we're covering all the bases here. The cases I've identified so far are: * Setting facts that include passwords * Reading and writing to files that include passwords (as content may be logged) * Calling modules with passwords passed as arguments (the module invocation is logged) I've also set no_log on zuul_return that passes up credentials because while the logging for zuul_return is minimal today, I don't want to count on it remaining that way. We also use the yet to be merged secret_data attribute on zuul_return to ensure that zuul_return itself does not expose anything unwanted. Finally it would be great if others could check over the use of buildset_registry variables to make sure there aren't any that got missed. One thing I'm not sure of is whether or not when conditionals get logged and if we need to be careful about their use too. Temporarily remove some buildset-regitry jobs which are in a catch-22. Change-Id: I2dea683e27f00b99a7766bf830981bf91b925265
111 lines
4.1 KiB
YAML
111 lines
4.1 KiB
YAML
# This can be removed if we add this functionality to Zuul directly
|
|
- name: Load information from zuul_return
|
|
when: buildset_registry is not defined
|
|
set_fact:
|
|
buildset_registry: "{{ (lookup('file', zuul.executor.result_data_file) | from_json)['secret_data']['buildset_registry'] }}"
|
|
no_log: true
|
|
|
|
# Start a socat tunnel to the buildset registry to work around the
|
|
# fact that docker does not correctly parse ipv6 addresses. The socat
|
|
# process will terminate when the playbook ends.
|
|
- name: Start socat to work around https://github.com/moby/moby/issues/39033
|
|
shell: "socat -d -d TCP-LISTEN:0,fork TCP:{{ buildset_registry.host | ipwrap }}:{{ buildset_registry.port }} 2> {{ zuul.executor.work_root }}/socat_port &"
|
|
|
|
# Use slurp instead of file lookup to make this testable on a fake
|
|
# executor node.
|
|
- name: Read socat port
|
|
slurp:
|
|
src: "{{ zuul.executor.work_root }}/socat_port"
|
|
register: read_socat_port
|
|
- name: Set socat port
|
|
set_fact:
|
|
socat_port: "{{ read_socat_port['content'] | b64decode | regex_replace('.*?0\\.0\\.0\\.0:(\\d+)', '\\1') | regex_replace('\n', '') }}"
|
|
|
|
# Set up cert files for the buildset registry
|
|
- name: Ensure registry cert directory exists
|
|
file:
|
|
path: "/etc/docker/certs.d/127.0.0.1:{{ socat_port }}/"
|
|
state: directory
|
|
mode: 0755
|
|
- name: Write registry TLS certificate
|
|
copy:
|
|
content: "{{ buildset_registry.cert }}"
|
|
dest: "/etc/docker/certs.d/127.0.0.1:{{ socat_port }}/ca.crt"
|
|
mode: 0644
|
|
|
|
# Update user config for intermediate and buildset registries
|
|
- name: Ensure docker user directory exists
|
|
file:
|
|
state: directory
|
|
path: "~/.docker"
|
|
mode: 0700
|
|
- name: Check if docker user configuration exists
|
|
stat:
|
|
path: "~/.docker/config.json"
|
|
register: docker_config_stat
|
|
- name: Load docker user configuration
|
|
when: docker_config_stat.stat.exists
|
|
slurp:
|
|
path: "~/.docker/config.json"
|
|
register: docker_config
|
|
no_log: true
|
|
- name: Parse docker user configuration
|
|
when: docker_config_stat.stat.exists
|
|
set_fact:
|
|
docker_config: "{{ docker_config.content | b64decode | from_json }}"
|
|
no_log: true
|
|
- name: Set default docker user configuration
|
|
when: not docker_config_stat.stat.exists
|
|
set_fact:
|
|
docker_config:
|
|
auths: {}
|
|
- name: Add registry to docker user configuration
|
|
no_log: true
|
|
vars:
|
|
new_config:
|
|
auths: |
|
|
{
|
|
"{{ intermediate_registry.host | ipwrap }}:{{ intermediate_registry.port }}":
|
|
{"auth": "{{ (intermediate_registry.username + ":" + intermediate_registry.password) | b64encode }}"},
|
|
"127.0.0.1:{{ socat_port }}":
|
|
{"auth": "{{ (buildset_registry.username + ":" + buildset_registry.password) | b64encode }}"},
|
|
}
|
|
set_fact:
|
|
new_docker_config: "{{ docker_config | combine(new_config, recursive=True) }}"
|
|
- name: Save docker user configuration
|
|
copy:
|
|
content: "{{ new_docker_config | to_nice_json }}"
|
|
dest: "~/.docker/config.json"
|
|
mode: 0600
|
|
no_log: true
|
|
|
|
# Pull the images
|
|
|
|
# To support usage with both docker and podman, the buildset registry
|
|
# keeps "docker.io" entries un-namespaced, and any other namespaces
|
|
# are namespaced. Therefore, if we see docker.io in the repository
|
|
# name, we strip it here.
|
|
- name: Pull artifacts from intermediate registry
|
|
block:
|
|
- name: Pull artifacts from intermediate registry
|
|
command: >-
|
|
skopeo --insecure-policy copy --all
|
|
{{ zj_zuul_artifact.url }}
|
|
docker://127.0.0.1:{{ socat_port }}/{{ zj_zuul_artifact.metadata.repository | regex_replace('^docker\.io/(.*)', '\1') }}:{{ zj_zuul_artifact.metadata.tag }}
|
|
retries: 3
|
|
register: result
|
|
until: result is success
|
|
when: "'metadata' in zj_zuul_artifact and zj_zuul_artifact.metadata.type | default('') == 'container_image'"
|
|
loop: "{{ zuul_artifacts | default([]) }}"
|
|
loop_control:
|
|
loop_var: zj_zuul_artifact
|
|
always:
|
|
- name: Remove docker user config
|
|
command: "shred ~/.docker/config.json"
|
|
- name: Replace docker user configuration
|
|
copy:
|
|
content: "{{ docker_config | to_nice_json }}"
|
|
dest: "~/.docker/config.json"
|
|
mode: 0600
|
|
no_log: true
|