123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- #!/bin/bash
- set -x
- umask 022
- ### functions
- fatal () {
- echo "$*" >&2
- exit 1
- }
- syslinux_utils_upstream_version () {
- dpkg-query -W -f='${Version}\n' syslinux-utils | \
- # drop epoch
- sed -e 's,.*:,,' | \
- # drop +dfsg and everything that follows
- sed -e 's,\+dfsg.*,,'
- }
- print_iso_size () {
- local isofile="$1"
- [ -f "$isofile" ] || return 23
- size=$(stat --printf='%s' "$isofile")
- echo "The ISO is ${size} bytes large."
- }
- ### Main
- # we require building from git
- git rev-parse --is-inside-work-tree &> /dev/null \
- || fatal "${PWD} is not a Git tree."
- . config/amnesia
- if [ -e config/amnesia.local ] ; then
- . config/amnesia.local
- fi
- # a clean starting point
- rm -rf cache/stages_rootfs
- # get LB_BINARY_IMAGES
- . config/binary
- # get LB_ARCHITECTURE and LB_DISTRIBUTION
- . config/bootstrap
- # save variables that are needed by chroot_local-hooks
- echo "KERNEL_VERSION=${KERNEL_VERSION}" \
- >> config/chroot_local-includes/usr/share/amnesia/build/variables
- echo "KERNEL_SOURCE_VERSION=${KERNEL_SOURCE_VERSION}" \
- >> config/chroot_local-includes/usr/share/amnesia/build/variables
- echo "LB_DISTRIBUTION=${LB_DISTRIBUTION}" >> config/chroot_local-includes/usr/share/amnesia/build/variables
- echo "POTFILES_DOT_IN='$(
- /bin/grep -E --no-filename '[^ #]*\.in$' po/POTFILES.in \
- | sed -e 's,^config/chroot_local-includes,,' | tr "\n" ' '
- )'" \
- >> config/chroot_local-includes/usr/share/amnesia/build/variables
- # fix permissions on some source files that will be copied as is to the chroot.
- # they may be wrong, e.g. if the Git repository was cloned with a strict umask.
- chmod -R go+rX config/binary_local-includes/
- chmod -R go+rX config/chroot_local-includes/etc
- chmod 0440 config/chroot_local-includes/etc/sudoers.d/*
- chmod go+rX config/chroot_local-includes/home
- chmod go+rX config/chroot_local-includes/lib
- chmod go+rX config/chroot_local-includes/lib/live
- chmod -R go+rx config/chroot_local-includes/lib/live/config
- chmod go+rX config/chroot_local-includes/lib/live/mount
- chmod -R go+rX config/chroot_local-includes/lib/systemd
- chmod go+rX config/chroot_local-includes/live
- chmod -R go+rX config/chroot_local-includes/usr
- chmod -R go+rx config/chroot_local-includes/usr/local/bin
- chmod -R go+rx config/chroot_local-includes/usr/local/sbin
- chmod -R go+rX config/chroot_local-includes/usr/share/doc/tails
- chmod -R go+rX config/chroot_local-includes/var
- chmod -R go+rX config/chroot_apt
- chmod -R go+rX config/chroot_sources
- # build the image
- # we need /debootstrap/deburis to build a manifest of used packages:
- DEBOOTSTRAP_OPTIONS="$DEBOOTSTRAP_OPTIONS --keep-debootstrap-dir"
- # we're not ready for merged-/usr yet: Debian#843461, Tails#11903
- DEBOOTSTRAP_OPTIONS="$DEBOOTSTRAP_OPTIONS --no-merged-usr"
- # use our own APT repository's key:
- DEBOOTSTRAP_GNUPG_HOMEDIR=$(mktemp -d)
- gpg --homedir "$DEBOOTSTRAP_GNUPG_HOMEDIR" \
- --import config/chroot_sources/tails.chroot.gpg
- DEBOOTSTRAP_OPTIONS="$DEBOOTSTRAP_OPTIONS --keyring=$DEBOOTSTRAP_GNUPG_HOMEDIR/pubring.gpg"
- export DEBOOTSTRAP_OPTIONS
- : ${MKSQUASHFS_OPTIONS:='-comp xz -Xbcj x86 -b 1024K -Xdict-size 1024K'}
- MKSQUASHFS_OPTIONS="${MKSQUASHFS_OPTIONS} -wildcards -ef chroot/usr/share/amnesia/build/mksquashfs-excludes"
- export MKSQUASHFS_OPTIONS
- # get git branch or tag so we can set the basename appropriately, i.e.:
- # * if we build from a tag: tails-$ARCH-$TAG.iso
- # * otherwise: tails-$ARCH-$BRANCH-$VERSION-$TIME-$COMMIT.iso
- if GIT_REF="$(git symbolic-ref HEAD)"; then
- GIT_BRANCH="${GIT_REF#refs/heads/}"
- CLEAN_GIT_BRANCH=$(echo "$GIT_BRANCH" | sed 's,/,_,g')
- GIT_SHORT_ID="$(git rev-parse --short HEAD)"
- BUILD_BASENAME="tails-${LB_ARCHITECTURE}-${CLEAN_GIT_BRANCH}-${AMNESIA_VERSION}-${AMNESIA_NOW}-${GIT_SHORT_ID}"
- else
- GIT_CURRENT_COMMIT="$(git rev-parse HEAD)"
- if GIT_TAG="$(git describe --tags --exact-match ${GIT_CURRENT_COMMIT})"; then
- CLEAN_GIT_TAG=$(echo "$GIT_TAG" | tr '/-' '_~')
- BUILD_BASENAME="tails-${LB_ARCHITECTURE}-${CLEAN_GIT_TAG}"
- else
- # this shouldn't reasonably happen (e.g. only if you checkout a
- # tag, remove the tag and then build)
- fatal "Neither a Git branch nor a tag, exiting."
- fi
- fi
- GIT_BASE_BRANCH=$(head -n1 config/base_branch) \
- || fatal "GIT_BASE_BRANCH could not be guessed."
- # Merge base branch into the branch being built, iff. we're building
- # in Jenkins, and not building from a tag, and not building the base
- # branch itself
- if [ -n "$JENKINS_URL" ] && [ -z "$GIT_TAG" ] \
- && [ "$GIT_BRANCH" != "$GIT_BASE_BRANCH" ] ; then
- GIT_BASE_BRANCH_COMMIT=$(git rev-parse "origin/${GIT_BASE_BRANCH}") \
- || fatal "Base branch's top commit could not be guessed."
- echo "Merging base branch origin/${GIT_BASE_BRANCH}"
- echo "(at commit ${GIT_BASE_BRANCH_COMMIT})..."
- git merge --no-edit "origin/${GIT_BASE_BRANCH}" \
- || fatal "Failed to merge base branch."
- # Adjust BUILD_BASENAME to embed the base branch name and its top commit
- CLEAN_GIT_BASE_BRANCH=$(echo "$GIT_BASE_BRANCH" | sed 's,/,_,g')
- GIT_BASE_BRANCH_SHORT_ID=$(git rev-parse --short "origin/${GIT_BASE_BRANCH}") \
- || fatal "Base branch's top commit short ID could not be guessed."
- BUILD_BASENAME="${BUILD_BASENAME}+${CLEAN_GIT_BASE_BRANCH}"
- BUILD_BASENAME="${BUILD_BASENAME}@${GIT_BASE_BRANCH_SHORT_ID}"
- fi
- # build the doc wiki
- ./build-website
- # refresh translations of our programs
- ./refresh-translations || fatal "refresh-translations failed ($?)."
- case "$LB_BINARY_IMAGES" in
- iso)
- BUILD_FILENAME_EXT=iso
- BUILD_FILENAME=binary
- which isohybrid >/dev/null || fatal 'Cannot find isohybrid in $PATH'
- installed_syslinux_utils_upstream_version="$(syslinux_utils_upstream_version)"
- if dpkg --compare-versions \
- "$installed_syslinux_utils_upstream_version" \
- 'lt' \
- "$REQUIRED_SYSLINUX_UTILS_UPSTREAM_VERSION" ; then
- fatal \
- "syslinux-utils '${installed_syslinux_utils_upstream_version}' is installed, " \
- "while we need at least '${REQUIRED_SYSLINUX_UTILS_UPSTREAM_VERSION}'."
- fi
- ;;
- iso-hybrid)
- BUILD_FILENAME_EXT=iso
- BUILD_FILENAME=binary-hybrid
- ;;
- tar)
- BUILD_FILENAME_EXT=tar.gz
- BUILD_FILENAME=binary-tar
- ;;
- usb-hdd)
- BUILD_FILENAME_EXT=img
- BUILD_FILENAME=binary
- ;;
- *)
- fatal "Image type ${LB_BINARY_IMAGES} is not supported."
- ;;
- esac
- BUILD_DEST_FILENAME="${BUILD_BASENAME}.${BUILD_FILENAME_EXT}"
- BUILD_MANIFEST="${BUILD_DEST_FILENAME}.build-manifest"
- BUILD_APT_SOURCES="${BUILD_DEST_FILENAME}.apt-sources"
- BUILD_PACKAGES="${BUILD_DEST_FILENAME}.packages"
- BUILD_LOG="${BUILD_DEST_FILENAME}.buildlog"
- BUILD_START_FILENAME="${BUILD_DEST_FILENAME}.start.timestamp"
- BUILD_END_FILENAME="${BUILD_DEST_FILENAME}.end.timestamp"
- # Clone all output, from this point on, to the log file
- exec > >(tee -a "$BUILD_LOG")
- trap "kill -9 $! 2>/dev/null" EXIT HUP INT QUIT TERM
- exec 2> >(tee -a "$BUILD_LOG" >&2)
- trap "kill -9 $! 2>/dev/null" EXIT HUP INT QUIT TERM
- (
- echo "Mirrors:"
- apt-mirror debian
- apt-mirror debian-security
- apt-mirror torproject
- echo "Additional sources:"
- cat config/chroot_sources/*.chroot
- ) > "$BUILD_APT_SOURCES"
- echo "Building $LB_BINARY_IMAGES image ${BUILD_BASENAME}..."
- set -o pipefail
- [ -z "$JENKINS_URL" ] || date --utc '+%s' > "$BUILD_START_FILENAME"
- time eatmydata lb build noauto ${@}
- RET=$?
- if [ -e "${BUILD_FILENAME}.${BUILD_FILENAME_EXT}" ]; then
- echo "Image was successfully created"
- [ "$RET" -eq 0 ] || \
- echo "Warning: lb build exited with code $RET"
- [ -z "$JENKINS_URL" ] || date --utc '+%s' > "$BUILD_END_FILENAME"
- if [ "$LB_BINARY_IMAGES" = iso ]; then
- ISO_FILE="${BUILD_FILENAME}.${BUILD_FILENAME_EXT}"
- print_iso_size "$ISO_FILE"
- echo "Hybriding it..."
- isohybrid $AMNESIA_ISOHYBRID_OPTS "$ISO_FILE"
- print_iso_size "$ISO_FILE"
- truncate -s %2048 "$ISO_FILE"
- print_iso_size "$ISO_FILE"
- fi
- echo "Renaming generated files..."
- mv -i "${BUILD_FILENAME}.${BUILD_FILENAME_EXT}" "${BUILD_DEST_FILENAME}"
- mv -i binary.packages "${BUILD_PACKAGES}"
- generate-build-manifest chroot/debootstrap "${BUILD_MANIFEST}"
- else
- fatal "lb build failed ($?)."
- fi
|