openwrtbuilder 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. #!/usr/bin/env bash
  2. #
  3. # Copyright 2022-23 Bryan C. Roessler
  4. #
  5. # Build and deploy OpenWRT images
  6. #
  7. # Apache 2.0 License
  8. # Set default release
  9. : "${RELEASE:="22.03.3"}"
  10. printHelp() {
  11. debug "${FUNCNAME[0]}"
  12. cat <<-'EOF'
  13. Create and deploy OpenWRT images using the Image Builder.
  14. USAGE:
  15. openwrtbuilder [OPTION [VALUE]] -p PROFILE [-p PROFILE2]...
  16. OPTIONS
  17. --profile, -p PROFILE
  18. --info, -i (print profile info)
  19. --list-profiles, -l
  20. --release, -r, --version, -v RELEASE_VERSION ("snapshot", "22.03.3", etc.)
  21. --buildroot, -b PATH
  22. --ssh-upgrade HOST
  23. Example: root@192.168.1.1
  24. --ssh-backup SSH_PATH
  25. (Enabled by default for --ssh-upgrade)
  26. --flash, -f DEVICE
  27. Example: /dev/sdX
  28. --reset
  29. Cleanup all source and output files
  30. --debug, -d
  31. --help, -h
  32. EOF
  33. }
  34. readInput() {
  35. debug "${FUNCNAME[0]}"
  36. unset RESET
  37. declare -ga PROFILES
  38. declare -g PROFILE_INFO
  39. if _input=$(getopt -o +r:v:p:i:lb:sf:dh -l release:,version:,profile:,info:,list-profiles,buildroot:,from-source,ssh-upgrade:,ssh-backup:,flash:,reset,debug,help -- "$@"); then
  40. eval set -- "$_input"
  41. while true; do
  42. case "$1" in
  43. --release|-r|--version|-v)
  44. shift && declare -g USER_RELEASE="$1"
  45. ;;
  46. --profile|-p)
  47. shift && PROFILES+=("$1")
  48. ;;
  49. --info|-i)
  50. PROFILE_INFO=1
  51. ;;
  52. --list-profiles|-l)
  53. listProfiles && exit $?
  54. ;;
  55. --buildroot|-b)
  56. shift && BUILDROOT="$1"
  57. ;;
  58. --from-source|-s)
  59. FROM_SOURCE=1
  60. ;;
  61. --ssh-upgrade)
  62. shift && SSH_UPGRADE_PATH="$1"
  63. ;;
  64. --ssh-backup)
  65. shift && SSH_BACKUP_PATH="$1"
  66. ;;
  67. --flash|-f)
  68. shift && FLASH_DEV="$1"
  69. ;;
  70. --reset)
  71. RESET=1
  72. ;;
  73. --debug|-d)
  74. echo "Debugging on"
  75. DEBUG=1
  76. ;;
  77. --help|-h)
  78. printHelp && exit 0
  79. ;;
  80. --)
  81. shift
  82. break
  83. ;;
  84. esac
  85. shift
  86. done
  87. else
  88. echo "Incorrect options provided"
  89. printHelp && exit 1
  90. fi
  91. }
  92. listProfiles() {
  93. debug "${FUNCNAME[0]}"
  94. grep "declare -Ag" "$PFILE" | cut -d" " -f3
  95. }
  96. installDependencies() {
  97. debug "${FUNCNAME[0]}"
  98. declare -a pkg_list
  99. # TODO please contribute your platform here
  100. if (( FROM_SOURCE )); then
  101. # For building from source with make
  102. # https://openwrt.org/docs/guide-developer/toolchain/install-buildsystem
  103. case "$ID" in
  104. fedora|centos)
  105. pkg_list+=(
  106. "bash-completion"
  107. "bzip2"
  108. "gcc"
  109. "gcc-c++"
  110. "git"
  111. "make"
  112. "ncurses-devel"
  113. "patch"
  114. "rsync"
  115. "tar"
  116. "unzip"
  117. "wget"
  118. "which"
  119. "diffutils"
  120. "python2"
  121. "python3"
  122. "perl-base"
  123. "perl-Data-Dumper"
  124. "perl-File-Compare"
  125. "perl-File-Copy"
  126. "perl-FindBin"
  127. "perl-Thread-Queue"
  128. )
  129. ;;
  130. debian|ubuntu)
  131. pkg_list+=(
  132. "build-essential"
  133. "clang"
  134. "flex"
  135. "g++"
  136. "gawk"
  137. "gcc-multilib"
  138. "gettext"
  139. "git"
  140. "libncurses5-dev"
  141. "libssl-dev"
  142. "python3-distutils"
  143. "rsync"
  144. "unzip"
  145. "zlib1g-dev"
  146. "file"
  147. "wget"
  148. )
  149. ;;
  150. arch)
  151. pkg_list+=(
  152. "base-devel"
  153. "autoconf"
  154. "automake"
  155. "bash"
  156. "binutils"
  157. "bison"
  158. "bzip2"
  159. "fakeroot"
  160. "file"
  161. "findutils"
  162. "flex"
  163. "gawk"
  164. "gcc"
  165. "gettext"
  166. "git"
  167. "grep"
  168. "groff"
  169. "gzip"
  170. "libelf"
  171. "libtool"
  172. "libxslt"
  173. "m4"
  174. "make"
  175. "ncurses"
  176. "openssl"
  177. "patch"
  178. "pkgconf"
  179. "python"
  180. "rsync"
  181. "sed"
  182. "texinfo"
  183. "time"
  184. "unzip"
  185. "util-linux"
  186. "wget"
  187. "which"
  188. "zlib"
  189. )
  190. ;;
  191. esac
  192. else
  193. # For Imagebuilder
  194. case "$ID" in
  195. fedora|centos)
  196. pkg_list+=(
  197. "@c-development"
  198. "@development-tools"
  199. "@development-libs"
  200. "perl-FindBin"
  201. "zlib-static"
  202. "elfutils-libelf-devel"
  203. "gawk"
  204. "unzip"
  205. "file"
  206. "wget"
  207. "python3"
  208. "python2"
  209. "axel"
  210. )
  211. ;;
  212. debian|ubuntu)
  213. pkg_list+=(
  214. "build-essential"
  215. "libncurses5-dev"
  216. "libncursesw5-dev"
  217. "zlib1g-dev"
  218. "gawk"
  219. "git"
  220. "gettext"
  221. "libssl-dev"
  222. "xsltproc"
  223. "wget"
  224. "unzip"
  225. "python"
  226. "axel"
  227. )
  228. ;;
  229. esac
  230. fi
  231. pkg_install "${pkg_list[@]}"
  232. }
  233. getImageBuilder() {
  234. debug "${FUNCNAME[0]}"
  235. declare dl_tool
  236. if [[ -f "${P_ARR[ib_archive]}" ]]; then
  237. if askOk "Redownload ImageBuilder archive?"; then
  238. rm -f "${P_ARR[ib_archive]}"
  239. else
  240. return 0
  241. fi
  242. fi
  243. if hash axel &>/dev/null; then
  244. dl_tool="axel"
  245. elif hash curl &>/dev/null; then
  246. dl_tool="curl"
  247. else
  248. echo "Downloading the ImageBuilder requires axel or curl!"
  249. return 1
  250. fi
  251. echo "Downloading imagebuilder archive using $dl_tool"
  252. debug "$dl_tool -o ${P_ARR[ib_archive]} ${P_ARR[ib_url]}"
  253. if ! "$dl_tool" -o "${P_ARR[ib_archive]}" "${P_ARR[ib_url]}"; then
  254. echo "Could not download imagebuilder archive"
  255. exit 1
  256. fi
  257. if [[ ! -f "${P_ARR[ib_archive]}" ]]; then
  258. echo "Archive missing"
  259. exit 1
  260. fi
  261. # if hash sha256sum &>/dev/null; then
  262. # echo "Verifying checksums"
  263. # debug "$dl_tool -s "${P_ARR[SHA256_URL]}" | grep $filename | cut -f1 -d' '"
  264. # sha256sum=$($dl_tool -s "${P_ARR[SHA256_URL]}" |grep "$filename" |cut -f1 -d' ')
  265. # debug "Downloaded sha256sum: $sha256sum"
  266. # fi
  267. echo "Extracting image archive"
  268. [[ ! -d "${P_ARR[sources_dir]}" ]] && mkdir -p "${P_ARR[sources_dir]}"
  269. debug "tar -xf ${P_ARR[ib_archive]} -C ${P_ARR[sources_dir]} --strip-components 1"
  270. if ! tar -xf "${P_ARR[ib_archive]}" -C "${P_ARR[sources_dir]}" --strip-components 1; then
  271. echo "Extraction failed"
  272. exit 1
  273. fi
  274. }
  275. addRepos() {
  276. debug "${FUNCNAME[0]}"
  277. if [[ -v P_ARR[repo] ]]; then
  278. if ! grep -q "${P_ARR[repo]}" "${P_ARR[sources_dir]}/repositories.conf"; then
  279. echo "${P_ARR[repo]}" >> "${P_ARR[sources_dir]}/repositories.conf"
  280. fi
  281. sed -i '/option check_signature/d' "${P_ARR[sources_dir]}/repositories.conf"
  282. fi
  283. }
  284. sshBackup() {
  285. debug "${FUNCNAME[0]}"
  286. local _date _hostname _backup_fname
  287. [[ -d "$FILESDIR" ]] || mkdir -p "$FILESDIR"
  288. printf -v _date '%(%Y-%m-%d-%H-%M-%S)T'
  289. _hostname=$(ssh -qt "$SSH_BACKUP_PATH" echo -n \$HOSTNAME)
  290. _backup_fname="backup-$_hostname-$_date.tar.gz"
  291. # Make backup archive on remote
  292. debug "ssh -t $SSH_BACKUP_PATH sysupgrade -b /tmp/$_backup_fname"
  293. if ! ssh -t "$SSH_BACKUP_PATH" "sysupgrade -b /tmp/$_backup_fname"; then
  294. echo "SSH backup failed"
  295. exit 1
  296. fi
  297. # Move backup archive locally
  298. debug "rsync -avz --remove-source-files $SSH_BACKUP_PATH:/tmp/$_backup_fname ${P_ARR[build_dir]}/"
  299. if ! rsync -avz --remove-source-files "$SSH_BACKUP_PATH":"/tmp/$_backup_fname" "${P_ARR[build_dir]}/"; then
  300. echo "Could not copy SSH backup"
  301. exit 1
  302. fi
  303. # Extract backup archive
  304. debug "tar -C $FILESDIR -xzf ${P_ARR[build_dir]}/$_backup_fname"
  305. if ! tar -C "$FILESDIR" -xzf "${P_ARR[build_dir]}/$_backup_fname"; then
  306. echo "Could not extract SSH backup"
  307. exit 1
  308. fi
  309. rm "${P_ARR[build_dir]}/$_backup_fname"
  310. }
  311. makeImage() {
  312. debug "${FUNCNAME[0]}"
  313. # Reuse the existing output
  314. if [[ -d "${P_ARR[bin_dir]}" ]]; then
  315. if askOk "${P_ARR[bin_dir]} exists. Rebuild?"; then
  316. rm -rf "${P_ARR[bin_dir]}"
  317. else
  318. return 0
  319. fi
  320. fi
  321. [[ ! -d "${P_ARR[bin_dir]}" ]] && mkdir -p "${P_ARR[bin_dir]}"
  322. if ! make image \
  323. BIN_DIR="${P_ARR[bin_dir]}" \
  324. PROFILE="${P_ARR[profile]}" \
  325. PACKAGES="${P_ARR[packages]}" \
  326. FILES="$FILESDIR" \
  327. --directory="${P_ARR[sources_dir]}" \
  328. --jobs=$(( $(nproc) - 1 )) \
  329. > make.log; then
  330. echo "Make image failed!"
  331. exit 1
  332. fi
  333. }
  334. flashImage() {
  335. debug "${FUNCNAME[0]}"
  336. local _umount
  337. if [[ ! -e "$FLASH_DEV" ]]; then
  338. echo "The device specified by --flash could not be found"
  339. exit 1
  340. fi
  341. # TODO Roughly chooses the correct image
  342. if [[ -f "${P_ARR[factory_img_gz]}" ]]; then
  343. img_gz="${P_ARR[factory_img_gz]}"
  344. img="${P_ARR[factory_img]}"
  345. elif [[ -f "${P_ARR[sysupgrade_img_gz]}" ]]; then
  346. img_gz="${P_ARR[sysupgrade_img_gz]}"
  347. img="${P_ARR[sysupgrade_img]}"
  348. else
  349. return 1
  350. fi
  351. debug "$img_gz $img"
  352. debug "gunzip -qfk $img_gz"
  353. gunzip -qfk "$img_gz"
  354. echo "Unmounting target device $FLASH_DEV partitions"
  355. _umount=( "$FLASH_DEV"?* )
  356. debug "umount ${_umount[*]}"
  357. sudo umount "${_umount[@]}"
  358. debug "sudo dd if=\"$img\" of=\"$FLASH_DEV\" bs=2M conv=fsync"
  359. if sudo dd if="$img" of="$FLASH_DEV" bs=2M conv=fsync; then
  360. sync
  361. echo "Image flashed sucessfully!"
  362. else
  363. echo "dd failed!"
  364. exit 1
  365. fi
  366. }
  367. sshUpgrade() {
  368. debug "${FUNCNAME[0]}"
  369. echo "Copying \"${P_ARR[sysupgrade_bin_gz]}\" to $SSH_UPGRADE_PATH/tmp/"
  370. debug "scp \"${P_ARR[sysupgrade_bin_gz]}\" \"$SSH_UPGRADE_PATH\":\"/tmp/${P_ARR[sysupgrade_bin_gz_fname]}\""
  371. # shellcheck disable=SC2140
  372. if ! scp "${P_ARR[sysupgrade_bin_gz]}" "$SSH_UPGRADE_PATH":"/tmp/${P_ARR[sysupgrade_bin_gz_fname]}"; then
  373. echo "Could not access the --ssh-upgrade PATH"
  374. exit 1
  375. fi
  376. echo "Executing remote sysupgrade"
  377. debug "ssh \"$SSH_UPGRADE_PATH\" \"sysupgrade -F /tmp/${P_ARR[sysupgrade_bin_gz_fname]}\""
  378. # shellcheck disable=SC2029
  379. ssh "$SSH_UPGRADE_PATH" "sysupgrade -F /tmp/${P_ARR[sysupgrade_bin_gz_fname]}"
  380. }
  381. fromSource() {
  382. debug "${FUNCNAME[0]}"
  383. declare src_url="https://github.com/openwrt/openwrt.git"
  384. declare src_dir="${P_ARR[build_dir]}/sources/openwrt"
  385. declare -a pkg_list
  386. echo "Building from source is under development"
  387. if [[ ! -d "$src_dir" ]]; then
  388. mkdir -p "$src_dir"
  389. git clone "$src_url" "$src_dir"
  390. fi
  391. pushd "$src_dir" || return 1
  392. if [[ ${P_ARR['release']} == "snapshot" ]]; then
  393. git checkout master
  394. else
  395. git checkout "v${P_ARR[release]}"
  396. fi
  397. ./scripts/feeds update -a
  398. ./scripts/feeds install -a
  399. # Grab the release config.seed
  400. k_options=$(curl -s https://downloads.openwrt.org/releases/22.03.3/targets/rockchip/armv8/config.buildinfo)
  401. debug "$k_options"
  402. make distclean
  403. make download
  404. make -j"$(nproc)" world
  405. popd || return 1
  406. exit # TODO exit here for fromSource() testing
  407. }
  408. debug() { (( DEBUG )) && echo "Debug: $*"; }
  409. askOk() {
  410. local _response
  411. read -r -p "$* [y/N]" _response
  412. _response=${_response,,}
  413. [[ ! "$_response" =~ ^(yes|y)$ ]] && return 1
  414. return 0
  415. }
  416. resetAll() {
  417. debug "${FUNCNAME[0]}"
  418. askOk "Remove ${BUILDROOT}/sources and ${BUILDROOT}/bin?" || exit $?
  419. debug "rm -rf ${BUILDROOT}/sources ${BUILDROOT}/bin"
  420. find "${BUILDROOT}/sources" "${BUILDROOT}/bin" \
  421. ! -dir "$FILESDIR" -type f -delete +
  422. #rm -rf "${BUILDROOT}/sources" "${BUILDROOT}/bin"
  423. }
  424. resetProfile() {
  425. debug "${FUNCNAME[0]}"
  426. askOk "Remove ${P_ARR[sources_dir]} ${P_ARR[bin_dir]}?" || exit $?
  427. debug "rm -rf ${P_ARR[sources_dir]} ${P_ARR[bin_dir]}"
  428. rm -rf "${P_ARR[sources_dir]}" "${P_ARR[bin_dir]}"
  429. }
  430. loadProfiles() {
  431. debug "${FUNCNAME[0]}"
  432. declare -g PFILE
  433. # https://stackoverflow.com/a/4774063
  434. PFILE="$SCRIPTDIR/profiles"
  435. # shellcheck source=./profiles
  436. ! source "$PFILE" && echo "profiles file missing!" && return 1
  437. }
  438. init() {
  439. debug "${FUNCNAME[0]}"
  440. declare -g ID RPM_MGR SCRIPTDIR
  441. debug || echo "To enable debugging output, use --debug or -d"
  442. # Save the script directory
  443. SCRIPTDIR="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 || exit $? ; pwd -P)"
  444. if [[ -e "/etc/os-release" ]]; then
  445. source "/etc/os-release"
  446. else
  447. err "/etc/os-release not found"
  448. err "Your OS is unsupported"
  449. printHelp
  450. exit 1
  451. fi
  452. debug "Detected host platform: $ID $VERSION_ID"
  453. # normalize distro ID
  454. case "$ID" in
  455. debian|arch)
  456. ;;
  457. centos|fedora)
  458. if hash dnf &>/dev/null; then
  459. RPM_MGR="dnf"
  460. elif hash yum &>/dev/null; then
  461. RPM_MGR="yum"
  462. fi
  463. ;;
  464. rhel)
  465. ID="centos"
  466. ;;
  467. linuxmint|neon|*ubuntu*)
  468. ID="ubuntu"
  469. ;;
  470. *suse*)
  471. ID="suse"
  472. ;;
  473. raspbian)
  474. ID="debian"
  475. ;;
  476. *)
  477. echo "Autodetecting distro, this may be unreliable and --compat may also be required"
  478. if hash dnf &>/dev/null; then
  479. ID="fedora"
  480. RPM_MGR="dnf"
  481. elif hash yum &>/dev/null; then
  482. ID="centos"
  483. RPM_MGR="yum"
  484. elif hash apt &>/dev/null; then
  485. ID="ubuntu"
  486. elif hash pacman &>/dev/null; then
  487. ID="arch"
  488. else
  489. return 1
  490. fi
  491. ;;
  492. esac
  493. debug "Using host platform: $ID $VERSION_ID"
  494. # Set distro-specific functions
  495. case "$ID" in
  496. fedora|centos)
  497. pkg_install(){ sudo "$RPM_MGR" install -y "$@"; }
  498. ;;
  499. debian|ubuntu)
  500. pkg_install(){ sudo apt-get install -y -q0 "$@"; }
  501. ;;
  502. suse)
  503. pkg_install(){ sudo zypper --non-interactive -q install --force --no-confirm "$@"; }
  504. ;;
  505. arch)
  506. pkg_install(){ sudo pacman -S --noconfirm --needed "$@"; }
  507. ;;
  508. esac
  509. }
  510. main() {
  511. debug "${FUNCNAME[0]}"
  512. init
  513. loadProfiles
  514. readInput "$@"
  515. # Allow --reset without a profile
  516. if [[ ${#PROFILES} -lt 1 ]]; then
  517. if (( RESET )); then
  518. resetAll
  519. exit
  520. else
  521. echo "No profile supplied" && return 1
  522. fi
  523. fi
  524. installDependencies
  525. for profile in "${PROFILES[@]}"; do
  526. debug "Profile: $profile"
  527. [[ ! ${!profile@a} = A ]] && echo "Profile does not exist" && return 1
  528. # Set profile vars in the P_ARR array
  529. declare -gn P_ARR="$profile"
  530. # Fallback to SCRIPTDIR if BUILDROOT has not been set
  531. BUILDROOT="${BUILDROOT:=$SCRIPTDIR}"
  532. FILESDIR="${FILESDIR:=$BUILDROOT/files}"
  533. # precedence: user input>profile>env>hardcode
  534. P_ARR[release]="${USER_RELEASE:=${P_ARR[release]:=$RELEASE}}"
  535. P_ARR[build_dir]="$BUILDROOT/${P_ARR[profile]}-${P_ARR[release]}"
  536. P_ARR[sources_dir]="$BUILDROOT/sources"
  537. P_ARR[ib_archive]="${P_ARR[sources_dir]}/${P_ARR[profile]}-${P_ARR[release]}.tar.xz"
  538. P_ARR[bin_dir]="${P_ARR[build_dir]}"
  539. # shellcheck disable=SC2154
  540. # TODO: I don't knwo why shellcheck is catching this
  541. if [[ "${P_ARR[release]}" == "snapshot" ]]; then
  542. P_ARR[out_prefix]="${P_ARR[bin_dir]}/openwrt-${P_ARR[target]//\//-}-${P_ARR[profile]}"
  543. P_ARR[url_prefix]="https://downloads.openwrt.org/snapshots/targets/${P_ARR[target]}"
  544. P_ARR[url_filename]="openwrt-imagebuilder-${P_ARR[target]//\//-}.Linux-x86_64.tar.xz"
  545. P_ARR[ib_url]="${P_ARR[url_prefix]}/${P_ARR[url_filename]}"
  546. else
  547. P_ARR[out_prefix]="${P_ARR[bin_dir]}/openwrt-${P_ARR[release]}-${P_ARR[target]//\//-}-${P_ARR[profile]}"
  548. P_ARR[url_prefix]="https://downloads.openwrt.org/releases/${P_ARR[release]}/targets/${P_ARR[target]}"
  549. P_ARR[url_filename]="openwrt-imagebuilder-${P_ARR[release]}-${P_ARR[target]//\//-}.Linux-x86_64.tar.xz"
  550. P_ARR[ib_url]="${P_ARR[url_prefix]}/${P_ARR[url_filename]}"
  551. fi
  552. P_ARR[factory_img]="${P_ARR[out_prefix]}-${P_ARR[filesystem]}-factory.img"
  553. P_ARR[factory_img_gz]="${P_ARR[factory_img]}.gz"
  554. P_ARR[sysupgrade_img]="${P_ARR[out_prefix]}-${P_ARR[filesystem]}-sysupgrade.img"
  555. P_ARR[sysupgrade_img_gz]="${P_ARR[sysupgrade_img]}.gz"
  556. #P_ARR[sysupgrade_bin]=$out_prefix-${P_ARR[filesystem]}-sysupgrade.img
  557. #P_ARR[sysupgrade_bin_fname]=${P_ARR[sysupgrade_bin]##*/}
  558. P_ARR[sysupgrade_bin_gz]="${P_ARR[sysupgrade_bin]}.gz"
  559. P_ARR[sysupgrade_bin_gz_fname]="${P_ARR[sysupgrade_bin_gz]##*/}"
  560. P_ARR[SHA256_URL]="${P_ARR[url_prefix]}/sha256sums"
  561. P_ARR[CONFIG_SEED]="${P_ARR[url_prefix]}"
  562. if (( DEBUG )) || (( PROFILE_INFO )); then
  563. echo "Profile settings:"
  564. for x in "${!P_ARR[@]}"; do printf "%s=%s\n" "$x" "${P_ARR[$x]}"; done
  565. fi
  566. (( RESET )) && resetProfile
  567. # Experimental
  568. (( FROM_SOURCE )) && fromSource
  569. getImageBuilder
  570. addRepos
  571. #copyFiles
  572. [[ -v SSH_BACKUP_PATH ]] && sshBackup
  573. if makeImage; then
  574. [[ -v SSH_UPGRADE_PATH ]] && sshUpgrade
  575. [[ -v FLASH_DEV ]] && flashImage
  576. fi
  577. done
  578. }
  579. main "$@"
  580. exit