refactor: rename Chrome references to Chromium
- Rename hook file: 0060-install-chrome -> 0060-install-chromium - Update all logs and comments to say "Chromium" instead of "Chrome" - Rename chromeStatus -> chromiumStatus in daemon - Update UI to show "Chromium Browser" instead of "Chrome Browser" - Update documentation (readme.plan.md, readme.hints.md) Note: Binary paths (/opt/chromium/chrome) remain as the actual Chromium executable is named "chrome"
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
* Runs as root via systemd and orchestrates:
|
* Runs as root via systemd and orchestrates:
|
||||||
* - Management UI on :3006
|
* - Management UI on :3006
|
||||||
* - Sway compositor as ecouser
|
* - Sway compositor as ecouser
|
||||||
* - Chrome browser in kiosk mode
|
* - Chromium browser in kiosk mode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EcoDaemon } from './ts/daemon/index.ts';
|
import { EcoDaemon } from './ts/daemon/index.ts';
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export class EcoDaemon {
|
|||||||
private uiServer: UIServer;
|
private uiServer: UIServer;
|
||||||
private logs: string[] = [];
|
private logs: string[] = [];
|
||||||
private swayStatus: ServiceStatus = { state: 'stopped' };
|
private swayStatus: ServiceStatus = { state: 'stopped' };
|
||||||
private chromeStatus: ServiceStatus = { state: 'stopped' };
|
private chromiumStatus: ServiceStatus = { state: 'stopped' };
|
||||||
|
|
||||||
constructor(config?: Partial<DaemonConfig>) {
|
constructor(config?: Partial<DaemonConfig>) {
|
||||||
this.config = {
|
this.config = {
|
||||||
@@ -64,8 +64,8 @@ export class EcoDaemon {
|
|||||||
return {
|
return {
|
||||||
sway: this.swayStatus.state === 'running',
|
sway: this.swayStatus.state === 'running',
|
||||||
swayStatus: this.swayStatus,
|
swayStatus: this.swayStatus,
|
||||||
chrome: this.chromeStatus.state === 'running',
|
chromium: this.chromiumStatus.state === 'running',
|
||||||
chromeStatus: this.chromeStatus,
|
chromiumStatus: this.chromiumStatus,
|
||||||
systemInfo: this.systemInfo.getInfo(),
|
systemInfo: this.systemInfo.getInfo(),
|
||||||
logs: this.logs.slice(-50),
|
logs: this.logs.slice(-50),
|
||||||
};
|
};
|
||||||
@@ -79,7 +79,7 @@ export class EcoDaemon {
|
|||||||
await this.uiServer.start();
|
await this.uiServer.start();
|
||||||
this.log('Management UI started successfully');
|
this.log('Management UI started successfully');
|
||||||
|
|
||||||
// Start the Sway/Chrome initialization in the background
|
// Start the Sway/Chromium initialization in the background
|
||||||
// This allows the UI server to remain responsive even if Sway fails
|
// This allows the UI server to remain responsive even if Sway fails
|
||||||
this.startServicesInBackground();
|
this.startServicesInBackground();
|
||||||
|
|
||||||
@@ -95,15 +95,15 @@ export class EcoDaemon {
|
|||||||
this.log('Checking seatd service...');
|
this.log('Checking seatd service...');
|
||||||
await this.ensureSeatd();
|
await this.ensureSeatd();
|
||||||
|
|
||||||
// Try to start Sway and Chrome
|
// Try to start Sway and Chromium
|
||||||
await this.tryStartSwayAndChrome();
|
await this.tryStartSwayAndChromium();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.log(`Service initialization error: ${error}`);
|
this.log(`Service initialization error: ${error}`);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async tryStartSwayAndChrome(): Promise<void> {
|
private async tryStartSwayAndChromium(): Promise<void> {
|
||||||
// Try DRM mode first, fall back to headless if it fails
|
// Try DRM mode first, fall back to headless if it fails
|
||||||
const modes = ['drm', 'headless'] as const;
|
const modes = ['drm', 'headless'] as const;
|
||||||
|
|
||||||
@@ -129,8 +129,8 @@ export class EcoDaemon {
|
|||||||
this.swayStatus = { state: 'running' };
|
this.swayStatus = { state: 'running' };
|
||||||
this.log(`Sway compositor running with ${mode} backend`);
|
this.log(`Sway compositor running with ${mode} backend`);
|
||||||
|
|
||||||
// Start Chrome in kiosk mode
|
// Start Chromium in kiosk mode
|
||||||
await this.startChromeAfterSway();
|
await this.startChromiumAfterSway();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
this.log(`Sway ${mode} backend failed - Wayland socket did not appear`);
|
this.log(`Sway ${mode} backend failed - Wayland socket did not appear`);
|
||||||
@@ -147,21 +147,21 @@ export class EcoDaemon {
|
|||||||
this.log('All Sway backend modes failed');
|
this.log('All Sway backend modes failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
private async startChromeAfterSway(): Promise<void> {
|
private async startChromiumAfterSway(): Promise<void> {
|
||||||
this.chromeStatus = { state: 'starting', lastAttempt: new Date().toISOString() };
|
this.chromiumStatus = { state: 'starting', lastAttempt: new Date().toISOString() };
|
||||||
this.log('Starting Chrome browser...');
|
this.log('Starting Chromium browser...');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.startChrome();
|
await this.startChromium();
|
||||||
this.chromeStatus = { state: 'running' };
|
this.chromiumStatus = { state: 'running' };
|
||||||
this.log('Chrome browser started');
|
this.log('Chromium browser started');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.chromeStatus = {
|
this.chromiumStatus = {
|
||||||
state: 'failed',
|
state: 'failed',
|
||||||
error: String(error),
|
error: String(error),
|
||||||
lastAttempt: new Date().toISOString()
|
lastAttempt: new Date().toISOString()
|
||||||
};
|
};
|
||||||
this.log(`Failed to start Chrome: ${error}`);
|
this.log(`Failed to start Chromium: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,11 +230,11 @@ export class EcoDaemon {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async startChrome(): Promise<void> {
|
private async startChromium(): Promise<void> {
|
||||||
const uid = await this.getUserUid();
|
const uid = await this.getUserUid();
|
||||||
const runtimeDir = `/run/user/${uid}`;
|
const runtimeDir = `/run/user/${uid}`;
|
||||||
|
|
||||||
await this.processManager.startChrome({
|
await this.processManager.startBrowser({
|
||||||
runtimeDir,
|
runtimeDir,
|
||||||
waylandDisplay: this.config.waylandDisplay,
|
waylandDisplay: this.config.waylandDisplay,
|
||||||
url: 'http://localhost:' + this.config.uiPort,
|
url: 'http://localhost:' + this.config.uiPort,
|
||||||
@@ -278,26 +278,26 @@ export class EcoDaemon {
|
|||||||
if (this.swayStatus.state === 'running' && !this.processManager.isSwayRunning()) {
|
if (this.swayStatus.state === 'running' && !this.processManager.isSwayRunning()) {
|
||||||
this.log('Sway process died, attempting restart...');
|
this.log('Sway process died, attempting restart...');
|
||||||
this.swayStatus = { state: 'stopped' };
|
this.swayStatus = { state: 'stopped' };
|
||||||
this.chromeStatus = { state: 'stopped' };
|
this.chromiumStatus = { state: 'stopped' };
|
||||||
await this.tryStartSwayAndChrome();
|
await this.tryStartSwayAndChromium();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If Sway is running but Chrome died, restart Chrome
|
// If Sway is running but Chromium died, restart Chromium
|
||||||
if (this.swayStatus.state === 'running' && this.chromeStatus.state === 'running'
|
if (this.swayStatus.state === 'running' && this.chromiumStatus.state === 'running'
|
||||||
&& !this.processManager.isChromeRunning()) {
|
&& !this.processManager.isBrowserRunning()) {
|
||||||
this.log('Chrome process died, attempting restart...');
|
this.log('Chromium process died, attempting restart...');
|
||||||
this.chromeStatus = { state: 'starting', lastAttempt: new Date().toISOString() };
|
this.chromiumStatus = { state: 'starting', lastAttempt: new Date().toISOString() };
|
||||||
try {
|
try {
|
||||||
await this.startChrome();
|
await this.startChromium();
|
||||||
this.chromeStatus = { state: 'running' };
|
this.chromiumStatus = { state: 'running' };
|
||||||
this.log('Chrome browser restarted');
|
this.log('Chromium browser restarted');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.chromeStatus = {
|
this.chromiumStatus = {
|
||||||
state: 'failed',
|
state: 'failed',
|
||||||
error: String(error),
|
error: String(error),
|
||||||
lastAttempt: new Date().toISOString()
|
lastAttempt: new Date().toISOString()
|
||||||
};
|
};
|
||||||
this.log(`Failed to restart Chrome: ${error}`);
|
this.log(`Failed to restart Chromium: ${error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +309,7 @@ export class EcoDaemon {
|
|||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
if (now - lastAttempt > 30000) {
|
if (now - lastAttempt > 30000) {
|
||||||
this.log('Retrying Sway startup...');
|
this.log('Retrying Sway startup...');
|
||||||
await this.tryStartSwayAndChrome();
|
await this.tryStartSwayAndChromium();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Process Manager
|
* Process Manager
|
||||||
*
|
*
|
||||||
* Manages spawning and monitoring of Sway and Chrome processes
|
* Manages spawning and monitoring of Sway and Chromium processes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export interface SwayConfig {
|
export interface SwayConfig {
|
||||||
@@ -202,7 +202,7 @@ for_window [class="chromium-browser"] fullscreen enable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start Chrome browser in kiosk mode
|
* Start Chromium browser in kiosk mode
|
||||||
*/
|
*/
|
||||||
async startBrowser(config: BrowserConfig): Promise<void> {
|
async startBrowser(config: BrowserConfig): Promise<void> {
|
||||||
const env: Record<string, string> = {
|
const env: Record<string, string> = {
|
||||||
@@ -213,7 +213,7 @@ for_window [class="chromium-browser"] fullscreen enable
|
|||||||
XDG_DATA_HOME: `/home/${this.user}/.local/share`,
|
XDG_DATA_HOME: `/home/${this.user}/.local/share`,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Chrome arguments for kiosk mode on Wayland
|
// Chromium arguments for kiosk mode on Wayland
|
||||||
const browserArgs = [
|
const browserArgs = [
|
||||||
'--ozone-platform=wayland',
|
'--ozone-platform=wayland',
|
||||||
'--enable-features=UseOzonePlatform',
|
'--enable-features=UseOzonePlatform',
|
||||||
@@ -269,17 +269,17 @@ for_window [class="chromium-browser"] fullscreen enable
|
|||||||
this.browserProcess = command.spawn();
|
this.browserProcess = command.spawn();
|
||||||
|
|
||||||
// Log output in background
|
// Log output in background
|
||||||
this.pipeOutput(this.browserProcess, 'chrome');
|
this.pipeOutput(this.browserProcess, 'chromium');
|
||||||
|
|
||||||
// Force fullscreen via swaymsg after Chrome window appears (backup)
|
// Force fullscreen via swaymsg after Chromium window appears (backup)
|
||||||
this.forceFullscreenAfterDelay(config);
|
this.forceFullscreenAfterDelay(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Force fullscreen for Chrome window after a delay (backup for kiosk mode)
|
* Force fullscreen for Chromium window after a delay (backup for kiosk mode)
|
||||||
*/
|
*/
|
||||||
private async forceFullscreenAfterDelay(config: { runtimeDir: string; waylandDisplay: string }): Promise<void> {
|
private async forceFullscreenAfterDelay(config: { runtimeDir: string; waylandDisplay: string }): Promise<void> {
|
||||||
// Wait for Chrome window to appear
|
// Wait for Chromium window to appear
|
||||||
await new Promise((resolve) => setTimeout(resolve, 3000));
|
await new Promise((resolve) => setTimeout(resolve, 3000));
|
||||||
|
|
||||||
console.log('[chromium] Forcing fullscreen via swaymsg');
|
console.log('[chromium] Forcing fullscreen via swaymsg');
|
||||||
@@ -379,7 +379,7 @@ for_window [class="chromium-browser"] fullscreen enable
|
|||||||
console.log(`[${name}] Process exited with code ${status.code}`);
|
console.log(`[${name}] Process exited with code ${status.code}`);
|
||||||
if (name === 'sway') {
|
if (name === 'sway') {
|
||||||
this.swayProcess = null;
|
this.swayProcess = null;
|
||||||
} else if (name === 'chrome') {
|
} else if (name === 'chromium') {
|
||||||
this.browserProcess = null;
|
this.browserProcess = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -201,8 +201,8 @@ export class UIServer {
|
|||||||
Sway Compositor
|
Sway Compositor
|
||||||
</div>
|
</div>
|
||||||
<div class="stat">
|
<div class="stat">
|
||||||
<span class="status-dot" id="chrome-status"></span>
|
<span class="status-dot" id="chromium-status"></span>
|
||||||
Chrome Browser
|
Chromium Browser
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
@@ -252,8 +252,8 @@ export class UIServer {
|
|||||||
// Services
|
// Services
|
||||||
document.getElementById('sway-status').className =
|
document.getElementById('sway-status').className =
|
||||||
'status-dot ' + (data.sway ? 'running' : 'stopped');
|
'status-dot ' + (data.sway ? 'running' : 'stopped');
|
||||||
document.getElementById('chrome-status').className =
|
document.getElementById('chromium-status').className =
|
||||||
'status-dot ' + (data.chrome ? 'running' : 'stopped');
|
'status-dot ' + (data.chromium ? 'running' : 'stopped');
|
||||||
|
|
||||||
// System info
|
// System info
|
||||||
if (data.systemInfo) {
|
if (data.systemInfo) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Create ecouser for running Sway and Chrome
|
# Create ecouser for running Sway and Chromium
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ fonts-noto-color-emoji
|
|||||||
fonts-liberation
|
fonts-liberation
|
||||||
fonts-dejavu
|
fonts-dejavu
|
||||||
|
|
||||||
# Browser dependencies (Chrome installed via hook)
|
# Browser dependencies (Chromium installed via Dockerfile)
|
||||||
libnss3
|
libnss3
|
||||||
libatk1.0-0
|
libatk1.0-0
|
||||||
libatk-bridge2.0-0
|
libatk-bridge2.0-0
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ The installer (`install.sh`) creates this config explicitly during installation.
|
|||||||
The project uses **Chromium** for the kiosk browser.
|
The project uses **Chromium** for the kiosk browser.
|
||||||
|
|
||||||
### Key Files
|
### Key Files
|
||||||
- `isobuild/config/hooks/normal/0060-install-chrome.hook.chroot` - Installs Chromium from Debian repos
|
- `isobuild/config/hooks/normal/0060-install-chromium.hook.chroot` - Installs Chromium dependencies
|
||||||
- `ecoos_daemon/ts/daemon/process-manager.ts` - Launches Chromium with Wayland support
|
- `ecoos_daemon/ts/daemon/process-manager.ts` - Launches Chromium with Wayland support
|
||||||
|
|
||||||
### Why Chromium from Debian?
|
### Why Chromium from Debian?
|
||||||
@@ -101,7 +101,7 @@ Source: ArchWiki Sway page, GitHub issue swaywm/sway#6210
|
|||||||
|
|
||||||
## CRITICAL: Hook Permissions
|
## CRITICAL: Hook Permissions
|
||||||
|
|
||||||
**ISSUE**: Chrome not installed in ISO.
|
**ISSUE**: Chromium not installed in ISO.
|
||||||
|
|
||||||
**FIX**: All hook files must be `chmod +x`:
|
**FIX**: All hook files must be `chmod +x`:
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ When "Install EcoOS" is selected:
|
|||||||
When "EcoOS Live" is selected:
|
When "EcoOS Live" is selected:
|
||||||
1. Boots into RAM (squashfs)
|
1. Boots into RAM (squashfs)
|
||||||
2. eco-daemon starts via systemd
|
2. eco-daemon starts via systemd
|
||||||
3. Sway + Chrome should start
|
3. Sway + Chromium should start
|
||||||
4. **No persistent storage** - changes lost on reboot
|
4. **No persistent storage** - changes lost on reboot
|
||||||
|
|
||||||
### After Installation (Normal Boot)
|
### After Installation (Normal Boot)
|
||||||
@@ -52,7 +52,7 @@ When "EcoOS Live" is selected:
|
|||||||
2. eco-daemon.service starts
|
2. eco-daemon.service starts
|
||||||
3. Daemon writes Sway config to `~/.config/sway/config`
|
3. Daemon writes Sway config to `~/.config/sway/config`
|
||||||
4. Daemon starts Sway compositor
|
4. Daemon starts Sway compositor
|
||||||
5. Daemon starts Chrome in kiosk mode pointing to localhost:3006
|
5. Daemon starts Chromium in kiosk mode pointing to localhost:3006
|
||||||
6. Management UI serves on port 3006
|
6. Management UI serves on port 3006
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
@@ -63,7 +63,7 @@ eco_os/
|
|||||||
│ └── ts/
|
│ └── ts/
|
||||||
│ ├── daemon/
|
│ ├── daemon/
|
||||||
│ │ ├── index.ts # Main daemon orchestration
|
│ │ ├── index.ts # Main daemon orchestration
|
||||||
│ │ ├── process-manager.ts # Sway/Chrome process control
|
│ │ ├── process-manager.ts # Sway/Chromium process control
|
||||||
│ │ └── system-info.ts # CPU/memory stats
|
│ │ └── system-info.ts # CPU/memory stats
|
||||||
│ └── ui/
|
│ └── ui/
|
||||||
│ └── server.ts # HTTP server + WebSocket
|
│ └── server.ts # HTTP server + WebSocket
|
||||||
@@ -73,7 +73,7 @@ eco_os/
|
|||||||
│ │ ├── hooks/normal/ # Chroot hooks (MUST BE EXECUTABLE)
|
│ │ ├── hooks/normal/ # Chroot hooks (MUST BE EXECUTABLE)
|
||||||
│ │ │ ├── 0050-setup-ecouser.hook.chroot
|
│ │ │ ├── 0050-setup-ecouser.hook.chroot
|
||||||
│ │ │ ├── 0055-fix-networkmanager.hook.chroot
|
│ │ │ ├── 0055-fix-networkmanager.hook.chroot
|
||||||
│ │ │ ├── 0060-install-chrome.hook.chroot # Installs Chrome
|
│ │ │ ├── 0060-install-chromium.hook.chroot # Installs Chromium
|
||||||
│ │ │ └── 0100-enable-services.hook.chroot
|
│ │ │ └── 0100-enable-services.hook.chroot
|
||||||
│ │ ├── includes.chroot/ # Files copied into ISO
|
│ │ ├── includes.chroot/ # Files copied into ISO
|
||||||
│ │ │ ├── etc/
|
│ │ │ ├── etc/
|
||||||
@@ -104,7 +104,7 @@ Features:
|
|||||||
- 1920x1080 resolution
|
- 1920x1080 resolution
|
||||||
- No window borders
|
- No window borders
|
||||||
- All windows forced fullscreen
|
- All windows forced fullscreen
|
||||||
- Chrome app_id rules for fullscreen
|
- Chromium app_id rules for fullscreen
|
||||||
|
|
||||||
### Chromium Launch
|
### Chromium Launch
|
||||||
Command: `chromium-browser` (or `chromium`)
|
Command: `chromium-browser` (or `chromium`)
|
||||||
@@ -117,7 +117,7 @@ Flags:
|
|||||||
|
|
||||||
### Port 3006 Management UI
|
### Port 3006 Management UI
|
||||||
- Serves HTML dashboard
|
- Serves HTML dashboard
|
||||||
- Shows Sway/Chrome status
|
- Shows Sway/Chromium status
|
||||||
- Shows CPU/memory stats
|
- Shows CPU/memory stats
|
||||||
- Shows daemon logs
|
- Shows daemon logs
|
||||||
- WebSocket for live updates
|
- WebSocket for live updates
|
||||||
@@ -146,7 +146,7 @@ All files in `isobuild/config/hooks/normal/*.hook.chroot` MUST be executable:
|
|||||||
chmod +x isobuild/config/hooks/normal/*.hook.chroot
|
chmod +x isobuild/config/hooks/normal/*.hook.chroot
|
||||||
```
|
```
|
||||||
|
|
||||||
If hooks aren't executable, Chrome won't be installed!
|
If hooks aren't executable, Chromium won't be installed!
|
||||||
|
|
||||||
## Testing in QEMU
|
## Testing in QEMU
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user