diff --git a/ansible/roles/devstack-gate/files/inspector-grenade.sh b/ansible/roles/devstack-gate/files/inspector-grenade.sh new file mode 100644 index 0000000..9e63f1d --- /dev/null +++ b/ansible/roles/devstack-gate/files/inspector-grenade.sh @@ -0,0 +1,177 @@ +#!/bin/bash + +set -o xtrace +set -o errexit + +# short_source prints out the current location of the caller in a way +# that strips redundant directories. This is useful for PS4 usage. +function short_source { + saveIFS=$IFS + IFS=" " + called=($(caller 0)) + IFS=$saveIFS + file=${called[2]} + printf "%-40s " "$file:${called[1]}:${called[0]}" +} +# PS4 is exported to child shells and uses the 'short_source' function, so +# export it so child shells have access to the 'short_source' function also. +export -f short_source +export PS4='+ $(short_source): ' + +TOPDIR=$(cd $(dirname $0) && pwd) +source $TOPDIR/patch_.sh + +export LANG=en_US.utf8 +export REPO_URL=https://git.openstack.org +export ZUUL_URL=/home/jenkins/cache-workspace +mkdir -p $ZUUL_URL +export ZUUL_REF=HEAD +export WORKSPACE=/home/jenkins/workspace/testing +mkdir -p $WORKSPACE + +export ZUUL_PROJECT=openstack/ironic-inspector +export ZUUL_BRANCH=master + +export ZUUL_REF=$(review 327667 | cut -d\ -f3,3 ||:) + +# git clone $REPO_URL/$ZUUL_PROJECT $ZUUL_URL/$ZUUL_PROJECT \ +# && cd $ZUUL_URL/$ZUUL_PROJECT \ +# && git checkout remotes/origin/$ZUUL_BRANCH + +ARGS_RSYNC="-rlptDH" +if [ -d /opt/git/pip-cache/ ] +then + for user in jenkins root + do + eval user_dir=~${user} + echo Copying pip cache from /opt/git/pip-cache/ to ${user_dir}/.cache/pip/ + sudo mkdir -p ${user_dir}/.cache/pip/ + sudo rsync ${ARGS_RSYNC} --exclude=selfcheck.json /opt/git/pip-cache/ ${user_dir}/.cache/pip/ + sudo chown -R $user:$user ${user_dir}/.cache/pip/ + done +fi + +cd $WORKSPACE +[ -d devstack-gate ] || git clone --depth 1 $REPO_URL/openstack-infra/devstack-gate + +# # Cherry pick our patch: Send DEVSTACK_GATE_TEMPEST_REGEX to grenade jobs +# (cd devstack-gate; git fetch https://review.openstack.org/openstack-infra/devstack-gate refs/changes/44/241044/3 && git cherry-pick FETCH_HEAD) + +export DEVSTACK_GATE_SETTINGS="/home/jenkins/update-projects.sh" + + +# At this point you're ready to set the same environment variables and run the +# same commands/scripts as used in the desired job. The definitions for these +# are found in the openstack-infra/project-config project under the +# jenkins/jobs directory in a file named devstack-gate.yaml. It will probably +# look something like: + +# # Let's use KVM +# export DEVSTACK_GATE_LIBVIRT_TYPE=kvm + + +# From openstack-infra/project-config/jenkins/jobs/devstack-gate.yaml +# ***************** Grenade stuff ************************ +# Local mods +export PROJECTS="openstack/ironic $PROJECTS" +export PROJECTS="openstack/ironic-lib $PROJECTS" +export PROJECTS="openstack/ironic-python-agent $PROJECTS" +export PROJECTS="openstack/python-ironicclient $PROJECTS" +export PROJECTS="openstack/ironic-inspector $PROJECTS" +export PROJECTS="openstack/python-ironic-inspector-client $PROJECTS" +export PROJECTS="openstack-dev/grenade $PROJECTS" +export PYTHONUNBUFFERED=true +export GIT_BASE=http://git.openstack.org/ +#export GIT_BASE=http://github.com/ +export DEVSTACK_GATE_TIMEOUT=120 +export DEVSTACK_GATE_GRENADE=pullup +export DEVSTACK_GATE_IRONIC=1 +export DEVSTACK_GATE_NEUTRON=1 +export DEVSTACK_GATE_VIRT_DRIVER=ironic +export DEVSTACK_GATE_OS_TEST_TIMEOUT=2400 +export DEVSTACK_GATE_TEMPEST_BAREMETAL_BUILD_TIMEOUT=1200 +export TARGET_RUN_SMOKE=true + + +# export DEVSTACK_GATE_TEMPEST=1 +# export DEVSTACK_GATE_TEMPEST_ALL_PLUGINS="1" + + +# BEGIN: Since stable/mitaka ******************************************************** +export GRENADE_PLUGINRC+=$'\n'"enable_grenade_plugin ironic http://git.openstack.org/openstack/ironic" +export GRENADE_PLUGINRC+=$'\n'"enable_grenade_plugin ironic-inspector http://git.openstack.org/openstack/ironic-inspector $ZUUL_REF" + +# END: Since stable/mitaka ********************************************************** + +#export TEMPEST_CONCURRENCY=2 +export TEMPEST_CONCURRENCY=1 + + + +#------------------------ RAMDISK START ------------------------------------- +# Use TinyIPA +export IRONIC_RAMDISK_TYPE=tinyipa +export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_VM_SPECS_RAM=384" +export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_VM_COUNT=5" +# Bug in stable/mitaka. Make sure it is true to use tinyipa, though that is the +# default. +export IRONIC_BUILD_DEPLOY_RAMDISK=true + + +# For CoreOS +#export IRONIC_RAMDISK_TYPE=coreos +# The CoreOS IPA ramdisk needs at least 1GB of RAM to run +#export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_VM_SPECS_RAM=1024" +#export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_VM_COUNT=2" + + +export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_RAMDISK_TYPE=$IRONIC_RAMDISK_TYPE" +#------------------------ RAMDISK END ------------------------------------- + + +# Need to explicitly set IRONIC_IPXE_ENABLED value as default value changed +# between Mitaka and Newton. Need to have consistent value. +export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_IPXE_ENABLED=True" +export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_DEPLOY_DRIVER_ISCSI_WITH_IPA=True" +export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_INSPECTOR_RAMDISK_ELEMENT=ironic-agent" +export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_INSPECTOR_MANAGE_FIREWALL=True" + + +# export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_HW_NODE_DISK=2" +# export DEVSTACK_LOCAL_CONFIG+=$'\n'"IRONIC_VM_SPECS_DISK=2" + +# JLV set GIT_BASE since those devstack people refuse to change to a sensible +# default and insist on using 'git://' :( Yay for insecurity! +export DEVSTACK_LOCAL_CONFIG+=$'\n'"GIT_BASE=$GIT_BASE" + + + +# export BRANCH_OVERRIDE={branch-override} +export BRANCH_OVERRIDE=default +if [ "$BRANCH_OVERRIDE" != "default" ] ; then + export OVERRIDE_ZUUL_BRANCH=$BRANCH_OVERRIDE +fi +cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh + +# So the safe-devstack-vm-gate-wrap.sh is likely going to fail. So don't error +# exit +set +o errexit +# Pipe in /dev/null as had strange issues occur if didn't +./safe-devstack-vm-gate-wrap.sh &1 | tee console.txt +# cp ~/console.txt /opt/stack/logs/console.txt + +cd /opt/stack/logs/ && ~/bin/uncompress-gz-files.py > /dev/null + +if [ -d /opt/git/pip-cache/ ] +then + set +o errexit + for user in jenkins root stack + do + eval user_dir=~${user} + echo Copying pip cache files from ${user_dir}/.cache/pip/ to /opt/git/pip-cache/ + sudo rsync ${ARGS_RSYNC} --exclude=selfcheck.json ${user_dir}/.cache/pip/ /opt/git/pip-cache/ + done +fi diff --git a/ansible/roles/devstack-gate/files/ironic-grenade.sh b/ansible/roles/devstack-gate/files/ironic-grenade.sh index 118c696..08a5845 100644 --- a/ansible/roles/devstack-gate/files/ironic-grenade.sh +++ b/ansible/roles/devstack-gate/files/ironic-grenade.sh @@ -46,8 +46,8 @@ then done fi -cd $WORKSPACE \ - && git clone --depth 1 $REPO_URL/openstack-infra/devstack-gate +cd $WORKSPACE +[ -d devstack-gate ] || git clone --depth 1 $REPO_URL/openstack-infra/devstack-gate # # Cherry pick our patch: Send DEVSTACK_GATE_TEMPEST_REGEX to grenade jobs # (cd devstack-gate; git fetch https://review.openstack.org/openstack-infra/devstack-gate refs/changes/44/241044/3 && git cherry-pick FETCH_HEAD) diff --git a/ansible/roles/devstack-gate/files/patch_.sh b/ansible/roles/devstack-gate/files/patch_.sh new file mode 100644 index 0000000..f3f0a11 --- /dev/null +++ b/ansible/roles/devstack-gate/files/patch_.sh @@ -0,0 +1,61 @@ +### figure out patch of a gerrit review + +errexit=$(set +o | grep errexit) +set -o errexit +xtrace=$(set +o | grep xtrace) +set -o xtrace + +# workaround non-writable $HOME of stack user :-/ +export HTTPIE_CONFIG_DIR=/tmp/$USER-httpie-config + + +patch_repo() { + local repo=${1:?repo not specified} + local remote=${2:?remote not specified} + local ref=${3:?ref not specified} + + pushd ${repo} + flock -w 900 . bash -c \ + "git fetch ${remote} ${ref} && git cherry-pick --keep-redundant-commits FETCH_HEAD || git reset" + popd +} + + +patch_() { + local number=${1:?number not specified} + local epoch=${2:-both} + + local details=() + # nothing to do if review returns 1 + details=($(review ${number})) || return 0 + + local project=$(basename ${details[0]}) + local remote=${details[1]} + local ref=${details[2]} + local dir=/opt/stack + local repos=() + case ${epoch} in + old) + repos=(${dir}/old/${project});; + new) + repos=(${dir}/new/${project});; + both) + repos=(${dir}/old/${project} ${dir}/new/${project});; + *) + repos=(${dir}) + esac + for repo in ${repos[@]}; do + patch_repo ${repo} ${remote} ${ref} + done +} + + +review() { + # echo project url ref to cherry pick + # return 1 if already merged + local number=${1:?no number specified} + local result=() + result=($(http GET https://review.openstack.org/changes/${number}/revisions/current/review | tail -n+2 | jq -er 'debug | if .status == "NEW" then ({project} + .revisions[.current_revision].fetch["anonymous http"])["project", "url","ref"] else false end | debug')) || return ${?} + [ ${#result[@]} -eq 3 ] || return 1 + echo ${result[@]} +} diff --git a/ansible/roles/devstack-gate/files/unbound.conf b/ansible/roles/devstack-gate/files/unbound.conf new file mode 100644 index 0000000..892baa2 --- /dev/null +++ b/ansible/roles/devstack-gate/files/unbound.conf @@ -0,0 +1,24 @@ +# Unbound configuration file for Debian. +# +# See the unbound.conf(5) man page. +# +# See /usr/share/doc/unbound/examples/unbound.conf for a commented +# reference config file. +# +# The following line includes additional configuration files from the +# /etc/unbound/unbound.conf.d directory. + +server: + local-zone: "localhost." static + local-data: "localhost. 10800 IN NS localhost." + local-data: "localhost. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" + local-data: "localhost. 10800 IN A 127.0.0.1" + local-zone: "127.in-addr.arpa." static + local-data: "127.in-addr.arpa. 10800 IN NS localhost." + local-data: "127.in-addr.arpa. 10800 IN SOA localhost. nobody.invalid. 2 3600 1200 604800 10800" + local-data: "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost." + +forward-zone: + name: "." + forward-addr: 8.8.8.8 + forward-addr: 8.8.4.4 diff --git a/ansible/roles/devstack-gate/files/update-projects.sh b/ansible/roles/devstack-gate/files/update-projects.sh index 58317a2..14aaac4 100644 --- a/ansible/roles/devstack-gate/files/update-projects.sh +++ b/ansible/roles/devstack-gate/files/update-projects.sh @@ -8,52 +8,58 @@ set -o errexit xtrace=$(set +o | grep xtrace) set -o xtrace +PATCH_DIR=$(cd $(dirname $DEVSTACK_GATE_SETTINGS) && pwd) +source $PATCH_DIR/patch_.sh + # ***** grenade project patches **************************************************** echo "***: Open up firewall for ironic provisioning" # https://review.openstack.org/#/c/315268/ -(cd /opt/stack/new/grenade; git fetch https://git.openstack.org/openstack-dev/grenade refs/changes/68/315268/1 && git cherry-pick FETCH_HEAD || git reset) -(cd /opt/stack/old/grenade; git fetch https://git.openstack.org/openstack-dev/grenade refs/changes/68/315268/1 && git cherry-pick FETCH_HEAD || git reset) +(patch_ 315268) echo "***: Enable PS4 for grenade.sh" # https://review.openstack.org/#/c/318352/ -(cd /opt/stack/new/grenade; git fetch https://git.openstack.org/openstack-dev/grenade refs/changes/52/318352/1 && git cherry-pick FETCH_HEAD || git reset) -(cd /opt/stack/old/grenade; git fetch https://git.openstack.org/openstack-dev/grenade refs/changes/52/318352/1 && git cherry-pick FETCH_HEAD || git reset) +(patch_ 318352) + echo "***: Load settings from plugins in upgrade-tempest" # https://review.openstack.org/#/c/317993/ -(cd /opt/stack/new/grenade; git fetch https://git.openstack.org/openstack-dev/grenade refs/changes/93/317993/1 && git cherry-pick FETCH_HEAD || git reset) -(cd /opt/stack/old/grenade; git fetch https://git.openstack.org/openstack-dev/grenade refs/changes/93/317993/1 && git cherry-pick FETCH_HEAD || git reset) - +(patch_ 317993) # ***** tempest project patches **************************************************** echo "****: Fetching the tempest smoke patch" # https://review.openstack.org/#/c/315422/ -(cd /opt/stack/new/tempest; git fetch https://git.openstack.org/openstack/tempest refs/changes/22/315422/9 && git cherry-pick FETCH_HEAD || git reset) -(cd /opt/stack/old/tempest; git fetch https://git.openstack.org/openstack/tempest refs/changes/22/315422/9 && git cherry-pick FETCH_HEAD || git reset) +(patch_ 315422) # # ***** devstack-gate project patches **************************************************** +# openstack-infra/devstack-gate: Allow to pass OS_TEST_TIMEOUT for grenade job +# https://review.openstack.org/#/c/316662/ +(patch_ 316662) + +# openstack-infra/devstack-gate: Allow to set Ironic provision timeout from the job +# https://review.openstack.org/#/c/315496/ +(patch_ 315496) + echo "***: WIP: Add some debugging code (PS4 & xtrace)" # https://review.openstack.org/#/c/318227/ -(cd /opt/stack/new/devstack-gate; git fetch https://git.openstack.org/openstack-infra/devstack-gate refs/changes/27/318227/1 && git cherry-pick FETCH_HEAD) -(cd /home/jenkins/workspace/testing/devstack-gate; git fetch https://git.openstack.org/openstack-infra/devstack-gate refs/changes/27/318227/1 && git cherry-pick FETCH_HEAD) - +(patch_ 318227 new) +details=($(review 318227)) && { + (patch_repo /home/jenkins/workspace/testing/devstack-gate ${details[1]} ${details[2]}) +} # ***** devstack project patches **************************************************** echo "***: Export the 'short_source' function" # https://review.openstack.org/#/c/313132/ -(cd /opt/stack/old/devstack; git fetch https://git.openstack.org/openstack-dev/devstack refs/changes/32/313132/6 && git cherry-pick FETCH_HEAD) +(patch_ 313132 old) echo "***: Fix ironic compute_driver name" # https://review.openstack.org/#/c/318027/ -(cd /opt/stack/old/devstack; git fetch https://git.openstack.org/openstack-dev/devstack refs/changes/27/318027/1 && git cherry-pick FETCH_HEAD || git reset) - +(patch_ 318027 old) # ***** nova project patches **************************************************** echo '***: Fix update inventory for multiple providers' # https://review.openstack.org/#/c/316031/ -(cd /opt/stack/old/nova; git fetch https://git.openstack.org/openstack/nova refs/changes/31/316031/5 && git cherry-pick FETCH_HEAD) -(cd /opt/stack/new/nova; git fetch https://git.openstack.org/openstack/nova refs/changes/31/316031/5 && git cherry-pick FETCH_HEAD) +(patch_ 316031) # ***** ironic-python-agent project patches **************************************************** @@ -64,40 +70,70 @@ echo '***: Fix update inventory for multiple providers' # start vsaienko/vdrok patches echo '***: Gracefully degrade start_iscsi_target for Mitaka ramdisk' # https://review.openstack.org/#/c/319183/ -(cd /opt/stack/new/ironic; git fetch https://git.openstack.org/openstack/ironic refs/changes/83/319183/5 && git cherry-pick FETCH_HEAD) +(patch_ 319183 new) echo '***: Restart n-cpu after Ironic install' # https://review.openstack.org/#/c/318479/ -(cd /opt/stack/new/ironic; git fetch https://git.openstack.org/openstack/ironic refs/changes/79/318479/8 && git cherry-pick FETCH_HEAD) +(patch_ 318479 new) echo "***: Move all cleanups to cleanup_ironic" # https://review.openstack.org/#/c/318660/ -(cd /opt/stack/new/ironic; git fetch https://git.openstack.org/openstack/ironic refs/changes/60/318660/6 && git cherry-pick FETCH_HEAD) +(patch_ 318660 new) echo 'Keep backward compatibility for openstack port create' # https://review.openstack.org/#/c/319232/ -(cd /opt/stack/new/ironic; git fetch https://git.openstack.org/openstack/ironic refs/changes/32/319232/3 && git cherry-pick FETCH_HEAD) +(patch_ 319232 new) echo '***: Make sure create_ovs_taps creates unique taps' # https://review.openstack.org/#/c/319101/ -(cd /opt/stack/new/ironic; git fetch https://git.openstack.org/openstack/ironic refs/changes/01/319101/4 && git cherry-pick FETCH_HEAD) +(patch_ 319101 new) echo '***: Revert "Run smoke tests after upgrade"' # https://review.openstack.org/#/c/319372/ -(cd /opt/stack/new/ironic; git fetch https://git.openstack.org/openstack/ironic refs/changes/72/319372/1 && git cherry-pick FETCH_HEAD) +(patch_ 319372 new) ##### end vsaienko/vdrok patches echo "***: Fetching the Ironic disable cleaning patch" # https://review.openstack.org/#/c/309115/ -(cd /opt/stack/old/ironic; git fetch https://git.openstack.org/openstack/ironic refs/changes/15/309115/1 && git cherry-pick FETCH_HEAD) +(patch_ 309115 old) echo "***: Update resources subnet CIDR" # https://review.openstack.org/#/c/317082/ -(cd /opt/stack/new/ironic; git fetch https://git.openstack.org/openstack/ironic refs/changes/82/317082/2 && git cherry-pick FETCH_HEAD) +(patch_ 317082 new) + +echo "*** Allow Devstack on Xenial in Mitaka" +# https://review.openstack.org/#/c/324295/1 +(patch_ 324295 old) + +echo "*** Remove neutron stuff from devstack deb packages" +# https://review.openstack.org/#/c/325346/ +(patch_ 325346) +# cherry-picked to stable/mitaka +# https://review.ope nstack.org/#/c/326250/ +(patch_ 326250 old) +# *** ironic python client +# openstack/python-ironicclient: Catch RetriableConnectionFailures from KAuth and retry +# https://review.openstack.org/323851 +# if this works, won't need to do extra reboots of nova compute during upgrade (so we'd undo the code that is doing the reboots) +(patch_ 323851 new) +# *** inspector patch for grenade +echo applying inspector patch for grenade +(patch_ 327667) +# *** fix devstack screen_start--screen_stop for non-screen cases +echo applying Setsid to fix "old" screen_it--screen_stop chain +(patch_ 333155) + +# *** missing install_tempest_plugins +echo Add missing install_tempest_plugins call to upgrade-tempest +(patch_ 337372) + +# *** inspector smoke tests +echo Add a simple smoke test to be run in the grenade gate +(patch_ 336532) # Prep the pip cache for the stack user, which is owned by the 'jenkins' user at this point if [ -d /opt/git/pip-cache/ ] @@ -118,3 +154,4 @@ fi $xtrace $errexit + diff --git a/ansible/roles/devstack-gate/tasks/main.yml b/ansible/roles/devstack-gate/tasks/main.yml index eec31d7..f8ea6e7 100644 --- a/ansible/roles/devstack-gate/tasks/main.yml +++ b/ansible/roles/devstack-gate/tasks/main.yml @@ -26,6 +26,7 @@ name: "{{ item }}" state: present with_items: + - ntpdate - bridge-utils - docker.io # Install docker, so proxy settings get setup (if needed) - ebtables @@ -33,8 +34,19 @@ - libffi-dev # Ansible compilation - libssl-dev # Ansible compilation - python-dev # Ansible compilation + - automake # compile jq + - libtool # compile jq + - bison # compile jq sudo: yes +- name: Install up-to-date Ipxe + apt: deb=http://archive.ubuntu.com/ubuntu/pool/main/i/ipxe/ipxe_1.0.0+git-20150424.a25a16d-1ubuntu2_all.deb + state=present + +- name: Install up-to-date Qemu Ipxe + apt: deb=http://archive.ubuntu.com/ubuntu/pool/main/i/ipxe/ipxe-qemu_1.0.0+git-20150424.a25a16d-1ubuntu2_all.deb + state=present + - name: Check if we have a /opt/git/pip-cache/ stat: path="/opt/git/pip-cache" register: has_pip_cache @@ -145,3 +157,52 @@ with_items: - jenkins - root + +- name: fetch jq + git: repo=https://github.com/stedolan/jq.git + dest=/usr/local/src/jq + tags: jq + +- name: autoreconfigure jq + shell: autoreconf -i + chdir=/usr/local/src/jq + creates=configure + tags: jq + +- name: configure jq + shell: ./configure + chdir=/usr/local/src/jq + creates=config.status + tags: jq + +- name: make install jq + shell: make install + chdir=/usr/local/src/jq + tags: jq + +- name: pip install httpie + pip: name=httpie + state=latest + tags: httpie + +- name: install unbound + # Infra's default setup workarounding http://www.stgraber.org/2012/02/24/dns-in-ubuntu-12-04/ by accident + apt: name=unbound state=latest + +- name: configure unbound + copy: src=unbound.conf + dest=/etc/unbound/ + mode="0644" + owner="root" + group="root" + +- name: enable unbound + service: name=unbound state=restarted enabled=yes + +- name: install dnsmasq + # ... in advance to workaround later issues with ubuntu using it as local resolver + apt: name=dnsmasq state=latest + +- name: disable dnsmasq + # ... to avoid port races with unbound + service: name=dnsmasq state=stopped enabled=no diff --git a/ansible/roles/devstack-gate/vars/main.yml b/ansible/roles/devstack-gate/vars/main.yml index ea48adb..3b8785c 100644 --- a/ansible/roles/devstack-gate/vars/main.yml +++ b/ansible/roles/devstack-gate/vars/main.yml @@ -9,6 +9,10 @@ dirs_to_create: mode: "0755" owner: jenkins group: jenkins + - path: /opt/stack/cache/files + mode: "0755" + owner: jenkins + group: jenkins files_to_copy: - src: ironic-grenade.sh @@ -16,6 +20,16 @@ files_to_copy: mode: "0755" owner: jenkins group: jenkins + - src: inspector-grenade.sh + dest: "~jenkins/inspector-grenade.sh" + mode: "0755" + owner: jenkins + group: jenkins + - src: patch_.sh + dest: "~jenkins/patch_.sh" + mode: "0644" + owner: jenkins + group: jenkins - src: update-projects.sh dest: "~jenkins/update-projects.sh" mode: "0644" diff --git a/setup_git_cache.sh b/setup_git_cache.sh index 70393f0..89cc13d 100755 --- a/setup_git_cache.sh +++ b/setup_git_cache.sh @@ -90,5 +90,6 @@ END_REPOS for repo in $repo_list do - git clone $git_root/$repo $repo + git clone $git_root/$repo $repo & done +wait