#!/bin/bash # core/environment.sh - environment init, OS check, pre-install prep # Migrated verbatim from install.sh (lines 12-20,22-23,32-36,693-697,699-713,715-725). init_environment() { clear printf " ####################################################################### # ServerStack for Debian 9+ and Ubuntu 16+ # # For more information please visit https://oneinstack.com # ####################################################################### " # Check if user is root [ $(id -u) != "0" ] && { echo "${CFAILURE}Error: You must be root to run this script${CEND}"; exit 1; } # bin/install.sh already sets oneinstack_dir to the project root and cd's there. # Derive it robustly from THIS script's own location only as a fallback, so the # relative sources (./lib, ./config, ./modules) always resolve to the project # root instead of breaking into bin/ when $0 points at bin/install.sh. if [ -z "${oneinstack_dir}" ] || [ ! -d "${oneinstack_dir}/lib" ]; then oneinstack_dir="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.." && pwd)" fi cd "${oneinstack_dir}" || exit 1 } # init_variables: generate random credentials. Runs AFTER load_configs so the # fresh random values intentionally override any dbrootpwd stored in # config/options.conf (matches the original install.sh ordering: lines 32-36 run # after the config/options.conf source at lines 24-30). init_variables() { dbrootpwd=`< /dev/urandom tr -dc A-Za-z0-9 | head -c8` dbpostgrespwd=`< /dev/urandom tr -dc A-Za-z0-9 | head -c8` dbmongopwd=`< /dev/urandom tr -dc A-Za-z0-9 | head -c8` xcachepwd=`< /dev/urandom tr -dc A-Za-z0-9 | head -c8` dbinstallmethod=1 } # get_local_ipaddr: resolve the server's primary (outbound) IPv4 address with pure # shell, so the install summary never ends up with an EMPTY IP that produces broken # URLs like "http:///ocp.php". The legacy ./lib/py/get_ipaddr.py relied on a `python` # interpreter (via its shebang) which is absent on Ubuntu 22.04+ (only `python3` # exists); when that script silently failed, IPADDR came back empty. This shell # implementation is interpreter-independent and falls back through several methods. get_local_ipaddr() { local ip="" # 1) Source address the kernel would use to reach the public Internet. if command -v ip >/dev/null 2>&1; then ip=$(ip route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src"){print $(i+1); exit}}') fi # 2) First address reported by `hostname -I` (already skips 127.0.0.1 normally). if [ -z "$ip" ] && command -v hostname >/dev/null 2>&1; then ip=$(hostname -I 2>/dev/null | awk '{print $1}') fi # 3) First global (non-loopback) IPv4 from `ip addr`. if [ -z "$ip" ] && command -v ip >/dev/null 2>&1; then ip=$(ip -o -4 addr show scope global 2>/dev/null | awk '{print $4}' | cut -d/ -f1 | head -n1) fi # 4) Last resort. [ -z "$ip" ] && ip="127.0.0.1" # On a VPC / private-network instance the local IP is an RFC1918 address that # is NOT reachable from outside the VPC. When we already resolved the public IP # (PUBLIC_IPADDR, used for mirror selection) prefer it for the control-panel # URLs so they are actually clickable from the Internet. If the public IP is # unavailable (no egress, etc.) we keep the private IP as a safe fallback. case "$ip" in 10.*|172.1[6-9].*|172.2[0-9].*|172.3[01].*|192.168.*) [ -n "${PUBLIC_IPADDR}" ] && ip="${PUBLIC_IPADDR}" ;; esac echo "$ip" } # core/environment.sh (cont) - prepare_install # Migrated verbatim from install.sh (lines 693-697,699-713,715-725). prepare_install() { if [[ ${nginx_option} =~ ^[1-2]$ ]]; then [ ! -d ${wwwroot_dir}/default ] && mkdir -p ${wwwroot_dir}/default [ ! -d ${wwwlogs_dir} ] && mkdir -p ${wwwlogs_dir} fi [ -d /data ] && chmod 755 /data # install wget gcc curl python3 if [ ! -e ~/.oneinstack ]; then downloadDepsSrc=1 echo "${CMSG}Updating apt package lists (this may take a few minutes)...${CEND}" apt-get -y update 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log echo "${CMSG}Installing base tools (wget gcc curl python3)...${CEND}" ${PM} -y install wget gcc curl python3 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log clear fi # Make sure a `python` interpreter is available for the legacy *.py helpers # (get_public_ipaddr.py / get_ipaddr_state.py) regardless of whether the OS ships # `python` (Ubuntu 22.04+ only provides `python3`). Create the symlink UNCONDITIONALLY # here (not gated by the first-install ~/.oneinstack check) so those scripts keep # working on every run and on re-installs. if [ ! -e "/usr/bin/python" ] && command -v python3 >/dev/null 2>&1; then ln -s "$(command -v python3)" /usr/bin/python fi # get the IP information # Resolve the PUBLIC IP first so get_local_ipaddr() can prefer it on private / # VPC networks (where the local IP is not externally reachable). Then the local # IP for the summary URLs, then the country code from the public IP. PUBLIC_IPADDR=$(./lib/py/get_public_ipaddr.py) IPADDR=$(get_local_ipaddr) IPADDR_COUNTRY=$(./lib/py/get_ipaddr_state.py ${PUBLIC_IPADDR}) # openSSL . ./lib/openssl.sh # Check download source packages . ./lib/check_download.sh [ "${armplatform}" == "y" ] && dbinstallmethod=2 checkDownload 2>&1 | tee -a ${oneinstack_dir}/runtime/install.log # get OS Memory . ./lib/memory.sh } # check_environment: lightweight guard that the OS was detected. # (check_os.sh already hard-exits on unsupported OS during load_configs.) check_environment() { if [ -z "${PM}" ] || [ -z "${Family}" ]; then error_exit "Unsupported operating system or system detection failed." fi }