Files
Bridge-and-Join-s/deploy/iso/bj-firstboot
T

114 lines
8.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Первая загрузка сервера, установленного с образа Bridge&Join. Спрашивает ключ продукта на консоли;
# без ключа ставит ядро bj с образа (/var/lib/bj/bundle), а ключ вводится в браузере на первой
# странице настройки. Пока bj не установлен, вопрос повторяется при каждой загрузке (с таймаутом),
# адрес и подсказки всегда есть на экране входа (bj-welcome).
set -u
MARK=/var/lib/bj/.bj/installed-from-iso
SERVER=https://lic.zetit.ru
CHANNEL=stable
BUNDLE=/var/lib/bj/bundle
[ -s /etc/bj/channel ] && CHANNEL=$(tr -d ' \n' < /etc/bj/channel)
finish() {
mkdir -p "$(dirname "$MARK")" && date -Iseconds > "$MARK"
systemctl disable bj-firstboot.service >/dev/null 2>&1
[ -x /usr/local/sbin/bj-welcome ] && /usr/local/sbin/bj-welcome
}
urls() { ip -4 -o addr show scope global 2>/dev/null | awk '{split($4,a,"/"); printf " https://%s:8443%s\n", a[1], "'"$1"'"}'; }
# Пока идут вопросы, сообщения загрузки на консоль не выводятся (ядро — только аварийные,
# systemd — без строк «[ OK ] Started …»), иначе они перемешиваются с текстом на экране.
quiet_console() { dmesg -n 1 2>/dev/null; kill -s RTMIN+21 1 2>/dev/null; sleep 2; }
quiet_console
ACC_DONE=/var/lib/bj/.bj/os-accounts-set
ACCOUNTS=""
genpw() { local p=""; while [ ${#p} -lt 12 ]; do p="$p$(head -c 48 /dev/urandom | tr -dc 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789')"; done; printf '%s-%s-%s' "${p:0:4}" "${p:4:4}" "${p:8:4}"; }
askpw() { # $1 — логин, $2 — предложенный пароль; печатает итоговый пароль
while true; do
printf ' Пароль для %s: %s\n Enter — принять, или введите свой (не короче 10 символов): ' "$1" "$2" > /dev/tty
stty -echo < /dev/tty; read -r P1 < /dev/tty; stty echo < /dev/tty; printf '\n' > /dev/tty
[ -z "$P1" ] && { printf '%s' "$2"; return; }
[ ${#P1} -lt 10 ] && { printf ' Короче 10 символов, ещё раз.\n' > /dev/tty; continue; }
printf ' Повторите: ' > /dev/tty; stty -echo < /dev/tty; read -r P2 < /dev/tty; stty echo < /dev/tty; printf '\n' > /dev/tty
[ "$P1" = "$P2" ] && { printf '%s' "$P1"; return; }
printf ' Не совпало, ещё раз.\n' > /dev/tty
done
}
setup_accounts() {
[ -f "$ACC_DONE" ] && return
id user_bj >/dev/null 2>&1 || useradd -m -s /bin/bash -c "Пользователь сервера bj" -G adm,systemd-journal user_bj
id root_bj >/dev/null 2>&1 && usermod -aG sudo root_bj
clear
printf '\n Bridge&Join: учётные записи сервера\n ────────────────────────────────────────────────────────────\n'
printf ' root_bj — администратор сервера (команды через sudo)\n user_bj — обычный вход (журналы, без прав администратора)\n'
printf ' Работа с bj — в браузере; эти учётные записи нужны для обслуживания ОС.\n\n'
printf ' Шаг 1 из 2 — пароли. Для каждой учётной записи предложен пароль:\n'
printf ' • Enter — оставить предложенный (он будет показан ещё раз в конце, запишите его);\n'
printf ' • или наберите свой (не короче 10 символов, при вводе не отображается) и Enter.\n\n'
PA=$(askpw root_bj "$(genpw)"); PU=$(askpw user_bj "$(genpw)")
printf 'root_bj:%s\nuser_bj:%s\n' "$PA" "$PU" | chpasswd
mkdir -p "$(dirname "$ACC_DONE")" && date -Iseconds > "$ACC_DONE"
ACCOUNTS=$(printf ' root_bj (администратор, sudo) пароль: %s\n user_bj (обычный вход) пароль: %s\n' "$PA" "$PU")
unset PA PU
}
show_accounts() {
[ -n "$ACCOUNTS" ] || return
printf '\n ┌── ЗАПИШИТЕ: учётные записи сервера ──────────────────────────┐\n%s\n' "$ACCOUNTS"
printf ' └── пароли нигде не сохранены и больше не будут показаны ──────┘\n'
printf ' Сменить пароль: passwd (под своей учётной записью)\n\n'
}
setup_accounts
# постоянный адрес: DHCP может выдать серверу другой адрес, и bj «потеряется» (только Ubuntu/netplan)
if [ ! -f /var/lib/bj/.bj/network-asked ] && [ -x /usr/local/sbin/bj-network ] && command -v netplan >/dev/null; then
mkdir -p /var/lib/bj/.bj && date -Iseconds > /var/lib/bj/.bj/network-asked
printf '\n Сейчас адрес сервера: %s\n' "$(ip -4 -o addr show scope global 2>/dev/null | awk '{print $4}' | tr '\n' ' ')"
read -t 60 -r -p " Задать постоянный адрес (рекомендуется)? [д/Н]: " ANS < /dev/tty || ANS=""
case "$ANS" in [дДyY]*) /usr/local/sbin/bj-network < /dev/tty ;; esac
fi
clear
printf '\n Bridge&Join: установка на сервер\n ────────────────────────────────────────────────────────────\n'
printf ' Шаг 2 из 2 — установка bj. Система установлена, осталось поставить bj.\n\n'
if [ -f "$BUNDLE/manifest.json" ]; then
printf ' Ключ продукта (BJ-XXXX-XXXX-XXXX) есть в портале клиента %s/portal/.\n' "$SERVER"
printf ' Вводить его здесь необязательно: нажмите Enter — ядро bj установится с образа,\n а ключ вы введёте в браузере на первой странице настройки (там его удобно вставить).\n\n'
else
printf ' Нужен ключ продукта (BJ-XXXX-XXXX-XXXX): он есть в портале клиента %s/portal/\n\n' "$SERVER"
fi
for i in $(seq 1 30); do
curl -fsS -m 5 -o /dev/null "$SERVER/healthz" && break
[ "$i" = 1 ] && printf ' Жду сеть и связь с %s…\n' "$SERVER"
sleep 2
done
while true; do
CODE=""
if [ -f "$BUNDLE/manifest.json" ]; then
read -t 120 -r -p " Ключ продукта (Enter — установить с образа, ключ ввести в браузере): " CODE || true
else
read -t 120 -r -p " Ключ продукта (Enter — установить позже): " CODE || true
fi
CODE=$(printf '%s' "${CODE:-}" | tr -d ' ' | tr '[:lower:]' '[:upper:]')
if [ -z "$CODE" ]; then
if [ -f "$BUNDLE/manifest.json" ]; then
if /usr/local/sbin/bj-installer install --bundle "$BUNDLE" --server "$SERVER" --channel "$CHANNEL"; then
finish # адрес, код и подсказку про ключ продукта уже вывел bj-installer
show_accounts
read -r -p " Нажмите Enter, чтобы перейти к экрану входа. " _ || true
exit 0
fi
show_accounts
printf '\n Установка с образа не завершилась. Подробности выше; повторить:\n sudo bj-installer install --bundle %s\n\n' "$BUNDLE"
sleep 5; exit 0
fi
show_accounts
printf '\n Установка bj отложена. Вопрос повторится при следующей загрузке; вручную:\n sudo bj-installer install --code КЛЮЧ-ПРОДУКТА\n\n'
read -r -p " Нажмите Enter, чтобы перейти к экрану входа. " _ || true
exit 0
fi
if /usr/local/sbin/bj-installer install --code "$CODE" --server "$SERVER" --channel "$CHANNEL"; then
finish
show_accounts
read -r -p " Нажмите Enter, чтобы перейти к экрану входа. " _ || true
exit 0
fi
printf '\n Установка не завершилась. Проверьте ключ продукта и сеть и попробуйте ещё раз.\n\n'
done