summaryrefslogtreecommitdiffstats
path: root/auto/build
blob: d464959c1cd5127db6d88c15dadc3fa43a5ba5ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#!/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 "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/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

: ${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
# * if we build from a branch: tails-$ARCH-$BRANCH-$VERSION-$DATE.iso
# * if Jenkins builds from a branch: 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')
    if [ -n "$JENKINS_URL" ]; then
        GIT_SHORT_ID="$(git rev-parse --short HEAD)"
        BUILD_BASENAME="tails-${LB_ARCHITECTURE}-${CLEAN_GIT_BRANCH}-${AMNESIA_VERSION}-${AMNESIA_NOW}-${GIT_SHORT_ID}"
    else
        BUILD_BASENAME="tails-${LB_ARCHITECTURE}-${CLEAN_GIT_BRANCH}-${AMNESIA_VERSION}-${AMNESIA_TODAY}"
    fi
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}.list"
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 "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
   if [ "$RET" -eq 0 ]; then
      [ -z "$JENKINS_URL" ] || date --utc '+%s' > "$BUILD_END_FILENAME"
      echo "Image was successfully created"
      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
   else
      echo "Warning: image created, but lb build exited with code $RET"
   fi
   echo "Renaming generated files..."
   mv -i "${BUILD_FILENAME}.${BUILD_FILENAME_EXT}" "${BUILD_DEST_FILENAME}"
   mv -i binary.packages "${BUILD_PACKAGES}"
else
   fatal "lb build failed ($?)."
fi