From e34b464f2cd50052e92aa267624eaa0f09098cf4 Mon Sep 17 00:00:00 2001 From: Andre Anjos <andre.anjos@idiap.ch> Date: Tue, 27 Sep 2016 11:11:36 +0200 Subject: [PATCH] Use filesystem locks to prevent concurrent use of ~/.pypirc (fixes #11) --- gitlab/after_deploy.sh | 2 +- gitlab/before_deploy.sh | 1 - gitlab/deploy.sh | 14 ++++--- gitlab/functions.sh | 81 +++++++++++++++++++++++++++++++++-------- 4 files changed, 75 insertions(+), 23 deletions(-) diff --git a/gitlab/after_deploy.sh b/gitlab/after_deploy.sh index 2cdd86c..dc97ec3 100755 --- a/gitlab/after_deploy.sh +++ b/gitlab/after_deploy.sh @@ -3,4 +3,4 @@ source $(dirname ${0})/functions.sh -run_cmd rm -rf ${HOME}/.pypirc +log_info "*** Not yet implemented ***" diff --git a/gitlab/before_deploy.sh b/gitlab/before_deploy.sh index 1fd16d3..25fc0ba 100755 --- a/gitlab/before_deploy.sh +++ b/gitlab/before_deploy.sh @@ -3,5 +3,4 @@ source $(dirname ${0})/functions.sh -run_cmd rm -f ${HOME}/.pypirc run_cmd $(dirname ${0})/before_test.sh diff --git a/gitlab/deploy.sh b/gitlab/deploy.sh index fafec8f..1429525 100755 --- a/gitlab/deploy.sh +++ b/gitlab/deploy.sh @@ -3,18 +3,20 @@ source $(dirname ${0})/functions.sh -dot_pypirc +lock_pypirc -setup register --repository staging -setup check sdist --formats zip upload --repository staging +setup_deploy register --repository staging +setup_deploy check sdist --formats zip upload --repository staging # if that worked, uploads documentation to pythonhosted if any exists if [ -d sphinx ]; then log_info "Uploading documentation to ${PYPISERVER} on behalf of ${PYPIUSER}..." - setup upload_docs --upload-dir sphinx --repository production + setup_deploy upload_docs --upload-dir sphinx --repository production fi # if that worked, uploads source package to the production index log_info "Uploading package to ${PYPISERVER} on behalf of ${PYPIUSER}..." -setup register --repository production -setup check sdist --formats zip upload --repository production +setup_deploy register --repository production +setup_deploy check sdist --formats zip upload --repository production + +unlock_pypirc diff --git a/gitlab/functions.sh b/gitlab/functions.sh index 840be05..3bdf6ab 100644 --- a/gitlab/functions.sh +++ b/gitlab/functions.sh @@ -16,12 +16,12 @@ log_info() { log_warn() { - echo -e "(`date +%T`) \033[1;35mWarning: ${@}\033[0m" + echo -e "(`date +%T`) \033[1;35mWarning: ${@}\033[0m" >&2 } log_error() { - echo -e "(`date +%T`) \033[1;31mError: ${@}\033[0m" + echo -e "(`date +%T`) \033[1;31mError: ${@}\033[0m" >&2 } @@ -71,20 +71,29 @@ run_cmd() { } -# Runs setup.py -setup() { - run_cmd ${PREFIX}/bin/python setup.py ${@} -} - - # Prepares ~/.pypirc -dot_pypirc() { +lock_pypirc() { + local lockfile=/var/tmp/pypirc_lock local rc=${HOME}/.pypirc - log_info "Creating ${rc}..." - if [ -e ${rc} ]; then - run_cmd rm -f ${rc} - fi - cat <<EOT >> ${rc} + local maxtries=10 + local try=0 + local sleeptime=30 #seconds + + while true; do + if [[ ${try} -lt ${maxtries} ]]; then + ((try++)) + if ( set -o noclobber; echo "$$" > "${lockfile}") 2> /dev/null; then + log_info "Successfully acquired ${lockfile}" + echo $$ > ${lockfile} + log_info "trapping on ${lockfile}..." + trap 'rm -f "${lockfile}"; exit $?' INT TERM EXIT + + # start: protected code + log_info "Creating ${rc}..." + if [ -e ${rc} ]; then + run_cmd rm -f ${rc} + fi + cat <<EOT >> ${rc} [distutils] index-servers = production @@ -100,7 +109,49 @@ repository: ${TESTSERVER} username: ${PYPIUSER} password: ${PYPIPASS} EOT - run_cmd chmod 600 ${rc} + run_cmd chmod 600 ${rc} + # end: protected code + break + else + log_warn "${lockfile} exists, owned by process $(cat $lockfile)" + log_info "Will retry after a ${sleeptime} seconds sleep (${try}/${maxtries})" + run_cmd sleep ${sleeptime} + fi + else + log_error "I already retried deploying ${try} times. Aborting..." + log_error "You can retry this step when less packages are building." + exit 1 + fi + done +} + + +# Cleans ~/.pypirc, if the lock file belongs to us +unlock_pypirc() { + local lockfile=/var/tmp/pypirc_lock + local rc=${HOME}/.pypirc + + # untrap if lock belongs to the running process + if [[ $(cat ${lockfile}) == $$ ]]; then + run_cmd rm -r ${lockfile} + run_cmd rm -rf ${rc} + log_info "$ trap - INT TERM EXIT" + trap - INT TERM EXIT + fi +} + + +# Runs setup.py in a deployment context. If fails, tries to unlock +# the ${HOME}/.pypirc file lock +setup_deploy() { + log_info "$ ${@}" + ${PREFIX}/bin/python setup.py ${@} + local status=$? + if [ ${status} != 0 ]; then + log_error "Command Failed \"${@}\"" + unlock_pypirc #just tries + exit ${status} + fi } -- GitLab