Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

build.sh 11 KiB

10 miesięcy temu
10 miesięcy temu
10 miesięcy temu
10 miesięcy temu
10 miesięcy temu
10 miesięcy temu
10 miesięcy temu
10 miesięcy temu
10 miesięcy temu
10 miesięcy temu
10 miesięcy temu
10 miesięcy temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. #!/bin/bash -e
  2. # shellcheck disable=SC2119
  3. run_sub_stage()
  4. {
  5. log "Begin ${SUB_STAGE_DIR}"
  6. pushd "${SUB_STAGE_DIR}" > /dev/null
  7. for i in {00..99}; do
  8. if [ -f "${i}-debconf" ]; then
  9. log "Begin ${SUB_STAGE_DIR}/${i}-debconf"
  10. on_chroot << EOF
  11. debconf-set-selections <<SELEOF
  12. $(cat "${i}-debconf")
  13. SELEOF
  14. EOF
  15. log "End ${SUB_STAGE_DIR}/${i}-debconf"
  16. fi
  17. if [ -f "${i}-packages-nr" ]; then
  18. log "Begin ${SUB_STAGE_DIR}/${i}-packages-nr"
  19. PACKAGES="$(sed -f "${SCRIPT_DIR}/remove-comments.sed" < "${i}-packages-nr")"
  20. if [ -n "$PACKAGES" ]; then
  21. on_chroot << EOF
  22. apt-get -o Acquire::Retries=3 install --no-install-recommends -y $PACKAGES
  23. EOF
  24. if [ "${USE_QCOW2}" = "1" ]; then
  25. on_chroot << EOF
  26. apt-get clean
  27. EOF
  28. fi
  29. fi
  30. log "End ${SUB_STAGE_DIR}/${i}-packages-nr"
  31. fi
  32. if [ -f "${i}-packages" ]; then
  33. log "Begin ${SUB_STAGE_DIR}/${i}-packages"
  34. PACKAGES="$(sed -f "${SCRIPT_DIR}/remove-comments.sed" < "${i}-packages")"
  35. if [ -n "$PACKAGES" ]; then
  36. on_chroot << EOF
  37. apt-get -o Acquire::Retries=3 install -y $PACKAGES
  38. EOF
  39. if [ "${USE_QCOW2}" = "1" ]; then
  40. on_chroot << EOF
  41. apt-get clean
  42. EOF
  43. fi
  44. fi
  45. log "End ${SUB_STAGE_DIR}/${i}-packages"
  46. fi
  47. if [ -d "${i}-patches" ]; then
  48. log "Begin ${SUB_STAGE_DIR}/${i}-patches"
  49. pushd "${STAGE_WORK_DIR}" > /dev/null
  50. if [ "${CLEAN}" = "1" ]; then
  51. rm -rf .pc
  52. rm -rf ./*-pc
  53. fi
  54. QUILT_PATCHES="${SUB_STAGE_DIR}/${i}-patches"
  55. SUB_STAGE_QUILT_PATCH_DIR="$(basename "$SUB_STAGE_DIR")-pc"
  56. mkdir -p "$SUB_STAGE_QUILT_PATCH_DIR"
  57. ln -snf "$SUB_STAGE_QUILT_PATCH_DIR" .pc
  58. quilt upgrade
  59. if [ -e "${SUB_STAGE_DIR}/${i}-patches/EDIT" ]; then
  60. echo "Dropping into bash to edit patches..."
  61. bash
  62. fi
  63. RC=0
  64. quilt push -a || RC=$?
  65. case "$RC" in
  66. 0|2)
  67. ;;
  68. *)
  69. false
  70. ;;
  71. esac
  72. popd > /dev/null
  73. log "End ${SUB_STAGE_DIR}/${i}-patches"
  74. fi
  75. if [ -x ${i}-run.sh ]; then
  76. log "Begin ${SUB_STAGE_DIR}/${i}-run.sh"
  77. ./${i}-run.sh
  78. log "End ${SUB_STAGE_DIR}/${i}-run.sh"
  79. fi
  80. if [ -f ${i}-run-chroot.sh ]; then
  81. log "Begin ${SUB_STAGE_DIR}/${i}-run-chroot.sh"
  82. on_chroot < ${i}-run-chroot.sh
  83. log "End ${SUB_STAGE_DIR}/${i}-run-chroot.sh"
  84. fi
  85. done
  86. popd > /dev/null
  87. log "End ${SUB_STAGE_DIR}"
  88. }
  89. run_stage(){
  90. log "Begin ${STAGE_DIR}"
  91. STAGE="$(basename "${STAGE_DIR}")"
  92. pushd "${STAGE_DIR}" > /dev/null
  93. STAGE_WORK_DIR="${WORK_DIR}/${STAGE}"
  94. ROOTFS_DIR="${STAGE_WORK_DIR}"/rootfs
  95. if [ "${USE_QCOW2}" = "1" ]; then
  96. if [ ! -f SKIP ]; then
  97. load_qimage
  98. fi
  99. else
  100. # make sure we are not umounting during export-image stage
  101. if [ "${USE_QCOW2}" = "0" ] && [ "${NO_PRERUN_QCOW2}" = "0" ]; then
  102. unmount "${WORK_DIR}/${STAGE}"
  103. fi
  104. fi
  105. if [ ! -f SKIP_IMAGES ]; then
  106. if [ -f "${STAGE_DIR}/EXPORT_IMAGE" ]; then
  107. EXPORT_DIRS="${EXPORT_DIRS} ${STAGE_DIR}"
  108. fi
  109. fi
  110. if [ ! -f SKIP ]; then
  111. if [ "${CLEAN}" = "1" ] && [ "${USE_QCOW2}" = "0" ] ; then
  112. if [ -d "${ROOTFS_DIR}" ]; then
  113. rm -rf "${ROOTFS_DIR}"
  114. fi
  115. fi
  116. if [ -x prerun.sh ]; then
  117. log "Begin ${STAGE_DIR}/prerun.sh"
  118. ./prerun.sh
  119. log "End ${STAGE_DIR}/prerun.sh"
  120. fi
  121. for SUB_STAGE_DIR in "${STAGE_DIR}"/*; do
  122. if [ -d "${SUB_STAGE_DIR}" ] && [ ! -f "${SUB_STAGE_DIR}/SKIP" ]; then
  123. run_sub_stage
  124. fi
  125. done
  126. fi
  127. if [ "${USE_QCOW2}" = "1" ]; then
  128. unload_qimage
  129. else
  130. # make sure we are not umounting during export-image stage
  131. if [ "${USE_QCOW2}" = "0" ] && [ "${NO_PRERUN_QCOW2}" = "0" ]; then
  132. unmount "${WORK_DIR}/${STAGE}"
  133. fi
  134. fi
  135. PREV_STAGE="${STAGE}"
  136. PREV_STAGE_DIR="${STAGE_DIR}"
  137. PREV_ROOTFS_DIR="${ROOTFS_DIR}"
  138. popd > /dev/null
  139. log "End ${STAGE_DIR}"
  140. }
  141. if [ "$(id -u)" != "0" ]; then
  142. echo "Please run as root" 1>&2
  143. exit 1
  144. fi
  145. BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  146. if [[ $BASE_DIR = *" "* ]]; then
  147. echo "There is a space in the base path of pi-gen"
  148. echo "This is not a valid setup supported by debootstrap."
  149. echo "Please remove the spaces, or move pi-gen directory to a base path without spaces" 1>&2
  150. exit 1
  151. fi
  152. export BASE_DIR
  153. if [ -f config ]; then
  154. # shellcheck disable=SC1091
  155. source config
  156. fi
  157. while getopts "c:" flag
  158. do
  159. case "$flag" in
  160. c)
  161. EXTRA_CONFIG="$OPTARG"
  162. # shellcheck disable=SC1090
  163. source "$EXTRA_CONFIG"
  164. ;;
  165. *)
  166. ;;
  167. esac
  168. done
  169. term() {
  170. if [ "${USE_QCOW2}" = "1" ]; then
  171. log "Unloading image"
  172. unload_qimage
  173. fi
  174. }
  175. trap term EXIT INT TERM
  176. export PI_GEN=${PI_GEN:-pi-gen}
  177. export PI_GEN_REPO=${PI_GEN_REPO:-https://github.com/RPi-Distro/pi-gen}
  178. if [ -z "${IMG_NAME}" ]; then
  179. echo "IMG_NAME not set" 1>&2
  180. exit 1
  181. fi
  182. export USE_QEMU="${USE_QEMU:-0}"
  183. export IMG_DATE="${IMG_DATE:-"$(date +%Y-%m-%d)"}"
  184. export IMG_FILENAME="${IMG_FILENAME:-"${IMG_DATE}-${IMG_NAME}"}"
  185. export ARCHIVE_FILENAME="${ARCHIVE_FILENAME:-"image_${IMG_DATE}-${IMG_NAME}"}"
  186. export SCRIPT_DIR="${BASE_DIR}/scripts"
  187. export WORK_DIR="${WORK_DIR:-"${BASE_DIR}/work/${IMG_NAME}"}"
  188. export DEPLOY_DIR=${DEPLOY_DIR:-"${BASE_DIR}/deploy"}
  189. # DEPLOY_ZIP was deprecated in favor of DEPLOY_COMPRESSION
  190. # This preserve the old behavior with DEPLOY_ZIP=0 where no archive was created
  191. if [ -z "${DEPLOY_COMPRESSION}" ] && [ "${DEPLOY_ZIP:-1}" = "0" ]; then
  192. echo "DEPLOY_ZIP has been deprecated in favor of DEPLOY_COMPRESSION"
  193. echo "Similar behavior to DEPLOY_ZIP=0 can be obtained with DEPLOY_COMPRESSION=none"
  194. echo "Please update your config file"
  195. DEPLOY_COMPRESSION=none
  196. fi
  197. export DEPLOY_COMPRESSION=${DEPLOY_COMPRESSION:-zip}
  198. export COMPRESSION_LEVEL=${COMPRESSION_LEVEL:-6}
  199. export LOG_FILE="${WORK_DIR}/build.log"
  200. export TARGET_HOSTNAME=${TARGET_HOSTNAME:-raspberrypi}
  201. export FIRST_USER_NAME=${FIRST_USER_NAME:-pi}
  202. export FIRST_USER_PASS
  203. export DISABLE_FIRST_BOOT_USER_RENAME=${DISABLE_FIRST_BOOT_USER_RENAME:-0}
  204. export RELEASE=${RELEASE:-bullseye} # Don't forget to update stage0/prerun.sh
  205. export WPA_ESSID
  206. export WPA_PASSWORD
  207. export WPA_COUNTRY
  208. export ENABLE_SSH="${ENABLE_SSH:-0}"
  209. export PUBKEY_ONLY_SSH="${PUBKEY_ONLY_SSH:-0}"
  210. export LOCALE_DEFAULT="${LOCALE_DEFAULT:-en_GB.UTF-8}"
  211. export KEYBOARD_KEYMAP="${KEYBOARD_KEYMAP:-gb}"
  212. export KEYBOARD_LAYOUT="${KEYBOARD_LAYOUT:-English (UK)}"
  213. export TIMEZONE_DEFAULT="${TIMEZONE_DEFAULT:-Europe/London}"
  214. export GIT_HASH=${GIT_HASH:-"$(git rev-parse HEAD)"}
  215. export PUBKEY_SSH_FIRST_USER
  216. export CLEAN
  217. export IMG_NAME
  218. export APT_PROXY
  219. export STAGE
  220. export STAGE_DIR
  221. export STAGE_WORK_DIR
  222. export PREV_STAGE
  223. export PREV_STAGE_DIR
  224. export ROOTFS_DIR
  225. export PREV_ROOTFS_DIR
  226. export IMG_SUFFIX
  227. export NOOBS_NAME
  228. export NOOBS_DESCRIPTION
  229. export EXPORT_DIR
  230. export EXPORT_ROOTFS_DIR
  231. export QUILT_PATCHES
  232. export QUILT_NO_DIFF_INDEX=1
  233. export QUILT_NO_DIFF_TIMESTAMPS=1
  234. export QUILT_REFRESH_ARGS="-p ab"
  235. # shellcheck source=scripts/common
  236. source "${SCRIPT_DIR}/common"
  237. # shellcheck source=scripts/dependencies_check
  238. source "${SCRIPT_DIR}/dependencies_check"
  239. export NO_PRERUN_QCOW2="${NO_PRERUN_QCOW2:-1}"
  240. export USE_QCOW2="${USE_QCOW2:-0}"
  241. export BASE_QCOW2_SIZE=${BASE_QCOW2_SIZE:-12G}
  242. source "${SCRIPT_DIR}/qcow2_handling"
  243. if [ "${USE_QCOW2}" = "1" ]; then
  244. NO_PRERUN_QCOW2=1
  245. else
  246. NO_PRERUN_QCOW2=0
  247. fi
  248. export NO_PRERUN_QCOW2="${NO_PRERUN_QCOW2:-1}"
  249. if [ "$SETFCAP" != "1" ]; then
  250. export CAPSH_ARG="--drop=cap_setfcap"
  251. fi
  252. dependencies_check "${BASE_DIR}/depends"
  253. #check username is valid
  254. if [[ ! "$FIRST_USER_NAME" =~ ^[a-z][-a-z0-9_]*$ ]]; then
  255. echo "Invalid FIRST_USER_NAME: $FIRST_USER_NAME"
  256. exit 1
  257. fi
  258. if [[ "$DISABLE_FIRST_BOOT_USER_RENAME" == "1" ]] && [ -z "${FIRST_USER_PASS}" ]; then
  259. echo "To disable user rename on first boot, FIRST_USER_PASS needs to be set"
  260. echo "Not setting FIRST_USER_PASS makes your system vulnerable and open to cyberattacks"
  261. exit 1
  262. fi
  263. if [[ "$DISABLE_FIRST_BOOT_USER_RENAME" == "1" ]]; then
  264. echo "User rename on the first boot is disabled"
  265. echo "Be advised of the security risks linked to shipping a device with default username/password set."
  266. fi
  267. if [[ -n "${APT_PROXY}" ]] && ! curl --silent "${APT_PROXY}" >/dev/null ; then
  268. echo "Could not reach APT_PROXY server: ${APT_PROXY}"
  269. exit 1
  270. fi
  271. if [[ -n "${WPA_PASSWORD}" && ${#WPA_PASSWORD} -lt 8 || ${#WPA_PASSWORD} -gt 63 ]] ; then
  272. echo "WPA_PASSWORD" must be between 8 and 63 characters
  273. exit 1
  274. fi
  275. if [[ "${PUBKEY_ONLY_SSH}" = "1" && -z "${PUBKEY_SSH_FIRST_USER}" ]]; then
  276. echo "Must set 'PUBKEY_SSH_FIRST_USER' to a valid SSH public key if using PUBKEY_ONLY_SSH"
  277. exit 1
  278. fi
  279. mkdir -p "${WORK_DIR}"
  280. log "Begin ${BASE_DIR}"
  281. STAGE_LIST=${STAGE_LIST:-${BASE_DIR}/stage*}
  282. for STAGE_DIR in $STAGE_LIST; do
  283. STAGE_DIR=$(realpath "${STAGE_DIR}")
  284. run_stage
  285. done
  286. CLEAN=1
  287. for EXPORT_DIR in ${EXPORT_DIRS}; do
  288. STAGE_DIR=${BASE_DIR}/export-image
  289. # shellcheck source=/dev/null
  290. source "${EXPORT_DIR}/EXPORT_IMAGE"
  291. EXPORT_ROOTFS_DIR=${WORK_DIR}/$(basename "${EXPORT_DIR}")/rootfs
  292. if [ "${USE_QCOW2}" = "1" ]; then
  293. USE_QCOW2=0
  294. EXPORT_NAME="${IMG_FILENAME}${IMG_SUFFIX}"
  295. echo "------------------------------------------------------------------------"
  296. echo "Running export stage for ${EXPORT_NAME}"
  297. rm -f "${WORK_DIR}/export-image/${EXPORT_NAME}.img" || true
  298. rm -f "${WORK_DIR}/export-image/${EXPORT_NAME}.qcow2" || true
  299. rm -f "${WORK_DIR}/${EXPORT_NAME}.img" || true
  300. rm -f "${WORK_DIR}/${EXPORT_NAME}.qcow2" || true
  301. EXPORT_STAGE=$(basename "${EXPORT_DIR}")
  302. for s in $STAGE_LIST; do
  303. TMP_LIST=${TMP_LIST:+$TMP_LIST }$(basename "${s}")
  304. done
  305. FIRST_STAGE=${TMP_LIST%% *}
  306. FIRST_IMAGE="image-${FIRST_STAGE}.qcow2"
  307. pushd "${WORK_DIR}" > /dev/null
  308. echo "Creating new base "${EXPORT_NAME}.qcow2" from ${FIRST_IMAGE}"
  309. cp "./${FIRST_IMAGE}" "${EXPORT_NAME}.qcow2"
  310. ARR=($TMP_LIST)
  311. # rebase stage images to new export base
  312. for CURR_STAGE in "${ARR[@]}"; do
  313. if [ "${CURR_STAGE}" = "${FIRST_STAGE}" ]; then
  314. PREV_IMG="${EXPORT_NAME}"
  315. continue
  316. fi
  317. echo "Rebasing image-${CURR_STAGE}.qcow2 onto ${PREV_IMG}.qcow2"
  318. qemu-img rebase -f qcow2 -u -b ${PREV_IMG}.qcow2 image-${CURR_STAGE}.qcow2
  319. if [ "${CURR_STAGE}" = "${EXPORT_STAGE}" ]; then
  320. break
  321. fi
  322. PREV_IMG="image-${CURR_STAGE}"
  323. done
  324. # commit current export stage into base export image
  325. echo "Committing image-${EXPORT_STAGE}.qcow2 to ${EXPORT_NAME}.qcow2"
  326. qemu-img commit -f qcow2 -p -b "${EXPORT_NAME}.qcow2" image-${EXPORT_STAGE}.qcow2
  327. # rebase stage images back to original first stage for easy re-run
  328. for CURR_STAGE in "${ARR[@]}"; do
  329. if [ "${CURR_STAGE}" = "${FIRST_STAGE}" ]; then
  330. PREV_IMG="image-${CURR_STAGE}"
  331. continue
  332. fi
  333. echo "Rebasing back image-${CURR_STAGE}.qcow2 onto ${PREV_IMG}.qcow2"
  334. qemu-img rebase -f qcow2 -u -b ${PREV_IMG}.qcow2 image-${CURR_STAGE}.qcow2
  335. if [ "${CURR_STAGE}" = "${EXPORT_STAGE}" ]; then
  336. break
  337. fi
  338. PREV_IMG="image-${CURR_STAGE}"
  339. done
  340. popd > /dev/null
  341. mkdir -p "${WORK_DIR}/export-image/rootfs"
  342. mv "${WORK_DIR}/${EXPORT_NAME}.qcow2" "${WORK_DIR}/export-image/"
  343. echo "Mounting image ${WORK_DIR}/export-image/${EXPORT_NAME}.qcow2 to rootfs ${WORK_DIR}/export-image/rootfs"
  344. mount_qimage "${WORK_DIR}/export-image/${EXPORT_NAME}.qcow2" "${WORK_DIR}/export-image/rootfs"
  345. CLEAN=0
  346. run_stage
  347. CLEAN=1
  348. USE_QCOW2=1
  349. else
  350. run_stage
  351. fi
  352. if [ "${USE_QEMU}" != "1" ]; then
  353. if [ -e "${EXPORT_DIR}/EXPORT_NOOBS" ]; then
  354. # shellcheck source=/dev/null
  355. source "${EXPORT_DIR}/EXPORT_NOOBS"
  356. STAGE_DIR="${BASE_DIR}/export-noobs"
  357. if [ "${USE_QCOW2}" = "1" ]; then
  358. USE_QCOW2=0
  359. run_stage
  360. USE_QCOW2=1
  361. else
  362. run_stage
  363. fi
  364. fi
  365. fi
  366. done
  367. if [ -x postrun.sh ]; then
  368. log "Begin postrun.sh"
  369. cd "${BASE_DIR}"
  370. ./postrun.sh
  371. log "End postrun.sh"
  372. fi
  373. if [ "${USE_QCOW2}" = "1" ]; then
  374. unload_qimage
  375. fi
  376. log "End ${BASE_DIR}"