Lukas Kranz ce2bea51d4 Deprecate mirror-workspace-git-repos
This change is preparation for https://review.opendev.org/c/zuul/zuul-jobs/+/887917

In the beginning, there was only prepare-workspace[0] which rsynced repos.

Then we added mirror-workspace-git[1] to make it more efficient by using git operation, but it required some openstack-specific code in project-config to work.

Then we added prepare-workspace-git[2] which completed the git-based sync solution by locating everything requried in zuul-jobs.  It used mirror-workspace-git by reference and added this TODO:

  # TODO(tobiash): we might want to deprecate the role mirror-workspace-git-repos
  # and move it here.

This change completes that TODO by moving the mirror-workspace-git-repos code into prepare-workspace-git and places the repo in a sensible and maintainable state with two simple and good options:

 * prepare-workspace (rsync)
 * prepare-workspace-git (git)

In the unlikely event anyone is still using mirror-workspace-git-repos standalone (OpenStack/OpenDev is not, and that solution was haphazard as described above) they would be well served by a notification that there is a better alternative which is what most of the community actually uses now.

[0] cfffd4431b8efc2f4df1999ecb89384a29c59238
[1] 348598e96aac742954fa326a15a4ef8fd7f71b8b
[2] 7cee7156bcde8bc396ac4b6581bf2cae02eea0e9

Change-Id: Ib80e0447d49363182fd0d4c4d4e269841bc3aa95
2023-09-25 14:51:26 -07:00

90 lines
3.7 KiB
YAML

# Do all the steps in a single shell script. This reduces the number of times
# ansible must loop over the list of projects which reduces the amount of
# task startup time we incur.
- name: Set initial repo states in workspace
shell: |
set -ex
if [ -d "{{ cached_repos_root }}/{{ zj_project.canonical_name }}" ] ; then
# We do a bare clone here first so that we skip creating a working
# copy that will be overwritten later anyway.
git clone --bare {{ cached_repos_root }}/{{ zj_project.canonical_name }} {{ zuul_workspace_root }}/{{ zj_project.src_dir }}/.git
else
git init {{ zuul_workspace_root }}/{{ zj_project.src_dir }}
fi
cd {{ zuul_workspace_root }}/{{ zj_project.src_dir }}
git config --local --bool core.bare false
git remote -v | grep origin && git remote rm origin || true
git remote add origin file:///dev/null
args:
creates: "{{ zuul_workspace_root }}/{{ zj_project.src_dir }}"
with_items: "{{ zuul.projects.values() | list }}"
loop_control:
loop_var: zj_project
# We're using git in a shell script because it is faster and the module
# doesn't support features we need.
tags:
- skip_ansible_lint
- name: Allow pushing to non-bare repo
git_config:
name: receive.denyCurrentBranch
value: ignore
scope: local
repo: "{{ zuul_workspace_root }}/{{ zj_project.value.src_dir }}"
with_dict: "{{ zuul.projects }}"
loop_control:
loop_var: zj_project
- name: Synchronize src repos to workspace directory
command: |-
{% if ansible_connection == "kubectl" %}
git push {% if mirror_workspace_quiet %}--quiet{% endif %} --mirror "ext::kubectl --context {{ zuul.resources[inventory_hostname].context }} -n {{ zuul.resources[inventory_hostname].namespace }} exec -i {{ zuul.resources[inventory_hostname].pod }} -- %S {{ zuul_workspace_root }}/{{ zj_project.value.src_dir }}"
{% else %}
git push {% if mirror_workspace_quiet %}--quiet{% endif %} --mirror git+ssh://{{ ansible_user }}@{{ ansible_host | ipwrap }}:{{ ansible_port }}/{{ zuul_workspace_root }}/{{ zj_project.value.src_dir }}
{% endif %}
args:
chdir: "{{ zuul.executor.work_root }}/{{ zj_project.value.src_dir }}"
environment:
GIT_ALLOW_PROTOCOL: ext:ssh
with_dict: "{{ zuul.projects }}"
loop_control:
loop_var: zj_project
delegate_to: localhost
# We occasionally see git pushes in the middle of this loop fail then
# subsequent pushes for other repos succeed. The entire loop ends up
# failing because one of the pushes failed. Mitigate this by retrying
# on failure.
register: git_push
until: git_push is success
retries: 3
# ANSIBLE0006: Skip linting since it triggers on the "git" command,
# but push is not supported by ansible git module.
tags:
- skip_ansible_lint
# Do this as a multi-line shell so that we can do the loop once
- name: Update remote repository state correctly
shell: |
set -eu
# Reset is needed because we pushed to a non-bare repo
git reset --hard
# Clean is needed because we pushed to a non-bare repo
git clean -xdf
# Undo the config setting we did above
git config --local --unset receive.denyCurrentBranch
# checkout the branch matching the branch set up by the executor
git checkout {% if mirror_workspace_quiet %}--quiet{% endif %} {{ zj_project.value.checkout }}
# put out a status line with the current HEAD
echo "{{ zj_project.value.canonical_name }} checked out to:"
git log --pretty=oneline -1
args:
chdir: "{{ zuul_workspace_root }}/{{ zj_project.value.src_dir }}"
with_dict: "{{ zuul.projects }}"
loop_control:
loop_var: zj_project
# ANSIBLE0006: Skip linting since it triggers on the "git" command,
# but we prefer the shell above
tags:
- skip_ansible_lint