Kimarite

setup_balena-io_etcher2debian.deb.sh

Aug 19th, 2021 (edited)
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.69 KB | None | 0 0
  1. #!/usr/bin/env bash
  2. #
  3. # The core commands execute start from the "MAIN" section below.
  4. # The script to Debian (Buster, Bullseye,...)
  5. # Modified line: 488
  6. # https://pastebin.com/qV6zgSmb
  7.  
  8. test -z "$BASH_SOURCE" && {
  9. self="sudo -E bash"
  10. prefix="<curl command> |"
  11. } || {
  12. self=$(readlink -f ${BASH_SOURCE:-$0})
  13. prefix=""
  14. }
  15.  
  16. tmp_log=$(mktemp .csm_setup_XXXXXXXXX)
  17.  
  18. colours=$(tput colors 2>/dev/null || echo "256")
  19. no_colour="\e[39;49m"
  20. green_colour="\e[32m"
  21. red_colour="\e[41;97m"
  22. bold="\e[1m"
  23. reset="\e[0m"
  24. use_colours=$(test -n "$colours" && test $colours -ge 8 && echo "yes")
  25. test "$use_colours" == "yes" || {
  26. no_colour=""
  27. green_colour=""
  28. red_colour=""
  29. bold=""
  30. reset=""
  31. }
  32.  
  33.  
  34. example_name="Ubuntu/Xenial (16.04)"
  35. example_distro="ubuntu"
  36. example_codename="xenial"
  37. example_version="16.04"
  38.  
  39.  
  40. function echo_helptext {
  41. local help_text="$*"
  42. echo " ^^^^: ... $help_text"
  43. }
  44.  
  45. function die {
  46. local text="$@"
  47. test ! -z "$text" && {
  48. echo_helptext "$text" 1>&2
  49. }
  50.  
  51. local prefix="${red_colour} !!!!${no_colour}"
  52.  
  53. echo -e "$prefix: Oh no, your setup failed! :-( ... But we might be able to help. :-)"
  54. echo -e "$prefix: "
  55. echo -e "$prefix: ${bold}You can contact balena for further assistance.${reset}"
  56. echo -e "$prefix: "
  57.  
  58. echo -e "$prefix: ${bold}URL: https://github.com/balena-io/etcher${reset}"
  59. echo -e "$prefix: "
  60.  
  61.  
  62. test -f "$tmp_log" && {
  63. local n=20
  64. echo -e "$prefix: Last $n log lines from $tmp_log (might not be errors, nor even relevant):"
  65. echo -e "$prefix:"
  66. check_tool_silent "xargs" && {
  67. check_tool_silent "fmt" && {
  68. tail -n $n $tmp_log | fmt -t | xargs -Ilog echo -e "$prefix: > log"
  69. } || {
  70. tail -n $n $tmp_log | xargs -Ilog echo -e "$prefix: > log"
  71. }
  72. } || {
  73. echo
  74. tail -n $n $tmp_log
  75. }
  76. }
  77. exit 1
  78. }
  79.  
  80. function echo_colour {
  81. local colour="${1:-"no"}_colour"; shift
  82. echo -e "${!colour}$@${no_colour}"
  83. }
  84.  
  85. function echo_green_or_red {
  86. local rc="$1"
  87. local good="${2:-YES}"
  88. local bad="${3:-NO}"
  89.  
  90. test "$rc" -eq 0 && {
  91. echo_colour "green" "$good"
  92. } || {
  93. echo_colour "red" "$bad"
  94. }
  95. return $rc
  96. }
  97.  
  98. function echo_clearline {
  99. local rc="$?"
  100. echo -e -n "\033[1K\r"
  101. return $rc
  102. }
  103.  
  104. function echo_status {
  105. local rc="$1"
  106. local good="$2"
  107. local bad="$3"
  108. local text="$4"
  109. local help_text="$5"
  110. local newline=$(test "$6" != "no" && echo "\n" || echo "")
  111. local status_text=$(echo_green_or_red "$rc" "$good" "$bad")
  112.  
  113. echo_clearline
  114. local width=$(test "$use_colours" == "yes" && echo "16" || echo "5")
  115. printf "%${width}s %s${newline}" "${status_text}:" "$text"
  116. test $rc -ne 0 && test ! -z "$help_text" && {
  117. echo_helptext "$help_text"
  118. echo
  119. }
  120.  
  121. return $rc
  122. }
  123.  
  124. function echo_running {
  125. local rc=$?
  126. local text="$1"
  127. echo_status 0 " RUN" " RUN" "$text" "" "no"
  128. return $rc
  129. }
  130.  
  131. function echo_okfail_rc {
  132. local rc=$1
  133. local text="$2"
  134. local help_text="$3"
  135. echo_clearline
  136. echo_status $rc " OK" " NOPE" "$text" "$help_text"
  137. return $rc
  138. }
  139.  
  140. function echo_okfail {
  141. echo_okfail_rc $? "$@"
  142. return $?
  143. }
  144.  
  145. function check_tool_silent {
  146. local tool=${1}
  147. command -v $tool &>/dev/null || which $tool &>/dev/null
  148. return $?
  149. }
  150.  
  151. function check_tool {
  152. local tool=${1}
  153. local optional=${2:-false}
  154. local required_text="optional"
  155. if ! $optional; then required_text="required"; fi
  156. local text="Checking for $required_text executable '$tool' ..."
  157. echo_running "$text"
  158. check_tool_silent "$tool"
  159. echo_okfail "$text" || {
  160. if ! $optional; then
  161. die "$tool is not installed, but is required by this script."
  162. fi
  163. return 1
  164. }
  165. return 0
  166. }
  167.  
  168. function cleanup {
  169. echo
  170.  
  171.  
  172. rm -rf $tmp_log
  173. }
  174.  
  175. function shutdown {
  176. echo_colour "red" " !!!!: Operation cancelled by user!"
  177. exit 2
  178. }
  179.  
  180.  
  181.  
  182. function check_os {
  183. test ! -z "$distro" && test ! -z "${version}${codename}"
  184. return $?
  185. }
  186.  
  187. function detect_os_system {
  188. check_os && return 0
  189. echo_running "$text"
  190. local text="Detecting your OS distribution and release using system methods ..."
  191.  
  192. local tool_rc=1
  193. test -f '/etc/os-release' && {
  194. . /etc/os-release
  195. distro=${distro:-$ID}
  196. codename=${codename:-$VERSION_CODENAME}
  197. codename=${codename:-$(echo $VERSION | cut -d '(' -f 2 | cut -d ')' -f 1)}
  198. version=${version:-$VERSION_ID}
  199.  
  200. test -z "${version}${codename}" && test -f '/etc/debian_version' && {
  201. # Workaround for Debian unstable releases; get the codename from debian_version
  202. codename=$(cat /etc/debian_version | cut -d '/' -f1)
  203. }
  204.  
  205. tool_rc=0
  206. }
  207.  
  208. check_os
  209. local rc=$?
  210. echo_okfail_rc $rc "$text"
  211.  
  212. test $tool_rc -eq 0 && {
  213. report_os_expanded
  214. }
  215.  
  216. return $rc
  217. }
  218.  
  219. function report_os_attribute {
  220. local name=$1
  221. local value=$2
  222. local coloured=""
  223. echo -n "$name="
  224. test -z "$value" && {
  225. echo -e -n "${red_colour}<empty>${no_colour} "
  226. } || {
  227. echo -e -n "${green_colour}${value}${no_colour} "
  228. }
  229. }
  230.  
  231. function report_os_expanded {
  232. echo_helptext "Detected/provided for your OS/distribution, version and architecture:"
  233. echo " >>>>:"
  234. report_os_values
  235. }
  236.  
  237. function report_os_values {
  238. echo -n " >>>>: ... "
  239. report_os_attribute "distro" $distro
  240. report_os_attribute "version" $version
  241. report_os_attribute "codename" $codename
  242. report_os_attribute "arch" $arch
  243. echo
  244. echo " >>>>:"
  245. }
  246.  
  247. function detect_os_legacy_python {
  248. check_os && return 0
  249.  
  250. local text="Detecting your OS distribution and release using legacy python ..."
  251. echo_running "$text"
  252.  
  253. IFS='' read -r -d '' script <<-'EOF'
  254. from __future__ import unicode_literals, print_function
  255. import platform;
  256. info = platform.linux_distribution() or ('', '', '');
  257. for key, value in zip(('distro', 'version', 'codename'), info):
  258. print("local guess_%s=\"%s\"\n" % (key, value.lower().replace(' ', '')));
  259. EOF
  260.  
  261. local tool_rc=1
  262. check_tool_silent "python" && {
  263. eval $(python -c "$script")
  264. distro=${distro:-$guess_distro}
  265. codename=${codename:-$guess_codename}
  266. version=${version:-$guess_version}
  267. tool_rc=$?
  268. }
  269.  
  270. check_os
  271. local rc=$?
  272. echo_okfail_rc $rc "$text"
  273.  
  274. check_tool_silent "python" || {
  275. echo_helptext "Python isn't available, so skipping detection method (hint: install python)"
  276. }
  277.  
  278. test $tool_rc -eq 0 && {
  279. report_os
  280. }
  281.  
  282. return $rc
  283. }
  284.  
  285. function detect_os_modern_python {
  286. check_os && return 0
  287.  
  288. check_tool_silent "python" && {
  289. local text="Ensuring python-pip is installed ..."
  290. echo_running "$text"
  291. check_tool_silent "pip"
  292. echo_okfail "$text" || {
  293. local text="Checking if pip can be bootstrapped without get-pip ..."
  294. echo_running "$text"
  295. python -m ensurepip --default-pip &>$tmp_log
  296. echo_okfail "$text" || {
  297. local text="Installing pip via get-pip bootstrap ..."
  298. echo_running "$text"
  299. curl -1sLf https://bootstrap.pypa.io/get-pip.py 2>$tmp/log | python &>$tmp_log
  300. echo_okfail "$text" || die "Failed to install pip!"
  301. }
  302. }
  303.  
  304. # FIXME(ls): Install distro into a temporary virtualenv
  305. local text="Installing 'distro' python library ..."
  306. echo_running "$text"
  307. python -c 'import distro' &>$tmp_log || python -m pip install distro &>$tmp_log
  308. echo_okfail "$text" || die "Failed to install required 'distro' python library!"
  309. }
  310.  
  311. IFS='' read -r -d '' script <<-'EOF'
  312. from __future__ import unicode_literals, print_function
  313. import distro;
  314. info = distro.linux_distribution(full_distribution_name=False) or ('', '', '');
  315. for key, value in zip(('distro', 'version', 'codename'), info):
  316. print("local guess_%s=\"%s\"\n" % (key, value.lower().replace(' ', '')));
  317. EOF
  318.  
  319. local text="Detecting your OS distribution and release using modern python ..."
  320. echo_running "$text"
  321.  
  322. local tool_rc=1
  323. check_tool_silent "python" && {
  324. eval $(python -c "$script")
  325. distro=${distro:-$guess_distro}
  326. codename=${codename:-$guess_codename}
  327. version=${version:-$guess_version}
  328. tool_rc=$?
  329. }
  330.  
  331. check_os
  332. local rc=$?
  333. echo_okfail_rc $rc "$text"
  334.  
  335. check_tool_silent "python" || {
  336. echo_helptext "Python isn't available, so skipping detection method (hint: install python)"
  337. }
  338.  
  339. test $tool_rc -eq 0 && {
  340. report_os_expanded
  341. }
  342.  
  343. return $rc
  344. }
  345.  
  346. function detect_os {
  347. # Backwards compat for old distribution parameter names
  348. distro=${distro:-$os}
  349. codename=${codename:-$dist}
  350.  
  351. arch=${arch:-$(arch || uname -m)}
  352.  
  353. detect_os_system ||
  354. detect_os_legacy_python ||
  355. detect_os_modern_python
  356.  
  357. (test -z "$distro" || test -z "${version}${codename}") && {
  358. echo_okfail_rc "1" "Unable to detect your OS distribution and/or release!"
  359. cat <<EOF
  360. >>>>:
  361. >>>>: The 'distro' value is required, and either 'version' or 'codename' values,
  362. >>>>: or both. Without these, the install script cannot retrieve the correct
  363. >>>>: configuration for this system.
  364. >>>>:
  365. >>>>: You can force this script to use a particular value by specifying distro,
  366. >>>>: version, or codename via environment variable. E.g., to specify a distro
  367. >>>>: such as $example_name, use the following:
  368. >>>>:
  369. >>>>: $prefix distro=$example_distro version=$example_version codename=$example_codename $self
  370. >>>>:
  371. EOF
  372. die
  373. }
  374. }
  375.  
  376.  
  377. function config_url {
  378. echo "https://dl.cloudsmith.io/public/balena/etcher/config.deb.txt?distro=${distro}&codename=${codename}&version=${version}&arch=${arch}" | sed 's/ /%20/g'
  379. }
  380.  
  381. function check_fetch_config {
  382. local text="Checking if upstream install config is OK ..."
  383. echo_running "$text"
  384. local code="$(curl -1IsL -w "%{http_code}\\n" "$(config_url)" -o /dev/null --connect-timeout 15 --max-time 60)"
  385. test "$code" == "200" && {
  386. echo_okfail_rc 0 "$text"
  387. return 0
  388. } || {
  389. echo_okfail_rc 1 "$text"
  390. echo_helptext "Failed to fetch configuration for your OS distribution release/version."
  391. cat <<EOF
  392. >>>>:
  393. EOF
  394. test "$code" == "404" && {
  395. cat <<EOF
  396. >>>>: It looks like we don't currently support your distribution release and
  397. >>>>: version. This is something that we can fix by adding it to our list of
  398. >>>>: supported versions (see contact us below), or you can manually override
  399. >>>>: the values below to an equivalent distribution that we do support:
  400. >>>>:
  401. EOF
  402. report_os_values
  403. } || {
  404. cat <<EOF
  405. >>>>: It looks like it might be because the configuration endpoint is not
  406. >>>>: currently available. Please try again in 10-15 minutes. If it still
  407. >>>>: doesn't work after an hour, please contact balena
  408. >>>>: for assistance.
  409. >>>>:
  410. EOF
  411. }
  412.  
  413. cat <<EOF
  414. >>>>: You can force this script to use a particular value by specifying distro,
  415. >>>>: version, or codename via environment variable. E.g., to specify a distro
  416. >>>>: such as $example_name, use the following:
  417. >>>>:
  418. >>>>: $prefix distro=$example_distro version=$example_version codename=$example_codename $self
  419. >>>>:
  420. EOF
  421. die
  422. }
  423. }
  424.  
  425. function fetch_config {
  426. curl -1sLf "$(config_url)"
  427. }
  428.  
  429.  
  430. function check_dpkg_tool {
  431. local tool=${1}
  432. local required=${2:-true}
  433. local install=${3:-true}
  434.  
  435. local text="Checking for apt dependency '$tool' ..."
  436. echo_running "$text"
  437. dpkg -l | grep "$tool\>" &>$tmp_log
  438. echo_okfail "$text" || {
  439. if $install; then
  440. test "$apt_updated" == "yes" || update_apt
  441. local text="Attempting to install '$tool' ..."
  442. echo_running "$text"
  443. apt-get install -y "$tool" &>$tmp_log
  444. echo_okfail "$text" || {
  445. if $required; then
  446. die "Could not install '$tool', check your permissions, etc."
  447. fi
  448. }
  449. else
  450. if $required; then
  451. die "$tool is not installed, but is required by this script."
  452. fi
  453. fi
  454. }
  455. return 0
  456. }
  457.  
  458. function update_apt {
  459. local text="Updating apt repository metadata cache ..."
  460. local tmp_log=$(mktemp .csm_deb_output_XXXXXXXXX.log)
  461. echo_running "$text"
  462. apt-get update &>$tmp_log
  463. echo_okfail "$text" || {
  464. echo_colour "red" "Failed to update via apt-get update"
  465. cat $tmp_log
  466. rm -rf $tmp_log
  467. die "Failed to update via apt-get update - Context above."
  468. }
  469. rm -rf $tmp_log
  470. apt_updated="yes"
  471. }
  472.  
  473. function install_apt_prereqs {
  474. # Debian-archive-keyring has to be installed for apt-transport-https.
  475. test "${os}" == "debian" && {
  476. check_dpkg_tool "debian-keyring"
  477. check_dpkg_tool "debian-archive-keyring"
  478. }
  479.  
  480. check_dpkg_tool "apt-transport-https"
  481. check_dpkg_tool "ca-certificates" false
  482. check_dpkg_tool "gnupg"
  483. }
  484.  
  485. function import_gpg_key {
  486. local text="Importing 'balena/etcher' repository GPG key into apt ..."
  487. echo_running "$text"
  488. curl -1sLf "https://dl.cloudsmith.io/public/balena/etcher/gpg.70528471AFF9A051.key" | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/balena_etcher.gpg - &>$tmp_log
  489. echo_okfail "$text" || die "Could not import the GPG key for this repository"
  490. }
  491.  
  492. function setup_repository {
  493. local repo_path="/etc/apt/sources.list.d/balena-etcher.list"
  494. check_fetch_config
  495.  
  496. local text="Installing 'balena/etcher' repository via apt ..."
  497. echo_running "$text"
  498. fetch_config > "$repo_path"
  499. echo_okfail "$text" || die "Could not install the repository, do you have permissions?"
  500. }
  501.  
  502.  
  503.  
  504. function usage () {
  505. cat <<EOF
  506. Usage: $self [opts]
  507. -h Displays this usage text.
  508. -i Ignore repository setup errors during setup and
  509. continue with install. This will leave the repository config
  510. in place rather than removing it upon errors.
  511. EOF
  512. exit 0
  513. }
  514.  
  515.  
  516. trap cleanup EXIT
  517. trap shutdown INT
  518.  
  519.  
  520.  
  521. ignore_errors=1
  522.  
  523. apt_updated="no"
  524.  
  525.  
  526.  
  527. while getopts ":ih" OPT; do
  528. case $OPT in
  529. i) ignore_errors=0 ;;
  530. h) usage ;;
  531. \?) usage ;;
  532. esac
  533. done
  534. shift $(($OPTIND - 1))
  535.  
  536.  
  537. #
  538. # MAIN
  539. #
  540.  
  541. echo "Executing the setup script for the 'balena/etcher' repository ..."
  542. echo
  543.  
  544.  
  545.  
  546. check_tool "curl"
  547.  
  548. check_tool "apt-get"
  549.  
  550.  
  551.  
  552. detect_os
  553.  
  554. install_apt_prereqs
  555. import_gpg_key
  556. setup_repository
  557. update_apt
  558.  
  559.  
  560. echo_okfail_rc "0" "The repository has been installed successfully - You're ready to rock!"
  561.  
Add Comment
Please, Sign In to add comment