Prepare submodules on an explicit request

Change-Id: I060b2169d332e079d3b208c7cbfc53ffeb2769b4
diff --git a/playbooks/git-submodules/run.yaml b/playbooks/git-submodules/run.yaml
new file mode 100644
index 0000000..475d677
--- /dev/null
+++ b/playbooks/git-submodules/run.yaml
@@ -0,0 +1,32 @@
+- hosts: all
+  tasks:
+
+    - name: Point the "origin" git remote to its filesystem location
+      shell: git config --get remote.origin.url > /dev/null && git config remote.origin.url "{{ ansible_user_dir }}/{{ item.src_dir}}" || true
+      args:
+        chdir: "{{ ansible_user_dir }}/{{ item.src_dir}}"
+      with_items: "{{ zuul.projects.values() | list }}"
+
+    # E.g. Boost uses submodule URLs which end with a .git trailing suffix.
+    # That happens to be handled by many git servers automagically.
+    # Instead of rewriting the submodule URLs within each repo (which would either mark
+    # the repo dirty, or change its hash), use a big hammer and provide these
+    # "compatibility" repository names.
+    # If both a `repo` and `repo.git` already exist, then we're screwed.
+    - name: Prepare path/to/foo.git repository aliases for each path/to/foo repository
+      file:
+        src: "{{ ansible_user_dir }}/{{ item.src_dir}}"
+        dest: "{{ ansible_user_dir }}/{{ item.src_dir}}.git"
+        state: link
+      with_items: "{{ zuul.projects.values() | list }}"
+
+    - name: Recursively prepare git submodules of the main project
+      shell: git submodule update --init --recursive
+      args:
+        chdir: "{{ ansible_user_dir }}/{{ zuul.project.src_dir}}"
+
+    - name: Set the "origin" git remote back to Zuul's fake /dev/null
+      shell: git config --get remote.origin.url > /dev/null && git config remote.origin.url file:///dev/null || true
+      args:
+        chdir: "{{ ansible_user_dir }}/{{ item.src_dir}}"
+      with_items: "{{ zuul.projects.values() | list }}"