9516b256f1
Duplicating this data on every record of the builds table cost approximately 4G of duplication. Note that the database migration included took about 4h45m on an untuned server which uses very slow rotational disks in a RAID5 setup, with not a lot of RAM. I imagine in production it might take an hour or two, but not 4. If this should become a chunked migration, I can do that. Note: Because of the question about chunked migrations, I have NOT YET tested this migration thoroughly enough for merge.
219 lines
5.8 KiB
Bash
219 lines
5.8 KiB
Bash
#! /usr/bin/env bash
|
||
|
||
main() {
|
||
|
||
# This script has been generated automatically by Hydra from the build
|
||
# at [% c.uri_for('/build' build.id) %].
|
||
|
||
set -e
|
||
|
||
tmpDir=${TMPDIR:-/tmp}/build-[% build.id +%]
|
||
declare -a args extraArgs
|
||
|
||
|
||
info() {
|
||
echo "[1;32m$1[0m" >&2
|
||
}
|
||
|
||
|
||
# Process the command line.
|
||
fetchOnly=
|
||
printFlags=
|
||
while [ $# -gt 0 ]; do
|
||
arg="$1"
|
||
shift
|
||
if [ "$arg" = --help ]; then
|
||
cat <<EOF
|
||
Usage: $0 [--dir PATH] [--run-env]
|
||
|
||
This script will reproduce Hydra build [% build.id %] of job [%
|
||
build.project.name %]:[% build.jobset.name %]:[% build.job.name +%]
|
||
(available at [%+ c.uri_for('/build' build.id) +%]). It will fetch
|
||
all inputs of the Hydra build, then invoke Nix to build the job and
|
||
all its dependencies.
|
||
|
||
The inputs will be stored in $tmpDir. This can be overriden using the
|
||
--dir flag. After the build, the result of the build is available via
|
||
the symlink $tmpDir/result.
|
||
|
||
Flags:
|
||
|
||
--dir PATH
|
||
Override the location where the inputs and result symlink are stored.
|
||
|
||
--run-env
|
||
Fetch the inputs and build the dependencies, then start an
|
||
interactive shell in which the environment is equal to that used
|
||
to perform the build. See the description of the --run-env flag
|
||
in the nix-build(1) manpage for more details.
|
||
|
||
--fetch
|
||
Fetch the inputs and then exit.
|
||
|
||
--print-flags
|
||
Fetch the inputs, then print the argument to nix-build on stdout
|
||
and exit.
|
||
|
||
Any additional flags are passed to nix-build. See the nix-build(1)
|
||
manpage for details.
|
||
EOF
|
||
exit 0
|
||
elif [ "$arg" = --dir ]; then
|
||
tmpDir="$1"
|
||
if [ -z "$tmpDir" ]; then
|
||
echo "$0: --dir requires an argument" >&2
|
||
exit 1
|
||
fi
|
||
shift
|
||
elif [ "$arg" = --fetch ]; then
|
||
fetchOnly=1
|
||
elif [ "$arg" = --print-flags ]; then
|
||
printFlags=1
|
||
else
|
||
extraArgs+=("$arg")
|
||
fi
|
||
done
|
||
|
||
|
||
mkdir -p "$tmpDir"
|
||
cd "$tmpDir"
|
||
info "storing inputs and results in $tmpDir..."
|
||
|
||
|
||
requireCommand() {
|
||
local cmd="$1"
|
||
if ! type -P "$cmd" > /dev/null; then
|
||
echo "$0: command ‘$cmd’ is not installed; please install it and try again" >&2
|
||
exit 1
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
|
||
# Fetch the inputs.
|
||
|
||
[% inputs = build.inputs ? build.inputs : eval.jobsetevalinputs %]
|
||
|
||
[%+ FOREACH input IN inputs %]
|
||
inputDir=
|
||
|
||
[%+ IF input.type == "git" %]
|
||
|
||
inputDir="$tmpDir/[% input.name %]/source"
|
||
|
||
if ! [ -d "$inputDir" ]; then
|
||
info "fetching Git input ‘[% input.name %]’ from ‘[% input.uri %]’ (commit [% input.revision %])..."
|
||
requireCommand git
|
||
inputDirTmp="$inputDir.tmp"
|
||
rm -rf "$inputDirTmp"
|
||
mkdir -p "$inputDirTmp"
|
||
git clone '[% input.uri %]' "$inputDirTmp"
|
||
(cd "$inputDirTmp" && git checkout '[% input.revision %]')
|
||
revCount="$(cd "$inputDirTmp" && (git rev-list '[% input.revision %]' | wc -l))"
|
||
rm -rf "$inputDirTmp/.git"
|
||
mv "$inputDirTmp" "$inputDir"
|
||
echo -n $revCount > "$tmpDir/[% input.name %]/rev-count"
|
||
else
|
||
revCount="$(cat "$tmpDir/[% input.name %]/rev-count")"
|
||
fi
|
||
|
||
args+=(--arg '[% input.name %]' "{ outPath = $inputDir; rev = \"[% input.revision %]\"; shortRev = \"[% input.revision.substr(0, 7) %]\"; revCount = $revCount; }")
|
||
|
||
[%+ ELSIF input.type == "hg" %]
|
||
|
||
inputDir="$tmpDir/[% input.name %]/source"
|
||
|
||
if ! [ -d "$inputDir" ]; then
|
||
info "fetching Mercurial input ‘[% input.name %]’ from ‘[% input.uri %]’ (commit [% input.revision %])..."
|
||
requireCommand hg
|
||
inputDirTmp="$inputDir.tmp"
|
||
rm -rf "$inputDirTmp"
|
||
mkdir -p "$inputDirTmp"
|
||
hg clone '[% input.uri %]' "$inputDirTmp"
|
||
(cd "$inputDirTmp" && hg update '[% input.revision %]')
|
||
revCount="$(cd "$inputDirTmp" && (hg log -r '[% input.revision %]' --template "{rev}"))"
|
||
rm -rf "$inputDirTmp/.hg"
|
||
mv "$inputDirTmp" "$inputDir"
|
||
echo -n $revCount > "$tmpDir/[% input.name %]/rev-count"
|
||
else
|
||
revCount="$(cat "$tmpDir/[% input.name %]/rev-count")"
|
||
fi
|
||
|
||
args+=(--arg '[% input.name %]' "{ outPath = $inputDir; rev = \"[% input.revision %]\"; revCount = $revCount; }")
|
||
|
||
[%+ ELSIF input.type == "svn" %]
|
||
|
||
inputDir="$tmpDir/[% input.name %]/source"
|
||
|
||
if ! [ -d "$inputDir" ]; then
|
||
info "fetching Subversion input ‘[% input.name %]’ from ‘[% input.uri %]’ (commit [% input.revision %])..."
|
||
requireCommand svn
|
||
rm -rf "$inputDir.tmp"
|
||
svn export '[% input.uri %]@[% input.revision %]' "$inputDir.tmp"
|
||
mv "$inputDir.tmp" "$inputDir"
|
||
fi
|
||
|
||
args+=(--arg '[% input.name %]' "{ outPath = $inputDir; rev = \"[% input.revision %]\"; }")
|
||
|
||
[% ELSIF input.type == "string" %]
|
||
args+=(--arg '[% input.name %]' '"[% input.value %]"') # FIXME: escape
|
||
|
||
[% ELSIF input.type == "boolean" %]
|
||
args+=(--arg '[% input.name %]' '[% input.value %]')
|
||
|
||
[% ELSIF input.type == "nix" %]
|
||
args+=(--arg '[% input.name %]' '[% input.value %]') # FIXME: escape
|
||
|
||
[% ELSE %]
|
||
echo "$0: input ‘[% input.name %]’ has unsupported type ‘[% input.type %]’" >&2
|
||
exit 1
|
||
[% END %]
|
||
|
||
[% IF input.name == eval.nixexprinput +%]
|
||
nixExprInputDir="$inputDir"
|
||
[%+ END %]
|
||
|
||
if [ -n "$inputDir" ]; then
|
||
args+=(-I [% input.name %]=$inputDir)
|
||
fi
|
||
|
||
[%+ END %]
|
||
|
||
if [ -n "$fetchOnly" ]; then exit 0; fi
|
||
|
||
|
||
# Run nix-build.
|
||
|
||
requireCommand nix-build
|
||
|
||
if [ -z "$nixExprInputDir" ]; then
|
||
echo "$0: don't know the path to the Nix expression!" >&2
|
||
exit 1
|
||
fi
|
||
|
||
args+=(--option extra-binary-caches '[% c.uri_for('/') %]')
|
||
|
||
# Since Hydra runs on x86_64-linux, pretend we're one. This matters
|
||
# when evaluating jobs that rely on builtins.currentSystem.
|
||
args+=(--option system x86_64-linux)
|
||
|
||
args+=("$nixExprInputDir/[% eval.nixexprpath %]" -A '[% build.job.name %]')
|
||
|
||
if [ -n "$printFlags" ]; then
|
||
first=1
|
||
for i in "${args[@]}"; do
|
||
if [ -z "$first" ]; then printf " "; fi
|
||
first=
|
||
printf "%q" "$i"
|
||
done
|
||
exit 0
|
||
fi
|
||
|
||
info "running nix-build..."
|
||
echo "using these flags: ${args[@]}" >&2
|
||
|
||
exec nix-build "${args[@]}" "${extraArgs[@]}"
|
||
|
||
}
|
||
|
||
main "$@"
|