|
1 | | -#! /usr/bin/env bash |
| 1 | +#! /bin/sh |
2 | 2 |
|
3 | | -# ----------------------------------------------- |
4 | | -# ---- Prologue ------------------------------- |
5 | | -# ----------------------------------------------- |
| 3 | +set -e |
6 | 4 |
|
7 | | -set -eE -u -o pipefail |
8 | | -shopt -s inherit_errexit |
| 5 | +. /etc/os-release |
9 | 6 |
|
10 | | -CURRENT_DIR="$(realpath -eL "$(dirname "${BASH_SOURCE[0]}")")" |
11 | | -readonly CURRENT_DIR |
| 7 | +if [ "${ID}" = "alpine" ]; then |
| 8 | + apk add --no-cache bash |
| 9 | +fi |
12 | 10 |
|
13 | | -# shellcheck source=./common.sh |
14 | | -source "${CURRENT_DIR}/common.sh" |
15 | | - |
16 | | -readonly DATA_DIR="${DATA_BASE_DIR}/rust" |
17 | | -mkdir -p "${DATA_DIR}" |
18 | | - |
19 | | -# ----------------------------------------------- |
20 | | -# ---- Argument Parsing ----------------------- |
21 | | -# ----------------------------------------------- |
22 | | - |
23 | | -function parse_dev_container_options() { |
24 | | - log 'info' 'Parsing input from options' |
25 | | - |
26 | | - readonly RUST_INSTALL="${RUST_INSTALL:?RUST_INSTALL not set or null}" |
27 | | - readonly RUST_INSTALL_BASE_PACKAGES="${RUST_INSTALL_BASE_PACKAGES:?RUST_INSTALL_BASE_PACKAGES not set or null}" |
28 | | - readonly RUST_RUSTUP_DEFAULT_TOOLCHAIN=${RUST_RUSTUP_DEFAULT_TOOLCHAIN:?RUST_RUSTUP_DEFAULT_TOOLCHAIN not set or null} |
29 | | - readonly RUST_RUSTUP_DEFAULT_TOOLCHAIN_FILE=${RUST_RUSTUP_DEFAULT_TOOLCHAIN_FILE?RUST_RUSTUP_DEFAULT_TOOLCHAIN_FILE not set} |
30 | | - readonly RUST_RUSTUP_UPDATE_DEFAULT_TOOLCHAIN=${RUST_RUSTUP_UPDATE_DEFAULT_TOOLCHAIN:?RUST_RUSTUP_UPDATE_DEFAULT_TOOLCHAIN not set or null} |
31 | | - readonly RUST_RUSTUP_PROFILE=${RUST_RUSTUP_PROFILE:?RUST_RUSTUP_PROFILE not set or null} |
32 | | - readonly RUST_RUSTUP_ADDITIONAL_TARGETS=${RUST_RUSTUP_ADDITIONAL_TARGETS?RUST_RUSTUP_ADDITIONAL_TARGETS not set} |
33 | | - readonly RUST_RUSTUP_ADDITIONAL_COMPONENTS=${RUST_RUSTUP_ADDITIONAL_COMPONENTS?RUST_RUSTUP_ADDITIONAL_COMPONENTS not set} |
34 | | - readonly RUST_RUSTUP_DIST_SERVER=${RUST_RUSTUP_DIST_SERVER:?RUST_RUSTUP_DIST_SERVER not set or null} |
35 | | - readonly RUST_RUSTUP_UPDATE_ROOT=${RUST_RUSTUP_UPDATE_ROOT:?RUST_RUSTUP_UPDATE_ROOT not set or null} |
36 | | - RUST_RUSTUP_RUSTUP_INIT_HOST_TRIPLE=${RUST_RUSTUP_RUSTUP_INIT_HOST_TRIPLE?RUST_RUSTUP_RUSTUP_INIT_HOST_TRIPLE not set or null} |
37 | | - |
38 | | - readonly SYSTEM_PACKAGES_PACKAGE_MANAGER_SET_PROXIES=${SYSTEM_PACKAGES_PACKAGE_MANAGER_SET_PROXIES:?SYSTEM_PACKAGES_PACKAGE_MANAGER_SET_PROXIES not set or null} |
39 | | - readonly SYSTEM_PACKAGES_ADDITIONAL_PACKAGES="${SYSTEM_PACKAGES_ADDITIONAL_PACKAGES?SYSTEM_PACKAGES_ADDITIONAL_PACKAGES not set}" |
40 | | - |
41 | | - readonly LINKER_MOLD_INSTALL=${LINKER_MOLD_INSTALL:?LINKER_MOLD_INSTALL not set or null} |
42 | | - readonly LINKER_MOLD_VERSION=${LINKER_MOLD_VERSION?LINKER_MOLD_VERSION not set} |
43 | | - |
44 | | - readonly DOWNLOAD_ACQUIRE_INSECURE="${DOWNLOAD_ACQUIRE_INSECURE:?DOWNLOAD_ACQUIRE_INSECURE set or null}" |
45 | | - |
46 | | - [[ -v http_proxy ]] || export http_proxy=${PROXY_HTTP_HTTP_ADDRESS?PROXY_HTTP_HTTP_ADDRESS not set} |
47 | | - [[ -v https_proxy ]] || export https_proxy=${PROXY_HTTP_HTTPS_ADDRESS?PROXY_HTTP_HTTPS_ADDRESS not set} |
48 | | - [[ -v no_proxy ]] || export no_proxy=${PROXY_HTTP_NO_PROXY_ADDRESS?PROXY_HTTP_NO_PROXY_ADDRESS not set} |
49 | | - |
50 | | - return 0 |
51 | | -} |
52 | | - |
53 | | -# ----------------------------------------------- |
54 | | -# ---- Pre-Flight Checks ---------------------- |
55 | | -# ----------------------------------------------- |
56 | | - |
57 | | -function pre_flight_checks() { |
58 | | - log 'info' 'Running pre-flight checks' |
59 | | - |
60 | | - case "${LINUX_DISTRIBUTION_NAME}" in |
61 | | - ( 'debian' ) |
62 | | - if value_is_true SYSTEM_PACKAGES_PACKAGE_MANAGER_SET_PROXIES; then |
63 | | - log 'debug' 'Setting proxies for APT' |
64 | | - local APT_CONFIG_FILE='/etc/apt/apt.conf' ; readonly APT_CONFIG_FILE |
65 | | - mkdir --parents "$(dirname "${APT_CONFIG_FILE}")" |
66 | | - if [[ -n ${https_proxy} ]]; then |
67 | | - echo "Acquire::http::Proxy \"${https_proxy}\";" >>"${APT_CONFIG_FILE}" |
68 | | - elif [[ -n ${http_proxy} ]]; then |
69 | | - echo "Acquire::http::Proxy \"${http_proxy}\";" >>"${APT_CONFIG_FILE}" |
70 | | - fi |
71 | | - fi |
72 | | - |
73 | | - if value_is_true RUST_INSTALL_BASE_PACKAGES; then |
74 | | - log 'debug' 'Updating APT package index and installing required base packages' |
75 | | - apt-get --yes --quiet=2 --option=Dpkg::Use-Pty=0 update |
76 | | - apt-get --yes --quiet=2 --option=Dpkg::Use-Pty=0 install --no-install-recommends \ |
77 | | - 'build-essential' 'ca-certificates' 'curl' |
78 | | - fi |
79 | | - ;; |
80 | | - |
81 | | - ( * ) ;; |
82 | | - esac |
83 | | - |
84 | | - return 0 |
85 | | -} |
86 | | - |
87 | | -# ----------------------------------------------- |
88 | | -# ---- Actual Functionality ------------------- |
89 | | -# ----------------------------------------------- |
90 | | - |
91 | | -function install_additional_packages() { |
92 | | - if [[ -n ${SYSTEM_PACKAGES_ADDITIONAL_PACKAGES} ]]; then |
93 | | - local __SYSTEM_PACKAGES_ADDITIONAL_PACKAGES |
94 | | - IFS=',' read -r -a __SYSTEM_PACKAGES_ADDITIONAL_PACKAGES <<< "${SYSTEM_PACKAGES_ADDITIONAL_PACKAGES// /}" |
95 | | - |
96 | | - case "${LINUX_DISTRIBUTION_NAME}" in |
97 | | - ( 'debian' ) |
98 | | - log 'info' 'Installing additional packages via APT' |
99 | | - apt-get --yes --quiet=2 --option=Dpkg::Use-Pty=0 update |
100 | | - apt-get --yes --quiet=2 --option=Dpkg::Use-Pty=0 install --no-install-recommends \ |
101 | | - "${__SYSTEM_PACKAGES_ADDITIONAL_PACKAGES[@]}" |
102 | | - ;; |
103 | | - |
104 | | - ( * ) |
105 | | - log 'error' 'Distribution unknown - installing additional packages is not supported' |
106 | | - exit 1 |
107 | | - ;; |
108 | | - esac |
109 | | - fi |
110 | | - |
111 | | - return 0 |
112 | | -} |
113 | | - |
114 | | -function install_rustup() { |
115 | | - if ! value_is_true RUST_INSTALL; then |
116 | | - log 'info' 'Not installing rustup' |
117 | | - return 0 |
118 | | - fi |
119 | | - |
120 | | - log 'info' 'Installing rustup' |
121 | | - log 'debug' 'Setting installation environment variables' |
122 | | - # These directories contain metadata and files required by |
123 | | - # `rustup` (toolchain files, components, etc.) and `cargo` |
124 | | - # (crates, etc.). |
125 | | - export RUSTUP_HOME="${DATA_DIR}/rustup/home" |
126 | | - export CARGO_HOME="${DATA_DIR}/cargo/home" |
127 | | - |
128 | | - mkdir -p "${RUSTUP_HOME}" "${CARGO_HOME}" |
129 | | - |
130 | | - # These variables are used when acquiring and updating `rustup`. |
131 | | - export RUSTUP_DIST_SERVER |
132 | | - export RUST_RUSTUP_UPDATE_ROOT |
133 | | - |
134 | | - local RUSTUP_INSTALLER_ARGUMENTS=( |
135 | | - '-y' |
136 | | - '--no-modify-path' |
137 | | - '--default-toolchain' "${RUST_RUSTUP_DEFAULT_TOOLCHAIN}" |
138 | | - '--profile' "${RUST_RUSTUP_PROFILE}" |
139 | | - ) |
140 | | - |
141 | | - if ! value_is_true RUST_RUSTUP_UPDATE_DEFAULT_TOOLCHAIN; then |
142 | | - # do not update any existing default toolchain after install |
143 | | - log 'trace' 'Default toolchain will not be updated' |
144 | | - RUSTUP_INSTALLER_ARGUMENTS+=('--no-update-default-toolchain') |
145 | | - fi |
146 | | - |
147 | | - if [[ -z ${RUST_RUSTUP_RUSTUP_INIT_HOST_TRIPLE} ]]; then |
148 | | - RUST_RUSTUP_RUSTUP_INIT_HOST_TRIPLE="$(uname -m)-unknown-linux-gnu" |
149 | | - log 'debug' "Host triple set to '${RUST_RUSTUP_RUSTUP_INIT_HOST_TRIPLE}'" |
150 | | - fi |
151 | | - |
152 | | - if command -v curl &>/dev/null; then |
153 | | - DOWNLOAD_COMMAND=('curl' '--silent' '--show-error' '--location' '--fail') |
154 | | - value_is_true DOWNLOAD_ACQUIRE_INSECURE && DOWNLOAD_COMMAND+=('--insecure') |
155 | | - DOWNLOAD_COMMAND+=('--output' "${RUSTUP_HOME}/rustup-init") |
156 | | - elif command -v wget &>/dev/null; then |
157 | | - DOWNLOAD_COMMAND=('wget') |
158 | | - value_is_true DOWNLOAD_ACQUIRE_INSECURE && DOWNLOAD_COMMAND+=('--no-check-certificate') |
159 | | - DOWNLOAD_COMMAND+=("--output-document=${RUSTUP_HOME}/rustup-init") |
160 | | - else |
161 | | - log 'error' "Neither 'curl' nor 'wget' found, but required" |
162 | | - exit 1 |
163 | | - fi |
164 | | - |
165 | | - # This is the point where the actual installation takes place. |
166 | | - log 'debug' "Acquiring rustup-init" |
167 | | - "${DOWNLOAD_COMMAND[@]}" "${RUST_RUSTUP_UPDATE_ROOT}/dist/${RUST_RUSTUP_RUSTUP_INIT_HOST_TRIPLE}/rustup-init" |
168 | | - |
169 | | - log 'debug' "Installing rustup via rustup-init" |
170 | | - chmod +x "${RUSTUP_HOME}/rustup-init" |
171 | | - "${RUSTUP_HOME}/rustup-init" "${RUSTUP_INSTALLER_ARGUMENTS[@]}" |
172 | | - |
173 | | - # This commands exports a new PATH with `${CARGO_HOME}/bin` as an additional entry |
174 | | - # shellcheck source=/dev/null |
175 | | - source "${CARGO_HOME}/env" |
176 | | -} |
177 | | - |
178 | | -function additional_rust_setup() { |
179 | | - log 'info' 'Running additional setup steps now' |
180 | | - |
181 | | - log 'debug' 'Installing prettifier for LLDB' |
182 | | - cp "${CURRENT_DIR}/prettifier_for_lldb.py" "${DATA_DIR}/prettifier_for_lldb.py" |
183 | | - |
184 | | - if ! command -v rustup &>/dev/null; then |
185 | | - log 'warn' "Command 'rustup' could not be located but is required for the mojority of the additional setup steps" |
186 | | - return 0 |
187 | | - fi |
188 | | - |
189 | | - if [[ ${RUST_RUSTUP_DEFAULT_TOOLCHAIN} != 'none' ]]; then |
190 | | - log 'debug' "Setting default toolchain to '${RUST_RUSTUP_DEFAULT_TOOLCHAIN}'" |
191 | | - rustup default "${RUST_RUSTUP_DEFAULT_TOOLCHAIN}" |
192 | | - fi |
193 | | - |
194 | | - if [[ -n ${RUST_RUSTUP_ADDITIONAL_TARGETS} ]]; then |
195 | | - local __RUST_RUSTUP_ADDITIONAL_TARGETS |
196 | | - IFS=',' read -r -a __RUST_RUSTUP_ADDITIONAL_TARGETS <<< "${RUST_RUSTUP_ADDITIONAL_TARGETS// /}" |
197 | | - log 'debug' "Installing additional rustup targets: ${__RUST_RUSTUP_ADDITIONAL_TARGETS[*]}" |
198 | | - rustup target add "${__RUST_RUSTUP_ADDITIONAL_TARGETS[@]}" |
199 | | - fi |
200 | | - |
201 | | - if [[ -n ${RUST_RUSTUP_ADDITIONAL_COMPONENTS} ]]; then |
202 | | - local __RUST_RUSTUP_ADDITIONAL_COMPONENTS |
203 | | - IFS=',' read -r -a __RUST_RUSTUP_ADDITIONAL_COMPONENTS <<< "${RUST_RUSTUP_ADDITIONAL_COMPONENTS// /}" |
204 | | - log 'debug' "Adding additional rustup components: ${__RUST_RUSTUP_ADDITIONAL_COMPONENTS[*]}" |
205 | | - rustup component add "${__RUST_RUSTUP_ADDITIONAL_COMPONENTS[@]}" |
206 | | - fi |
207 | | - |
208 | | - log 'debug' 'Setting up bash completion' |
209 | | - mkdir -p /usr/share/bash-completion/completions |
210 | | - rustup completions bash >/usr/share/bash-completion/completions/rustup |
211 | | - rustup completions bash cargo >/usr/share/bash-completion/completions/cargo |
212 | | - |
213 | | - log 'trace' "Adjusting permissions for '${DATA_DIR}'" |
214 | | - chmod -R 777 "${DATA_DIR}" |
215 | | - |
216 | | - return 0 |
217 | | -} |
218 | | - |
219 | | -function linker_install_mold() { |
220 | | - value_is_true LINKER_MOLD_INSTALL || return 0 |
221 | | - log 'info' "Installing linker 'mold'" |
222 | | - |
223 | | - local MOLD_DIR |
224 | | - MOLD_DIR="mold-${LINKER_MOLD_VERSION}-$(uname -m)-linux" |
225 | | - |
226 | | - if command -v curl &>/dev/null; then |
227 | | - DOWNLOAD_COMMAND=('curl' '--silent' '--show-error' '--location' '--fail') |
228 | | - value_is_true DOWNLOAD_ACQUIRE_INSECURE && DOWNLOAD_COMMAND+=('--insecure') |
229 | | - elif command -v wget &>/dev/null; then |
230 | | - DOWNLOAD_COMMAND=('wget') |
231 | | - value_is_true DOWNLOAD_ACQUIRE_INSECURE && DOWNLOAD_COMMAND+=('--no-check-certificate') |
232 | | - else |
233 | | - log 'error' "Neither 'curl' nor 'wget' found but required for acquiring 'mold'" |
234 | | - exit 1 |
235 | | - fi |
236 | | - |
237 | | - "${DOWNLOAD_COMMAND[@]}" \ |
238 | | - "https://github.com/rui314/mold/releases/download/v${LINKER_MOLD_VERSION}/${MOLD_DIR}.tar.gz" \ |
239 | | - | tar xz -C /tmp |
240 | | - |
241 | | - cp "/tmp/${MOLD_DIR}/"{bin/{mold,ld.mold},lib/mold/mold-wrapper.so} /usr/local/bin/ |
242 | | - rm -r "/tmp/${MOLD_DIR}" |
243 | | - |
244 | | - return 0 |
245 | | -} |
246 | | - |
247 | | -function setup_post_start_command() { |
248 | | - log 'info' 'Setting up postStartCommand script' |
249 | | - |
250 | | - local SCRIPT_FILE="${DATA_DIR}/post_start_command.sh" |
251 | | - readonly SCRIPT_FILE |
252 | | - |
253 | | - cp "${CURRENT_DIR}/post_start_command.sh" "${SCRIPT_FILE}" |
254 | | - sed --in-place \ |
255 | | - "s|RUST_RUSTUP_DEFAULT_TOOLCHAIN_FILE|${RUST_RUSTUP_DEFAULT_TOOLCHAIN_FILE}|g" \ |
256 | | - "${SCRIPT_FILE}" |
257 | | - chmod +x "${SCRIPT_FILE}" |
258 | | -} |
259 | | - |
260 | | -function main() { |
261 | | - parse_dev_container_options |
262 | | - parse_linux_distribution |
263 | | - pre_flight_checks |
264 | | - |
265 | | - install_additional_packages |
266 | | - install_rustup |
267 | | - additional_rust_setup |
268 | | - linker_install_mold |
269 | | - |
270 | | - setup_post_start_command |
271 | | -} |
272 | | - |
273 | | -main "${@}" |
| 11 | +exec /bin/bash "$(dirname "${0}")/install_actual.sh" "${@}" |
0 commit comments