mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-07-04 16:23:04 +02:00
feat: virtualbox remote control scripts
This commit is contained in:
parent
e7527a3d32
commit
b2facbc444
416
scripts/control_from_mobile.sh
Executable file
416
scripts/control_from_mobile.sh
Executable file
@ -0,0 +1,416 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
SCRIPT_NAME="$(basename "$0")"
|
||||
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/control-from-mobile"
|
||||
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/control-from-mobile"
|
||||
PASSWORD_FILE="$CONFIG_DIR/vnc.pass"
|
||||
ENV_FILE="$CONFIG_DIR/env"
|
||||
RUNNER_FILE="$CONFIG_DIR/start-x11vnc.sh"
|
||||
SERVICE_NAME="control-from-mobile.service"
|
||||
SYSTEMD_USER_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user"
|
||||
SERVICE_FILE="$SYSTEMD_USER_DIR/$SERVICE_NAME"
|
||||
DEFAULT_DISPLAY="${DISPLAY:-:0}"
|
||||
DEFAULT_PORT=5901
|
||||
DEFAULT_BIND_ADDR="0.0.0.0"
|
||||
readonly SCRIPT_NAME CONFIG_DIR STATE_DIR PASSWORD_FILE ENV_FILE RUNNER_FILE SERVICE_NAME SYSTEMD_USER_DIR SERVICE_FILE DEFAULT_DISPLAY DEFAULT_PORT DEFAULT_BIND_ADDR
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: control_from_mobile.sh <command> [options]
|
||||
|
||||
Commands:
|
||||
setup [--force-password] Install dependencies, create configs, and write the systemd user service.
|
||||
start Start the VNC bridge (via systemd user unit when available).
|
||||
stop Stop the bridge.
|
||||
restart Restart the bridge.
|
||||
status Show whether the bridge service is running.
|
||||
enable Enable the service so it starts after login.
|
||||
disable Disable automatic start after login.
|
||||
info Show connection details and Android app suggestions.
|
||||
uninstall Stop the service and remove generated files (keeps password unless --purge).
|
||||
help Show this message.
|
||||
|
||||
Options:
|
||||
--force-password Regenerate the VNC password during setup.
|
||||
--purge Delete the stored VNC password during uninstall.
|
||||
|
||||
Examples:
|
||||
./control_from_mobile.sh setup
|
||||
./control_from_mobile.sh start
|
||||
./control_from_mobile.sh info
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
log() {
|
||||
printf '[%s] %s\n' "$SCRIPT_NAME" "$*"
|
||||
}
|
||||
|
||||
warn() {
|
||||
printf '[%s] %s\n' "$SCRIPT_NAME" "$*" >&2
|
||||
}
|
||||
|
||||
die() {
|
||||
warn "$*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
require_non_root() {
|
||||
if [[ "${EUID:-$(id -u)}" -eq 0 ]]; then
|
||||
die "Run this script as a regular desktop user, not root."
|
||||
fi
|
||||
}
|
||||
|
||||
prompt_yes_no() {
|
||||
local prompt="$1"
|
||||
local reply
|
||||
read -r -p "$prompt [y/N]: " reply
|
||||
case "$reply" in
|
||||
[Yy][Ee][Ss]|[Yy]) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
ensure_directories() {
|
||||
mkdir -p "$CONFIG_DIR" "$STATE_DIR" "$SYSTEMD_USER_DIR"
|
||||
chmod 700 "$CONFIG_DIR"
|
||||
}
|
||||
|
||||
missing_commands() {
|
||||
local missing=()
|
||||
for cmd in "$@"; do
|
||||
if ! command -v "$cmd" >/dev/null 2>&1; then
|
||||
missing+=("$cmd")
|
||||
fi
|
||||
done
|
||||
printf '%s\n' "${missing[@]-}"
|
||||
}
|
||||
|
||||
install_dependencies() {
|
||||
if ! command -v systemctl >/dev/null 2>&1; then
|
||||
die "systemctl not found. Install systemd before running this script."
|
||||
fi
|
||||
|
||||
local required=(x11vnc qrencode ssh)
|
||||
local needed=()
|
||||
mapfile -t needed < <(missing_commands "${required[@]}")
|
||||
if (( ${#needed[@]} == 0 )); then
|
||||
log "All required packages (${required[*]}) are present."
|
||||
return
|
||||
fi
|
||||
|
||||
if command -v pacman >/dev/null 2>&1; then
|
||||
log "Installing missing packages: ${needed[*]}"
|
||||
sudo pacman -S --needed --noconfirm "${needed[@]}"
|
||||
else
|
||||
die "Missing commands (${needed[*]}). Install them manually and rerun setup."
|
||||
fi
|
||||
}
|
||||
|
||||
create_password_file() {
|
||||
local force=${1:-0}
|
||||
if [[ -f "$PASSWORD_FILE" && "$force" -ne 1 ]];
|
||||
then
|
||||
log "Using existing VNC password file at $PASSWORD_FILE"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ -f "$PASSWORD_FILE" ]]; then
|
||||
if ! prompt_yes_no "Regenerate the stored VNC password?"; then
|
||||
log "Keeping existing password."
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
local password confirm generated=0
|
||||
read -rsp "Enter VNC password (leave blank to auto-generate): " password
|
||||
printf '\n'
|
||||
if [[ -z "$password" ]]; then
|
||||
generated=1
|
||||
password=$(LC_ALL=C tr -dc 'A-Za-z0-9' </dev/urandom | head -c 8)
|
||||
log "Generated VNC password: $password"
|
||||
else
|
||||
read -rsp "Confirm password: " confirm
|
||||
printf '\n'
|
||||
if [[ "$password" != "$confirm" ]]; then
|
||||
die "Passwords do not match."
|
||||
fi
|
||||
fi
|
||||
|
||||
local tmp
|
||||
tmp=$(mktemp)
|
||||
x11vnc -storepasswd "$password" "$tmp" >/dev/null
|
||||
install -m 600 "$tmp" "$PASSWORD_FILE"
|
||||
rm -f "$tmp"
|
||||
|
||||
if (( generated == 0 )); then
|
||||
log "Password stored securely at $PASSWORD_FILE (hashed)."
|
||||
else
|
||||
log "Please write down the generated password; it will be needed on your Android device."
|
||||
fi
|
||||
}
|
||||
|
||||
create_env_file() {
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
return
|
||||
fi
|
||||
cat >"$ENV_FILE" <<EOF
|
||||
# control-from-mobile configuration
|
||||
# Adjust these values if needed and rerun: systemctl --user restart $SERVICE_NAME
|
||||
X11_DISPLAY="$DEFAULT_DISPLAY"
|
||||
VNC_PORT="$DEFAULT_PORT"
|
||||
# Use 127.0.0.1 to force SSH tunnel-only access, or 0.0.0.0 to expose on LAN.
|
||||
VNC_BIND_ADDR="$DEFAULT_BIND_ADDR"
|
||||
EOF
|
||||
chmod 600 "$ENV_FILE"
|
||||
}
|
||||
|
||||
create_runner_script() {
|
||||
cat >"$RUNNER_FILE" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
CONFIG_DIR="$(dirname "$(readlink -f "$0")")"
|
||||
PASSWORD_FILE="$CONFIG_DIR/vnc.pass"
|
||||
ENV_FILE="$CONFIG_DIR/env"
|
||||
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/control-from-mobile"
|
||||
mkdir -p "$STATE_DIR"
|
||||
|
||||
if [[ ! -f "$PASSWORD_FILE" ]]; then
|
||||
echo "Missing VNC password file at $PASSWORD_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
# shellcheck disable=SC1090
|
||||
source "$ENV_FILE"
|
||||
fi
|
||||
|
||||
X11_DISPLAY="${X11_DISPLAY:-${DISPLAY:-:0}}"
|
||||
VNC_PORT="${VNC_PORT:-5901}"
|
||||
VNC_BIND_ADDR="${VNC_BIND_ADDR:-0.0.0.0}"
|
||||
|
||||
LOG_FILE="$STATE_DIR/x11vnc.log"
|
||||
exec /usr/bin/x11vnc \
|
||||
-display "$X11_DISPLAY" \
|
||||
-rfbport "$VNC_PORT" \
|
||||
-listen "$VNC_BIND_ADDR" \
|
||||
-forever \
|
||||
-shared \
|
||||
-auth guess \
|
||||
-rfbauth "$PASSWORD_FILE" \
|
||||
-noxdamage \
|
||||
-repeat \
|
||||
-ncache 10 \
|
||||
-ncache_cr \
|
||||
-o "$LOG_FILE"
|
||||
EOF
|
||||
chmod 700 "$RUNNER_FILE"
|
||||
}
|
||||
|
||||
create_service_file() {
|
||||
cat >"$SERVICE_FILE" <<EOF
|
||||
[Unit]
|
||||
Description=Expose X11 desktop over VNC for Android control
|
||||
After=graphical-session.target
|
||||
PartOf=graphical-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
EnvironmentFile=$ENV_FILE
|
||||
ExecStart=$RUNNER_FILE
|
||||
Restart=on-failure
|
||||
RestartSec=2
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF
|
||||
}
|
||||
|
||||
reload_user_daemon() {
|
||||
systemctl --user daemon-reload
|
||||
}
|
||||
|
||||
ensure_service_present() {
|
||||
if [[ ! -f "$SERVICE_FILE" || ! -x "$RUNNER_FILE" ]]; then
|
||||
die "Service files missing. Run: $SCRIPT_NAME setup"
|
||||
fi
|
||||
}
|
||||
|
||||
start_service() {
|
||||
ensure_service_present
|
||||
systemctl --user start "$SERVICE_NAME"
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
systemctl --user stop "$SERVICE_NAME" || true
|
||||
}
|
||||
|
||||
status_service() {
|
||||
if systemctl --user is-active --quiet "$SERVICE_NAME"; then
|
||||
log "Service is active."
|
||||
else
|
||||
log "Service is inactive."
|
||||
fi
|
||||
systemctl --user status "$SERVICE_NAME" --no-pager || true
|
||||
}
|
||||
|
||||
enable_service() {
|
||||
ensure_service_present
|
||||
systemctl --user enable "$SERVICE_NAME"
|
||||
}
|
||||
|
||||
disable_service() {
|
||||
systemctl --user disable "$SERVICE_NAME" || true
|
||||
}
|
||||
|
||||
show_info() {
|
||||
ensure_service_present
|
||||
# shellcheck disable=SC1090
|
||||
[[ -f "$ENV_FILE" ]] && source "$ENV_FILE"
|
||||
local port="${VNC_PORT:-$DEFAULT_PORT}"
|
||||
local bind_addr="${VNC_BIND_ADDR:-$DEFAULT_BIND_ADDR}"
|
||||
local display="${X11_DISPLAY:-$DEFAULT_DISPLAY}"
|
||||
|
||||
local is_active="inactive"
|
||||
if systemctl --user is-active --quiet "$SERVICE_NAME"; then
|
||||
is_active="active"
|
||||
fi
|
||||
|
||||
log "Service status: $is_active"
|
||||
log "Display: $display"
|
||||
log "Listening address: $bind_addr"
|
||||
log "VNC port: $port"
|
||||
log "Password file: $PASSWORD_FILE"
|
||||
|
||||
local -a ip_list=()
|
||||
if command -v hostname >/dev/null 2>&1; then
|
||||
while IFS= read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
ip_list+=("$line")
|
||||
done < <(hostname -I 2>/dev/null | tr ' ' '\n' | grep -E '^[0-9]' || true)
|
||||
fi
|
||||
|
||||
if (( ${#ip_list[@]} > 0 )); then
|
||||
log "Detected LAN IPs:"
|
||||
for ip in "${ip_list[@]}"; do
|
||||
printf ' - %s\n' "$ip"
|
||||
done
|
||||
else
|
||||
warn "Could not detect LAN IPs."
|
||||
fi
|
||||
|
||||
printf '\nRecommended Android clients (FOSS):\n'
|
||||
printf ' • bVNC (available on F-Droid) — supports full control.\n'
|
||||
printf ' • Termux + OpenSSH for establishing an SSH tunnel when exposing only on 127.0.0.1.\n'
|
||||
printf '\nConnect via VNC:\n'
|
||||
printf ' Host: <your-ip>\n Port: %s\n Password: <stored during setup>\n' "$port"
|
||||
|
||||
local qr_host
|
||||
if (( ${#ip_list[@]} > 0 )); then
|
||||
qr_host="${ip_list[0]}"
|
||||
else
|
||||
qr_host="$bind_addr"
|
||||
if [[ "$qr_host" == "0.0.0.0" || "$qr_host" == "::" ]]; then
|
||||
qr_host="127.0.0.1"
|
||||
fi
|
||||
warn "Using fallback host $qr_host for QR code; replace with an accessible IP if needed."
|
||||
fi
|
||||
|
||||
if command -v qrencode >/dev/null 2>&1; then
|
||||
printf '\nConnection QR (vnc://%s:%s):\n' "$qr_host" "$port"
|
||||
qrencode -o - "vnc://$qr_host:$port" -t ASCII || true
|
||||
else
|
||||
warn "qrencode not found; reinstall qrencode to get QR codes."
|
||||
fi
|
||||
|
||||
printf '\nFor encrypted access outside your LAN, use Termux on Android:\n'
|
||||
printf ' ssh -L %s:localhost:%s <user>@<public-ip>\n' "$port" "$port"
|
||||
printf 'Then point bVNC to 127.0.0.1:%s.\n' "$port"
|
||||
}
|
||||
|
||||
uninstall_files() {
|
||||
local purge_password=${1:-0}
|
||||
stop_service
|
||||
disable_service
|
||||
rm -f "$SERVICE_FILE"
|
||||
rm -f "$RUNNER_FILE"
|
||||
rm -f "$ENV_FILE"
|
||||
if (( purge_password )); then
|
||||
rm -f "$PASSWORD_FILE"
|
||||
log "Removed password file."
|
||||
fi
|
||||
reload_user_daemon
|
||||
log "Removed generated files."
|
||||
}
|
||||
|
||||
main() {
|
||||
require_non_root
|
||||
|
||||
local cmd="${1:-}"
|
||||
shift || true
|
||||
|
||||
case "$cmd" in
|
||||
setup)
|
||||
local force=0
|
||||
if [[ "${1:-}" == "--force-password" ]]; then
|
||||
force=1
|
||||
shift || true
|
||||
fi
|
||||
ensure_directories
|
||||
install_dependencies
|
||||
create_password_file "$force"
|
||||
create_env_file
|
||||
create_runner_script
|
||||
create_service_file
|
||||
reload_user_daemon
|
||||
log "Setup complete. Start the service with: $SCRIPT_NAME start"
|
||||
;;
|
||||
start)
|
||||
start_service
|
||||
show_info
|
||||
;;
|
||||
stop)
|
||||
stop_service
|
||||
;;
|
||||
restart)
|
||||
stop_service
|
||||
start_service
|
||||
;;
|
||||
status)
|
||||
status_service
|
||||
;;
|
||||
enable)
|
||||
enable_service
|
||||
;;
|
||||
disable)
|
||||
disable_service
|
||||
;;
|
||||
info)
|
||||
show_info
|
||||
;;
|
||||
uninstall)
|
||||
local purge=0
|
||||
if [[ "${1:-}" == "--purge" ]]; then
|
||||
purge=1
|
||||
shift || true
|
||||
fi
|
||||
uninstall_files "$purge"
|
||||
;;
|
||||
help|--help|-h|"" )
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
die "Unknown command: $cmd"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
196
scripts/fix_virtualbox.sh
Normal file
196
scripts/fix_virtualbox.sh
Normal file
@ -0,0 +1,196 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
on_error() {
|
||||
local exit_code=$?
|
||||
local line_number=$1
|
||||
printf '\033[1;31m[ERROR]\033[0m Unexpected failure at line %s (exit code %s).\n' "${line_number}" "${exit_code}" >&2
|
||||
}
|
||||
trap 'on_error ${LINENO}' ERR
|
||||
|
||||
log_info() {
|
||||
printf '\033[1;34m[INFO]\033[0m %s\n' "$*"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
printf '\033[1;33m[WARN]\033[0m %s\n' "$*"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
printf '\033[1;31m[ERROR]\033[0m %s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
require_root() {
|
||||
if [[ "${EUID}" -ne 0 ]]; then
|
||||
log_error "This script must be run as root (try again with sudo)."
|
||||
fi
|
||||
}
|
||||
|
||||
require_pacman() {
|
||||
if ! command -v pacman >/dev/null 2>&1; then
|
||||
log_error "pacman not found. This script is intended for Arch Linux systems."
|
||||
fi
|
||||
}
|
||||
|
||||
detect_kernel_release() {
|
||||
uname -r
|
||||
}
|
||||
|
||||
select_host_package() {
|
||||
local kernel_release=$1
|
||||
case "${kernel_release}" in
|
||||
*-lts)
|
||||
echo "virtualbox-host-modules-lts"
|
||||
;;
|
||||
*-arch*)
|
||||
echo "virtualbox-host-modules-arch"
|
||||
;;
|
||||
*)
|
||||
echo "virtualbox-host-dkms"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
collect_kernel_headers() {
|
||||
local -a headers=()
|
||||
local kernel_pkg header_pkg
|
||||
for kernel_pkg in linux linux-lts linux-zen linux-hardened; do
|
||||
if pacman -Q "${kernel_pkg}" >/dev/null 2>&1; then
|
||||
header_pkg="${kernel_pkg}-headers"
|
||||
headers+=("${header_pkg}")
|
||||
fi
|
||||
done
|
||||
if [[ ${#headers[@]} -gt 0 ]]; then
|
||||
printf '%s\n' "${headers[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
maybe_remove_conflicting_host_packages() {
|
||||
local selected_package=$1
|
||||
local -a candidates=("virtualbox-host-dkms" "virtualbox-host-modules-arch" "virtualbox-host-modules-lts")
|
||||
local pkg
|
||||
for pkg in "${candidates[@]}"; do
|
||||
if [[ "${pkg}" != "${selected_package}" ]] && pacman -Q "${pkg}" >/dev/null 2>&1; then
|
||||
log_warn "Removing conflicting package ${pkg} before installing ${selected_package}."
|
||||
pacman -Rsn "${PACMAN_REMOVE_FLAGS[@]}" "${pkg}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
install_packages() {
|
||||
local -a packages=()
|
||||
local -a headers=()
|
||||
local host_package=$1
|
||||
shift
|
||||
if [[ $# -gt 0 ]]; then
|
||||
mapfile -t headers < <(printf '%s\n' "$@" | sort -u)
|
||||
fi
|
||||
packages+=("virtualbox" "virtualbox-guest-iso" "${host_package}")
|
||||
if [[ "${host_package}" == "virtualbox-host-dkms" ]]; then
|
||||
packages+=("dkms")
|
||||
fi
|
||||
if [[ ${#headers[@]} -gt 0 ]]; then
|
||||
packages+=("${headers[@]}")
|
||||
fi
|
||||
log_info "Installing packages: ${packages[*]}"
|
||||
pacman -S "${PACMAN_INSTALL_FLAGS[@]}" "${packages[@]}"
|
||||
}
|
||||
|
||||
rebuild_virtualbox_modules() {
|
||||
local host_package=$1
|
||||
if [[ "${host_package}" == "virtualbox-host-dkms" ]]; then
|
||||
if command -v dkms >/dev/null 2>&1; then
|
||||
log_info "Rebuilding VirtualBox DKMS modules for all installed kernels."
|
||||
dkms autoinstall
|
||||
else
|
||||
log_warn "dkms command not found; skipping DKMS rebuild."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
reload_virtualbox_modules() {
|
||||
log_info "Loading VirtualBox kernel modules."
|
||||
if [[ -x /sbin/rcvboxdrv ]]; then
|
||||
/sbin/rcvboxdrv setup || log_warn "rcvboxdrv reported an issue while setting up modules."
|
||||
elif [[ -x /usr/lib/virtualbox/vboxdrv.sh ]]; then
|
||||
/usr/lib/virtualbox/vboxdrv.sh setup || log_warn "vboxdrv.sh reported an issue while setting up modules."
|
||||
fi
|
||||
|
||||
local -a modules=(vboxdrv vboxnetflt vboxnetadp vboxpci)
|
||||
local mod
|
||||
for mod in "${modules[@]}"; do
|
||||
if ! lsmod | awk '{print $1}' | grep -Fxq "${mod}"; then
|
||||
if ! modprobe "${mod}" >/dev/null 2>&1; then
|
||||
log_warn "Module ${mod} failed to load; check dmesg for details."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if ! lsmod | awk '{print $1}' | grep -Fxq "vboxdrv"; then
|
||||
log_error "VirtualBox kernel driver (vboxdrv) failed to load. Review /var/log and dmesg output for clues."
|
||||
fi
|
||||
log_info "VirtualBox kernel driver loaded successfully."
|
||||
}
|
||||
|
||||
warn_if_secure_boot_enabled() {
|
||||
local secure_boot_file
|
||||
if [[ -d /sys/firmware/efi/efivars ]]; then
|
||||
secure_boot_file=$(find /sys/firmware/efi/efivars -maxdepth 1 -name 'SecureBoot-*' -print -quit 2>/dev/null || true)
|
||||
if [[ -n "${secure_boot_file}" && -r "${secure_boot_file}" ]]; then
|
||||
local state
|
||||
state=$(hexdump -n 1 -s 4 -e '1 "%d"' "${secure_boot_file}" 2>/dev/null || echo "0")
|
||||
if [[ "${state}" == "1" ]]; then
|
||||
log_warn "EFI Secure Boot appears to be enabled. You may need to sign VirtualBox modules manually."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
remind_group_membership() {
|
||||
local invoking_user=${SUDO_USER:-}
|
||||
if [[ -n "${invoking_user}" && "${invoking_user}" != "root" ]]; then
|
||||
if ! id -nG "${invoking_user}" | grep -qw "vboxusers"; then
|
||||
log_warn "User ${invoking_user} is not in the vboxusers group. Add them with: sudo gpasswd -a ${invoking_user} vboxusers"
|
||||
else
|
||||
log_info "User ${invoking_user} is already in the vboxusers group."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
require_root
|
||||
require_pacman
|
||||
|
||||
PACMAN_INSTALL_FLAGS=(--needed)
|
||||
PACMAN_REMOVE_FLAGS=()
|
||||
if [[ "${PACMAN_CONFIRM:-0}" == "1" ]]; then
|
||||
log_info "PACMAN_CONFIRM=1 detected; pacman will prompt for confirmation."
|
||||
else
|
||||
PACMAN_INSTALL_FLAGS+=(--noconfirm)
|
||||
PACMAN_REMOVE_FLAGS+=(--noconfirm)
|
||||
fi
|
||||
|
||||
local kernel_release host_package
|
||||
kernel_release=$(detect_kernel_release)
|
||||
log_info "Detected running kernel: ${kernel_release}"
|
||||
host_package=$(select_host_package "${kernel_release}")
|
||||
log_info "Selected VirtualBox host package: ${host_package}"
|
||||
|
||||
mapfile -t kernel_headers < <(collect_kernel_headers)
|
||||
if [[ "${host_package}" == "virtualbox-host-dkms" && ${#kernel_headers[@]} -eq 0 ]]; then
|
||||
log_warn "No matching kernel headers detected. Ensure you've installed headers for your kernel so DKMS can build modules."
|
||||
fi
|
||||
|
||||
maybe_remove_conflicting_host_packages "${host_package}"
|
||||
install_packages "${host_package}" "${kernel_headers[@]}"
|
||||
rebuild_virtualbox_modules "${host_package}"
|
||||
reload_virtualbox_modules
|
||||
warn_if_secure_boot_enabled
|
||||
remind_group_membership
|
||||
|
||||
log_info "VirtualBox installation and driver setup complete."
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@ -120,7 +120,6 @@ function is_blocked_package_name() {
|
||||
|
||||
# Explicitly blocked names list
|
||||
local blocked=(
|
||||
"freetube-bin" "virtualbox" "virtualbox-host-modules-arch" "virtualbox-guest-iso" "virtualbox-ext-vnc" "virtualbox-guest-utils" "virtualbox-host-dkms"
|
||||
"brave" "brave-bin" "freetube" "seamonkey-bin" "seamonkey" "min-browser-bin" "min-browser" "beaker-browser" "catalyst-browser-bin" "hamsket" "min"
|
||||
"vieb-bin" "yt-dlp" "yt-dlp-git" "stremio" "stremio-git" "angelfish" "dooble" "eric" "falkon" "fiery" "maui" "konqueror" "liri" "otter"
|
||||
"quotebrowser" "beaker" "catalyst" "badwolf" "eolie" "epiphany" "surf" "uzbl" "vimb" "vimb-git" "web-browser" "web-browser-git"
|
||||
@ -222,30 +221,6 @@ function check_for_steam() {
|
||||
return 1 # No steam package found
|
||||
}
|
||||
|
||||
# Function to check if user is trying to install virtualbox (always challenge-eligible package)
|
||||
function check_for_virtualbox() {
|
||||
# List of packages that require challenge (virtualbox packages)
|
||||
local virtualbox_packages=("virtualbox" "virtualbox-host-modules-arch" "virtualbox-guest-iso" "virtualbox-ext-vnc" "virtualbox-guest-utils" "virtualbox-host-dkms")
|
||||
|
||||
# Check if the command is an installation command
|
||||
if [[ "$1" == "-S" || "$1" == "-Sy" || "$1" == "-Syu" || "$1" == "-Syyu" || "$1" == "-U" ]]; then
|
||||
# Check all arguments
|
||||
for arg in "$@"; do
|
||||
# Strip repository prefix if present (like extra/ or community/)
|
||||
local package_name="${arg##*/}"
|
||||
|
||||
# Check if argument matches virtualbox
|
||||
for package in "${virtualbox_packages[@]}"; do
|
||||
if [[ "$arg" == "$package" || "$arg" == *"/$package-"* || "$arg" == *"/$package/"* ||
|
||||
"$arg" == *"/$package" || "$package_name" == "$package" ]]; then
|
||||
return 0 # VirtualBox package found
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
return 1 # No virtualbox package found
|
||||
}
|
||||
|
||||
# Function to check if current day is a weekday (after 4PM Friday until midnight Sunday)
|
||||
function is_weekday() {
|
||||
local day_of_week=$(date +%u) # %u gives 1-7 (Monday is 1, Sunday is 7)
|
||||
@ -535,14 +510,6 @@ if check_for_always_blocked "$@"; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for virtualbox (always challenge-eligible package)
|
||||
if check_for_virtualbox "$@"; then
|
||||
prompt_for_virtualbox_challenge
|
||||
if [[ $? -ne 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for steam (challenge-eligible package)
|
||||
if check_for_steam "$@"; then
|
||||
prompt_for_steam_challenge
|
||||
|
||||
Loading…
Reference in New Issue
Block a user