Test os configuration
This commit is contained in:
422
os/install.sh
Normal file
422
os/install.sh
Normal file
@@ -0,0 +1,422 @@
|
||||
#!/bin/bash
|
||||
|
||||
# OpenWall Dashboard Installer for Debian
|
||||
# Installs and configures the dashboard app for touch displays with 9:16 ratio
|
||||
# Supports Wayland session with auto-start
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
APP_USER="openwall"
|
||||
APP_DIR="/opt/openwall"
|
||||
DISPLAY_WIDTH="1080"
|
||||
DISPLAY_HEIGHT="1920"
|
||||
SERVICE_NAME="openwall-dashboard"
|
||||
|
||||
echo -e "${BLUE}OpenWall Dashboard Installer${NC}"
|
||||
echo -e "${BLUE}==============================${NC}"
|
||||
|
||||
# Check if running as root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo -e "${RED}This script must be run as root${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update system
|
||||
echo -e "${YELLOW}Updating system packages...${NC}"
|
||||
apt update && apt upgrade -y
|
||||
|
||||
# Install required packages
|
||||
echo -e "${YELLOW}Installing required packages...${NC}"
|
||||
apt install -y \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
build-essential \
|
||||
python3 \
|
||||
python3-pip \
|
||||
nodejs \
|
||||
npm \
|
||||
wayland-protocols \
|
||||
wayland-utils \
|
||||
weston \
|
||||
sway \
|
||||
swaylock \
|
||||
swayidle \
|
||||
xwayland \
|
||||
libdrm2 \
|
||||
libinput-tools \
|
||||
udev \
|
||||
systemd \
|
||||
xinput \
|
||||
x11-xserver-utils \
|
||||
mesa-utils \
|
||||
vulkan-tools \
|
||||
libgl1-mesa-dri \
|
||||
libgles2-mesa \
|
||||
libegl1-mesa \
|
||||
firefox-esr \
|
||||
chromium \
|
||||
fonts-liberation \
|
||||
fonts-dejavu-core \
|
||||
unclutter \
|
||||
xdotool
|
||||
|
||||
# Install Node.js LTS
|
||||
echo -e "${YELLOW}Installing Node.js LTS...${NC}"
|
||||
curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
|
||||
apt install -y nodejs
|
||||
|
||||
# Install pnpm
|
||||
echo -e "${YELLOW}Installing pnpm...${NC}"
|
||||
npm install -g pnpm
|
||||
|
||||
# Create application user
|
||||
echo -e "${YELLOW}Creating application user...${NC}"
|
||||
if ! id "$APP_USER" &>/dev/null; then
|
||||
useradd -m -s /bin/bash "$APP_USER"
|
||||
usermod -aG video,input,audio "$APP_USER"
|
||||
fi
|
||||
|
||||
# Create application directory
|
||||
echo -e "${YELLOW}Setting up application directory...${NC}"
|
||||
mkdir -p "$APP_DIR"
|
||||
chown "$APP_USER:$APP_USER" "$APP_DIR"
|
||||
|
||||
# Copy application files
|
||||
echo -e "${YELLOW}Installing application files...${NC}"
|
||||
if [ -d "$(dirname "$0")/../dashboard" ]; then
|
||||
cp -r "$(dirname "$0")/../dashboard/"* "$APP_DIR/"
|
||||
cp -r "$(dirname "$0")/../server" "$APP_DIR/"
|
||||
chown -R "$APP_USER:$APP_USER" "$APP_DIR"
|
||||
else
|
||||
echo -e "${RED}Dashboard directory not found. Please run this script from the OpenWall project root.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install application dependencies
|
||||
echo -e "${YELLOW}Installing application dependencies...${NC}"
|
||||
cd "$APP_DIR"
|
||||
sudo -u "$APP_USER" pnpm install
|
||||
|
||||
# Install server dependencies
|
||||
cd "$APP_DIR/server"
|
||||
sudo -u "$APP_USER" npm install
|
||||
|
||||
# Create Wayland session configuration
|
||||
echo -e "${YELLOW}Configuring Wayland session...${NC}"
|
||||
cat > /usr/share/wayland-sessions/openwall.desktop << EOF
|
||||
[Desktop Entry]
|
||||
Name=OpenWall Dashboard
|
||||
Comment=OpenWall Touch Dashboard Session
|
||||
Exec=/opt/openwall/start-session.sh
|
||||
Type=Application
|
||||
DesktopNames=openwall
|
||||
EOF
|
||||
|
||||
# Create session start script
|
||||
cat > "$APP_DIR/start-session.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# OpenWall Dashboard Session Starter
|
||||
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
|
||||
export XDG_SESSION_TYPE=wayland
|
||||
export XDG_CURRENT_DESKTOP=openwall
|
||||
export QT_QPA_PLATFORM=wayland
|
||||
export GDK_BACKEND=wayland
|
||||
export MOZ_ENABLE_WAYLAND=1
|
||||
|
||||
# Start Wayland compositor (Sway)
|
||||
exec sway --config /opt/openwall/sway-config
|
||||
EOF
|
||||
|
||||
chmod +x "$APP_DIR/start-session.sh"
|
||||
|
||||
# Create Sway configuration for dashboard
|
||||
cat > "$APP_DIR/sway-config" << EOF
|
||||
# OpenWall Dashboard Sway Configuration
|
||||
# Optimized for touch displays with 9:16 ratio
|
||||
|
||||
# Set display configuration
|
||||
output * {
|
||||
mode ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT}@60Hz
|
||||
scale 1
|
||||
transform normal
|
||||
bg #000000 solid_color
|
||||
}
|
||||
|
||||
# Input configuration for touch
|
||||
input type:touch {
|
||||
events enabled
|
||||
tap enabled
|
||||
natural_scroll enabled
|
||||
dwt disabled
|
||||
}
|
||||
|
||||
# Input configuration for touchpad
|
||||
input type:touchpad {
|
||||
events enabled
|
||||
tap enabled
|
||||
natural_scroll enabled
|
||||
dwt enabled
|
||||
accel_profile adaptive
|
||||
pointer_accel 0.3
|
||||
}
|
||||
|
||||
# Disable window decorations and gaps
|
||||
default_border none
|
||||
default_floating_border none
|
||||
gaps inner 0
|
||||
gaps outer 0
|
||||
|
||||
# Hide cursor after 3 seconds
|
||||
seat * hide_cursor 3000
|
||||
|
||||
# Disable screen timeout
|
||||
exec swayidle timeout 0 '' before-sleep 'true'
|
||||
|
||||
# Start the dashboard application
|
||||
exec /opt/openwall/start-dashboard.sh
|
||||
EOF
|
||||
|
||||
# Create dashboard start script
|
||||
cat > "$APP_DIR/start-dashboard.sh" << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
# Start the backend server
|
||||
cd /opt/openwall/server
|
||||
node index.js &
|
||||
|
||||
# Wait for server to start
|
||||
sleep 3
|
||||
|
||||
# Start the dashboard in fullscreen
|
||||
cd /opt/openwall
|
||||
pnpm run electron -- --kiosk --touch-events --disable-pinch --overscroll-history-navigation=0 --disable-features=TranslateUI
|
||||
EOF
|
||||
|
||||
chmod +x "$APP_DIR/start-dashboard.sh"
|
||||
|
||||
# Update Electron main process for kiosk mode
|
||||
cat > "$APP_DIR/src/main/index.js" << 'EOF'
|
||||
import { app, shell, BrowserWindow, screen } from 'electron'
|
||||
import { join } from 'path'
|
||||
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
||||
import icon from '../../resources/icon.png?asset'
|
||||
|
||||
function createWindow() {
|
||||
// Get the primary display
|
||||
const primaryDisplay = screen.getPrimaryDisplay()
|
||||
const { width, height } = primaryDisplay.workAreaSize
|
||||
|
||||
// Create the browser window in kiosk mode for touch displays
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: width,
|
||||
height: height,
|
||||
show: false,
|
||||
fullscreen: true,
|
||||
kiosk: true,
|
||||
frame: false,
|
||||
autoHideMenuBar: true,
|
||||
webPreferences: {
|
||||
preload: join(__dirname, '../preload/index.js'),
|
||||
sandbox: false,
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
webSecurity: false
|
||||
}
|
||||
})
|
||||
|
||||
// Disable zoom and context menu for touch interface
|
||||
mainWindow.webContents.on('before-input-event', (event, input) => {
|
||||
if (input.control && (input.key === '+' || input.key === '-' || input.key === '=')) {
|
||||
event.preventDefault()
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.webContents.on('context-menu', (event) => {
|
||||
event.preventDefault()
|
||||
})
|
||||
|
||||
mainWindow.on('ready-to-show', () => {
|
||||
mainWindow.show()
|
||||
mainWindow.setFullScreen(true)
|
||||
})
|
||||
|
||||
mainWindow.webContents.setWindowOpenHandler((details) => {
|
||||
shell.openExternal(details.url)
|
||||
return { action: 'deny' }
|
||||
})
|
||||
|
||||
// Load the app
|
||||
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||||
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
|
||||
} else {
|
||||
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
|
||||
}
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
electronApp.setAppUserModelId('com.openwall.dashboard')
|
||||
|
||||
app.on('browser-window-created', (_, window) => {
|
||||
optimizer.watchWindowShortcuts(window)
|
||||
})
|
||||
|
||||
createWindow()
|
||||
|
||||
app.on('activate', function () {
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
})
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') app.quit()
|
||||
})
|
||||
EOF
|
||||
|
||||
# Create systemd service for auto-start
|
||||
echo -e "${YELLOW}Creating systemd service...${NC}"
|
||||
cat > "/etc/systemd/system/${SERVICE_NAME}.service" << EOF
|
||||
[Unit]
|
||||
Description=OpenWall Dashboard Service
|
||||
After=graphical-session.target
|
||||
Wants=graphical-session.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=${APP_USER}
|
||||
Group=${APP_USER}
|
||||
WorkingDirectory=${APP_DIR}
|
||||
Environment=HOME=/home/${APP_USER}
|
||||
Environment=XDG_RUNTIME_DIR=/run/user/1001
|
||||
ExecStart=${APP_DIR}/start-dashboard.sh
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=graphical-session.target
|
||||
EOF
|
||||
|
||||
# Create udev rules for touch input
|
||||
echo -e "${YELLOW}Configuring touch input...${NC}"
|
||||
cat > /etc/udev/rules.d/99-openwall-touch.rules << 'EOF'
|
||||
# OpenWall touch input configuration
|
||||
SUBSYSTEM=="input", ATTRS{name}=="*touch*", ENV{LIBINPUT_CALIBRATION_MATRIX}="1 0 0 0 1 0"
|
||||
SUBSYSTEM=="input", ATTRS{name}=="*Touch*", ENV{LIBINPUT_CALIBRATION_MATRIX}="1 0 0 0 1 0"
|
||||
EOF
|
||||
|
||||
# Configure X11 display settings (fallback)
|
||||
echo -e "${YELLOW}Configuring display settings...${NC}"
|
||||
cat > /etc/X11/xorg.conf.d/99-openwall-display.conf << EOF
|
||||
Section "Monitor"
|
||||
Identifier "HDMI-1"
|
||||
Option "PreferredMode" "${DISPLAY_WIDTH}x${DISPLAY_HEIGHT}"
|
||||
Option "Position" "0 0"
|
||||
Option "Rotate" "normal"
|
||||
EndSection
|
||||
|
||||
Section "Screen"
|
||||
Identifier "Default Screen"
|
||||
Monitor "HDMI-1"
|
||||
DefaultDepth 24
|
||||
SubSection "Display"
|
||||
Depth 24
|
||||
Modes "${DISPLAY_WIDTH}x${DISPLAY_HEIGHT}"
|
||||
EndSubSection
|
||||
EndSection
|
||||
EOF
|
||||
|
||||
# Create auto-login configuration
|
||||
echo -e "${YELLOW}Configuring auto-login...${NC}"
|
||||
mkdir -p /etc/systemd/system/getty@tty1.service.d
|
||||
cat > /etc/systemd/system/getty@tty1.service.d/override.conf << EOF
|
||||
[Service]
|
||||
ExecStart=
|
||||
ExecStart=-/sbin/agetty --autologin ${APP_USER} --noclear %I \$TERM
|
||||
EOF
|
||||
|
||||
# Configure user session to start Wayland
|
||||
echo -e "${YELLOW}Configuring user session...${NC}"
|
||||
mkdir -p "/home/${APP_USER}/.config/systemd/user"
|
||||
cat > "/home/${APP_USER}/.config/systemd/user/openwall-session.service" << EOF
|
||||
[Unit]
|
||||
Description=OpenWall Dashboard Session
|
||||
After=graphical-session.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
ExecStart=/opt/openwall/start-session.sh
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF
|
||||
|
||||
# Set up user environment
|
||||
cat > "/home/${APP_USER}/.profile" << 'EOF'
|
||||
# OpenWall Dashboard Environment
|
||||
export XDG_SESSION_TYPE=wayland
|
||||
export XDG_CURRENT_DESKTOP=openwall
|
||||
export QT_QPA_PLATFORM=wayland
|
||||
export GDK_BACKEND=wayland
|
||||
export MOZ_ENABLE_WAYLAND=1
|
||||
|
||||
# Auto-start Wayland session on login
|
||||
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = "1" ]; then
|
||||
exec /opt/openwall/start-session.sh
|
||||
fi
|
||||
EOF
|
||||
|
||||
chown -R "${APP_USER}:${APP_USER}" "/home/${APP_USER}"
|
||||
|
||||
# Enable services
|
||||
echo -e "${YELLOW}Enabling services...${NC}"
|
||||
systemctl daemon-reload
|
||||
systemctl enable "${SERVICE_NAME}.service"
|
||||
|
||||
# Enable user service
|
||||
sudo -u "$APP_USER" systemctl --user enable openwall-session.service
|
||||
|
||||
# Build the application
|
||||
echo -e "${YELLOW}Building application...${NC}"
|
||||
cd "$APP_DIR"
|
||||
sudo -u "$APP_USER" pnpm run build
|
||||
|
||||
# Set file permissions
|
||||
chown -R "$APP_USER:$APP_USER" "$APP_DIR"
|
||||
chmod +x "$APP_DIR"/*.sh
|
||||
|
||||
# Reload udev rules
|
||||
udevadm control --reload-rules
|
||||
udevadm trigger
|
||||
|
||||
echo -e "${GREEN}Installation completed successfully!${NC}"
|
||||
echo -e "${GREEN}==============================${NC}"
|
||||
echo ""
|
||||
echo -e "${BLUE}Installation Summary:${NC}"
|
||||
echo -e "• Application installed to: ${APP_DIR}"
|
||||
echo -e "• User created: ${APP_USER}"
|
||||
echo -e "• Display configured for: ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT} (9:16 ratio)"
|
||||
echo -e "• Wayland session: openwall"
|
||||
echo -e "• Service: ${SERVICE_NAME}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Next steps:${NC}"
|
||||
echo -e "1. Reboot the system: ${BLUE}reboot${NC}"
|
||||
echo -e "2. The dashboard will start automatically on boot"
|
||||
echo -e "3. Access the dashboard at the configured display"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Manual control:${NC}"
|
||||
echo -e "• Start service: ${BLUE}systemctl start ${SERVICE_NAME}${NC}"
|
||||
echo -e "• Stop service: ${BLUE}systemctl stop ${SERVICE_NAME}${NC}"
|
||||
echo -e "• View logs: ${BLUE}journalctl -u ${SERVICE_NAME} -f${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}Reboot now to start the OpenWall Dashboard!${NC}"
|
Reference in New Issue
Block a user