diff --git a/image_build/rustup.sh b/image_build/rustup.sh new file mode 100755 index 0000000000000000000000000000000000000000..ae936e010362cc5869c79607997d1564ef06e9bf --- /dev/null +++ b/image_build/rustup.sh @@ -0,0 +1,402 @@ +#!/bin/bash +# Copyright 2018 The Rust Project Developers. See the COPYRIGHT +# Some fixes and directory change by Bob Mottram <bob@freedombone.net> +# file at the top-level directory of this distribution and at +# http://rust-lang.org/COPYRIGHT. +# +# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +# This is just a little script that can be downloaded from the internet to +# install rustup. It just does platform detection, downloads the installer +# and runs it. + +set -u + +RUSTUP_UPDATE_ROOT="https://static.rust-lang.org/rustup/dist" + +#XXX: If you change anything here, please make the same changes in setup_mode.rs +usage() { + cat 1>&2 <<EOF +rustup-init 1.0.0 (408ed84 2017-02-11) +The installer for rustup + +USAGE: + rustup-init [FLAGS] [OPTIONS] + +FLAGS: + -v, --verbose Enable verbose output + -y Disable confirmation prompt. + --no-modify-path Don't configure the PATH environment variable + -h, --help Prints help information + -V, --version Prints version information + +OPTIONS: + --default-host <default-host> Choose a default host triple + --default-toolchain <default-toolchain> Choose a default toolchain to install + --default-toolchain none Do not install any toolchains +EOF +} + +main() { + downloader --check + need_cmd uname + need_cmd mktemp + need_cmd chmod + need_cmd mkdir + need_cmd rm + need_cmd rmdir + + get_architecture || return 1 + local _arch="$RETVAL" + assert_nz "$_arch" "arch" + + local _ext="" + case "$_arch" in + *windows*) + _ext=".exe" + ;; + esac + + local _url="$RUSTUP_UPDATE_ROOT/$_arch/rustup-init$_ext" + + local _dir + _dir=/root/build/rustup + local _file="$_dir/rustup-init$_ext" + + local _ansi_escapes_are_valid=false + if [ -t 2 ]; then + if [ "${TERM+set}" = 'set' ]; then + case "$TERM" in + xterm*|rxvt*|urxvt*|linux*|vt*) + _ansi_escapes_are_valid=true + ;; + esac + fi + fi + + # check if we have to use /dev/tty to prompt the user + local need_tty=yes + for arg in "$@"; do + case "$arg" in + -h|--help) + usage + exit 0 + ;; + -y) + # user wants to skip the prompt -- we don't need /dev/tty + need_tty=no + ;; + *) + ;; + esac + done + + if $_ansi_escapes_are_valid; then + printf "\33[1minfo:\33[0m downloading installer\n" 1>&2 + else + printf '%s\n' 'info: downloading installer' 1>&2 + fi + + ensure mkdir -p "$_dir" + ensure downloader "$_url" "$_file" + ensure chmod u+x "$_file" + if [ ! -x "$_file" ]; then + printf '%s\n' "Cannot execute $_file (likely because of mounting /root/build/rustup as noexec)." 1>&2 + printf '%s\n' "Please copy the file to a location where you can execute binaries and run ./rustup-init$_ext." 1>&2 + exit 1 + fi + + + + if [ "$need_tty" = "yes" ]; then + # The installer is going to want to ask for confirmation by + # reading stdin. This script was piped into `sh` though and + # doesn't have stdin to pass to its children. Instead we're going + # to explicitly connect /dev/tty to the installer's stdin. + if [ ! -t 1 ]; then + err "Unable to run interactively. Run with -y to accept defaults, --help for additional options" + fi + + ignore "$_file" "$@" < /dev/tty + else + ignore "$_file" "$@" + fi + + local _retval=$? + + ignore rm "$_file" + ignore rmdir "$_dir" + + return "$_retval" +} + +get_bitness() { + need_cmd head + # Architecture detection without dependencies beyond coreutils. + # ELF files start out "\x7fELF", and the following byte is + # 0x01 for 32-bit and + # 0x02 for 64-bit. + # The printf builtin on some shells like dash only supports octal + # escape sequences, so we use those. + local _current_exe_head + _current_exe_head=$(head -c 5 /proc/self/exe ) + if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then + echo 32 + elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then + echo 64 + else + err "unknown platform bitness" + fi +} + +get_endianness() { + local cputype=$1 + local suffix_eb=$2 + local suffix_el=$3 + + # detect endianness without od/hexdump, like get_bitness() does. + need_cmd head + need_cmd tail + + local _current_exe_endianness + _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)" + if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then + echo "${cputype}${suffix_el}" + elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then + echo "${cputype}${suffix_eb}" + else + err "unknown platform endianness" + fi +} + +get_architecture() { + + local _ostype + local _cputype + _ostype="$(uname -s)" + _cputype="$(uname -m)" + + if [ "$_ostype" = Linux ]; then + if [ "$(uname -o)" = Android ]; then + local _ostype=Android + fi + fi + + if [ "$_ostype" = Darwin ]; then + if [ "$_cputype" = i386 ]; then + # Darwin `uname -s` lies + if sysctl hw.optional.x86_64 | grep -q ': 1'; then + local _cputype=x86_64 + fi + fi + fi + + case "$_ostype" in + + Android) + local _ostype=linux-android + ;; + + Linux) + local _ostype=unknown-linux-gnu + ;; + + FreeBSD) + local _ostype=unknown-freebsd + ;; + + NetBSD) + local _ostype=unknown-netbsd + ;; + + DragonFly) + local _ostype=unknown-dragonfly + ;; + + Darwin) + local _ostype=apple-darwin + ;; + + MINGW* | MSYS* | CYGWIN*) + local _ostype=pc-windows-gnu + ;; + + *) + err "unrecognized OS type: $_ostype" + ;; + + esac + + case "$_cputype" in + + i386 | i486 | i686 | i786 | x86) + local _cputype=i686 + ;; + + xscale | arm) + local _cputype=arm + if [ "$_ostype" = "linux-android" ]; then + local _ostype=linux-androideabi + fi + ;; + + armv6l) + local _cputype=arm + if [ "$_ostype" = "linux-android" ]; then + local _ostype=linux-androideabi + else + local _ostype="${_ostype}eabihf" + fi + ;; + + armv7l | armv8l) + local _cputype=armv7 + if [ "$_ostype" = "linux-android" ]; then + local _ostype=linux-androideabi + else + local _ostype="${_ostype}eabihf" + fi + ;; + + aarch64) + local _cputype=aarch64 + ;; + + x86_64 | x86-64 | x64 | amd64) + local _cputype=x86_64 + ;; + + mips) + local _cputype + _cputype="$(get_endianness $_cputype "" 'el')" + ;; + + mips64) + local _bitness + _bitness="$(get_bitness)" + if [ "$_bitness" = "32" ]; then + if [ $_ostype = "unknown-linux-gnu" ]; then + # 64-bit kernel with 32-bit userland + # endianness suffix is appended later + local _cputype=mips + fi + else + # only n64 ABI is supported for now + local _ostype="${_ostype}abi64" + fi + + local _cputype + _cputype="$(get_endianness $_cputype "" 'el')" + ;; + + ppc) + local _cputype=powerpc + ;; + + ppc64) + local _cputype=powerpc64 + ;; + + ppc64le) + local _cputype=powerpc64le + ;; + + *) + err "unknown CPU type: $_cputype" + + esac + + # Detect 64-bit linux with 32-bit userland + if [ $_ostype = unknown-linux-gnu ]; then + if [ $_cputype = x86_64 ]; then + if [ "$(get_bitness)" = "32" ]; then + local _cputype=i686 + fi + fi + fi + + # Detect armv7 but without the CPU features Rust needs in that build, + # and fall back to arm. + # See https://github.com/rust-lang/rustup.rs/issues/587. + if [ $_ostype = "unknown-linux-gnueabihf" ]; then + if [ $_cputype = armv7 ]; then + if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then + # At least one processor does not have NEON. + local _cputype=arm + fi + fi + fi + + local _arch="$_cputype-$_ostype" + + RETVAL="$_arch" +} + +say() { + echo "rustup: $1" +} + +err() { + say "$1" >&2 + exit 1 +} + +need_cmd() { + if ! check_cmd "$1" + then err "need '$1' (command not found)" + fi +} + +check_cmd() { + command -v "$1" > /dev/null 2>&1 + return $? +} + +need_ok() { + if [ $? != 0 ]; then err "$1"; fi +} + +assert_nz() { + if [ -z "$1" ]; then err "assert_nz $2"; fi +} + +# Run a command that should never fail. If the command fails execution +# will immediately terminate with an error showing the failing +# command. +ensure() { + "$@" + need_ok "command failed: $*" +} + +# This is just for indicating that commands' results are being +# intentionally ignored. Usually, because it's being executed +# as part of error handling. +ignore() { + "$@" +} + +# This wraps curl or wget. Try curl first, if not installed, +# use wget instead. +downloader() { + if check_cmd curl + then _dld=curl + elif check_cmd wget + then _dld=wget + else _dld='curl or wget' # to be used in error message of need_cmd + fi + + if [ "$1" = --check ] + then need_cmd "$_dld" + elif [ "$_dld" = curl ] + then curl -sSfL "$1" -o "$2" + elif [ "$_dld" = wget ] + then wget "$1" -O "$2" + else err "Unknown downloader" # should not reach here + fi +} + +main "$@" || exit 1 diff --git a/src/freedombone-image-customise b/src/freedombone-image-customise index f0adc524ce32e63bbf8987357cf299568b211b0a..89e096cb8bdab65c0e0914faf540048e2df776c5 100755 --- a/src/freedombone-image-customise +++ b/src/freedombone-image-customise @@ -2319,6 +2319,7 @@ image_setup_utils image_install_inadyn if [[ $VARIANT != "mesh"* ]]; then image_install_web_server + install_rust fi image_install_web_admin image_install_pleroma diff --git a/src/freedombone-utils-rust b/src/freedombone-utils-rust new file mode 100755 index 0000000000000000000000000000000000000000..004941eca514fcc738eb6c535b8a085970894472 --- /dev/null +++ b/src/freedombone-utils-rust @@ -0,0 +1,63 @@ +#!/bin/bash +# _____ _ _ +# | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___ +# | __| _| -_| -_| . | . | | . | . | | -_| +# |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___| +# +# Freedom in the Cloud +# +# Rust language helper functions +# +# License +# ======= +# +# Copyright (C) 2018 Bob Mottram <bob@freedombone.net> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +function install_rust { + if [ ! "$INSTALL_DIR" ]; then + echo $'No install directory specified' + exit 35435 + fi + + if [ ! -d "$rootdir$INSTALL_DIR" ]; then + mkdir -p "$rootdir$INSTALL_DIR" + fi + + if [ ! -f "$rootdir$INSTALL_DIR/rustup.sh" ]; then + if [ -f "$rootdir/root/${PROJECT_NAME}/image_build/rustup.sh" ]; then + cp "$rootdir/root/${PROJECT_NAME}/image_build/rustup.sh" "$rootdir$INSTALL_DIR" + else + if [ -f "$rootdir/home/${MY_USERNAME}/${PROJECT_NAME}/image_build/rustup.sh" ]; then + cp "$rootdir/home/${MY_USERNAME}/${PROJECT_NAME}/image_build/rustup.sh" "$rootdir$INSTALL_DIR" + fi + fi + fi + + if [ ! -f "$rootdir$INSTALL_DIR/rustup.sh" ]; then + exit 4687365 + fi + + cd "$rootdir$INSTALL_DIR" || exit 234682 + chmod +x "$rootdir$INSTALL_DIR/rustup.sh" + + if [ ! "$rootdir" ]; then + ."$rootdir$INSTALL_DIR/rustup.sh" -y + else + chroot "$rootdir" ."$INSTALL_DIR/rustup.sh" -y + fi +} + +# NOTE: deliberately there is no "exit 0" diff --git a/src/freedombone-utils-setup b/src/freedombone-utils-setup index ba638194082a306f276a9aad3f78d397e1568d89..10fbbbd3c346f0d19f0b8c909985161538928bec 100755 --- a/src/freedombone-utils-setup +++ b/src/freedombone-utils-setup @@ -1132,6 +1132,9 @@ function setup_utils { function_check configure_cpu_monitor configure_cpu_monitor + + function_check install_rust + install_rust } function setup_email {