2013-05-23 13:09:04 +00:00
|
|
|
#!/bin/bash
|
|
|
|
|
2013-07-18 03:02:31 +00:00
|
|
|
set -eu
|
2014-04-03 02:24:15 +00:00
|
|
|
set -o pipefail
|
2013-05-23 13:09:04 +00:00
|
|
|
|
2014-10-15 16:07:33 +00:00
|
|
|
# Don't provide any source repositories in environments where they are not allowed
|
|
|
|
if [ -n "${NO_SOURCE_REPOSITORIES:-}" ]; then
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
2014-03-10 20:36:47 +00:00
|
|
|
# If the old cache exists, move it to the new name
|
|
|
|
function make_new_cache(){
|
|
|
|
local OLD_CACHE_BASE=$1
|
|
|
|
local CACHE_BASE=$2
|
|
|
|
|
|
|
|
# If the old cache name exists, move it to the new cache name
|
|
|
|
if [ -e "$OLD_CACHE_BASE" ] ; then
|
|
|
|
if [ ! -e "$CACHE_BASE" ] ; then
|
|
|
|
mv -n $OLD_CACHE_BASE $CACHE_BASE
|
|
|
|
else
|
|
|
|
echo "Not replacing new cache location with old cache"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2013-09-01 21:52:04 +00:00
|
|
|
# Gets repositories or individual files listed in the a repository file
|
|
|
|
# and places them in the specified destination path.
|
2013-05-23 13:09:04 +00:00
|
|
|
# The format of the repository file is one or more lines matching
|
|
|
|
# <name> <type> <destination> <location> [<ref>]
|
|
|
|
function get_repos_for_element(){
|
|
|
|
local REPO_SOURCES=$1
|
2013-09-01 21:52:04 +00:00
|
|
|
local CACHE_URL=$TMP_HOOKS_PATH/bin/cache-url
|
|
|
|
|
2014-01-09 16:07:23 +00:00
|
|
|
local REGEX="^([^ ]+) (git|tar|file|package) ?(/[^ ]+)? ?([^ ]+)? ?([^ ]*)$"
|
2013-05-23 13:09:04 +00:00
|
|
|
|
2014-02-25 00:29:24 +00:00
|
|
|
while read line; do
|
2014-07-03 21:20:08 +00:00
|
|
|
# temporarily turn off globbing '*' (since it may be used as the REPOREF for tarballs)
|
|
|
|
set -f
|
|
|
|
|
2014-02-25 00:29:24 +00:00
|
|
|
# expand variables
|
|
|
|
line=$(eval echo $line)
|
2013-05-23 13:09:04 +00:00
|
|
|
|
2014-07-03 21:20:08 +00:00
|
|
|
# restore globbing
|
|
|
|
set +f
|
|
|
|
|
2014-02-07 06:42:04 +00:00
|
|
|
# ignore blank lines and lines beginning in '#'
|
2013-05-23 13:09:04 +00:00
|
|
|
[[ "$line" == \#* ]] || [[ -z "$line" ]] && continue
|
|
|
|
|
|
|
|
if [[ "$line" =~ $REGEX ]] ; then
|
|
|
|
local REPONAME=${BASH_REMATCH[1]}
|
|
|
|
local REPOTYPE=${BASH_REMATCH[2]}
|
|
|
|
local REPOPATH=${BASH_REMATCH[3]}
|
|
|
|
local REPOLOCATION=${BASH_REMATCH[4]}
|
2013-07-18 03:02:31 +00:00
|
|
|
local REPO_ORIG_LOCATION=$REPOLOCATION
|
2014-07-03 21:20:08 +00:00
|
|
|
|
|
|
|
if [ $REPONAME = "tar" -a -z "${BASH_REMATCH[5]:-}" ] ; then
|
|
|
|
echo "Warning: Default tarball REPOREF of '*' is deprecated; do not rely on it."
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Default of '*' for tar repositories is deprecated; do not rely on it.
|
|
|
|
local REPOREF_DEFAULT_TAR=*
|
|
|
|
local REPOREF_DEFAULT_GIT=master
|
|
|
|
local REPOREF_LOOKUP_DEFAULT=REPOREF_DEFAULT_${REPOTYPE^^}
|
|
|
|
|
|
|
|
local REPOREF=${BASH_REMATCH[5]:-${!REPOREF_LOOKUP_DEFAULT:-}}
|
2013-05-23 13:09:04 +00:00
|
|
|
|
2013-09-01 21:52:04 +00:00
|
|
|
local REPO_DEST=$TMP_MOUNT_PATH$REPOPATH
|
|
|
|
local REPO_SUB_DIRECTORY=$(dirname $REPO_DEST)
|
2013-05-23 13:09:04 +00:00
|
|
|
|
|
|
|
# REPOTYPE can be overridden with DIB_REPOTYPE_{name}
|
2014-02-26 22:22:40 +00:00
|
|
|
local REPOTYPE_OVERRIDE=DIB_REPOTYPE_${REPONAME//[^A-Za-z0-9]/_}
|
2013-05-23 13:09:04 +00:00
|
|
|
REPOTYPE=${!REPOTYPE_OVERRIDE:-$REPOTYPE}
|
|
|
|
|
|
|
|
# REPOLOCATION can be overridden with DIB_REPOLOCATION_{name}
|
2014-02-26 22:22:40 +00:00
|
|
|
local REPOLOCATION_OVERRIDE=DIB_REPOLOCATION_${REPONAME//[^A-Za-z0-9]/_}
|
2013-05-23 13:09:04 +00:00
|
|
|
REPOLOCATION=${!REPOLOCATION_OVERRIDE:-$REPOLOCATION}
|
|
|
|
|
|
|
|
# REPOREF can be overridden with DIB_REPOREF_{name}
|
2014-02-26 22:22:40 +00:00
|
|
|
local REPOREF_OVERRIDE=DIB_REPOREF_${REPONAME//[^A-Za-z0-9]/_}
|
2013-05-23 13:09:04 +00:00
|
|
|
REPOREF=${!REPOREF_OVERRIDE:-$REPOREF}
|
|
|
|
|
2013-12-20 14:35:34 +00:00
|
|
|
# Determine a unique cache path for this repo
|
|
|
|
CACHE_NAME=$(echo "${REPOTYPE}_${REPOLOCATION}" | sha1sum | awk '{ print $1 }' )
|
2014-02-24 10:43:59 +00:00
|
|
|
OLD_CACHE_PATH=${CACHE_BASE}/${CACHE_NAME}
|
|
|
|
# Add the repo name to the sha1sum for readability
|
2014-03-11 13:13:10 +00:00
|
|
|
CACHE_NAME=${REPONAME//[^A-Za-z0-9]/_}_${CACHE_NAME}
|
2014-02-24 10:43:59 +00:00
|
|
|
CACHE_PATH=${CACHE_BASE}/$CACHE_NAME
|
2014-03-10 20:36:47 +00:00
|
|
|
make_new_cache $OLD_CACHE_PATH $CACHE_PATH
|
2013-12-20 14:35:34 +00:00
|
|
|
|
2014-03-06 22:23:12 +00:00
|
|
|
# Return if install type is not source
|
|
|
|
local INSTALL_TYPE_VAR=DIB_INSTALLTYPE_${REPONAME//[^A-Za-z0-9]/_}
|
2014-10-27 16:49:30 +00:00
|
|
|
local INSTALL_TYPE=${!INSTALL_TYPE_VAR:-$DIB_DEFAULT_INSTALLTYPE}
|
2014-03-06 22:23:12 +00:00
|
|
|
if [ ! $INSTALL_TYPE = "source" ]; then
|
|
|
|
echo "$REPONAME install type not set to source"
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
2013-05-23 13:09:04 +00:00
|
|
|
case $REPOTYPE in
|
|
|
|
git)
|
2014-02-19 17:38:34 +00:00
|
|
|
if [ -z "${!REPOLOCATION_OVERRIDE:-""}" -a -n "${DIB_GITREPOBASE:-""}" ] ; then
|
|
|
|
# Transform the current repo base to the new one
|
|
|
|
local NEW_REPOLOCATION=$(echo $REPOLOCATION |\
|
|
|
|
sed "s,^[^:]\+://[^/]\+/\(~[^/]\+\)\?\(.*\)$,${DIB_GITREPOBASE}\2,g")
|
|
|
|
echo "Transformed ${REPOLOCATION} to ${NEW_REPOLOCATION}"
|
|
|
|
REPOLOCATION=$NEW_REPOLOCATION
|
|
|
|
# Also update the cache location
|
|
|
|
CACHE_NAME=$(echo "${REPOTYPE}_${REPOLOCATION}" | sha1sum | awk '{ print $1 }' )
|
|
|
|
CACHE_PATH=~/.cache/image-create/repository-sources/$CACHE_NAME
|
|
|
|
fi
|
2013-05-23 13:09:04 +00:00
|
|
|
sudo mkdir -p $REPO_SUB_DIRECTORY
|
2013-12-20 14:35:34 +00:00
|
|
|
|
|
|
|
if [ ! -e "$CACHE_PATH" ] ; then
|
|
|
|
echo "Caching $REPONAME from $REPOLOCATION in $CACHE_PATH"
|
|
|
|
git clone $REPOLOCATION $CACHE_PATH.tmp
|
|
|
|
mv ${CACHE_PATH}{.tmp,}
|
2013-07-18 03:02:31 +00:00
|
|
|
fi
|
2013-12-20 14:35:34 +00:00
|
|
|
|
2014-02-28 12:21:07 +00:00
|
|
|
HAS_REF=$(git --git-dir=$CACHE_PATH/.git name-rev $REPOREF 2>/dev/null || true)
|
2013-12-20 14:35:34 +00:00
|
|
|
if [ -z "$DIB_OFFLINE" -o -z "$HAS_REF" ] ; then
|
|
|
|
echo "Updating cache of $REPOLOCATION in $CACHE_PATH with ref $REPOREF"
|
2014-05-20 09:49:15 +00:00
|
|
|
# Copy named refs (which might be outside the usual heads
|
|
|
|
# pattern) - e.g. gerrit
|
|
|
|
if ! git --git-dir=$CACHE_PATH/.git fetch --update-head-ok $REPOLOCATION \
|
|
|
|
+${REPOREF}:${REPOREF} ; then
|
|
|
|
# Copy all heads from the remote repository - this permits
|
|
|
|
# using a SHA1 object reference so long as the object
|
|
|
|
# reference is reachable from one of the heads. git does
|
|
|
|
# not permit arbitrary sha fetching from remote servers.
|
|
|
|
# This is a separate fetch to the prior one as the prior
|
|
|
|
# one will fail when REPOREF is a SHA1.
|
|
|
|
git --git-dir=$CACHE_PATH/.git fetch --update-head-ok $REPOLOCATION \
|
|
|
|
+refs/heads/*:refs/heads/*
|
|
|
|
fi
|
|
|
|
# Ensure that we have a reference to the revision.
|
|
|
|
git --git-dir=$CACHE_PATH/.git rev-parse -q --verify $REPOREF^{commit}
|
2013-12-20 14:35:34 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
echo "Cloning from $REPONAME cache and applying ref $REPOREF"
|
|
|
|
sudo git clone $CACHE_PATH $REPO_DEST
|
2013-09-01 21:52:04 +00:00
|
|
|
pushd $REPO_DEST
|
2013-12-20 14:35:34 +00:00
|
|
|
sudo git fetch $CACHE_PATH $REPOREF
|
|
|
|
sudo git reset --hard FETCH_HEAD
|
2014-05-07 03:24:46 +00:00
|
|
|
# Get the sha in use
|
|
|
|
git_sha=$(git rev-parse FETCH_HEAD)
|
2013-05-23 13:09:04 +00:00
|
|
|
popd
|
2014-02-21 16:51:46 +00:00
|
|
|
|
2014-05-07 03:24:46 +00:00
|
|
|
# Write the sha being used into the source-repositories manifest
|
|
|
|
echo "$REPONAME git $REPOPATH $REPOLOCATION $git_sha" >> $GIT_MANIFEST
|
2013-05-23 13:09:04 +00:00
|
|
|
;;
|
|
|
|
tar)
|
|
|
|
# The top level directory of the tarball mightn't have a fixed name i.e.
|
|
|
|
# it could contain version numbers etc... so we write it to a tmpdir
|
2014-07-03 21:20:08 +00:00
|
|
|
# for inspection before transferring the contents into the target directory
|
2013-05-23 13:09:04 +00:00
|
|
|
local tmpdir=$(mktemp --tmpdir=$TMP_MOUNT_PATH/tmp -d)
|
2013-07-18 03:02:31 +00:00
|
|
|
if [ -n "$CACHE_PATH" ] ; then
|
2013-12-04 17:18:18 +00:00
|
|
|
echo "Caching $REPONAME tarball from $REPOLOCATION in $CACHE_PATH"
|
2013-07-18 03:02:31 +00:00
|
|
|
if [ ! -f "$CACHE_PATH" -o -z "$DIB_OFFLINE" ] ; then
|
2013-09-01 21:52:04 +00:00
|
|
|
$CACHE_URL $REPOLOCATION $CACHE_PATH
|
2013-07-18 03:02:31 +00:00
|
|
|
fi
|
|
|
|
tar -C $tmpdir -xzf $CACHE_PATH
|
|
|
|
else
|
2013-12-04 17:18:18 +00:00
|
|
|
echo "Fetching $REPONAME tarball from $REPOLOCATION"
|
2013-07-18 03:02:31 +00:00
|
|
|
curl $REPOLOCATION | tar -C $tmpdir -xzf -
|
|
|
|
fi
|
2014-07-03 21:20:08 +00:00
|
|
|
|
2013-09-01 21:52:04 +00:00
|
|
|
sudo mkdir -p $REPO_DEST
|
2014-07-03 21:20:08 +00:00
|
|
|
|
|
|
|
# A REPOREF of '.' will select the entire contents of the tarball,
|
|
|
|
# while '*' will select only the contents of its subdirectories.
|
|
|
|
sudo rsync -a --remove-source-files $tmpdir/$REPOREF/. $REPO_DEST
|
|
|
|
|
2013-05-23 13:09:04 +00:00
|
|
|
rm -rf $tmpdir
|
2014-07-03 21:20:08 +00:00
|
|
|
|
2013-05-23 13:09:04 +00:00
|
|
|
;;
|
2013-09-01 21:52:04 +00:00
|
|
|
file)
|
|
|
|
sudo mkdir -p $REPO_SUB_DIRECTORY
|
|
|
|
if [ -n "$CACHE_PATH" ] ; then
|
2013-12-04 17:18:18 +00:00
|
|
|
echo "Caching $REPONAME file from $REPOLOCATION in $CACHE_PATH"
|
2013-09-01 21:52:04 +00:00
|
|
|
if [ ! -f "$CACHE_PATH" -o -z "$DIB_OFFLINE" ] ; then
|
|
|
|
$CACHE_URL $REPOLOCATION $CACHE_PATH
|
|
|
|
fi
|
|
|
|
sudo cp $CACHE_PATH $REPO_DEST
|
|
|
|
else
|
2013-12-04 17:18:18 +00:00
|
|
|
echo "Fetching $REPONAME file from $REPOLOCATION"
|
2013-09-01 21:52:04 +00:00
|
|
|
sudo curl $REPOLOCATION -o $REPO_DEST
|
|
|
|
fi
|
|
|
|
;;
|
2013-05-23 13:09:04 +00:00
|
|
|
*)
|
2013-12-20 14:53:53 +00:00
|
|
|
echo "Unsupported repository type: $REPOTYPE"
|
2013-05-23 13:09:04 +00:00
|
|
|
return 1
|
|
|
|
;;
|
|
|
|
esac
|
2014-01-14 21:51:49 +00:00
|
|
|
|
2013-08-02 10:56:48 +00:00
|
|
|
# Capture the in-instance repository path for later review / other
|
|
|
|
# elements (like a pypi dependency cache).
|
|
|
|
echo "$REPOPATH" | sudo dd of=$TMP_MOUNT_PATH/etc/dib-source-repositories oflag=append conv=notrunc
|
2014-01-14 21:51:49 +00:00
|
|
|
|
2013-05-23 13:09:04 +00:00
|
|
|
else
|
|
|
|
echo "Couldn't parse '$line' as a source repository"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
done < $REPO_SOURCES
|
|
|
|
}
|
|
|
|
|
2014-10-05 20:55:34 +00:00
|
|
|
CACHE_BASE=$DIB_IMAGE_CACHE/source-repositories
|
|
|
|
OLD_CACHE_BASE=$DIB_IMAGE_CACHE/repository-sources
|
2014-03-10 20:36:47 +00:00
|
|
|
make_new_cache $OLD_CACHE_BASE $CACHE_BASE
|
2014-02-24 10:43:59 +00:00
|
|
|
mkdir -p $CACHE_BASE
|
2014-02-21 16:51:46 +00:00
|
|
|
# Use the IMAGE_NAME from the calling script, and make it unique with the temporary path
|
2014-03-28 18:02:36 +00:00
|
|
|
GIT_MANIFEST_NAME=dib-manifest-git-$(basename ${IMAGE_NAME})
|
2014-02-21 16:51:46 +00:00
|
|
|
GIT_MANIFEST_CACHE_NAME=${GIT_MANIFEST_NAME}_$(dirname ${TMP_MOUNT_PATH##*.})
|
|
|
|
GIT_MANIFEST=$CACHE_BASE/${GIT_MANIFEST_CACHE_NAME}
|
|
|
|
rm -f $GIT_MANIFEST
|
2013-07-18 03:02:31 +00:00
|
|
|
|
2013-05-23 13:09:04 +00:00
|
|
|
# Get source repositories for the target
|
2013-07-27 18:46:33 +00:00
|
|
|
for _SOURCEREPO in $(find $TMP_HOOKS_PATH -maxdepth 1 -name "source-repository-*" -not -name '*~'); do
|
2014-06-30 17:34:41 +00:00
|
|
|
repo_flock=$CACHE_BASE/repositories_flock
|
|
|
|
(
|
|
|
|
echo "Getting $repo_flock: $(date)"
|
|
|
|
if ! flock -w 600 9 ; then
|
|
|
|
echo "Did not get $repo_flock: $(date)"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
get_repos_for_element $_SOURCEREPO
|
|
|
|
) 9> $repo_flock
|
2013-05-23 13:09:04 +00:00
|
|
|
done
|
2014-02-21 16:51:46 +00:00
|
|
|
|
|
|
|
# Copy the manifest into the image if it exists (there may be no git repositories used)
|
|
|
|
if [ -e "$GIT_MANIFEST" ] ; then
|
2014-04-15 10:24:43 +00:00
|
|
|
sudo mv $GIT_MANIFEST $TMP_MOUNT_PATH/${DIB_MANIFEST_IMAGE_DIR}/$GIT_MANIFEST_NAME
|
2014-02-21 16:51:46 +00:00
|
|
|
fi
|