release: public alpha 0.6.0 baseline
This commit is contained in:
Executable
+180
@@ -0,0 +1,180 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
action=${1:-}
|
||||
source_dir=${2:-}
|
||||
target_user=${3:-jwebot}
|
||||
profile_id=${4:-default}
|
||||
runtime_root=${JWEBOT_RUNTIME_ROOT:-/opt/jwebot}
|
||||
runtime_python="${runtime_root}/venv/bin/python"
|
||||
|
||||
usage() {
|
||||
cat >&2 <<'EOF'
|
||||
usage:
|
||||
bootstrap-jwebot.sh prepare SOURCE_DIR [TARGET_USER] [PROFILE]
|
||||
bootstrap-jwebot.sh verify SOURCE_DIR [TARGET_USER] [PROFILE]
|
||||
bootstrap-jwebot.sh deploy SOURCE_DIR [TARGET_USER] [PROFILE]
|
||||
EOF
|
||||
exit 64
|
||||
}
|
||||
|
||||
[[ -n "${action}" && -n "${source_dir}" ]] || usage
|
||||
[[ "${target_user}" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]] || {
|
||||
echo "[JWeBot] error: invalid target user" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ "${profile_id}" =~ ^[a-z][a-z0-9-]{0,47}$ ]] || {
|
||||
echo "[JWeBot] error: invalid profile id" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ "${EUID}" -eq 0 ]] || {
|
||||
echo "[JWeBot] error: bootstrap must run as root" >&2
|
||||
exit 1
|
||||
}
|
||||
[[ -d "${source_dir}" ]] || {
|
||||
echo "[JWeBot] error: source directory is unavailable" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
progress() {
|
||||
local step=$1
|
||||
local total=$2
|
||||
local label=$3
|
||||
local width=20
|
||||
local filled=$((step * width / total))
|
||||
local empty=$((width - filled))
|
||||
local bar padding
|
||||
printf -v bar '%*s' "${filled}" ''
|
||||
printf -v padding '%*s' "${empty}" ''
|
||||
printf '[JWeBot] [%s%s] %3d%% %s\n' \
|
||||
"${bar// /#}" "${padding// /-}" "$((step * 100 / total))" "${label}"
|
||||
}
|
||||
|
||||
account_home() {
|
||||
getent passwd "${target_user}" | cut -d: -f6
|
||||
}
|
||||
|
||||
as_runtime_user() {
|
||||
local home
|
||||
home=$(account_home)
|
||||
/usr/sbin/runuser -u "${target_user}" -- /usr/bin/env \
|
||||
HOME="${home}" \
|
||||
JWEBOT_CONFIG_ROOT="${home}/.config/jwebot" \
|
||||
JWEBOT_CONFIG_STATE_ROOT="${home}/.local/state/jwebot" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
progress 1 6 "operating-system packages"
|
||||
command -v apt-get >/dev/null 2>&1 || {
|
||||
echo "[JWeBot] error: automatic prepare currently supports apt-based systems" >&2
|
||||
exit 1
|
||||
}
|
||||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
libx11-6 \
|
||||
libxdamage1 \
|
||||
scrot \
|
||||
tesseract-ocr \
|
||||
tesseract-ocr-chi-sim \
|
||||
wmctrl \
|
||||
xclip \
|
||||
xdotool
|
||||
|
||||
progress 2 6 "runtime account"
|
||||
if ! id "${target_user}" >/dev/null 2>&1; then
|
||||
useradd --create-home --shell /bin/bash "${target_user}"
|
||||
fi
|
||||
target_home=$(account_home)
|
||||
[[ -n "${target_home}" && -d "${target_home}" ]]
|
||||
|
||||
progress 3 6 "python environment"
|
||||
install -d -o root -g root -m 0755 "${runtime_root}"
|
||||
if [[ ! -x "${runtime_python}" ]]; then
|
||||
python3 -m venv "${runtime_root}/venv"
|
||||
fi
|
||||
"${runtime_python}" -m pip install --upgrade pip
|
||||
"${runtime_python}" -m pip install -r "${source_dir}/requirements-runtime.txt"
|
||||
"${runtime_python}" -m pip install \
|
||||
"${source_dir}/packages/jwebot-config" \
|
||||
"${source_dir}/packages/jwebot-sdk" \
|
||||
"${source_dir}/packages/jwebot-official-extensions" \
|
||||
"${source_dir}/packages/jwebot-kernel" \
|
||||
"${source_dir}/packages/jwebot-extension-host"
|
||||
|
||||
progress 4 6 "configuration profile"
|
||||
if [[ ! -L "${target_home}/.config/jwebot/current" ]]; then
|
||||
as_runtime_user "${runtime_python}" -m jwebot_config \
|
||||
init "${profile_id}" --activate
|
||||
else
|
||||
as_runtime_user "${runtime_python}" -m jwebot_config \
|
||||
validate "${profile_id}"
|
||||
fi
|
||||
|
||||
progress 5 6 "private state permissions"
|
||||
install -d -o "${target_user}" -g "${target_user}" -m 0700 \
|
||||
"${target_home}/.config/jwebot" \
|
||||
"${target_home}/.local/state/jwebot" \
|
||||
"${target_home}/.local/state/jwebot-edge" \
|
||||
"${target_home}/.local/state/wechat-adaptive-ocr"
|
||||
|
||||
progress 6 6 "prepare ready"
|
||||
cat <<EOF
|
||||
Edit and activate:
|
||||
${target_home}/.config/jwebot/profiles/${profile_id}/
|
||||
|
||||
Then install and sign in to desktop WeChat on display :1 before running:
|
||||
$0 verify ${source_dir} ${target_user} ${profile_id}
|
||||
EOF
|
||||
}
|
||||
|
||||
verify() {
|
||||
progress 1 5 "runtime account"
|
||||
id "${target_user}" >/dev/null
|
||||
target_home=$(account_home)
|
||||
[[ -d "${target_home}" ]]
|
||||
|
||||
progress 2 5 "runtime dependencies"
|
||||
for command in xdotool scrot xclip wmctrl tesseract; do
|
||||
command -v "${command}" >/dev/null
|
||||
done
|
||||
"${runtime_python}" -c \
|
||||
'import cv2,numpy,PIL,rapidocr,jwebot_config,jwebot_kernel'
|
||||
|
||||
progress 3 5 "configuration profile"
|
||||
as_runtime_user "${runtime_python}" -m jwebot_config validate "${profile_id}"
|
||||
as_runtime_user "${runtime_python}" -m jwebot_config activate "${profile_id}"
|
||||
|
||||
progress 4 5 "repository gate"
|
||||
PATH="${runtime_root}/venv/bin:${PATH}" \
|
||||
"${source_dir}/tools/check-config.sh"
|
||||
PATH="${runtime_root}/venv/bin:${PATH}" \
|
||||
"${source_dir}/tools/check-secrets.py"
|
||||
|
||||
progress 5 5 "desktop prerequisites"
|
||||
/usr/sbin/runuser -u "${target_user}" -- /usr/bin/env \
|
||||
HOME="${target_home}" \
|
||||
DISPLAY=:1 \
|
||||
XAUTHORITY="${target_home}/.Xauthority" \
|
||||
xdotool search --onlyvisible --class wechat >/dev/null
|
||||
echo "[JWeBot] verify ready"
|
||||
}
|
||||
|
||||
deploy() {
|
||||
verify
|
||||
progress 1 2 "coordinated deployment"
|
||||
JWEBOT_RUNTIME_PYTHON="${runtime_python}" \
|
||||
"${source_dir}/deploy/scripts/deploy-jwebot-production.sh" \
|
||||
"${source_dir}" "${target_user}"
|
||||
progress 2 2 "running"
|
||||
}
|
||||
|
||||
case "${action}" in
|
||||
prepare) prepare ;;
|
||||
verify) verify ;;
|
||||
deploy) deploy ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
Reference in New Issue
Block a user