109 lines
3.1 KiB
TypeScript
109 lines
3.1 KiB
TypeScript
import { $ } from "bun"
|
|
import { writeFileSync } from "fs"
|
|
|
|
const AP_SERVICE_FILE = "/etc/systemd/system/phone-ap.service"
|
|
const WEB_SERVICE_FILE = "/etc/systemd/system/phone-web.service"
|
|
const PHONE_SERVICE_FILE = "/etc/systemd/system/phone.service"
|
|
|
|
export const setupServices = async (installDir: string) => {
|
|
console.log("\nInstalling systemd services...")
|
|
|
|
// Detect user from environment or use default
|
|
// SUDO_USER is set when running with sudo, which is what we want
|
|
const serviceUser = process.env.SERVICE_USER || process.env.SUDO_USER || process.env.USER || "corey"
|
|
const userUid = await $`id -u ${serviceUser}`.text().then((s) => s.trim())
|
|
|
|
console.log(`Setting up services for user: ${serviceUser} (UID: ${userUid})`)
|
|
|
|
// Find where bun is installed
|
|
const bunPath = await $`which bun`
|
|
.quiet()
|
|
.nothrow()
|
|
.text()
|
|
.then((p) => p.trim())
|
|
|
|
if (!bunPath) {
|
|
console.error("Error: bun not found in PATH. Please ensure bun is available system-wide.")
|
|
process.exit(1)
|
|
}
|
|
console.log(`Using bun at: ${bunPath}`)
|
|
|
|
// Create AP monitor service
|
|
const apServiceContent = `[Unit]
|
|
Description=Phone WiFi AP Monitor
|
|
After=network.target
|
|
Before=phone-web.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=${bunPath} ${installDir}/src/services/ap-monitor.ts
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
`
|
|
writeFileSync(AP_SERVICE_FILE, apServiceContent, "utf8")
|
|
console.log("✓ Created phone-ap.service")
|
|
|
|
// Create web server service
|
|
const webServiceContent = `[Unit]
|
|
Description=Phone Web Server
|
|
After=network.target phone-ap.service
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=${bunPath} ${installDir}/src/services/server/server.tsx
|
|
WorkingDirectory=${installDir}
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
`
|
|
writeFileSync(WEB_SERVICE_FILE, webServiceContent, "utf8")
|
|
console.log("✓ Created phone-web.service")
|
|
|
|
// Create phone service (system service with environment variables for audio access)
|
|
const phoneServiceContent = `[Unit]
|
|
Description=Phone Application
|
|
After=network.target sound.target
|
|
Requires=sound.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=${serviceUser}
|
|
Group=audio
|
|
Environment=XDG_RUNTIME_DIR=/run/user/${userUid}
|
|
Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${userUid}/bus
|
|
ExecStart=${bunPath} ${installDir}/src/main.ts
|
|
WorkingDirectory=${installDir}
|
|
EnvironmentFile=${installDir}/.env
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
`
|
|
writeFileSync(PHONE_SERVICE_FILE, phoneServiceContent, "utf8")
|
|
console.log("✓ Created phone.service")
|
|
|
|
await $`systemctl daemon-reload`
|
|
await $`systemctl enable phone-ap.service`
|
|
await $`systemctl enable phone-web.service`
|
|
await $`systemctl enable phone.service`
|
|
console.log("✓ Services enabled")
|
|
|
|
console.log("\nRestarting the services...")
|
|
await $`systemctl restart phone-ap.service`
|
|
await $`systemctl restart phone-web.service`
|
|
await $`systemctl restart phone.service`
|
|
console.log("✓ Services restarted")
|
|
}
|