build 8.13 KB
Newer Older
1
#!/bin/bash
amnesia's avatar
amnesia committed
2

intrigeri's avatar
intrigeri committed
3
set -x
amnesia's avatar
amnesia committed
4

amnesia's avatar
amnesia committed
5
6
umask 022

7
8
9
10
11
12
13
### functions

fatal () {
   echo "$*" >&2
   exit 1
}

14
15
16
17
18
19
20
21
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.*,,'
}

22
23
24
25
26
27
28
print_iso_size () {
   local isofile="$1"
   [ -f "$isofile" ] || return 23
   size=$(stat --printf='%s' "$isofile")
   echo "The ISO is ${size} bytes large."
}

29
30
### Main

31
# we require building from git
32
33
git rev-parse --is-inside-work-tree &> /dev/null \
   || fatal "${PWD} is not a Git tree."
34

35
36
37
. config/amnesia
if [ -e config/amnesia.local ] ; then
   . config/amnesia.local
amnesia's avatar
amnesia committed
38
39
40
41
42
fi

# a clean starting point
rm -rf cache/stages_rootfs

43
# get LB_BINARY_IMAGES
44
45
. config/binary

46
# get LB_ARCHITECTURE and LB_DISTRIBUTION
47
. config/bootstrap
48

49
# save variables that are needed by chroot_local-hooks
50
51
52
53
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
54
echo "LB_DISTRIBUTION=${LB_DISTRIBUTION}" >> config/chroot_local-includes/usr/share/amnesia/build/variables
55
56
57
58
59
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
60

61
62
# 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.
63
chown    0:0   config/chroot_local-includes/etc/resolv.conf
64
chmod -R go+rX config/binary_local-includes/
65
chmod -R go+rX config/chroot_local-includes/etc
66
chmod    0440  config/chroot_local-includes/etc/sudoers.d/*
67
chmod    go+rX config/chroot_local-includes/home
68
69
70
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
71
chmod    go+rX config/chroot_local-includes/lib/live/mount
72
chmod -R go+rX config/chroot_local-includes/lib/systemd
73
chmod    go+rX config/chroot_local-includes/live
74
75
76
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
77
chmod -R go+rX config/chroot_local-includes/usr/share/doc/tails
78
chmod -R go+rX config/chroot_local-includes/var
79
80
chmod -R go+rX config/chroot_apt
chmod -R go+rX config/chroot_sources
81

82
# build the image
amnesia's avatar
amnesia committed
83

84
# we need /debootstrap/deburis to build a manifest of used packages:
85
86
DEBOOTSTRAP_OPTIONS="$DEBOOTSTRAP_OPTIONS --keep-debootstrap-dir"

87
88
89
# we're not ready for merged-/usr yet: Debian#843461, Tails#11903
DEBOOTSTRAP_OPTIONS="$DEBOOTSTRAP_OPTIONS --no-merged-usr"

90
91
92
93
94
95
96
# 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
97

98
: ${MKSQUASHFS_OPTIONS:='-comp xz -Xbcj x86 -b 1024K -Xdict-size 1024K'}
99
MKSQUASHFS_OPTIONS="${MKSQUASHFS_OPTIONS} -wildcards -ef chroot/usr/share/amnesia/build/mksquashfs-excludes"
100
export MKSQUASHFS_OPTIONS
101

102
# get git branch or tag so we can set the basename appropriately, i.e.:
anonym's avatar
anonym committed
103
104
# * if we build from a tag: tails-$ARCH-$TAG.iso
# * otherwise:              tails-$ARCH-$BRANCH-$VERSION-$TIME-$COMMIT.iso
105
if GIT_REF="$(git symbolic-ref HEAD)"; then
106
    GIT_BRANCH="${GIT_REF#refs/heads/}"
107
    CLEAN_GIT_BRANCH=$(echo "$GIT_BRANCH" | sed 's,/,_,g')
anonym's avatar
anonym committed
108
109
    GIT_SHORT_ID="$(git rev-parse --short HEAD)"
    BUILD_BASENAME="tails-${LB_ARCHITECTURE}-${CLEAN_GIT_BRANCH}-${AMNESIA_VERSION}-${AMNESIA_NOW}-${GIT_SHORT_ID}"
110
111
112
else
    GIT_CURRENT_COMMIT="$(git rev-parse HEAD)"
    if GIT_TAG="$(git describe --tags --exact-match ${GIT_CURRENT_COMMIT})"; then
113
        CLEAN_GIT_TAG=$(echo "$GIT_TAG" | tr '/-' '_~')
114
	BUILD_BASENAME="tails-${LB_ARCHITECTURE}-${CLEAN_GIT_TAG}"
115
116
117
    else
	# this shouldn't reasonably happen (e.g. only if you checkout a
        # tag, remove the tag and then build)
118
	fatal "Neither a Git branch nor a tag, exiting."
119
120
121
    fi
fi

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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."
137
138
139
140
141
142
143

    # 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}"
144
145
fi

146
# build the doc wiki
elouann's avatar
elouann committed
147
./build-website
148
149
150
151

# refresh translations of our programs
./refresh-translations || fatal "refresh-translations failed ($?)."

152
case "$LB_BINARY_IMAGES" in
153
154
155
   iso)
      BUILD_FILENAME_EXT=iso
      BUILD_FILENAME=binary
156
157
158
159
160
161
162
163
164
165
      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
166
167
      ;;
   iso-hybrid)
168
      BUILD_FILENAME_EXT=iso
169
      BUILD_FILENAME=binary-hybrid
170
171
172
173
174
175
176
177
178
179
      ;;
   tar)
      BUILD_FILENAME_EXT=tar.gz
      BUILD_FILENAME=binary-tar
      ;;
   usb-hdd)
      BUILD_FILENAME_EXT=img
      BUILD_FILENAME=binary
      ;;
   *)
180
      fatal "Image type ${LB_BINARY_IMAGES} is not supported."
181
182
183
      ;;
esac
BUILD_DEST_FILENAME="${BUILD_BASENAME}.${BUILD_FILENAME_EXT}"
184
BUILD_MANIFEST="${BUILD_DEST_FILENAME}.build-manifest"
185
BUILD_APT_SOURCES="${BUILD_DEST_FILENAME}.apt-sources"
186
187
BUILD_PACKAGES="${BUILD_DEST_FILENAME}.packages"
BUILD_LOG="${BUILD_DEST_FILENAME}.buildlog"
188
189
BUILD_START_FILENAME="${BUILD_DEST_FILENAME}.start.timestamp"
BUILD_END_FILENAME="${BUILD_DEST_FILENAME}.end.timestamp"
amnesia's avatar
amnesia committed
190

191
192
193
194
195
196
# 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

197
198
199
200
201
202
203
204
205
(
   echo "Mirrors:"
   apt-mirror debian
   apt-mirror debian-security
   apt-mirror torproject
   echo "Additional sources:"
   cat config/chroot_sources/*.chroot
) > "$BUILD_APT_SOURCES"

206
echo "Building $LB_BINARY_IMAGES image ${BUILD_BASENAME}..."
207
set -o pipefail
208
[ -z "$JENKINS_URL" ] || date --utc '+%s' > "$BUILD_START_FILENAME"
209
time lb build noauto ${@}
210
211
RET=$?
if [ -e "${BUILD_FILENAME}.${BUILD_FILENAME_EXT}" ]; then
212
213
214
215
216
217
218
219
220
221
222
223
   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"
224
   fi
225
226
   echo "Renaming generated files..."
   mv -i "${BUILD_FILENAME}.${BUILD_FILENAME_EXT}" "${BUILD_DEST_FILENAME}"
227
   mv -i binary.packages "${BUILD_PACKAGES}"
228
   generate-build-manifest chroot/debootstrap "${BUILD_MANIFEST}"
229
else
230
   fatal "lb build failed ($?)."
231
fi