mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
While it is unusual to run both NetworkManager and systemd-networkd simultaneiously and doing so can cause startup problems, there is nothing inherently wrong with doing so: the services are not incompatible and some people run both, each managing different interfaces. The Armbian build framework enables one or the other but not both. Therefore, if both are enabled at first login, it is probably because the user has manually modified the image. In this case, trust that the user knows what they are doing and don't disable one of them.
976 lines
33 KiB
Bash
Executable File
976 lines
33 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Copyright (c) Authors: https://www.armbian.com/authors
|
|
#
|
|
# This file is licensed under the terms of the GNU General Public
|
|
# License version 2. This program is licensed "as is" without any
|
|
# warranty of any kind, whether express or implied.
|
|
|
|
# read distribution status
|
|
# shellcheck source=/dev/null
|
|
[[ -f /etc/lsb-release ]] && . /etc/lsb-release
|
|
[[ -f /etc/os-release ]] && . /etc/os-release
|
|
[[ -z "$DISTRIB_CODENAME" ]] && DISTRIB_CODENAME="${VERSION_CODENAME}"
|
|
[[ -n "$DISTRIB_CODENAME" && -f /etc/armbian-distribution-status ]] && DISTRIBUTION_STATUS=$(grep "^$DISTRIB_CODENAME" /etc/armbian-distribution-status | cut -d"=" -f2 | cut -d";" -f1)
|
|
|
|
. /etc/armbian-release
|
|
|
|
check_abort() {
|
|
|
|
echo -e "\nDisabling user account creation procedure\n"
|
|
rm -f /root/.not_logged_in_yet
|
|
if [[ ${USER_SHELL} == zsh ]]; then
|
|
printf "\nYou selected \e[0;91mZSH\x1B[0m as your default shell. If you want to use it right away, please logout and login! \n\n"
|
|
fi
|
|
trap - INT
|
|
exit 0
|
|
|
|
}
|
|
|
|
mask2cidr() {
|
|
nbits=0
|
|
IFS=.
|
|
for dec in $1 ; do
|
|
case $dec in
|
|
255) let nbits+=8;;
|
|
254) let nbits+=7;;
|
|
252) let nbits+=6;;
|
|
248) let nbits+=5;;
|
|
240) let nbits+=4;;
|
|
224) let nbits+=3;;
|
|
192) let nbits+=2;;
|
|
128) let nbits+=1;;
|
|
0);;
|
|
*) echo "Error: $dec is not recognised"; exit 1
|
|
esac
|
|
done
|
|
echo "$nbits"
|
|
}
|
|
|
|
createYAML() {
|
|
local YAML="network:\n"
|
|
YAML+=" $DEVTYPE:\n"
|
|
YAML+=" $DEVICE_NAME:\n"
|
|
if [[ "${PRESET_NET_USE_STATIC}" == 0 ]]; then YAML+=" dhcp4: yes\n";fi
|
|
if [[ "${PRESET_NET_USE_STATIC}" == 0 ]]; then YAML+=" dhcp6: yes\n";fi
|
|
if [[ "${PRESET_NET_USE_STATIC}" == 1 ]]; then
|
|
YAML+=" addresses:\n"
|
|
YAML+=" - $PRESET_NET_STATIC_IP/$PRESET_NET_STATIC_MASK\n"
|
|
if [[ -n "${PRESET_NET_STATIC_GATEWAY}" ]]; then YAML+=" routes:\n";fi
|
|
if [[ -n "${PRESET_NET_STATIC_GATEWAY}" ]]; then YAML+=" - to: default\n";fi
|
|
if [[ -n "${PRESET_NET_STATIC_GATEWAY}" ]]; then YAML+=" via: ${PRESET_NET_STATIC_GATEWAY}\n";fi
|
|
if [[ -n "${PRESET_NET_STATIC_DNS}" ]]; then YAML+=" nameservers:\n"; fi
|
|
if [[ -n "${PRESET_NET_STATIC_DNS}" ]]; then YAML+=" addresses: [$PRESET_NET_STATIC_DNS]\n"; fi
|
|
fi
|
|
if [[ "${PRESET_NET_WIFI_ENABLED}" == 1 ]]; then
|
|
if [[ -n "${PRESET_NET_WIFI_COUNTRYCODE}" ]]; then YAML+=" regulatory-domain: $PRESET_NET_WIFI_COUNTRYCODE\n"; fi
|
|
if [[ -n "${PRESET_NET_WIFI_SSID}" ]]; then YAML+=" access-points:\n"; fi
|
|
if [[ -n "${PRESET_NET_WIFI_SSID}" ]]; then YAML+=" \"$PRESET_NET_WIFI_SSID\":\n"; fi
|
|
if [[ -n "${PRESET_NET_WIFI_KEY}" ]]; then YAML+=" password: \"$PRESET_NET_WIFI_KEY\"\n" ; fi
|
|
fi
|
|
printf "%s" "$YAML"
|
|
}
|
|
|
|
do_firstrun_automated_network_configuration()
|
|
{
|
|
#-----------------------------------------------------------------------------
|
|
#Config FP
|
|
local fp_config='/root/.not_logged_in_yet'
|
|
|
|
#-----------------------------------------------------------------------------
|
|
#Grab user requested settings
|
|
if [[ -f $fp_config ]]; then
|
|
|
|
# Convert line endings to Unix from Dos
|
|
sed -i $'s/\r$//' "$fp_config"
|
|
|
|
# check syntax
|
|
bash -n "$fp_config" || return
|
|
|
|
# Load vars directly from file
|
|
source "$fp_config"
|
|
|
|
# Obtain backward configuration compatibility
|
|
PRESET_NET_STATIC_DNS=${PRESET_NET_STATIC_DNS// /,}
|
|
PRESET_NET_STATIC_MASK=$(mask2cidr $PRESET_NET_STATIC_MASK)
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Set Network
|
|
if [[ $PRESET_NET_CHANGE_DEFAULTS == 1 ]]; then
|
|
|
|
# - Get name of 1st available ethernet and wifi adapter
|
|
eth_index="$(ip link | awk -F: '$0 !~ "lo|vir|wl|^[^0-9]"{print $2;getline}' | sed 's/^[ \t]*//' | grep "^e" | head -1)"
|
|
wlan_index="$(iw dev | awk '$1=="Interface"{print $2}' | head -n 1)"
|
|
|
|
local CONFIG_NAME="-dhcp"
|
|
# for static IP we only append settings
|
|
if [[ $PRESET_NET_USE_STATIC == 1 ]]; then
|
|
local CONFIG_NAME="-static"
|
|
fi
|
|
|
|
# at least one device has to exits
|
|
if [[ -n $eth_index || -n $wlan_index ]]; then
|
|
|
|
# - Wifi enable
|
|
if [[ $PRESET_NET_WIFI_ENABLED == 1 ]]; then
|
|
|
|
DEVICE_NAME=${wlan_index}
|
|
DEVTYPE=wifis
|
|
echo -e "$(createYAML)" > /etc/netplan/30-${DEVTYPE}${CONFIG_NAME}.yaml
|
|
chmod 600 /etc/netplan/30-${DEVTYPE}${CONFIG_NAME}.yaml
|
|
#Enable Wlan, disable Eth
|
|
PRESET_NET_ETHERNET_ENABLED=0
|
|
netplan apply > /dev/null 2>&1
|
|
|
|
# - Ethernet enable
|
|
elif [[ $PRESET_NET_ETHERNET_ENABLED == 1 ]]; then
|
|
|
|
# remove dhcp config
|
|
rm -f /etc/netplan/10-dhcp-all-interfaces.yaml
|
|
|
|
DEVICE_NAME=${eth_index}
|
|
DEVTYPE=ethernets
|
|
echo -e "$(createYAML)" > /etc/netplan/30-${DEVTYPE}${CONFIG_NAME}.yaml
|
|
chmod 600 /etc/netplan/30-${DEVTYPE}${CONFIG_NAME}.yaml
|
|
# Enable Eth, disable Wlan
|
|
PRESET_NET_WIFI_ENABLED=0
|
|
netplan apply > /dev/null 2>&1
|
|
fi
|
|
|
|
fi
|
|
fi
|
|
fi
|
|
} #do_firstrun_automated_network_configuration
|
|
|
|
# Try to retrieve the local IP address to display
|
|
get_local_ip_addr() {
|
|
# How many seconds to wait at maximum to find out the local IP address
|
|
local ip_wait_seconds_counter=6
|
|
local local_device_ip=""
|
|
local retry_message=""
|
|
|
|
while [[ -z "$local_device_ip" ]] && [ ${ip_wait_seconds_counter} -ge 0 ]; do
|
|
local_device_ip=$(ip -4 addr show scope global | grep inet | awk '{print $2}' | cut -d/ -f1 | awk '{$1=$1}1' FS='\n' OFS=',' RS=)
|
|
|
|
# Set retry message if some retries are left, but no IP address has been found yet
|
|
if [[ -z "$local_device_ip" ]] && [[ $ip_wait_seconds_counter -gt 0 ]]; then
|
|
retry_message="\e[1m\e[97mWaiting for local connection!\x1B[0m Retrying... (${ip_wait_seconds_counter})"
|
|
# Empty retry message if IP address has been found
|
|
elif [[ -n "$local_device_ip" ]]; then
|
|
retry_message=""
|
|
# Set timeout message if no retries are left and no IP address has been found
|
|
else
|
|
retry_message="\e[1m\e[31mNetwork connection timeout!\x1B[0m"
|
|
fi
|
|
|
|
# Display the message
|
|
echo -e "\e[1A\e[KIP address: \x1B[92m${local_device_ip}\x1B[0m ${retry_message}"
|
|
|
|
# Wait for 1 second if the IP has not yet been found
|
|
if [[ -z "$local_device_ip" ]]; then
|
|
sleep 1
|
|
fi
|
|
|
|
ip_wait_seconds_counter=$((ip_wait_seconds_counter - 1))
|
|
done
|
|
}
|
|
|
|
read_password() {
|
|
|
|
unset password
|
|
unset charcount
|
|
prompt="$1 password: "
|
|
|
|
stty -echo
|
|
|
|
charcount=0
|
|
while IFS= read -p "$prompt" -r -s -n 1 char; do
|
|
if [[ $char == $'\0' ]]; then
|
|
break
|
|
fi
|
|
|
|
# Handle backspace
|
|
if [[ $char == $'\177' ]]; then
|
|
if [ $charcount -gt 0 ]; then
|
|
charcount=$((charcount - 1))
|
|
prompt=$'\b \b'
|
|
password="${password%?}"
|
|
else
|
|
prompt=''
|
|
fi
|
|
else
|
|
charcount=$((charcount + 1))
|
|
prompt='*'
|
|
password+="$char"
|
|
fi
|
|
done
|
|
|
|
stty echo
|
|
|
|
}
|
|
|
|
set_shell() {
|
|
|
|
readarray -t optionsAudits <<< "$(grep "zsh\|/bash" /etc/shells | sed 's/\/bin\///g' | sed 's/\/usr//g' | uniq)"
|
|
USER_SHELL="bash"
|
|
|
|
if [[ "${#optionsAudits[@]}" -gt 1 ]]; then
|
|
while :; do
|
|
while [[ ! "${reply}" =~ ^(1|2)$ ]]; do
|
|
i=1
|
|
echo -e "\nChoose default system command shell:\n"
|
|
for o in "${optionsAudits[@]}"; do
|
|
echo "$i) $o"
|
|
((i++)) || true
|
|
done
|
|
if [ -z $PRESET_USER_SHELL ];then
|
|
read -r reply
|
|
else
|
|
reply=1
|
|
for index in "${!optionsAudits[@]}"; do
|
|
if [[ "${optionsAudits[$index]}" == "$PRESET_USER_SHELL" ]]; then
|
|
reply=$(($index + 1))
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
done
|
|
case $reply in
|
|
"1" | "${optionsAudits[0]}")
|
|
USER_SHELL="${optionsAudits[0]}"
|
|
break
|
|
;;
|
|
"2" | "${optionsAudits[1]}")
|
|
USER_SHELL="${optionsAudits[1]}"
|
|
break
|
|
;;
|
|
*)
|
|
USER_SHELL="${optionsAudits[0]}"
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
# Display shell selection only if needs to be selected
|
|
echo -e "\nShell: \x1B[92m${USER_SHELL^^}\x1B[0m"
|
|
fi
|
|
|
|
SHELL_PATH=$(grep "/$USER_SHELL$" /etc/shells | tail -1)
|
|
chsh -s "$(grep -iF "/$USER_SHELL" /etc/shells | tail -1)"
|
|
|
|
# change shell for future users
|
|
sed -i "s|^SHELL=.*|SHELL=${SHELL_PATH}|" /etc/default/useradd
|
|
sed -i "s|^DSHELL=.*|DSHELL=${SHELL_PATH}|" /etc/adduser.conf
|
|
|
|
}
|
|
|
|
set_timezone_and_locales() {
|
|
|
|
# Grab this machine's public IP address
|
|
PUBLIC_IP=$(curl --max-time 5 -s https://ipinfo.io/ip)
|
|
|
|
# Check if we have wireless adaptor
|
|
WIFI_DEVICE=$(LC_ALL=C iw dev | awk '$1=="Interface"{print $2}' 2> /dev/null)
|
|
|
|
if [ -z "$PUBLIC_IP" ]; then
|
|
|
|
# ask for connecting to wireless if wifi device is found
|
|
if [[ -n "$WIFI_DEVICE" ]]; then
|
|
echo -e "Internet connection was \x1B[91mnot detected\x1B[0m."
|
|
echo ""
|
|
unset response
|
|
while [[ ! "${response}" =~ ^(Y|y|N|n)$ ]]; do
|
|
if [ -z $PRESET_CONNECT_WIRELESS ];then
|
|
read -r -p "Connect via wireless? [Y/n] " response
|
|
response=${response:-Y}
|
|
else
|
|
response=n
|
|
fi
|
|
done
|
|
if [[ "${response}" =~ ^(Y|y)$ ]]; then
|
|
|
|
# We could have multiple devices
|
|
if (( $(grep -c . <<<"$WIFI_DEVICE") > 1 )); then
|
|
scanning=0
|
|
while [[ ${scanning} -lt 3 ]]; do
|
|
scanning=$(( scanning + 1 ))
|
|
echo -e "\nMultiple wireless adaptors detected. Choose primary:\n"
|
|
WIFI_DEVICES=($(printf '%s\n' "${WIFI_DEVICE[@]}" | sed 's/^[ \t]*//' | sed 's/"//g' | sed 's/ESSID://' | awk 'BEGIN{FS=OFS=","} {$NF=++count OFS $NF} 1'))
|
|
for str in ${WIFI_DEVICES[@]}; do echo $str | sed "s/,/ \t /g"; done
|
|
echo ""
|
|
read -r -p "Enter a number of wireles adaptor: " input
|
|
if [[ "$input" =~ ^[0-9]{,2}$ && -n "$input" ]] ; then break; fi
|
|
done
|
|
[[ -z $input ]] && input=1
|
|
WIFI_DEVICE=$(echo ${WIFI_DEVICES[$input-1]} | cut -d"," -f2)
|
|
fi
|
|
|
|
# bring up wifi device (not done by networkd, only by NetworkManager)
|
|
ip link set ${WIFI_DEVICE} up
|
|
# get list of wireless networks
|
|
scanning=0
|
|
broken=1
|
|
while [[ ${scanning} -lt 3 ]]; do
|
|
sleep 0.5
|
|
scanning=$(( scanning + 1 ))
|
|
readarray -t ARRAY < <(iw dev ${WIFI_DEVICE} scan 2> /dev/null | egrep 'SSID' | sed 's/^[ \t]*//' | sed 's/"//g' | sed 's/SSID: //' | sed '/^$/d' | sort | uniq | awk 'BEGIN{FS=OFS=","} {$NF=++count OFS $NF} 1')
|
|
if [[ ${#ARRAY[@]} -gt 0 ]]; then broken=0; break; fi
|
|
done
|
|
# wifi can also fail
|
|
if [[ ${broken} == 1 ]]; then
|
|
echo -e "\nWireless connection was \x1B[91mnot detected\x1B[0m.\n"
|
|
else
|
|
echo -e "\nDetected wireless networks:\n"
|
|
scanning=0
|
|
broken=1
|
|
while [[ ${scanning} -lt 3 ]]; do
|
|
scanning=$(( scanning + 1 ))
|
|
while [[ 1 ]] ; do
|
|
for str in "${ARRAY[@]}"; do echo $str | sed "s/,/ \t /"; done
|
|
echo ""
|
|
read -r -p "Enter a number of SSID: " input
|
|
if [[ "$input" =~ ^[0-9]{,2}$ ]] ; then break; fi
|
|
done
|
|
# get password
|
|
while [[ -n "${input}" ]] ; do
|
|
SSID=$(echo ${ARRAY[$input-1]} | cut -d"," -f2-)
|
|
echo ""
|
|
read -r -p "Enter a password for ${SSID}: " password
|
|
break
|
|
done
|
|
|
|
# generate config
|
|
cat <<- EOF > /etc/netplan/30-wifis-dhcp.yaml
|
|
# Created by Armbian firstlogin script
|
|
network:
|
|
wifis:
|
|
${WIFI_DEVICE}:
|
|
dhcp4: yes
|
|
dhcp6: yes
|
|
access-points:
|
|
"$SSID":
|
|
password: "${password}"
|
|
EOF
|
|
chmod 600 /etc/netplan/30-wifis-dhcp.yaml
|
|
|
|
# apply to netplan
|
|
systemctl daemon-reload
|
|
netplan apply --timeout 0 2>/dev/null
|
|
|
|
# wireless link probing
|
|
pinging=10
|
|
broken=1
|
|
WIRELESSLINK=""
|
|
echo ""
|
|
while [[ ${pinging} -gt 1 && -n "${input}" && -n "${password}" ]]; do
|
|
pinging=$(( pinging - 1 ))
|
|
printf "\rProbing wireless link ($pinging)"
|
|
WIRELESSLINK=$(iw "${WIFI_DEVICE}" link 2> /dev/null | grep "$SSID")
|
|
sleep 2
|
|
# exit if connection is suffesful
|
|
if [[ "${WIRELESSLINK}" == *$SSID* ]]; then
|
|
broken=0
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [[ ${broken} == 1 ]]; then
|
|
echo -e "\n\nWireless link was \x1B[91mnot detected\x1B[0m. Wrong password or weak signal."
|
|
fi
|
|
# get public IP probing
|
|
broken=1
|
|
pinging=10
|
|
|
|
while [[ ${pinging} -gt 1 && -n "${input}" && -n "${password}" && "${WIRELESSLINK}" == *$SSID* ]]; do
|
|
pinging=$(( pinging - 1 ))
|
|
printf "\rProbing internet connection ($pinging)"
|
|
PUBLIC_IP=$(curl --max-time 5 -s https://ipinfo.io/ip)
|
|
if [[ -n "$PUBLIC_IP" ]]; then
|
|
broken=0
|
|
break
|
|
else
|
|
sleep 5
|
|
fi
|
|
done
|
|
echo ""
|
|
|
|
if [[ ${broken} == 0 ]]; then
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [[ ${broken} == 1 ]]; then
|
|
echo -e "\n\x1B[91mUnable to connect to Access Point\x1B[0m.\n"
|
|
rm -f /etc/netplan/30-wifis-dhcp.yaml
|
|
netplan apply --timeout 0 2>/dev/null
|
|
systemctl daemon-reload
|
|
break
|
|
fi
|
|
|
|
fi # detected or not detected wireless network
|
|
fi
|
|
echo ""
|
|
fi
|
|
fi
|
|
|
|
# Grab IP once again if not found
|
|
sleep 3
|
|
[[ -z "$PUBLIC_IP" && -n "$WIFI_DEVICE" ]] && PUBLIC_IP=$(curl --max-time 5 -s https://ipinfo.io/ip)
|
|
|
|
# Call the geolocation API and capture the output
|
|
RES=$(
|
|
curl --max-time 5 -s "http://ipwhois.app/json/${PUBLIC_IP}" |
|
|
jq '.timezone, .country, .country_code' |
|
|
while read -r TIMEZONE; do
|
|
read -r COUNTRY
|
|
echo "${TIMEZONE},${COUNTRY},${COUNTRYCODE}" | tr --delete '"\n'
|
|
done
|
|
)
|
|
|
|
TZDATA=$(echo "${RES}" | cut -d"," -f1)
|
|
CCODE=$(echo "${RES}" | cut -d"," -f3 | xargs)
|
|
|
|
unset response
|
|
while [[ ! "${response}" =~ ^(Y|y|N|n)$ ]]; do
|
|
if [ -z "${SET_LANG_BASED_ON_LOCATION}" ] && [ -n "${TZDATA}" ];then
|
|
echo -e "Detected timezone: \x1B[92m$TZDATA\x1B[0m"
|
|
echo ""
|
|
read -r -p "Set user language based on your location? [Y/n] " response
|
|
response=${response:-Y}
|
|
else
|
|
response=$SET_LANG_BASED_ON_LOCATION
|
|
break
|
|
fi
|
|
done
|
|
# change it only if we have a match and if we agree
|
|
if [[ "${response}" =~ ^(N|n)$ ]]; then
|
|
unset CCODE TZDATA
|
|
fi
|
|
|
|
LOCALES=$(grep territory /usr/share/i18n/locales/* | grep _"$CCODE" | cut -d ":" -f 1 | cut -d "/" -f 6 |
|
|
xargs -I{} grep {} /usr/share/i18n/SUPPORTED | grep "UTF-8$" | cut -d " " -f 1)
|
|
# UTF8 is not present everywhere so check again in case it returns empty value
|
|
[[ -z "$LOCALES" ]] && LOCALES=$(grep territory /usr/share/i18n/locales/* | grep _"$CCODE" | cut -d ":" -f 1 | cut -d "/" -f 6 |
|
|
xargs -I{} grep {} /usr/share/i18n/SUPPORTED | cut -d " " -f 1)
|
|
readarray -t options <<< "${LOCALES}"
|
|
|
|
if [ -z $PRESET_LOCALE ];then
|
|
# when having more locales, prompt for choosing one
|
|
if [[ "${#options[@]}" -gt 1 ]]; then
|
|
options+=("Skip generating locales")
|
|
echo -e "\nAt your location, more locales are possible:\n"
|
|
PS3='Please enter your choice:'
|
|
select opt in "${options[@]}"; do
|
|
if [[ " ${options[*]} " == *" ${opt} "* ]]; then
|
|
LOCALES=${opt}
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
else
|
|
LOCALES=$PRESET_LOCALE
|
|
fi
|
|
|
|
if [[ "${LOCALES}" != *Skip* ]]; then
|
|
|
|
if [ -z $PRESET_TIMEZONE ];then
|
|
# if TZDATA was not detected, we need to select one
|
|
if [[ -z ${TZDATA} ]]; then
|
|
TZDATA=$(tzselect | tail -1)
|
|
fi
|
|
echo ""
|
|
else
|
|
TZDATA=$PRESET_TIMEZONE
|
|
fi
|
|
|
|
timedatectl set-timezone "${TZDATA}"
|
|
dpkg-reconfigure --frontend=noninteractive tzdata > /dev/null 2>&1
|
|
|
|
# change default locales
|
|
sed -i "s/=.*/=$(echo ${LOCALES} | cut -d" " -f1)/g" /etc/default/locale
|
|
|
|
# generate locales
|
|
sed -i 's/# '"${LOCALES}"'/'"${LOCALES}"'/' /etc/locale.gen
|
|
echo -e "Generating locales: \x1B[92m${LOCALES}\x1B[0m"
|
|
locale-gen "${LOCALES}" > /dev/null 2>&1
|
|
|
|
# setting detected locales only for user
|
|
{
|
|
echo "export LC_ALL=$LOCALES"
|
|
echo "export LANG=$LOCALES"
|
|
echo "export LANGUAGE=$LOCALES"
|
|
} >> /home/"$RealUserName"/.bashrc
|
|
{
|
|
echo "export LC_ALL=$LOCALES"
|
|
echo "export LANG=$LOCALES"
|
|
echo "export LANGUAGE=$LOCALES"
|
|
} >> /home/"$RealUserName"/.xsessionrc
|
|
|
|
fi
|
|
}
|
|
|
|
add_profile_sync_settings() {
|
|
if [[ ! -f /usr/bin/psd ]]; then
|
|
return 0
|
|
fi
|
|
|
|
/usr/bin/psd > /dev/null 2>&1
|
|
config_file="${HOME}/.config/psd/psd.conf"
|
|
if [ -f "${config_file}" ]; then
|
|
# test for overlayfs
|
|
sed -i 's/#USE_OVERLAYFS=.*/USE_OVERLAYFS="yes"/' "${config_file}"
|
|
case $(/usr/bin/psd p 2> /dev/null | grep Overlayfs) in
|
|
*active*)
|
|
echo -e "\nConfigured profile sync daemon with overlayfs."
|
|
;;
|
|
*)
|
|
echo -e "\nConfigured profile sync daemon."
|
|
sed -i 's/USE_OVERLAYFS="yes"/#USE_OVERLAYFS="no"/' "${config_file}"
|
|
;;
|
|
esac
|
|
fi
|
|
systemctl --user enable psd.service > /dev/null 2>&1
|
|
systemctl --user start psd.service > /dev/null 2>&1
|
|
}
|
|
|
|
add_user() {
|
|
read -r -t 0 _
|
|
REPEATS=3
|
|
while [ -f "/root/.not_logged_in_yet" ]; do
|
|
[[ -z "${PRESET_USER_NAME}" ]] && echo -e "\nPlease provide a username (eg. your first name): \c"
|
|
if [ -z "$PRESET_USER_NAME" ];then
|
|
read -r -e username
|
|
else
|
|
username="$PRESET_USER_NAME"
|
|
fi
|
|
if ! grep '^[a-zA-Z][a-zA-Z0-9]*$' <<< "$username" > /dev/null; then
|
|
echo -e "\n\x1B[91mError\x1B[0m: illegal characters in username"
|
|
return
|
|
fi
|
|
|
|
RealUserName="$(echo "$username" | tr '[:upper:]' '[:lower:]' | tr -d -c '[:alnum:]')"
|
|
[ -z "$RealUserName" ] && return
|
|
if ! id "$RealUserName" > /dev/null 2>&1; then break; else echo -e "Username \e[0;31m$RealUserName\x1B[0m already exists on the system."; fi
|
|
done
|
|
|
|
while [ -f "/root/.not_logged_in_yet" ]; do
|
|
if [ -z "$PRESET_USER_PASSWORD" ];then
|
|
read_password "Create user ($username)"
|
|
echo ""
|
|
else
|
|
password="$PRESET_USER_PASSWORD"
|
|
fi
|
|
first_input="$password"
|
|
if [ -z "$PRESET_USER_PASSWORD" ];then
|
|
read_password "Repeat user ($username)"
|
|
echo ""
|
|
else
|
|
password="$PRESET_USER_PASSWORD"
|
|
fi
|
|
second_input="$password"
|
|
if [[ "$first_input" == "$second_input" ]]; then
|
|
# minimal images might not have this
|
|
if command -v cracklib-check > /dev/null 2>&1; then
|
|
result="$(cracklib-check <<< "$password")"
|
|
okay="$(awk -F': ' '{ print $2}' <<< "$result")"
|
|
if [[ "$okay" != "OK" ]]; then
|
|
echo -e "\n\e[0;31mWarning:\x1B[0m Weak password, $okay \b!"
|
|
fi
|
|
fi
|
|
if [ -z "$PRESET_DEFAULT_REALNAME" ];then
|
|
echo -e ""
|
|
read -r -e -p "Please provide your real name: " -i "${RealUserName^}" RealName
|
|
else
|
|
RealName="$PRESET_DEFAULT_REALNAME"
|
|
fi
|
|
|
|
adduser --quiet --disabled-password --home /home/"$RealUserName" --gecos "$RealName" "$RealUserName"
|
|
|
|
# download and add SSH key if defined
|
|
if [[ -n "${PRESET_USER_KEY}" ]]; then
|
|
mkdir -p /home/"$RealUserName"/.ssh/
|
|
curl --retry 5 --connect-timeout 3 "${PRESET_ROOT_KEY}" > /home/"$RealUserName"/.ssh/authorized_keys 2> /dev/null
|
|
chown -R "$RealUserName":"$RealUserName" /home/"$RealUserName"/.ssh/
|
|
fi
|
|
|
|
if [[ -n "$first_input" ]]; then
|
|
(
|
|
echo "$first_input"
|
|
echo "$second_input"
|
|
) | passwd "$RealUserName" > /dev/null 2>&1
|
|
else
|
|
passwd -d "$RealUserName" > /dev/null 2>&1
|
|
fi
|
|
for additionalgroup in sudo netdev audio video disk tty users games dialout plugdev input bluetooth systemd-journal ssh render; do
|
|
usermod -aG "${additionalgroup}" "${RealUserName}" 2> /dev/null
|
|
done
|
|
|
|
# fix for gksu in Xenial
|
|
touch /home/"$RealUserName"/.Xauthority
|
|
chown "$RealUserName":"$RealUserName" /home/"$RealUserName"/.Xauthority
|
|
RealName="$(awk -F":" "/^${RealUserName}:/ {print \$5}" < /etc/passwd | cut -d',' -f1)"
|
|
[ -z "$RealName" ] && RealName="$RealUserName"
|
|
echo -e "\nDear \e[0;92m${RealName}\x1B[0m, your account \e[0;92m${RealUserName}\x1B[0m has been created and is sudo enabled."
|
|
echo -e "Please use this account for your daily work from now on.\n"
|
|
rm -f /root/.not_logged_in_yet
|
|
# set up profile sync daemon on desktop systems
|
|
if command -v psd > /dev/null 2>&1; then
|
|
echo -e "${RealUserName} ALL=(ALL) NOPASSWD: /usr/bin/psd-overlay-helper" >> /etc/sudoers
|
|
touch /home/"${RealUserName}"/.activate_psd
|
|
chown "$RealUserName":"$RealUserName" /home/"${RealUserName}"/.activate_psd
|
|
fi
|
|
break
|
|
elif [[ -n $password ]]; then
|
|
echo -e "Rejected - \e[0;31mpasswords do not match.\x1B[0m Try again [${REPEATS}]."
|
|
REPEATS=$((REPEATS - 1))
|
|
fi
|
|
[[ "$REPEATS" -eq 0 ]] && logout
|
|
done
|
|
|
|
}
|
|
|
|
if [[ -f /root/.not_logged_in_yet && -n $(tty) ]]; then
|
|
|
|
. /root/.not_logged_in_yet
|
|
|
|
# override configuration from URL
|
|
if [[ -n "${PRESET_CONFIGURATION}" ]]; then
|
|
curl --retry 5 --connect-timeout 3 "${PRESET_CONFIGURATION}" > /root/.not_logged_in_yet 2> /dev/null
|
|
fi
|
|
|
|
do_firstrun_automated_network_configuration
|
|
|
|
# disable autologin
|
|
rm -f /etc/systemd/system/getty@.service.d/override.conf
|
|
rm -f /etc/systemd/system/serial-getty@.service.d/override.conf
|
|
systemctl daemon-reload
|
|
|
|
declare desktop_dm="none"
|
|
declare -i desktop_is_sddm=0 desktop_is_lightdm=0 desktop_is_gdm3=0
|
|
if [[ -f /usr/bin/sddm ]]; then
|
|
desktop_dm="sddm"
|
|
desktop_is_sddm=1
|
|
fi
|
|
if [[ -f /usr/sbin/lightdm ]]; then
|
|
desktop_dm="lightdm"
|
|
desktop_is_lightdm=1
|
|
fi
|
|
if [[ -f /usr/sbin/gdm3 ]]; then
|
|
desktop_dm="gdm3"
|
|
desktop_is_gdm3=1
|
|
fi
|
|
|
|
echo -e "\nWaiting for system to finish booting ..."
|
|
systemctl is-system-running --wait > /dev/null
|
|
|
|
# enable networkManager-wait-online.service
|
|
# When NM is used the NetworkManager-wait-online.service must be enabled so that network-online.target is not reached until
|
|
# NetworkManager has brought up all the interfaces. Service units that require the network to be up before starting rely
|
|
# on network-online.target working correctly otherwise they will likely fail on boot
|
|
# Same goes for systemd-networkd stack
|
|
# https://github.com/armbian/build/issues/7896
|
|
if
|
|
systemctl is-enabled --quiet NetworkManager &&
|
|
! systemctl is-enabled --quiet NetworkManager-wait-online
|
|
then
|
|
systemctl enable NetworkManager-wait-online
|
|
# @TODO: determine if there is any value in starting it now
|
|
echo "Waiting for network startup to complete..."
|
|
systemctl start NetworkManager-wait-online
|
|
fi
|
|
|
|
if
|
|
systemctl is-enabled --quiet systemd-networkd &&
|
|
! systemctl is-enabled --quiet systemd-networkd-wait-online
|
|
then
|
|
systemctl enable systemd-networkd-wait-online
|
|
# @TODO: determine if there is any value in starting it now
|
|
echo "Waiting for network startup to complete..."
|
|
systemctl start systemd-networkd-wait-online
|
|
fi
|
|
|
|
# enable hiDPI support
|
|
if [[ "$(cut -d, -f1 < /sys/class/graphics/fb0/virtual_size 2> /dev/null)" -gt 1920 ]]; then
|
|
# lightdm
|
|
[[ -f /etc/lightdm/slick-greeter.conf ]] && echo "enable-hidpi = on" >> /etc/lightdm/slick-greeter.conf
|
|
# xfce
|
|
[[ -f /etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xsettings.xml ]] && sed -i 's|<property name="WindowScalingFactor" type="int" value=".*|<property name="WindowScalingFactor" type="int" value="2">|g' /etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xsettings.xml
|
|
|
|
# framebuffer console larger font
|
|
setfont /usr/share/consolefonts/Uni3-TerminusBold32x16.psf.gz
|
|
fi
|
|
|
|
clear
|
|
|
|
# In case VENDORPRETTYNAME is defined, display that
|
|
[[ -n "${VENDORPRETTYNAME}" ]] && VENDOR="$VENDORPRETTYNAME"
|
|
echo -e "Welcome to \e[1m\e[97m${VENDOR}\x1B[0m! \n"
|
|
echo -e "Documentation: \e[1m\e[92m${VENDORDOCS}\x1B[0m | Community support: \e[1m\e[92m${VENDORSUPPORT}\x1B[0m\n"
|
|
|
|
echo "" # empty line
|
|
|
|
# Try to get the local IP address (script halts until IP was found or x retries were done)
|
|
get_local_ip_addr
|
|
|
|
[[ -z "$PRESET_ROOT_PASSWORD" ]] && echo "" # empty line
|
|
|
|
trap '' 2
|
|
REPEATS=3
|
|
while [ -f "/root/.not_logged_in_yet" ]; do
|
|
. /root/.not_logged_in_yet
|
|
if [ -z "$PRESET_ROOT_PASSWORD" ];then
|
|
read_password "Create root"
|
|
else
|
|
# allow automated install also in interactive session
|
|
#if [ "$(who am i | awk '{print $2}')" != "tty1" ];then
|
|
# exit
|
|
#fi
|
|
password="$PRESET_ROOT_PASSWORD"
|
|
# download SSH key if defined
|
|
if [[ -n "${PRESET_ROOT_KEY}" ]]; then
|
|
mkdir -p /root/.ssh/
|
|
curl --retry 5 --connect-timeout 3 "${PRESET_ROOT_KEY}" > /root/.ssh/authorized_keys 2> /dev/null
|
|
fi
|
|
fi
|
|
|
|
# only allow one login. Once you enter root password, kill others.
|
|
loginfrom=$(who am i | awk '{print $2}')
|
|
who -la | grep root | grep -v "$loginfrom" | awk '{print $7}' | xargs --no-run-if-empty kill -9
|
|
|
|
# enable motd
|
|
chmod +x /etc/update-motd.d/*
|
|
|
|
first_input="$password"
|
|
if [ -z "$PRESET_ROOT_PASSWORD" ];then
|
|
echo ""
|
|
read_password "Repeat root"
|
|
echo ""
|
|
else
|
|
password="$PRESET_ROOT_PASSWORD"
|
|
fi
|
|
second_input="$password"
|
|
if [[ "$first_input" == "$second_input" ]]; then
|
|
# minimal might not have this
|
|
if command -v cracklib-check > /dev/null 2>&1; then
|
|
result="$(cracklib-check <<< "$password")"
|
|
okay="$(awk -F': ' '{ print $2}' <<< "$result")"
|
|
if [[ "$okay" != "OK" ]]; then
|
|
echo -e "\n\e[0;31mWarning:\x1B[0m Weak password, $okay \b!"
|
|
fi
|
|
fi
|
|
(
|
|
echo "$first_input"
|
|
echo "$second_input"
|
|
) | passwd root > /dev/null 2>&1
|
|
break
|
|
elif [[ -n $password ]]; then
|
|
echo -e "Rejected - \e[0;31mpasswords do not match.\x1B[0m Try again [${REPEATS}]."
|
|
REPEATS=$((REPEATS - 1))
|
|
fi
|
|
[[ "$REPEATS" -eq 0 ]] && exit
|
|
done
|
|
trap - INT TERM EXIT
|
|
|
|
# display support status
|
|
if [ "$IMAGE_TYPE" != "nightly" ]; then
|
|
if [[ "$BRANCH" == "edge" ]]; then
|
|
echo -e "\nSupport status: \e[0;31mcommunity support\x1B[0m (edge kernel branch)"
|
|
elif [[ "$DISTRIBUTION_STATUS" != "supported" ]]; then
|
|
echo -e "\nSupport status: \e[0;31mcommunity support\x1B[0m (unsupported userspace)"
|
|
elif [[ "$BOARD_TYPE" != "conf" ]]; then
|
|
echo -e "\nSupport status: \e[0;31mcommunity support\x1B[0m (looking for a dedicated maintainer)"
|
|
fi
|
|
else
|
|
|
|
echo -e "\e[0;31m\nWARNING!\x1B[0m\n\nYou are using an \e[0;31mautomated build\x1B[0m meant only for developers to provide"
|
|
echo -e "constructive feedback to improve build system, OS settings or UX.\n"
|
|
|
|
echo -e "If this does not apply to you, \e[0;31mSTOP NOW!\x1B[0m Especially don't use this "
|
|
echo -e "image for production since things might not work as expected or at "
|
|
echo -e "all. They may break anytime with next update."
|
|
|
|
fi
|
|
|
|
# ask user to select shell
|
|
trap '' 2
|
|
set_shell
|
|
trap - INT TERM EXIT
|
|
|
|
trap check_abort INT
|
|
|
|
while [ -f "/root/.not_logged_in_yet" ]; do
|
|
[[ -z "${PRESET_USER_NAME}" ]] && echo -e "\nCreating a new user account. Press <Ctrl-C> to abort"
|
|
[[ "${desktop_dm}" != "none" ]] && echo -e "\n\e[0;31mDesktop environment will not be enabled if you abort the new user creation\x1B[0m"
|
|
add_user
|
|
done
|
|
trap - INT TERM EXIT
|
|
|
|
# ask user to select automated locales or not
|
|
trap '' 2
|
|
set_timezone_and_locales
|
|
trap - INT TERM EXIT
|
|
|
|
if [[ ${USER_SHELL} == zsh ]]; then
|
|
printf "\nYou selected \e[0;91mZSH\x1B[0m as your default shell. If you want to use it right away, please logout and login! \n\n"
|
|
fi
|
|
|
|
# re-enable passing locale environment via ssh
|
|
sed -e '/^#AcceptEnv LANG/ s/^#//' -i /etc/ssh/sshd_config
|
|
# restart sshd daemon
|
|
systemctl restart ssh.service
|
|
|
|
# rpardini: hacks per-dm, very much legacy stuff that works by a miracle
|
|
if [[ "${desktop_dm}" == "lightdm" ]] && [ -n "$RealName" ]; then
|
|
|
|
mkdir -p /etc/lightdm/lightdm.conf.d
|
|
cat <<- EOF > /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
[Seat:*]
|
|
autologin-user=$RealUserName
|
|
autologin-user-timeout=0
|
|
user-session=xfce
|
|
EOF
|
|
|
|
# select gnome session (has to be first or it breaks budgie/cinnamon desktop autologin and user-session)
|
|
# @TODO: remove this, gnome should use gdm3, not lightdm
|
|
[[ -x $(command -v gnome-session) ]] && sed -i "s/user-session.*/user-session=ubuntu/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v gnome-session) ]] && sed -i "s/user-session.*/user-session=ubuntu/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
# select awesome session
|
|
[[ -x $(command -v awesome) ]] && sed -i "s/user-session.*/user-session=awesome/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v awesome) ]] && sed -i "s/user-session.*/user-session=awesome/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
# select budgie session
|
|
[[ -x $(command -v budgie-desktop) ]] && sed -i "s/user-session.*/user-session=budgie-desktop/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v budgie-desktop) ]] && sed -i "s/user-session.*/user-session=budgie-desktop/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
# select cinnamon session
|
|
[[ -x $(command -v cinnamon) ]] && sed -i "s/user-session.*/user-session=cinnamon/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v cinnamon) ]] && sed -i "s/user-session.*/user-session=cinnamon/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
# select deepin session
|
|
[[ -x $(command -v deepin-wm) ]] && sed -i "s/user-session.*/user-session=deepin/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v deepin-wm) ]] && sed -i "s/user-session.*/user-session=deepin/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
# select ice-wm session
|
|
[[ -x $(command -v icewm-session) ]] && sed -i "s/user-session.*/user-session=icewm-session/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v icewm-session) ]] && sed -i "s/user-session.*/user-session=icewm-session/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
# select i3 session
|
|
[[ -x $(command -v i3) ]] && sed -i "s/user-session.*/user-session=i3/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v i3) ]] && sed -i "s/user-session.*/user-session=i3/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
# select lxde session
|
|
[[ -x $(command -v startlxde) ]] && sed -i "s/user-session.*/user-session=LXDE/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v startlxde) ]] && sed -i "s/user-session.*/user-session=LXDE/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
# select lxqt session
|
|
[[ -x $(command -v startlxqt) ]] && sed -i "s/user-session.*/user-session=lxqt/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v startlxqt) ]] && sed -i "s/user-session.*/user-session=lxqt/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
# select mate session
|
|
[[ -x $(command -v mate-wm) ]] && sed -i "s/user-session.*/user-session=mate/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v mate-wm) ]] && sed -i "s/user-session.*/user-session=mate/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
# select sway wayland session
|
|
[[ -x $(command -v sway) ]] && sed -i "s/user-session.*/user-session=sway/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v sway) ]] && sed -i "s/user-session.*/user-session=sway/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
# select xmonad session
|
|
[[ -x $(command -v xmonad) ]] && sed -i "s/user-session.*/user-session=xmonad/" /etc/lightdm/lightdm.conf.d/11-armbian.conf
|
|
[[ -x $(command -v xmonad) ]] && sed -i "s/user-session.*/user-session=xmonad/" /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf
|
|
|
|
ln -sf /lib/systemd/system/lightdm.service /etc/systemd/system/display-manager.service
|
|
|
|
if [[ -f /var/run/resize2fs-reboot ]]; then
|
|
# Let the user reboot now otherwise start desktop environment
|
|
printf "\n\n\e[0;91mWarning: a reboot is needed to finish resizing the filesystem \x1B[0m \n"
|
|
printf "\e[0;91mPlease reboot the system now \x1B[0m \n\n"
|
|
else
|
|
echo -e "\n\e[1m\e[39mNow starting desktop environment...\x1B[0m\n"
|
|
sleep 1
|
|
service lightdm start 2> /dev/null
|
|
if [ -f /root/.desktop_autologin ]; then
|
|
rm /root/.desktop_autologin
|
|
else
|
|
systemctl -q enable armbian-disable-autologin.timer
|
|
systemctl start armbian-disable-autologin.timer
|
|
fi
|
|
# logout if logged at console
|
|
who -la | grep root | grep -q tty1 && exit 1
|
|
fi
|
|
|
|
elif [[ "${desktop_dm}" == "gdm3" ]] && [ -n "$RealName" ]; then
|
|
# 1st run goes without login
|
|
mkdir -p /etc/gdm3
|
|
cat <<- EOF > /etc/gdm3/custom.conf
|
|
[daemon]
|
|
AutomaticLoginEnable = true
|
|
AutomaticLogin = $RealUserName
|
|
EOF
|
|
|
|
ln -sf /lib/systemd/system/gdm3.service /etc/systemd/system/display-manager.service
|
|
|
|
if [[ -f /var/run/resize2fs-reboot ]]; then
|
|
# Let the user reboot now otherwise start desktop environment
|
|
printf "\n\n\e[0;91mWarning: a reboot is needed to finish resizing the filesystem \x1B[0m \n"
|
|
printf "\e[0;91mPlease reboot the system now \x1B[0m \n\n"
|
|
else
|
|
echo -e "\n\e[1m\e[39mNow starting desktop environment...\x1B[0m\n"
|
|
sleep 1
|
|
service gdm3 start 2> /dev/null
|
|
if [ -f /root/.desktop_autologin ]; then
|
|
rm /root/.desktop_autologin
|
|
else
|
|
(
|
|
sleep 20
|
|
sed -i "s/AutomaticLoginEnable.*/AutomaticLoginEnable = false/" /etc/gdm3/custom.conf
|
|
) &
|
|
fi
|
|
# logout if logged at console
|
|
who -la | grep root | grep -q tty1 && exit 1
|
|
fi
|
|
elif [[ "${desktop_dm}" == "sddm" ]] && [ -n "$RealName" ]; then
|
|
|
|
# create default sddm config
|
|
mkdir -p /etc/sddm.conf.d
|
|
cat <<- EOF > /etc/sddm.conf.d/armbian.conf
|
|
[Theme]
|
|
Current=breeze
|
|
[General]
|
|
InputMethod=none
|
|
EOF
|
|
|
|
# 1st run goes without login
|
|
cat <<- EOF > /etc/sddm.conf.d/autologin.conf
|
|
[Autologin]
|
|
User=$RealUserName
|
|
EOF
|
|
echo -e "\n\e[1m\e[39mNow starting desktop environment via ${desktop_dm}...\x1B[0m\n"
|
|
systemctl enable --now sddm 2> /dev/null
|
|
|
|
if [ -f /root/.desktop_autologin ]; then
|
|
rm /root/.desktop_autologin
|
|
else
|
|
systemctl -q enable armbian-disable-autologin.timer
|
|
fi
|
|
# logout if logged at console
|
|
who -la | grep root | grep -q tty1 && exit 1
|
|
|
|
else
|
|
# no display manager detected -> clear screen and show motd
|
|
clear
|
|
run-parts --lsbsysinit /etc/update-motd.d
|
|
|
|
# Display reboot recommendation if necessary
|
|
if [[ -f /var/run/resize2fs-reboot ]]; then
|
|
printf "\n\n\e[0;91mWarning: a reboot is needed to finish resizing the filesystem \x1B[0m \n"
|
|
printf "\e[0;91mPlease reboot the system now \x1B[0m \n\n"
|
|
fi
|
|
|
|
fi
|
|
fi
|
|
|
|
# Run provisioning script if exists
|
|
if [[ -f /root/provisioning.sh ]]; then
|
|
. /root/provisioning.sh
|
|
fi
|