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

101 lines
6.9 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 " http://%s:8080%s\n", a[1], "'"$1"'"}'; }
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'
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
clear
printf '\n Bridge&Join: установка на сервер\n ────────────────────────────────────────────────────────────\n'
printf ' Debian установлен. Осталось установить 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
printf '\n Ключ продукта спросит первая страница настройки в браузере:\n'; urls /first-run; printf '\n'
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