build-image 8.41 KB
Newer Older
Pedro Vicente's avatar
Pedro Vicente committed
1
#!/bin/bash
2
#
Guido Gunther's avatar
Guido Gunther committed
3
# Copyright (C) 2017-2019 Purism SPC
4 5 6
#
# SPDX-License-Identifier: GPL-3.0+
#
Pedro Vicente's avatar
Pedro Vicente committed
7 8

set -e
Guido Gunther's avatar
Guido Gunther committed
9
set -u
Pedro Vicente's avatar
Pedro Vicente committed
10

11 12 13
usage() {
  echo "Usage : $1 "
  echo "    -h Display this help message."
Angus Ainslie (Purism)'s avatar
Angus Ainslie (Purism) committed
14
  echo "    -b [imx6|imx8|devkit|librem5|qemu-x86_64] select the board type."
15
  echo "    -d <distro> distro to use. [ amber-phone, byzantium ]"
16
  # TODO: add stable and drop ci
Guido Gunther's avatar
Guido Gunther committed
17
  echo "    -T kernel/uboot build type (legacy/current/next/plain)"
Guido Gunther's avatar
Guido Gunther committed
18
  echo "    -B build rootfs tarball as well"
Guido Gunther's avatar
Guido Gunther committed
19
  echo "    -l <passphrase>: luks enrypt root volume with passphrase"
20 21
}

22

23 24
build_auth () {
    if [ -f conf/auth.conf ]; then
Guido Gunther's avatar
Guido Gunther committed
25
        # shellcheck disable=SC1091
26 27 28 29 30 31
        . ./conf/auth.conf
        JENKINS_AUTH=(--auth-no-challenge "--http-user=${JENKINS_USER}" "--http-password=${JENKINS_TOKEN}")
    fi
}


32
fetch_nitrogen_uboot_upgrade() {
Guido Gunther's avatar
Guido Gunther committed
33 34 35 36
    local board="$1"
    local url="$2"
    local out="$3"
    dest="${out}/uboot-${board}"
37

Guido Gunther's avatar
Guido Gunther committed
38
    [ ! -d "${dest}" ] || return 0
39

Guido Gunther's avatar
Guido Gunther committed
40 41 42
    echo -n "Fetching uboot upgrade..."
    wget -q -Ascr -Aupgrade -A"*nitrogen*" -P"${dest}" -nd -l 1 --mirror "${url}/uboot-${board}/"
    echo "done."
43 44
}

45

46 47
fetch_kernel() {
    [ -n "${kernel_url}" ] || { echo "kernel_url not set in board config"; exit 1; }
48
    rm -f files/archive.zip
49
    echo "Fetching kernel from ${kernel_url}"
50 51 52 53 54 55 56
    if [[  "${kernel_url}" =~ https:// ]]; then
        wget "${JENKINS_AUTH[@]}" -nv --no-glob -Pfiles/ "${kernel_url}"
        (cd files/ && unzip -ojq archive.zip)
    else
        # shellcheck disable=SC2086
        cp ${kernel_url} files/
    fi
57 58 59
}


60
fetch_uboot() {
61 62
    local dir="files/uboot-${1}"

63
    [ -n "${uboot_url}" ] || { echo "uboot_url not set in board config"; exit 1; }
64
    rm -f "${dir}/archive.zip"
65
    echo "Fetching uboot from ${uboot_url}"
66
    if [[  "${uboot_url}" =~ https:// ]]; then
67 68 69 70 71 72 73
        wget "${JENKINS_AUTH[@]}" -nv --no-glob -P"${dir}" "${uboot_url}"
        (cd "${dir}" && unzip -ojq archive.zip)
    else
        mkdir -p "${dir}"
        # shellcheck disable=SC2086
        cp ${uboot_url} "${dir}/"
    fi
74 75 76
}


77

78 79 80 81
setup_loop() {
    local image="$1"
    set -x

82
    loop=$(/sbin/losetup -f)
83 84 85 86
    if [ -z "${loop}" ]; then
      return 1
    fi

87
    sudo /sbin/losetup -P "${loop}" "${image}"
88 89 90 91
    echo "${loop}"

    return 0
}
92

93 94 95
write_meta() {
    local out="$1"
    local image="$2"
96 97
    local image_sha256sum
    local image_size
98 99 100 101 102 103 104 105 106 107 108 109 110

    image_sha256sum=$(sha256sum "${image}" | sed 's/\([a-f0-9]\+\) .*/\1/')
    image_size=$(stat --format='%s' "${image}")
    echo "Image '${image} has sha256sum ${image_sha256sum}"

    cat <<EOF >> "${out}"
gitrev: $(git log --format=format:%H -1)
image:
  size: ${image_size}
  sha256sum: ${image_sha256sum}
EOF
}

111 112 113
append_boot_image_meta() {
    local out="$1"
    local image="$2"
114 115
    local image_sha256sum
    local image_size
116 117 118 119 120 121 122 123 124 125 126 127

    image_sha256sum=$(sha256sum "${image}" | sed 's/\([a-f0-9]\+\) .*/\1/')
    image_size=$(stat --format='%s' "${image}")
    echo "Image '${image} has sha256sum ${image_sha256sum}"

    cat <<EOF >> "${out}"
boot-image:
  size: ${image_size}
  sha256sum: ${image_sha256sum}
EOF
}

128 129 130 131 132 133
setup_laniakea_spark_build() {
  case "$distro" in
      amber)
        distro=amber-phone
      ;;
      *) echo "Unknown dist"
134
        exit 1
135 136 137
      ;;
  esac
  apt-get update
138
  apt-get -uyq install unzip sudo vmdebootstrap qemu-user-static
139 140
}

141
cwd=$(pwd)
Pedro Vicente's avatar
Pedro Vicente committed
142

143
distro=${DIST:-byzantium}
144
mirror=
145
pureos_board=devkit
146
build_type=plain
Guido Gunther's avatar
Guido Gunther committed
147
NULL=
148 149 150
# Device tree file name. Only set this if you're not using
# flash-kernel and want manual uboot script configuration.
fdt_file=
151
uboot_type=
152
# The URL to download the (unpackged) uboot binaries from
153
uboot_url=${UBOOT_URL:-}
Guido Gunther's avatar
Guido Gunther committed
154
build_tarball=
Guido Gunther's avatar
Guido Gunther committed
155
want_qcow2=
156
want_boot_image=
157
apt_sources=
158
debootstrap_dist=
159
kernel_deb=
160
# The URL to download the kernel deb from
161
kernel_url=${KERNEL_URL:-}
162
custom_package_opt=
Guido Gunther's avatar
Guido Gunther committed
163 164
use_luks=
luks_opts=
165
# Extra board specific packages to install
166
board_packages=
167
meta_yml=files/meta.yml
168
fk_machine=
169
JENKINS_AUTH=()
Guido Gunther's avatar
Guido Gunther committed
170
# in Megabytes
171
image_size=4100
Guido Gunther's avatar
Guido Gunther committed
172
passphrase=""
Pedro Vicente's avatar
Pedro Vicente committed
173

Guido Gunther's avatar
Guido Gunther committed
174
while getopts ":hb:d:T:Bl:" opt; do
175 176 177 178 179 180 181
  case ${opt} in
    b)
      pureos_board=$OPTARG
      ;;
    d)
      distro=$OPTARG
      ;;
182 183 184
    T)
      build_type=$OPTARG
      ;;
Guido Gunther's avatar
Guido Gunther committed
185 186 187
    B)
      build_tarball=1
      ;;
Guido Gunther's avatar
Guido Gunther committed
188 189 190
    l)
      passphrase=$OPTARG
      ;;
191 192
    \?)
      echo "Invalid Option: -$OPTARG" 1>&2
193
      usage "$0"
194 195 196
      exit 0
      ;;
    h )
197
      usage "$0"
198 199 200 201 202
      exit 0
      ;;
  esac
done

203
# Setup build environment if we are running in a Laniakea Spark builder nspawn container
204
[ -z "${SPARK_ID:-}" ] || setup_laniakea_spark_build
205

206 207 208 209
# If distro ends in CI use ci packages and cleanup distro name
[[ "${distro}" =~ \+ci ]] && ci_pkgs=1 || ci_pkgs=0
distro="${distro/+ci}"

210
mainimg="${pureos_board}.img"
Guido Gunther's avatar
Guido Gunther committed
211

212 213 214
# remember command line setting
_kernel_url="${kernel_url}"
_uboot_url="${uboot_url}"
215
. conf/board
216 217 218
# make sure command line setting takes precedenc over configuration file
[ -z "${_kernel_url}" ] || kernel_url="${_kernel_url}"
[ -z "${_uboot_url}" ] || uboot_url="${_uboot_url}"
219
. conf/packages
220
# shellcheck source=conf/dists/byzantium
221
. conf/dists/"${distro}"
222

223 224
build_auth

225
[ -n "${debootstrap_dist}" ] || debootstrap_dist="${distro}"
226
echo "Building ${mainimg} (board_type: ${board_type}, arch: ${arch}, build_type: ${build_type}, ci_pkgs: ${ci_pkgs}, ${debootstrap_dist})"
227
echo "Installing extra packages ${packages}"
228
[ -z "${board_packages}" ] || echo "Installing extra board specific packages ${board_packages}"
229

Guido Gunther's avatar
Guido Gunther committed
230
mkdir -p tmp/ files/
231 232 233
rm -f "./tmp/${pureos_board}-report.log"
# Create meta.yml here so it belongs to the user running image-builder
echo > "${meta_yml}"
Guido Gunther's avatar
Guido Gunther committed
234

235
if [ -n "${kernel_url}" ]; then
Guido Gunther's avatar
Guido Gunther committed
236 237 238 239 240 241 242 243 244 245 246
        fetch_kernel
        for deb in files/linux-image-*-*_arm64.deb; do
                ! [[ "${deb}" =~ dbg ]] || continue
                if [ -n "${kernel_deb}" ]; then
                        echo "Found more than one possible kernel deb in files/"
                        exit 1
                fi
                kernel_deb="$deb"
        done
        [ -n "${kernel_deb}" ] || { echo "No kernel found."; exit 1; }
        custom_package_opt=(--custom-package "${kernel_deb}")
247 248
fi

249 250 251 252 253
if [ -n "${uboot_url}" ]; then
        fetch_uboot "${uboot_type}"
        echo "Using unpackaged uboot from ${uboot_url}"
fi

254
[ -z "${kernel_deb}" ] || echo "Using kernel ${kernel_deb}"
255

Guido Gunther's avatar
Guido Gunther committed
256 257 258 259 260 261
if [ -n "${passphrase}" ]; then
    echo "Enabling encryption"
    luks_opts=(--no-update-initramfs --use-luks "--luks-passphrase=${passphrase}")
    use_luks=1
fi

262 263 264 265
# Preserve newlines as '|'
# shellcheck disable=SC2001
escaped_apt_sources=$(echo "${apt_sources}" | sed 's/$/|/g')

266
set -x
267
# shellcheck disable=SC2086
268 269
sudo pureos_board="${pureos_board}" \
     distro="${distro}" \
270
     packages="${packages} ${board_packages}" \
271
     uboot_type="${uboot_type}" \
272
     patched="${patched}" \
273 274 275
     http_proxy="${http_apt_proxy:-${http_proxy:-}}" \
     https_proxy="${https_apt_proxy:-${https_proxy:-}}" \
     qemu="${qemu}" \
276
     fdt_file="${fdt_file}" \
Guido Gunther's avatar
Guido Gunther committed
277
     build_tarball="${build_tarball}" \
278
     apt_sources="${escaped_apt_sources}" \
279
     ci_pkgs="${ci_pkgs}" \
280
     kernel_deb="${kernel_deb}" \
281
     FK_MACHINE="${fk_machine}" \
Guido Gunther's avatar
Guido Gunther committed
282
     use_luks="${use_luks}" \
Guido Gunther's avatar
Guido Gunther committed
283 284
    vmdebootstrap \
    --enable-dhcp \
Guido Gunther's avatar
Guido Gunther committed
285
    --verbose --image "${mainimg}" --log "tmp/${mainimg}.log" --size "${image_size}M"  \
286
    --mirror "${mirror}" \
Pedro Vicente's avatar
Pedro Vicente committed
287
    --configure-apt \
Guido Gunther's avatar
Guido Gunther committed
288
    --lock-root-password \
289
    --distribution "${debootstrap_dist}" \
Pedro Vicente's avatar
Pedro Vicente committed
290
    --serial-console-command "/sbin/getty -L ttymxc0 115200 vt100" \
Guido Gunther's avatar
Guido Gunther committed
291
    --hostname='pureos' --user=purism/123456 --sudo \
292
    --customize "${cwd}/root.sh" \
293
    --owner "$(whoami)" \
Guido Gunther's avatar
Guido Gunther committed
294
    --no-extlinux \
295
    "${custom_package_opt[@]}" \
296
    "${vmdebootstrap_opts[@]}" \
Guido Gunther's avatar
Guido Gunther committed
297
    "${luks_opts[@]}" \
298
    ${NULL}
299
set +x
300

301

302
if [ "${arch}" == "arm64" ]; then
303 304 305
    if [ "${want_boot_image}" == 1 ]; then
      # Copy the boot image as a separate file
      bootimg="${pureos_board}-boot.img"
306
      cp "files/uboot-${uboot_type}/${uboot_type}-boot.img" "${bootimg}"
307 308 309
    else
      # Merge boot image inside the main image
      loop=$(setup_loop "${mainimg}")
310
      sudo dd if="files/uboot-${uboot_type}/${uboot_type}-boot.img" of="${loop}" bs=1024 seek=2
311 312
      sudo sync
      sudo /sbin/losetup -d "${loop}"
313
    fi
314
fi
Guido Gunther's avatar
Guido Gunther committed
315

316 317
[ -f "./tmp/${pureos_board}-report.log" ] || { echo "No install report found."; exit 1; }

318 319 320 321
write_meta "${meta_yml}" "${mainimg}"
if [ "${want_boot_image}" == 1 ]; then
    append_boot_image_meta "${meta_yml}" "${bootimg}"
fi
322

Guido Gunther's avatar
Guido Gunther committed
323
if [ "${want_qcow2}" == 1 ]; then
324 325
    qcow2="$(basename "${mainimg}" .img)".qcow2
    qemu-img convert -f raw -O qcow2 "${mainimg}" "${qcow2}"
Guido Gunther's avatar
Guido Gunther committed
326 327
    qemu-img resize -f qcow2 "${qcow2}" +28G
fi