#!/bin/bash # Copyright 2010-2012, Asio Software Technologies # Distributed under the terms of the GNU General Public License v3 #------------------------------------------------------------------------------- # Creates a local mirror of specified GIT repository # Parameters: %dest_directory% %address% [%username%] #------------------------------------------------------------------------------- function mirrorGit() { local DIRECTORY="${1}" local ADDRESS="${2}" local USER="${3:-root}" if [ -d ${DIRECTORY} ]; then cd ${DIRECTORY} run "su ${USER} -s \"/bin/sh\" -c \"git fetch -all\"" || return 1 else run "su ${USER} -s \"/bin/sh\" -c \"git clone --mirror --bare \ ${ADDRESS} ${DIRECTORY}\"" || return 1 fi return 0 } #------------------------------------------------------------------------------- # Creates a local mirror of specified HG repository # Parameters: %dest_directory% %address% [%username%] #------------------------------------------------------------------------------- function mirrorMercurial() { local DIRECTORY="${1}" local ADDRESS="${2}" local USER="${3:-root}" if [ -d ${DIRECTORY} ]; then cd ${DIRECTORY} run "su ${USER} -s \"/bin/sh\" -c \"hg pull --update -e \ ${BINDIR}/ssh_wrapper.sh\"" || return 1 else run "su ${USER} -s \"/bin/sh\" -c \"hg clone ${ADDRESS} ${DIRECTORY} \ -e ${BINDIR}/ssh_wrapper.sh\"" || return 1 fi return 0 } #------------------------------------------------------------------------------- # Creates a local mirror of specified repository regardless its protocol # Parameters: %dest_directory% %protocol% %address% [%username%] #------------------------------------------------------------------------------- function mirrorRepository() { case "${2}" in [Gg][Ii][Tt]) mirrorGit "${1}" "${3}" "${4}" && return 0 ;; [Hh][Gg]) mirrorMercurial "${1}" "${3}" "${4}" && return 0 ;; [Rr][Ss][Yy][Nn][Cc]) mirrorRsync "${1}" "${3}" "${4}" && return 0 ;; *) printWarn "Tried to mirror data using unsupported protocol (${2})!" ;; esac return 1 } #------------------------------------------------------------------------------- # Creates a local mirror of specified RSYNC repository # Parameters: %dest_directory% %address% [%username%] #------------------------------------------------------------------------------- function mirrorRsync() { local DIRECTORY="${1}" local ADDRESS="${2}" local USER="${3:-root}" run "su ${USER} -s \"/bin/sh\" -c \"rsync --compress --devices --delete \ --links --perms --recursive --stats --timeout=${FETCHTIMEOUT} --times \ ${ADDRESS} ${DIRECTORY}\"" return ${?} } #------------------------------------------------------------------------------- # Downloads Portage tree ready for use at production using GIT protocol # Parameters: %dest_directory% %address% #------------------------------------------------------------------------------- function originGitPortage() { local DST="${1}" local SRC="${2}" if [ -e ${DST} ]; then return 1 fi run "git clone --depth 1 ${SRC} ${DST}" || return 1 cd ${DST} run "git config core.compression 0" || return 1 run "git gc --aggressive" || return 1 return 0 } #------------------------------------------------------------------------------- # Downloads Portage tree ready for use at production using RSYNC protocol # Parameters: %dest_directory% %address% #------------------------------------------------------------------------------- function originRsyncPortage() { local DST="${1}" local SRC="${2}" if [ -e ${DST} ]; then return 1 fi run "rsync --compress --delete --delete-after --devices --force --links \ --partial --perms --recursive --safe-links --stats --times \ --timeout=${FETCHTIMEOUT} --whole-file --exclude=/distfiles \ --exclude=/local --exclude=/packages ${SRC}/ ${DST}" || return 1 return 0 } #------------------------------------------------------------------------------- # Prepares SSH Wrappers for use with unknown hosts (requires key authentication) #------------------------------------------------------------------------------- function prepareWrappers() { run "cp ${EZROOT}/files/ssh_wrapper.sh ${BINDIR}/ssh_wrapper.sh" || return 1 run "chmod +x ${BINDIR}/ssh_wrapper.sh" || return 1 export CVS_PASSFILE="${TEMPDIR}/cvspass" export GIT_SSH="${BINDIR}/ssh_wrapper.sh" export SVN_SSH="${BINDIR}/ssh_wrapper.sh" return 0 } #------------------------------------------------------------------------------- # Downloads or updates specified CVS repository # Parameters: %dest_directory% %address% %module% #------------------------------------------------------------------------------- function pullCvs() { local DIRECTORY="${1}" local ADDRESS="${2}" local MODULE="${3}" if [ -d ${DIRECTORY} ]; then cd ${DIRECTORY} run "cvs update" || return 1 else touch ${CVS_PASSFILE} cd ${TEMPDIR} run "cvs -q -f -z3 -d:pserver:anonymous:@${ADDRESS} login" || return 1 run "cvs -q -f -z3 -d:pserver:anonymous@${ADDRESS} checkout \ -P ${MODULE}" || return 1 run "mv ${MODULE} ${DIRECTORY}" || return 1 rm -f ${CVS_PASSFILE} fi return 0 } #------------------------------------------------------------------------------- # Downloads or updates specified GIT repository # Parameters: %dest_directory% %address% [%branch%] #------------------------------------------------------------------------------- function pullGit() { local DIRECTORY="${1}" local ADDRESS="${2}" local BRANCH="${3:-master}" if [ -d ${DIRECTORY} ]; then cd ${DIRECTORY} run "git reset --hard origin/${BRANCH}" || return 1 run "git clean --force" || return 1 run "git pull --no-stat" || return 1 else run "git clone ${ADDRESS} ${DIRECTORY}" || return 1 if [ ${BRANCH} != "master" ]; then cd ${DIRECTORY} run "git checkout ${BRANCH}" || return 1 fi fi return 0 } #------------------------------------------------------------------------------- # Downloads or updates specified HG repository # Parameters: %dest_directory% %address% [%branch%] #------------------------------------------------------------------------------- function pullMercurial() { local DIRECTORY="${1}" local ADDRESS="${2}" local BRANCH="${3:-default}" if [ -d ${DIRECTORY} ]; then cd ${DIRECTORY} run "hg recover" run "hg revert -aC" || return 1 run "hg purge" || return 1 run "hg pull --update -e ${BINDIR}/ssh_wrapper.sh" || return 1 else run "hg clone ${ADDRESS} ${DIRECTORY} -e ${BINDIR}/ssh_wrapper.sh" \ || return 1 if [ ${BRANCH} != "default" ]; then run "hg branch ${BRANCH}" || return 1 fi echo -e "\n[extensions]\nhgext.purge=" >> ${DIRECTORY}/.hg/hgrc fi return 0 } #------------------------------------------------------------------------------- # Synchronizes specified repository regardless its protocol # Parameters: %dest_directory% %protocol% %address% [%branch%/%module%] #------------------------------------------------------------------------------- function pullRepository() { for ((i=0; $i<${FETCHTRIES}; i++)); do case "${2}" in [Cc][Vv][Ss]) pullCvs "${1}" "${3}" "${4}" && return 0 ;; [Gg][Ii][Tt]) pullGit "${1}" "${3}" "${4}" && return 0 ;; [Hh][Gg]) pullMercurial "${1}" "${3}" "${4}" && return 0 ;; [Rr][Ss][Yy][Nn][Cc]) pullRsync "${1}" "${3}" && return 0 ;; [Ss][Vv][Nn]) pullSubversion "${1}" "${3}" && return 0 ;; *) printWarn "Tried to pull data using unsupported protocol (${2})!" return 1 ;; esac sleep ${FETCHTIMEOUT} done return 1 } #------------------------------------------------------------------------------- # Downloads or updates specified RSYNC repository # Parameters: %dest_directory% %address% #------------------------------------------------------------------------------- function pullRsync() { DIRECTORY="${1}" ADDRESS="${2}" run "rsync --compress --delete --delete-after --devices --force --links \ --partial --perms --recursive --safe-links --stats --times \ --timeout=${FETCHTIMEOUT} --whole-file --exclude=/.git --exclude=/.hg \ --exclude=/.svn --exclude=CVS --exclude=/distfiles --exclude=/local \ --exclude=/metadata/cache --exclude=/metadata/md5-cache \ --exclude=/packages ${ADDRESS}/ ${DIRECTORY}" || return 1 return 0 } #------------------------------------------------------------------------------- # Downloads or updates specified SVN repository # Parameters: %dest_directory% %address% #------------------------------------------------------------------------------- function pullSubversion() { local DIRECTORY="${1}" local ADDRESS="${2}" if [ -d ${DIRECTORY} ]; then cd ${DIRECTORY} run "svn cleanup" || return 1 run "svn update" || return 1 else run "svn checkout ${ADDRESS} ${DIRECTORY}" || return 1 fi return 0 } #------------------------------------------------------------------------------- # Sends an update to remote GIT reository # Parameters: %directory% %message% #------------------------------------------------------------------------------- function pushGit() { local DIRECTORY="${1}" local MESSAGE="${2}" local STATUS [ ! -d ${DIRECTORY} ] && return 1 cd ${DIRECTORY} run "git add ." || return 1 STATUS=$(git status --porcelain) if [ "${STATUS}" != "" ]; then run "git commit -a -m \"${MESSAGE}\"" || return 1 run "git push" || return 1 fi return 0 } #------------------------------------------------------------------------------- # Sends an update to remote HG reository # Parameters: %directory% %message% #------------------------------------------------------------------------------- function pushMercurial() { local DIRECTORY="${1}" local MESSAGE="${2}" local STATUS [ ! -d ${DIRECTORY} ] && return 1 cd ${DIRECTORY} run "hg add ." || return 1 STATUS=$(hg status) if [ "${STATUS}" != "" ]; then run "hg commit -A -m \"${MESSAGE}\"" || return 1 run "hg push -e ${BINDIR}/ssh_wrapper.sh" || return 1 fi return 0 } #------------------------------------------------------------------------------- # Sends an update to specified remote repository regardless its protocol # Parameters: %directory% %protocol% %message% #------------------------------------------------------------------------------- function pushRepository() { case "${2}" in [Gg][Ii][Tt]) pushGit "${1}" "${3}" && return 0 ;; [Hh][Gg]) pushMercurial "${1}" "${3}" && return 0 ;; *) printWarn "Tried to push data using unsupported protocol (${2})!" ;; esac return 1 } #------------------------------------------------------------------------------- # Downloads Portage tree ready t ouse at production and creates a snapshot # Parameters: %address% %protocol% #------------------------------------------------------------------------------- function snapshotPortage() { local SOURCE="${1}" local TARBALL="portage-$(date +${TARBALLDATE}).tar.${TARBALLFORMAT}" if [ ! -d ${SNAPSHOTSDIR} ]; then makeDirectory ${SNAPSHOTSDIR} || return 1 elif [ ! -f ${SNAPSHOTSDIR}/${TARBALL} ]; then rm -rf "${TEMPDIR}/portage" case ${2} in [Gg][Ii][Tt]) originGitPortage ${TEMPDIR}/portage ${SOURCE} || return 1 ;; [Rr][Ss][Yy][Nn][Cc]) originRsyncPortage ${TEMPDIR}/portage ${SOURCE} || return 1 ;; *) printWarn "Tried to pull data using unsupported protocol (${2})!" return 1 ;; esac TARBALL=${TARBALL%.*} run "tar -c -C ${TEMPDIR} portage > ${SNAPSHOTSDIR}/${TARBALL}" if [ ${?} -ne 0 ]; then rm -f ${SNAPSHOTSDIR}/${TARBALL} return 1 fi case ${TARBALLFORMAT} in bz2) if [ -e /usr/bin/pbzip2 ]; then run "pbzip2 -p${MAXJOBS} ${SNAPSHOTSDIR}/${TARBALL}" else run "bzip2 ${SNAPSHOTSDIR}/${TARBALL}" fi ;; gz) run "gzip -9 ${SNAPSHOTSDIR}/${TARBALL}" ;; xz) run "xz ${SNAPSHOTSDIR}/${TARBALL}" ;; esac if [ ${?} -ne 0 ]; then rm -f ${SNAPSHOTSDIR}/${TARBALL} rm -f ${SNAPSHOTSDIR}/${TARBALL}.${TARBALLFORMAT} return 1 fi fi if [ ! -f ${SNAPSHOTSDIR}/${TARBALL}.DIGESTS ]; then cd ${SNAPSHOTSDIR} generateDigests ${TARBALL}.DIGESTS ${TARBALL} || return 1 fi return 0 }