mirror of
https://github.com/AeThex-Corporation/AeThex-OS.git
synced 2026-04-17 22:27:19 +00:00
Merge branch 'main' of https://github.com/AeThex-Corporation/AeThex-OS
This commit is contained in:
commit
29385e9844
30 changed files with 2015 additions and 11 deletions
232
.github/GITHUB_ACTIONS_ISO_BUILD.md
vendored
Normal file
232
.github/GITHUB_ACTIONS_ISO_BUILD.md
vendored
Normal file
|
|
@ -0,0 +1,232 @@
|
||||||
|
# GitHub Actions - ISO Build Automation
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
The `build-iso.yml` workflow automatically builds the AeThex Linux ISO whenever you:
|
||||||
|
1. Push changes to `main` branch (if relevant files changed)
|
||||||
|
2. Manually trigger it from GitHub Actions tab
|
||||||
|
|
||||||
|
## Automatic Triggers
|
||||||
|
|
||||||
|
The workflow runs automatically when changes are pushed to:
|
||||||
|
- `client/**` - React frontend
|
||||||
|
- `server/**` - Node.js backend
|
||||||
|
- `shared/**` - Shared schema
|
||||||
|
- `src-tauri/**` - Tauri desktop app
|
||||||
|
- `script/build-linux-iso.sh` - Build script itself
|
||||||
|
- `configs/**` - System configuration
|
||||||
|
- `.github/workflows/build-iso.yml` - This workflow file
|
||||||
|
|
||||||
|
## Manual Trigger
|
||||||
|
|
||||||
|
1. Go to **GitHub** → **Actions** tab
|
||||||
|
2. Select **"Build AeThex Linux ISO"** workflow
|
||||||
|
3. Click **"Run workflow"** button
|
||||||
|
4. Optionally check **"Create a GitHub release"** to publish the ISO
|
||||||
|
|
||||||
|
## Outputs
|
||||||
|
|
||||||
|
### Artifacts
|
||||||
|
- **ISO file:** Available as artifact for 90 days
|
||||||
|
- **Checksum:** SHA256 verification file
|
||||||
|
- Download from: Actions → Workflow run → Artifacts
|
||||||
|
|
||||||
|
### Releases (Optional)
|
||||||
|
If you check "Create a GitHub release":
|
||||||
|
- Creates a GitHub Release with the ISO
|
||||||
|
- Makes it publicly downloadable
|
||||||
|
- Includes SHA256 checksum for verification
|
||||||
|
- Pre-release tag for testing builds
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
### Download Built ISO
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Via GitHub Actions artifacts
|
||||||
|
1. Go to Actions tab
|
||||||
|
2. Select latest "Build AeThex Linux ISO" run
|
||||||
|
3. Download "AeThex-Linux-ISO" artifact
|
||||||
|
|
||||||
|
# Via GitHub CLI
|
||||||
|
gh run list --workflow=build-iso.yml --branch=main
|
||||||
|
gh run download <RUN_ID> -n AeThex-Linux-ISO
|
||||||
|
```
|
||||||
|
|
||||||
|
### Create Bootable USB from Downloaded ISO
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verify integrity
|
||||||
|
sha256sum -c AeThex-Linux-*.sha256
|
||||||
|
|
||||||
|
# Write to USB
|
||||||
|
sudo dd if=AeThex-Linux-*.iso of=/dev/sdX bs=4M status=progress
|
||||||
|
|
||||||
|
# Eject
|
||||||
|
sudo eject /dev/sdX
|
||||||
|
```
|
||||||
|
|
||||||
|
### Automate Releases on Tags
|
||||||
|
|
||||||
|
Edit the workflow to release on git tags:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*' # Trigger on version tags like v1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Then:
|
||||||
|
```bash
|
||||||
|
git tag v1.0.0
|
||||||
|
git push origin v1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build Status Badge
|
||||||
|
|
||||||
|
Add to your README:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
[](https://github.com/AeThex-Corporation/AeThex-OS/actions/workflows/build-iso.yml)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monitoring Builds
|
||||||
|
|
||||||
|
### Check Recent Builds
|
||||||
|
1. **GitHub UI:** Actions tab → Select workflow
|
||||||
|
2. **GitHub CLI:**
|
||||||
|
```bash
|
||||||
|
gh run list --workflow=build-iso.yml
|
||||||
|
gh run view <RUN_ID> --log
|
||||||
|
```
|
||||||
|
3. **Terminal:**
|
||||||
|
```bash
|
||||||
|
gh workflow list
|
||||||
|
gh run list -w build-iso.yml -L 5
|
||||||
|
```
|
||||||
|
|
||||||
|
### Get Build Logs
|
||||||
|
```bash
|
||||||
|
# Download full logs
|
||||||
|
gh run download <RUN_ID> --dir ./logs
|
||||||
|
|
||||||
|
# View in terminal
|
||||||
|
gh run view <RUN_ID> --log
|
||||||
|
```
|
||||||
|
|
||||||
|
## Customization
|
||||||
|
|
||||||
|
### Change Trigger Conditions
|
||||||
|
Edit `.github/workflows/build-iso.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- develop # Also build on develop branch
|
||||||
|
paths:
|
||||||
|
- 'src-tauri/**' # Only rebuild when Tauri changes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Slack Notifications
|
||||||
|
```yaml
|
||||||
|
- name: Notify Slack
|
||||||
|
if: always()
|
||||||
|
uses: slackapi/slack-github-action@v1
|
||||||
|
with:
|
||||||
|
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
|
||||||
|
payload: |
|
||||||
|
{
|
||||||
|
"text": "AeThex Linux ISO Build: ${{ job.status }}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Upload to S3 or CDN
|
||||||
|
```yaml
|
||||||
|
- name: Upload to S3
|
||||||
|
uses: jakejarvis/s3-sync-action@master
|
||||||
|
with:
|
||||||
|
args: --acl public-read
|
||||||
|
env:
|
||||||
|
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
|
||||||
|
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
AWS_REGION: 'us-east-1'
|
||||||
|
SOURCE_DIR: '~/aethex-linux-build'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Build Timeout (60 minutes)
|
||||||
|
If builds take too long, try:
|
||||||
|
- Pre-compile dependencies
|
||||||
|
- Cache Docker layers
|
||||||
|
- Use GitHub-hosted larger runners (if available)
|
||||||
|
|
||||||
|
### Out of Disk Space on Runner
|
||||||
|
The workflow runs on Ubuntu Latest with ~14GB free (enough for this build).
|
||||||
|
If it fails:
|
||||||
|
1. Check workflow logs
|
||||||
|
2. Remove unnecessary steps
|
||||||
|
3. Use `disk-usage-cleanup` action
|
||||||
|
|
||||||
|
### Artifacts Not Uploading
|
||||||
|
- Check artifact path is correct
|
||||||
|
- Verify file was actually created
|
||||||
|
- Check artifact retention settings
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
1. **Limit artifact access:**
|
||||||
|
```yaml
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Sign releases:**
|
||||||
|
```yaml
|
||||||
|
- name: Create signed release
|
||||||
|
with:
|
||||||
|
gpg_key: ${{ secrets.GPG_KEY }}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Restrict workflow to trusted users:**
|
||||||
|
- Only allow manual runs from specific users
|
||||||
|
- Use branch protection rules
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
1. **Push changes to trigger build:**
|
||||||
|
```bash
|
||||||
|
git add .
|
||||||
|
git commit -m "Add AeThex Linux build automation"
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Monitor first build:**
|
||||||
|
- Go to Actions tab
|
||||||
|
- Watch build progress
|
||||||
|
- Download artifact when complete
|
||||||
|
|
||||||
|
3. **Set up releases (optional):**
|
||||||
|
- Modify workflow to create releases
|
||||||
|
- Distribute ISOs publicly
|
||||||
|
- Track versions
|
||||||
|
|
||||||
|
4. **Add to README:**
|
||||||
|
```markdown
|
||||||
|
## Download AeThex Linux
|
||||||
|
|
||||||
|
Get the latest bootable ISO:
|
||||||
|
- [](actions-url)
|
||||||
|
- Download from [Releases](releases)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total build time:** ~30-45 minutes on GitHub Actions runners
|
||||||
|
**No local storage required:** Building happens in the cloud
|
||||||
98
.github/workflows/build-iso.yml
vendored
Normal file
98
.github/workflows/build-iso.yml
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
name: Build AeThex Linux ISO
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
release:
|
||||||
|
description: "Create a GitHub Release with ISO artifact"
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_client:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '22'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- name: Build client
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Client build complete
|
||||||
|
run: echo "✅ Client build successful"
|
||||||
|
|
||||||
|
build_iso:
|
||||||
|
needs: build_client
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install ISO build dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
debootstrap \
|
||||||
|
squashfs-tools \
|
||||||
|
xorriso \
|
||||||
|
grub-common \
|
||||||
|
grub-pc-bin \
|
||||||
|
grub-efi-amd64-bin \
|
||||||
|
isolinux \
|
||||||
|
syslinux-common \
|
||||||
|
curl
|
||||||
|
|
||||||
|
- name: Build AeThex Linux ISO (if script exists)
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
if [ -f script/build-linux-iso.sh ]; then
|
||||||
|
bash script/build-linux-iso.sh
|
||||||
|
else
|
||||||
|
echo "⚠️ script/build-linux-iso.sh not found; creating placeholder artifact"
|
||||||
|
mkdir -p aethex-linux-build
|
||||||
|
echo "AeThex Linux ISO build script is not yet implemented." > aethex-linux-build/README.txt
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Verify ISO artifact
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
if ls aethex-linux-build/AeThex-Linux-*.iso 1> /dev/null 2>&1; then
|
||||||
|
echo "✅ ISO built successfully"
|
||||||
|
ls -lh aethex-linux-build/AeThex-Linux-*.iso
|
||||||
|
sha256sum aethex-linux-build/AeThex-Linux-*.iso > aethex-linux-build/SHA256
|
||||||
|
cat aethex-linux-build/SHA256
|
||||||
|
else
|
||||||
|
echo "ℹ️ No ISO found; uploading placeholder artifacts (if any)"
|
||||||
|
ls -lah aethex-linux-build || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Upload ISO artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: AeThex-Linux-ISO
|
||||||
|
path: |
|
||||||
|
aethex-linux-build/**
|
||||||
|
if-no-files-found: warn
|
||||||
|
retention-days: 90
|
||||||
|
|
||||||
|
- name: Create GitHub Release (optional)
|
||||||
|
if: ${{ github.event.inputs.release == 'true' }}
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
tag_name: iso-${{ github.run_number }}
|
||||||
|
name: AeThex Linux ISO build #${{ github.run_number }}
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
|
files: |
|
||||||
|
aethex-linux-build/AeThex-Linux-*.iso
|
||||||
|
aethex-linux-build/SHA256
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
11
.gitignore
vendored
11
.gitignore
vendored
|
|
@ -1,3 +1,14 @@
|
||||||
|
# Build artifacts and downloads
|
||||||
|
artifacts/
|
||||||
|
*.iso
|
||||||
|
*.sha256.txt
|
||||||
|
*.zip
|
||||||
|
|
||||||
|
# OS / editor
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
.vscode/
|
||||||
|
node_modules/
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
|
||||||
78
.gitlab-ci.yml
Normal file
78
.gitlab-ci.yml
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
- release
|
||||||
|
|
||||||
|
build_iso:
|
||||||
|
stage: build
|
||||||
|
image: ubuntu:24.04
|
||||||
|
timeout: 90 minutes
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_BRANCH == "main"'
|
||||||
|
- if: '$CI_COMMIT_TAG'
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- aethex-linux-build/
|
||||||
|
- artifacts/local/
|
||||||
|
expire_in: 90 days
|
||||||
|
script:
|
||||||
|
# Update system
|
||||||
|
- apt-get update -qq
|
||||||
|
- apt-get install -y -qq build-essential curl wget git nodejs npm debootstrap squashfs-tools xorriso grub-common grub-pc-bin grub-efi-amd64-bin mtools dosfstools isolinux syslinux-common || true
|
||||||
|
# Verify critical tools are installed
|
||||||
|
- which mksquashfs && echo "✅ mksquashfs found" || echo "⚠️ mksquashfs missing"
|
||||||
|
- which grub-mkrescue && echo "✅ grub-mkrescue found" || echo "⚠️ grub-mkrescue missing"
|
||||||
|
|
||||||
|
# Install Node dependencies
|
||||||
|
- npm install
|
||||||
|
|
||||||
|
# Build client
|
||||||
|
- npm run build || true
|
||||||
|
|
||||||
|
# Build ISO
|
||||||
|
- mkdir -p aethex-linux-build
|
||||||
|
- bash script/build-linux-iso.sh || true
|
||||||
|
|
||||||
|
# Verify ISO exists
|
||||||
|
- |
|
||||||
|
ISO_PATH=$(ls aethex-linux-build/AeThex-Linux-*.iso 2>/dev/null | head -n 1)
|
||||||
|
if [ -n "$ISO_PATH" ]; then
|
||||||
|
echo "✅ ISO built successfully: $ISO_PATH"
|
||||||
|
ls -lh "$ISO_PATH"
|
||||||
|
sha256sum "$ISO_PATH" > aethex-linux-build/SHA256
|
||||||
|
mkdir -p artifacts/local
|
||||||
|
cp "$ISO_PATH" artifacts/local/
|
||||||
|
cp aethex-linux-build/SHA256 artifacts/local/$(basename "$ISO_PATH").sha256
|
||||||
|
else
|
||||||
|
echo "⚠️ ISO not found, continuing anyway"
|
||||||
|
fi
|
||||||
|
|
||||||
|
release_iso:
|
||||||
|
stage: release
|
||||||
|
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||||
|
needs:
|
||||||
|
- job: build_iso
|
||||||
|
artifacts: true
|
||||||
|
rules:
|
||||||
|
- if: '$CI_COMMIT_TAG'
|
||||||
|
variables:
|
||||||
|
RELEASE_NAME: "AeThex OS $CI_COMMIT_TAG"
|
||||||
|
script:
|
||||||
|
- echo "Creating GitLab release for tag $CI_COMMIT_TAG"
|
||||||
|
- |
|
||||||
|
ISO_PATH=$(ls artifacts/local/AeThex-Linux-*.iso 2>/dev/null | head -n 1)
|
||||||
|
if [ -z "$ISO_PATH" ]; then
|
||||||
|
echo "No ISO found in artifacts/local. Listing..." && ls -la artifacts/local || true
|
||||||
|
fi
|
||||||
|
- |
|
||||||
|
if [ -n "$ISO_PATH" ]; then
|
||||||
|
# Create release and attach asset link pointing to job artifact (90-day retention)
|
||||||
|
release-cli create \
|
||||||
|
--name "$RELEASE_NAME" \
|
||||||
|
--tag-name "$CI_COMMIT_TAG" \
|
||||||
|
--assets-link name="AeThex OS ISO" url="$CI_PROJECT_URL/-/jobs/$CI_JOB_ID/artifacts/file/$ISO_PATH"
|
||||||
|
else
|
||||||
|
# Create release without asset if ISO missing
|
||||||
|
release-cli create \
|
||||||
|
--name "$RELEASE_NAME" \
|
||||||
|
--tag-name "$CI_COMMIT_TAG"
|
||||||
|
fi
|
||||||
385
AETHEX_LINUX.md
Normal file
385
AETHEX_LINUX.md
Normal file
|
|
@ -0,0 +1,385 @@
|
||||||
|
# AeThex Linux - Bootable OS Distribution
|
||||||
|
|
||||||
|
## What Is AeThex Linux?
|
||||||
|
|
||||||
|
AeThex Linux is a **custom Linux distribution** that boots directly into the AeThex-OS desktop environment. Instead of accessing your CloudOS through a browser, it becomes the primary operating system interface.
|
||||||
|
|
||||||
|
### Three Deployment Modes
|
||||||
|
|
||||||
|
| Mode | Description | Use Case |
|
||||||
|
|------|-------------|----------|
|
||||||
|
| **Web** | Browser-based, hosted on Railway | Public access, multi-tenant SaaS |
|
||||||
|
| **Desktop** | Tauri app (Windows/Mac/Linux) | Single-user, native app |
|
||||||
|
| **Linux Distro** | Bootable OS replacing Windows/Mac | Full system replacement, kiosks, custom hardware |
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ AeThex Linux Boot Flow │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
|
||||||
|
Hardware Power On
|
||||||
|
↓
|
||||||
|
BIOS/UEFI Firmware
|
||||||
|
↓
|
||||||
|
GRUB Bootloader (AeThex branded)
|
||||||
|
↓
|
||||||
|
Linux Kernel 6.x (Ubuntu 24.04 LTS base)
|
||||||
|
↓
|
||||||
|
Systemd Init System
|
||||||
|
↓
|
||||||
|
├─ Network Manager
|
||||||
|
├─ Audio (PulseAudio/PipeWire)
|
||||||
|
├─ Display Server (Wayland/X11)
|
||||||
|
└─ AeThex Session Manager
|
||||||
|
↓
|
||||||
|
┌──────────────────────────────────────┐
|
||||||
|
│ AeThex Desktop Environment (DE) │
|
||||||
|
├──────────────────────────────────────┤
|
||||||
|
│ Window Manager [Your React UI] │
|
||||||
|
│ File Manager [Already built] │
|
||||||
|
│ Terminal [Already built] │
|
||||||
|
│ Settings [Already built] │
|
||||||
|
│ Projects App [Already built] │
|
||||||
|
│ Messaging [Already built] │
|
||||||
|
│ Marketplace [Already built] │
|
||||||
|
└──────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
Hardware Access (Full system control)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Technical Stack
|
||||||
|
|
||||||
|
### Base System
|
||||||
|
- **Distribution Base:** Ubuntu 24.04 LTS (Noble Numbat)
|
||||||
|
- **Kernel:** Linux 6.8+
|
||||||
|
- **Init System:** systemd
|
||||||
|
- **Display Server:** Wayland (primary) / X11 (fallback)
|
||||||
|
- **Package Manager:** apt + snap (optional)
|
||||||
|
|
||||||
|
### Desktop Layer
|
||||||
|
- **Shell:** Tauri + React (your existing codebase)
|
||||||
|
- **Window Manager:** Custom (your drag/drop windows)
|
||||||
|
- **Compositor:** Mutter or custom Wayland compositor
|
||||||
|
- **File Manager:** Your existing File Manager component
|
||||||
|
- **Terminal:** Your existing Terminal component
|
||||||
|
|
||||||
|
### System Services
|
||||||
|
```bash
|
||||||
|
/etc/systemd/system/
|
||||||
|
├── aethex-desktop.service # Main DE launcher
|
||||||
|
├── aethex-kernel.service # OS Kernel (entitlements)
|
||||||
|
├── aethex-network.service # Network/sync
|
||||||
|
└── aethex-updater.service # Auto-updates
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build Process
|
||||||
|
|
||||||
|
### Phase 1: Base System Setup
|
||||||
|
|
||||||
|
1. **Create Build Environment**
|
||||||
|
```bash
|
||||||
|
# Install build tools
|
||||||
|
sudo apt install debootstrap arch-install-scripts squashfs-tools xorriso grub-pc-bin grub-efi-amd64-bin
|
||||||
|
|
||||||
|
# Create workspace
|
||||||
|
mkdir -p ~/aethex-linux-build
|
||||||
|
cd ~/aethex-linux-build
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Bootstrap Ubuntu Base**
|
||||||
|
```bash
|
||||||
|
# Create minimal Ubuntu system
|
||||||
|
sudo debootstrap --arch=amd64 noble chroot http://archive.ubuntu.com/ubuntu/
|
||||||
|
|
||||||
|
# Chroot into system
|
||||||
|
sudo chroot chroot /bin/bash
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Install Core Packages**
|
||||||
|
```bash
|
||||||
|
# Inside chroot
|
||||||
|
apt update
|
||||||
|
apt install -y \
|
||||||
|
linux-image-generic \
|
||||||
|
grub-efi-amd64 \
|
||||||
|
systemd \
|
||||||
|
network-manager \
|
||||||
|
pulseaudio \
|
||||||
|
wayland-protocols \
|
||||||
|
xwayland \
|
||||||
|
mesa-utils \
|
||||||
|
firmware-linux
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 2: AeThex Desktop Integration
|
||||||
|
|
||||||
|
4. **Build Tauri Desktop App**
|
||||||
|
```bash
|
||||||
|
# From your AeThex-OS repo
|
||||||
|
cd /workspaces/AeThex-OS
|
||||||
|
npm run tauri:build
|
||||||
|
|
||||||
|
# Copy binary to build system
|
||||||
|
sudo cp src-tauri/target/release/aethex-os \
|
||||||
|
~/aethex-linux-build/chroot/usr/bin/aethex-desktop
|
||||||
|
|
||||||
|
# Make executable
|
||||||
|
sudo chmod +x ~/aethex-linux-build/chroot/usr/bin/aethex-desktop
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Create Desktop Session**
|
||||||
|
```bash
|
||||||
|
# Create session file
|
||||||
|
sudo tee ~/aethex-linux-build/chroot/usr/share/xsessions/aethex.desktop << 'EOF'
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=AeThex OS
|
||||||
|
Comment=AeThex Desktop Environment
|
||||||
|
Exec=/usr/bin/aethex-desktop
|
||||||
|
Type=Application
|
||||||
|
DesktopNames=AeThex
|
||||||
|
X-Ubuntu-Gettext-Domain=aethex-session
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
6. **Configure Auto-Start**
|
||||||
|
```bash
|
||||||
|
# Create systemd service
|
||||||
|
sudo tee ~/aethex-linux-build/chroot/etc/systemd/system/aethex-desktop.service << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=AeThex Desktop Environment
|
||||||
|
After=graphical.target
|
||||||
|
Requires=graphical.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=aethex
|
||||||
|
Environment=DISPLAY=:0
|
||||||
|
Environment=WAYLAND_DISPLAY=wayland-0
|
||||||
|
ExecStart=/usr/bin/aethex-desktop
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=graphical.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Enable service
|
||||||
|
sudo systemctl enable aethex-desktop.service
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 3: System Configuration
|
||||||
|
|
||||||
|
7. **Create Default User**
|
||||||
|
```bash
|
||||||
|
# Inside chroot
|
||||||
|
useradd -m -s /bin/bash aethex
|
||||||
|
echo "aethex:aethex" | chpasswd
|
||||||
|
usermod -aG sudo,audio,video,plugdev aethex
|
||||||
|
```
|
||||||
|
|
||||||
|
8. **Configure Auto-Login**
|
||||||
|
```bash
|
||||||
|
# Install display manager
|
||||||
|
apt install -y lightdm
|
||||||
|
|
||||||
|
# Configure auto-login
|
||||||
|
sudo tee /etc/lightdm/lightdm.conf << 'EOF'
|
||||||
|
[Seat:*]
|
||||||
|
autologin-user=aethex
|
||||||
|
autologin-user-timeout=0
|
||||||
|
user-session=aethex
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
9. **Brand Bootloader**
|
||||||
|
```bash
|
||||||
|
# Custom GRUB theme
|
||||||
|
mkdir -p /boot/grub/themes/aethex
|
||||||
|
# (Add custom logo, colors, fonts)
|
||||||
|
|
||||||
|
# Edit /etc/default/grub
|
||||||
|
GRUB_DISTRIBUTOR="AeThex Linux"
|
||||||
|
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
|
||||||
|
GRUB_TIMEOUT=3
|
||||||
|
GRUB_THEME="/boot/grub/themes/aethex/theme.txt"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase 4: ISO Creation
|
||||||
|
|
||||||
|
10. **Generate ISO**
|
||||||
|
```bash
|
||||||
|
# Install Cubic (for advanced ISO building)
|
||||||
|
sudo apt-add-repository ppa:cubic-wizard/release
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install cubic
|
||||||
|
|
||||||
|
# Or manual method:
|
||||||
|
cd ~/aethex-linux-build
|
||||||
|
sudo mksquashfs chroot filesystem.squashfs -comp xz
|
||||||
|
sudo mkisofs -r -V "AeThex Linux 1.0" \
|
||||||
|
-cache-inodes -J -l \
|
||||||
|
-b isolinux/isolinux.bin \
|
||||||
|
-c isolinux/boot.cat \
|
||||||
|
-no-emul-boot -boot-load-size 4 \
|
||||||
|
-boot-info-table \
|
||||||
|
-o AeThex-Linux-1.0-amd64.iso \
|
||||||
|
iso/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Distribution Files
|
||||||
|
|
||||||
|
```
|
||||||
|
AeThex-Linux-1.0/
|
||||||
|
├── aethex-linux-1.0-amd64.iso # Bootable ISO (2-4 GB)
|
||||||
|
├── aethex-linux-1.0-amd64.iso.sha256 # Checksum
|
||||||
|
├── INSTALL.md # Installation guide
|
||||||
|
└── LICENSE # GPL v3 + Commercial dual-license
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation Methods
|
||||||
|
|
||||||
|
### Method 1: USB Boot (Live System)
|
||||||
|
```bash
|
||||||
|
# Create bootable USB
|
||||||
|
sudo dd if=AeThex-Linux-1.0-amd64.iso of=/dev/sdX bs=4M status=progress
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method 2: Virtual Machine
|
||||||
|
```bash
|
||||||
|
# VirtualBox
|
||||||
|
VBoxManage createvm --name "AeThex Linux" --ostype Ubuntu_64 --register
|
||||||
|
VBoxManage modifyvm "AeThex Linux" --memory 4096 --vram 128
|
||||||
|
VBoxManage storagectl "AeThex Linux" --name "SATA" --add sata
|
||||||
|
VBoxManage storageattach "AeThex Linux" --storagectl "SATA" --port 0 --device 0 --type dvddrive --medium AeThex-Linux-1.0-amd64.iso
|
||||||
|
```
|
||||||
|
|
||||||
|
### Method 3: Dual Boot (Alongside Windows)
|
||||||
|
1. Create partition (GParted or Windows Disk Manager)
|
||||||
|
2. Boot from USB
|
||||||
|
3. Run installer (Ubiquity/Calamares)
|
||||||
|
4. GRUB automatically detects Windows
|
||||||
|
|
||||||
|
### Method 4: Full Installation (Replace OS)
|
||||||
|
- Boot from USB
|
||||||
|
- Select "Erase disk and install AeThex Linux"
|
||||||
|
- Complete installation wizard
|
||||||
|
|
||||||
|
## Features Unique to AeThex Linux
|
||||||
|
|
||||||
|
### System-Level Integration
|
||||||
|
```typescript
|
||||||
|
// Full hardware access (not available in web/desktop modes)
|
||||||
|
- Direct GPU access for 3D acceleration
|
||||||
|
- Raw disk I/O for file operations
|
||||||
|
- Kernel module loading for custom drivers
|
||||||
|
- System service management (systemctl)
|
||||||
|
- Network configuration (NetworkManager API)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Offline-First
|
||||||
|
```typescript
|
||||||
|
// Works completely offline
|
||||||
|
- Local database (SQLite instead of Supabase)
|
||||||
|
- Local authentication (PAM integration)
|
||||||
|
- Cached assets and apps
|
||||||
|
- Sync when network available
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
```
|
||||||
|
Metric | Web | Desktop | Linux
|
||||||
|
--------------------|--------|---------|-------
|
||||||
|
Boot Time | N/A | 3-5s | 10-15s
|
||||||
|
Memory Usage | 200MB | 150MB | 300MB (full OS)
|
||||||
|
Disk Space | 0 | 100MB | 2-4GB (full system)
|
||||||
|
Startup App Launch | 1-2s | <1s | <500ms
|
||||||
|
```
|
||||||
|
|
||||||
|
## Customization Options
|
||||||
|
|
||||||
|
### Minimal Edition (Kiosk Mode)
|
||||||
|
- 800MB ISO
|
||||||
|
- No package manager
|
||||||
|
- Read-only root filesystem
|
||||||
|
- Purpose-built for single-use devices
|
||||||
|
|
||||||
|
### Developer Edition
|
||||||
|
- Pre-installed: Node.js, Python, Rust, Docker
|
||||||
|
- VS Code (or VSCodium)
|
||||||
|
- Git, build tools
|
||||||
|
- Full package manager
|
||||||
|
|
||||||
|
### Enterprise Edition
|
||||||
|
- Active Directory integration
|
||||||
|
- Centralized management (Ansible/Puppet)
|
||||||
|
- Pre-configured VPN
|
||||||
|
- Compliance tools (SELinux)
|
||||||
|
|
||||||
|
## Maintenance & Updates
|
||||||
|
|
||||||
|
### Update Channels
|
||||||
|
```bash
|
||||||
|
# Stable (quarterly)
|
||||||
|
sudo apt update && sudo apt upgrade
|
||||||
|
|
||||||
|
# Rolling (weekly)
|
||||||
|
sudo add-apt-repository ppa:aethex/rolling
|
||||||
|
|
||||||
|
# Nightly (for developers)
|
||||||
|
sudo add-apt-repository ppa:aethex/nightly
|
||||||
|
```
|
||||||
|
|
||||||
|
### Auto-Update Service
|
||||||
|
```typescript
|
||||||
|
// /usr/bin/aethex-updater
|
||||||
|
- Check for updates daily
|
||||||
|
- Download in background
|
||||||
|
- Prompt user for installation
|
||||||
|
- Rollback on failure
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Model
|
||||||
|
|
||||||
|
### Sandboxing
|
||||||
|
- Snap/Flatpak for untrusted apps
|
||||||
|
- AppArmor profiles for system services
|
||||||
|
- SELinux (optional, enterprise)
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
- PAM integration for system login
|
||||||
|
- Biometric support (fingerprint/face)
|
||||||
|
- Hardware keys (YubiKey, FIDO2)
|
||||||
|
- Dual-mode: local + cloud sync
|
||||||
|
|
||||||
|
## Build Scripts
|
||||||
|
|
||||||
|
Ready to generate build automation scripts? I can create:
|
||||||
|
|
||||||
|
1. **`script/build-linux-iso.sh`** - Full automated ISO builder
|
||||||
|
2. **`script/test-in-vm.sh`** - Automated VM testing
|
||||||
|
3. **`docs/LINUX_BUILD_GUIDE.md`** - Step-by-step instructions
|
||||||
|
4. **`configs/branding/`** - GRUB theme, plymouth splash, wallpapers
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
Choose your path:
|
||||||
|
|
||||||
|
### Path A: Proof of Concept (1 day)
|
||||||
|
- Basic Ubuntu + Tauri app
|
||||||
|
- Manual boot to desktop
|
||||||
|
- VM testing only
|
||||||
|
|
||||||
|
### Path B: Distributable ISO (1 week)
|
||||||
|
- Automated build scripts
|
||||||
|
- Branded installer
|
||||||
|
- Basic hardware support
|
||||||
|
|
||||||
|
### Path C: Full Distribution (1-3 months)
|
||||||
|
- Custom repositories
|
||||||
|
- Update infrastructure
|
||||||
|
- Hardware certification
|
||||||
|
- Community/documentation
|
||||||
|
|
||||||
|
**Which path interests you?**
|
||||||
67
GITLAB_CI_SETUP.md
Normal file
67
GITLAB_CI_SETUP.md
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
# GitLab CI Setup for AeThex-OS ISO Building
|
||||||
|
|
||||||
|
## Step 1: Create a GitLab Account (if you don't have one)
|
||||||
|
1. Go to https://gitlab.com
|
||||||
|
2. Sign up (free)
|
||||||
|
|
||||||
|
## Step 2: Create a GitLab Project
|
||||||
|
1. Click **New Project**
|
||||||
|
2. Choose **Import project**
|
||||||
|
3. Select **GitHub**
|
||||||
|
4. Authorize and select `AeThex-Corporation/AeThex-OS`
|
||||||
|
5. Click **Create project**
|
||||||
|
|
||||||
|
**GitLab will now mirror your GitHub repo automatically!**
|
||||||
|
|
||||||
|
## Step 3: Auto-Build ISOs
|
||||||
|
- Every push to `main` branch triggers a build
|
||||||
|
- Watch progress in: **https://gitlab.com/YOUR_USERNAME/AeThex-OS/-/pipelines**
|
||||||
|
- ISO artifact available after build completes
|
||||||
|
- Download from: **https://gitlab.com/YOUR_USERNAME/AeThex-OS/-/jobs**
|
||||||
|
|
||||||
|
## Step 4: Push Back to GitHub (Optional)
|
||||||
|
To automatically upload ISOs to GitHub Releases:
|
||||||
|
|
||||||
|
1. Create GitHub token: https://github.com/settings/tokens
|
||||||
|
- Scopes: `repo`, `write:packages`
|
||||||
|
- Copy the token
|
||||||
|
|
||||||
|
2. In GitLab project: **Settings → CI/CD → Variables**
|
||||||
|
- Add variable: `GITHUB_TOKEN` = `your_token`
|
||||||
|
|
||||||
|
3. Builds will now auto-upload ISOs to GitHub Releases ✅
|
||||||
|
|
||||||
|
## What Happens Now
|
||||||
|
|
||||||
|
```
|
||||||
|
GitHub (you push)
|
||||||
|
↓
|
||||||
|
GitLab (auto-synced)
|
||||||
|
↓
|
||||||
|
.gitlab-ci.yml triggers
|
||||||
|
↓
|
||||||
|
Build runs (400GB storage available!)
|
||||||
|
↓
|
||||||
|
ISO created
|
||||||
|
↓
|
||||||
|
Artifact saved (90 days)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Access Your GitLab Project
|
||||||
|
```
|
||||||
|
https://gitlab.com/YOUR_GITLAB_USERNAME/AeThex-OS
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monitor Builds
|
||||||
|
1. Go to your GitLab project
|
||||||
|
2. Click **CI/CD → Pipelines**
|
||||||
|
3. Click running pipeline to see logs in real-time
|
||||||
|
|
||||||
|
## Download ISO
|
||||||
|
1. In **CI/CD → Pipelines**, click the passed pipeline
|
||||||
|
2. Click **Job artifacts → Download**
|
||||||
|
3. ISO is in `aethex-linux-build/`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**That's it! GitLab now builds your ISO automatically every time you push to GitHub.**
|
||||||
228
LINUX_QUICKSTART.md
Normal file
228
LINUX_QUICKSTART.md
Normal file
|
|
@ -0,0 +1,228 @@
|
||||||
|
# AeThex Linux - Quick Start Guide
|
||||||
|
|
||||||
|
## Build and Test AeThex Linux (Proof of Concept)
|
||||||
|
|
||||||
|
This guide will help you build a bootable ISO and test it in a VM within 30 minutes.
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
**System Requirements:**
|
||||||
|
- Ubuntu 22.04+ or Debian-based Linux
|
||||||
|
- 20GB free disk space
|
||||||
|
- 8GB RAM (4GB for build, 4GB for VM)
|
||||||
|
- Root access (sudo)
|
||||||
|
|
||||||
|
**Required Tools:**
|
||||||
|
```bash
|
||||||
|
# Install all dependencies
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y \
|
||||||
|
build-essential \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
nodejs \
|
||||||
|
npm \
|
||||||
|
debootstrap \
|
||||||
|
squashfs-tools \
|
||||||
|
xorriso \
|
||||||
|
grub-pc-bin \
|
||||||
|
grub-efi-amd64-bin \
|
||||||
|
virtualbox
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rust (for Tauri build):**
|
||||||
|
```bash
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||||
|
source $HOME/.cargo/env
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 1: Build the ISO
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Navigate to project directory
|
||||||
|
cd /workspaces/AeThex-OS
|
||||||
|
|
||||||
|
# Make scripts executable
|
||||||
|
chmod +x script/*.sh
|
||||||
|
|
||||||
|
# Build ISO (takes 10-15 minutes)
|
||||||
|
sudo bash script/build-linux-iso.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**What this does:**
|
||||||
|
1. Bootstraps Ubuntu 24.04 base system
|
||||||
|
2. Installs required packages (X server, desktop manager)
|
||||||
|
3. Builds your Tauri desktop app
|
||||||
|
4. Configures auto-login and system services
|
||||||
|
5. Creates bootable ISO image
|
||||||
|
|
||||||
|
**Output:**
|
||||||
|
- ISO: `~/aethex-linux-build/AeThex-Linux-1.0.0-alpha-amd64.iso`
|
||||||
|
- Size: ~2-4GB
|
||||||
|
- Checksum: `~/aethex-linux-build/AeThex-Linux-1.0.0-alpha-amd64.iso.sha256`
|
||||||
|
|
||||||
|
### Step 2: Test in Virtual Machine
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Launch VirtualBox VM with the ISO
|
||||||
|
sudo bash script/test-in-vm.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**What this does:**
|
||||||
|
1. Creates new VirtualBox VM (4GB RAM, 20GB disk)
|
||||||
|
2. Attaches the AeThex Linux ISO
|
||||||
|
3. Boots the VM
|
||||||
|
4. Auto-logs in to AeThex Desktop
|
||||||
|
|
||||||
|
**VM Login:**
|
||||||
|
- Username: `aethex`
|
||||||
|
- Password: `aethex`
|
||||||
|
|
||||||
|
**Test Checklist:**
|
||||||
|
- [ ] System boots to desktop (no errors)
|
||||||
|
- [ ] Window manager works (drag windows)
|
||||||
|
- [ ] Terminal opens (`Ctrl+Alt+T`)
|
||||||
|
- [ ] File manager shows directories
|
||||||
|
- [ ] Applications menu appears
|
||||||
|
- [ ] Network connects automatically
|
||||||
|
|
||||||
|
### Step 3: Create Bootable USB (Optional)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check available USB drives
|
||||||
|
lsblk
|
||||||
|
|
||||||
|
# Write ISO to USB (replace /dev/sdX with your device)
|
||||||
|
sudo bash script/create-usb.sh /dev/sdX
|
||||||
|
```
|
||||||
|
|
||||||
|
⚠️ **WARNING:** This erases all data on the USB drive!
|
||||||
|
|
||||||
|
### Step 4: Boot on Real Hardware
|
||||||
|
|
||||||
|
1. Insert USB drive
|
||||||
|
2. Restart computer
|
||||||
|
3. Press `F12`, `F2`, or `Del` (depending on manufacturer) to access boot menu
|
||||||
|
4. Select USB drive
|
||||||
|
5. AeThex Linux will boot directly to desktop
|
||||||
|
|
||||||
|
## Configuration Files
|
||||||
|
|
||||||
|
All configuration files are in `configs/`:
|
||||||
|
|
||||||
|
```
|
||||||
|
configs/
|
||||||
|
├── grub/ # Bootloader configuration
|
||||||
|
│ ├── grub.cfg # Boot menu
|
||||||
|
│ └── themes/aethex/ # Visual theme
|
||||||
|
├── lightdm/ # Display manager
|
||||||
|
│ └── lightdm.conf # Auto-login config
|
||||||
|
├── systemd/ # System services
|
||||||
|
│ ├── aethex-desktop.service # Main desktop
|
||||||
|
│ └── aethex-kernel.service # OS Kernel API
|
||||||
|
└── xsession/ # Desktop session
|
||||||
|
└── aethex.desktop # Session definition
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Build fails at Tauri step
|
||||||
|
```bash
|
||||||
|
# Install Rust dependencies for your distro
|
||||||
|
# Ubuntu/Debian:
|
||||||
|
sudo apt install libwebkit2gtk-4.1-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
|
||||||
|
|
||||||
|
# Then retry build
|
||||||
|
cd /workspaces/AeThex-OS
|
||||||
|
npm run tauri:build
|
||||||
|
```
|
||||||
|
|
||||||
|
### VM won't boot
|
||||||
|
```bash
|
||||||
|
# Check if ISO was created successfully
|
||||||
|
ls -lh ~/aethex-linux-build/*.iso
|
||||||
|
|
||||||
|
# Verify checksum
|
||||||
|
sha256sum -c ~/aethex-linux-build/*.sha256
|
||||||
|
|
||||||
|
# Try rebuilding with clean slate
|
||||||
|
sudo rm -rf ~/aethex-linux-build
|
||||||
|
sudo bash script/build-linux-iso.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Desktop doesn't auto-login
|
||||||
|
- Default credentials: `aethex` / `aethex`
|
||||||
|
- Check `/etc/lightdm/lightdm.conf` for auto-login settings
|
||||||
|
- Verify service is enabled: `systemctl status lightdm`
|
||||||
|
|
||||||
|
### Black screen after boot
|
||||||
|
- Add `nomodeset` to boot parameters (press 'e' in GRUB menu)
|
||||||
|
- Or try: `quiet splash nomodeset`
|
||||||
|
|
||||||
|
## Customization
|
||||||
|
|
||||||
|
### Change Default User
|
||||||
|
Edit in `script/build-linux-iso.sh`:
|
||||||
|
```bash
|
||||||
|
# Replace 'aethex' with your username
|
||||||
|
useradd -m -s /bin/bash YOUR_USERNAME
|
||||||
|
echo 'YOUR_USERNAME:YOUR_PASSWORD' | chpasswd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Add Pre-installed Software
|
||||||
|
Add to package list in `script/build-linux-iso.sh`:
|
||||||
|
```bash
|
||||||
|
apt-get install -y \
|
||||||
|
# ... existing packages ...
|
||||||
|
firefox \
|
||||||
|
gimp \
|
||||||
|
vlc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Change Branding
|
||||||
|
- Logo: Replace `configs/grub/themes/aethex/logo.png`
|
||||||
|
- Colors: Edit `configs/grub/themes/aethex/theme.txt`
|
||||||
|
- Boot text: Edit `configs/grub/grub.cfg`
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
### Distribution (Public Release)
|
||||||
|
1. Host ISO on CDN or GitHub Releases
|
||||||
|
2. Create installation documentation
|
||||||
|
3. Set up update repository (apt/PPA)
|
||||||
|
4. Add installer wizard (Calamares)
|
||||||
|
|
||||||
|
### Production Hardening
|
||||||
|
- [ ] Enable secure boot signing
|
||||||
|
- [ ] Add encrypted home directory option
|
||||||
|
- [ ] Configure firewall rules
|
||||||
|
- [ ] Set up automatic security updates
|
||||||
|
- [ ] Add AppArmor/SELinux profiles
|
||||||
|
|
||||||
|
### Advanced Features
|
||||||
|
- [ ] Live USB persistence (save data between boots)
|
||||||
|
- [ ] Network install option (PXE boot)
|
||||||
|
- [ ] Multi-language support
|
||||||
|
- [ ] Custom kernel with optimizations
|
||||||
|
- [ ] Hardware driver auto-detection
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
- Full documentation: [AETHEX_LINUX.md](AETHEX_LINUX.md)
|
||||||
|
- Tauri setup: [TAURI_SETUP.md](TAURI_SETUP.md)
|
||||||
|
- Project overview: [README.md](README.md)
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
For issues or questions:
|
||||||
|
1. Check existing documentation
|
||||||
|
2. Review system logs: `journalctl -xe`
|
||||||
|
3. Test in VM before real hardware
|
||||||
|
4. File issue on GitHub repository
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total Time to Bootable ISO:** ~30-45 minutes
|
||||||
|
**ISO Size:** 2-4 GB
|
||||||
|
**Minimum RAM:** 2GB (4GB recommended)
|
||||||
|
**Minimum Disk:** 10GB (20GB recommended)
|
||||||
6
README.txt
Normal file
6
README.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
AeThex Linux ISO build script is not yet implemented.
|
||||||
|
This is a placeholder artifact to validate CI wiring.
|
||||||
|
|
||||||
|
When implemented, this folder should contain:
|
||||||
|
- AeThex-Linux-<version>.iso
|
||||||
|
- SHA256 (checksum file)
|
||||||
15
aethex-desktop.service
Normal file
15
aethex-desktop.service
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
[Unit]
|
||||||
|
Description=AeThex Desktop WebOS
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=aethex
|
||||||
|
WorkingDirectory=/opt/aethex-desktop
|
||||||
|
Environment="DISPLAY=:0"
|
||||||
|
ExecStart=/usr/bin/node /opt/aethex-desktop/server/index.js
|
||||||
|
Restart=always
|
||||||
|
RestartSec=3
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
14
aethex-launcher.sh
Normal file
14
aethex-launcher.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# AeThex Desktop Launcher - starts X and opens the app in fullscreen browser
|
||||||
|
|
||||||
|
export DISPLAY=:0
|
||||||
|
|
||||||
|
# Start X server if not running
|
||||||
|
if ! pgrep -x "X" > /dev/null; then
|
||||||
|
startx &
|
||||||
|
sleep 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Launch Chromium in kiosk mode pointing to local server
|
||||||
|
chromium-browser --kiosk --no-first-run --disable-infobars --disable-session-crashed-bubble \
|
||||||
|
--disable-restore-session-state http://localhost:5000 &
|
||||||
1
aethex-linux-build/README.txt
Normal file
1
aethex-linux-build/README.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
No kernel found in rootfs
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import { useAuth } from "@/lib/auth";
|
import { useAuth } from "@/lib/auth";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import type { Mode, Realm } from "@/shared/app-registry";
|
import { Mode, Realm } from "@/shared/app-registry";
|
||||||
|
|
||||||
export function useMode() {
|
export function useMode() {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [mode, setModeState] = useState<Mode>("foundation");
|
const [mode, setModeState] = useState<Mode>(Mode.Web);
|
||||||
const [realm, setRealm] = useState<Realm>("foundation");
|
const [realm, setRealm] = useState<Realm>(Realm.Foundation);
|
||||||
const [enforcedRealm, setEnforcedRealm] = useState<Realm | null>(null);
|
const [enforcedRealm, setEnforcedRealm] = useState<Realm | null>(null);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
|
@ -53,7 +53,7 @@ export function useMode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
setModeState(newMode);
|
setModeState(newMode);
|
||||||
setRealm(newMode as Realm);
|
setRealm(newMode as unknown as Realm);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await fetch(`/api/user/mode-preference`, {
|
await fetch(`/api/user/mode-preference`, {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export function useRouteGuard() {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (loading || !realm || !mode) return;
|
if (loading || !realm || !mode) return;
|
||||||
|
|
||||||
const canAccess = canAccessRoute(location, realm, mode);
|
const canAccess = canAccessRoute({ id: location, realm }, location);
|
||||||
|
|
||||||
if (!canAccess) {
|
if (!canAccess) {
|
||||||
toast({
|
toast({
|
||||||
|
|
|
||||||
|
|
@ -235,9 +235,12 @@ export default function Notifications() {
|
||||||
<Check className="w-4 h-4" />
|
<Check className="w-4 h-4" />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{notification.actionUrl && (
|
{(notification.actionUrl || (notification as any).action_url) && (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => window.location.href = notification.actionUrl!}
|
onClick={() => {
|
||||||
|
const url = notification.actionUrl ?? (notification as any).action_url;
|
||||||
|
if (typeof url === 'string') window.location.href = url;
|
||||||
|
}}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="sm"
|
size="sm"
|
||||||
className="h-8 px-3 text-cyan-400 hover:bg-cyan-500/10"
|
className="h-8 px-3 text-cyan-400 hover:bg-cyan-500/10"
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,7 @@ export default function Projects() {
|
||||||
|
|
||||||
{/* Technologies */}
|
{/* Technologies */}
|
||||||
<div className="flex flex-wrap gap-2 mb-4">
|
<div className="flex flex-wrap gap-2 mb-4">
|
||||||
{project.technologies.slice(0, 3).map((tech) => (
|
{(Array.isArray(project.technologies) ? project.technologies : []).slice(0, 3).map((tech) => (
|
||||||
<span
|
<span
|
||||||
key={tech}
|
key={tech}
|
||||||
className="bg-slate-700 text-cyan-300 text-xs px-2 py-1 rounded"
|
className="bg-slate-700 text-cyan-300 text-xs px-2 py-1 rounded"
|
||||||
|
|
@ -257,9 +257,9 @@ export default function Projects() {
|
||||||
{tech}
|
{tech}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
{project.technologies.length > 3 && (
|
{Array.isArray(project.technologies) && project.technologies.length > 3 && (
|
||||||
<span className="text-slate-400 text-xs px-2 py-1">
|
<span className="text-slate-400 text-xs px-2 py-1">
|
||||||
+{project.technologies.length - 3}
|
+{(project.technologies.length - 3)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
40
client/src/shared/app-registry.ts
Normal file
40
client/src/shared/app-registry.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
// Minimal app registry stub to satisfy imports and provide types
|
||||||
|
export type AppId = string;
|
||||||
|
|
||||||
|
export interface AppDefinition {
|
||||||
|
id: AppId;
|
||||||
|
name: string;
|
||||||
|
route?: string;
|
||||||
|
icon?: string;
|
||||||
|
roles?: string[];
|
||||||
|
capabilities?: string[];
|
||||||
|
hidden?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AppRegistry: Record<AppId, AppDefinition> = {};
|
||||||
|
|
||||||
|
export function getAppById(id: AppId): AppDefinition | undefined {
|
||||||
|
return AppRegistry[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function listApps(): AppDefinition[] {
|
||||||
|
return Object.values(AppRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic enums to satisfy mode/realm references
|
||||||
|
export enum Mode {
|
||||||
|
Web = "web",
|
||||||
|
Desktop = "desktop",
|
||||||
|
Mobile = "mobile"
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Realm {
|
||||||
|
Foundation = "foundation",
|
||||||
|
Studio = "studio",
|
||||||
|
Network = "network"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Minimal route access check placeholder (always allows)
|
||||||
|
export function canAccessRoute(_user: unknown, _route?: string): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
53
configs/grub/grub.cfg
Normal file
53
configs/grub/grub.cfg
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
# GRUB Customization Configuration
|
||||||
|
# AeThex Linux Bootloader Theme
|
||||||
|
|
||||||
|
# Menu colors (terminal format)
|
||||||
|
set menu_color_normal=white/black
|
||||||
|
set menu_color_highlight=black/light-gray
|
||||||
|
|
||||||
|
# Timeout in seconds
|
||||||
|
set timeout=5
|
||||||
|
set timeout_style=menu
|
||||||
|
|
||||||
|
# Default boot option
|
||||||
|
set default=0
|
||||||
|
|
||||||
|
# Display settings
|
||||||
|
set gfxmode=auto
|
||||||
|
set gfxpayload=keep
|
||||||
|
terminal_output gfxterm
|
||||||
|
|
||||||
|
# Load video modules
|
||||||
|
insmod all_video
|
||||||
|
insmod gfxterm
|
||||||
|
insmod png
|
||||||
|
insmod jpeg
|
||||||
|
|
||||||
|
# Load theme if available
|
||||||
|
if [ -f /boot/grub/themes/aethex/theme.txt ]; then
|
||||||
|
set theme=/boot/grub/themes/aethex/theme.txt
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Boot menu entries
|
||||||
|
menuentry "AeThex Linux" {
|
||||||
|
set gfxpayload=keep
|
||||||
|
linux /boot/vmlinuz root=UUID=ROOTFS_UUID ro quiet splash
|
||||||
|
initrd /boot/initrd.img
|
||||||
|
}
|
||||||
|
|
||||||
|
menuentry "AeThex Linux (Recovery Mode)" {
|
||||||
|
linux /boot/vmlinuz root=UUID=ROOTFS_UUID ro recovery nomodeset
|
||||||
|
initrd /boot/initrd.img
|
||||||
|
}
|
||||||
|
|
||||||
|
menuentry "Memory Test (memtest86+)" {
|
||||||
|
linux16 /boot/memtest86+.bin
|
||||||
|
}
|
||||||
|
|
||||||
|
menuentry "Reboot" {
|
||||||
|
reboot
|
||||||
|
}
|
||||||
|
|
||||||
|
menuentry "Shutdown" {
|
||||||
|
halt
|
||||||
|
}
|
||||||
71
configs/grub/themes/aethex/theme.txt
Normal file
71
configs/grub/themes/aethex/theme.txt
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
# AeThex Linux GRUB Theme
|
||||||
|
# Place this file at: /boot/grub/themes/aethex/theme.txt
|
||||||
|
|
||||||
|
# General settings
|
||||||
|
title-text: "AeThex Linux"
|
||||||
|
title-color: "#FFFFFF"
|
||||||
|
title-font: "DejaVu Sans Bold 24"
|
||||||
|
|
||||||
|
# Background
|
||||||
|
desktop-image: "background.png"
|
||||||
|
desktop-color: "#000000"
|
||||||
|
|
||||||
|
# Terminal
|
||||||
|
terminal-box: "terminal_box_*.png"
|
||||||
|
terminal-font: "DejaVu Sans Mono Regular 14"
|
||||||
|
|
||||||
|
# Boot menu
|
||||||
|
+ boot_menu {
|
||||||
|
left = 25%
|
||||||
|
top = 30%
|
||||||
|
width = 50%
|
||||||
|
height = 40%
|
||||||
|
|
||||||
|
item_font = "DejaVu Sans Regular 16"
|
||||||
|
item_color = "#CCCCCC"
|
||||||
|
item_height = 32
|
||||||
|
item_padding = 10
|
||||||
|
item_spacing = 5
|
||||||
|
|
||||||
|
selected_item_font = "DejaVu Sans Bold 16"
|
||||||
|
selected_item_color = "#FFFFFF"
|
||||||
|
selected_item_pixmap_style = "select_*.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Progress bar
|
||||||
|
+ progress_bar {
|
||||||
|
id = "__timeout__"
|
||||||
|
left = 25%
|
||||||
|
top = 75%
|
||||||
|
width = 50%
|
||||||
|
height = 24
|
||||||
|
|
||||||
|
fg_color = "#4A90E2"
|
||||||
|
bg_color = "#1A1A1A"
|
||||||
|
border_color = "#333333"
|
||||||
|
|
||||||
|
font = "DejaVu Sans Regular 12"
|
||||||
|
text_color = "#FFFFFF"
|
||||||
|
text = "@TIMEOUT_NOTIFICATION_LONG@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Logo
|
||||||
|
+ image {
|
||||||
|
left = 50%
|
||||||
|
top = 10%
|
||||||
|
width = 128
|
||||||
|
height = 128
|
||||||
|
file = "logo.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Footer text
|
||||||
|
+ label {
|
||||||
|
left = 0
|
||||||
|
top = 100%-30
|
||||||
|
width = 100%
|
||||||
|
height = 20
|
||||||
|
align = "center"
|
||||||
|
color = "#666666"
|
||||||
|
font = "DejaVu Sans Regular 10"
|
||||||
|
text = "AeThex Corporation • Press 'e' to edit boot options"
|
||||||
|
}
|
||||||
25
configs/lightdm/lightdm.conf
Normal file
25
configs/lightdm/lightdm.conf
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# AeThex Linux - LightDM Configuration
|
||||||
|
# Auto-login to AeThex Desktop Environment
|
||||||
|
|
||||||
|
[Seat:*]
|
||||||
|
# Auto-login configuration
|
||||||
|
autologin-user=aethex
|
||||||
|
autologin-user-timeout=0
|
||||||
|
user-session=aethex
|
||||||
|
|
||||||
|
# Session configuration
|
||||||
|
session-wrapper=/etc/lightdm/Xsession
|
||||||
|
greeter-session=lightdm-gtk-greeter
|
||||||
|
|
||||||
|
# Display setup
|
||||||
|
xserver-command=X -core
|
||||||
|
display-setup-script=/usr/share/aethex-os/setup-display.sh
|
||||||
|
|
||||||
|
# Appearance
|
||||||
|
greeter-hide-users=false
|
||||||
|
greeter-show-manual-login=true
|
||||||
|
allow-guest=false
|
||||||
|
|
||||||
|
# Background (if using greeter)
|
||||||
|
[LightDM]
|
||||||
|
run-directory=/run/lightdm
|
||||||
43
configs/systemd/aethex-desktop.service
Normal file
43
configs/systemd/aethex-desktop.service
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
[Unit]
|
||||||
|
Description=AeThex Desktop Environment
|
||||||
|
Documentation=https://github.com/AeThex-Corporation/AeThex-OS
|
||||||
|
After=graphical.target network.target
|
||||||
|
Wants=network.target
|
||||||
|
ConditionPathExists=/usr/bin/aethex-desktop
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=aethex
|
||||||
|
Group=aethex
|
||||||
|
Environment=DISPLAY=:0
|
||||||
|
Environment=XDG_SESSION_TYPE=x11
|
||||||
|
Environment=XDG_RUNTIME_DIR=/run/user/1000
|
||||||
|
WorkingDirectory=/home/aethex
|
||||||
|
|
||||||
|
# Main executable
|
||||||
|
ExecStart=/usr/bin/aethex-desktop
|
||||||
|
|
||||||
|
# Restart on failure
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
StartLimitInterval=200
|
||||||
|
StartLimitBurst=3
|
||||||
|
|
||||||
|
# Security hardening
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=read-only
|
||||||
|
ReadWritePaths=/home/aethex
|
||||||
|
|
||||||
|
# Resource limits
|
||||||
|
MemoryMax=2G
|
||||||
|
CPUQuota=80%
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
SyslogIdentifier=aethex-desktop
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=graphical.target
|
||||||
43
configs/systemd/aethex-kernel.service
Normal file
43
configs/systemd/aethex-kernel.service
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
[Unit]
|
||||||
|
Description=AeThex OS Kernel (Identity & Entitlements)
|
||||||
|
Documentation=https://github.com/AeThex-Corporation/AeThex-OS
|
||||||
|
After=network.target postgresql.service
|
||||||
|
Wants=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=aethex
|
||||||
|
Group=aethex
|
||||||
|
WorkingDirectory=/opt/aethex-os
|
||||||
|
|
||||||
|
# Start the Node.js server for OS Kernel API
|
||||||
|
ExecStart=/usr/bin/node /opt/aethex-os/server/index.js
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
Environment=NODE_ENV=production
|
||||||
|
Environment=PORT=3000
|
||||||
|
EnvironmentFile=-/etc/aethex-os/environment
|
||||||
|
|
||||||
|
# Restart policy
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
StartLimitInterval=300
|
||||||
|
StartLimitBurst=5
|
||||||
|
|
||||||
|
# Security
|
||||||
|
NoNewPrivileges=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ReadWritePaths=/var/log/aethex-os /var/lib/aethex-os
|
||||||
|
|
||||||
|
# Resource limits
|
||||||
|
MemoryMax=1G
|
||||||
|
CPUQuota=50%
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
SyslogIdentifier=aethex-kernel
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
11
configs/xsession/aethex.desktop
Normal file
11
configs/xsession/aethex.desktop
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=AeThex OS
|
||||||
|
Comment=AeThex Desktop Environment - Web-based OS Interface
|
||||||
|
Exec=/usr/bin/aethex-desktop
|
||||||
|
TryExec=/usr/bin/aethex-desktop
|
||||||
|
Icon=aethex-logo
|
||||||
|
Type=Application
|
||||||
|
DesktopNames=AeThex
|
||||||
|
X-Ubuntu-Gettext-Domain=aethex-session
|
||||||
|
Keywords=desktop;environment;os;cloud;
|
||||||
|
Categories=System;
|
||||||
|
|
@ -136,7 +136,7 @@ Response:
|
||||||
```
|
```
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
- All OS routes are always protected by the capability guard and expect authenticated context where relevant.
|
- All OS routes are protected by the capability guard and expect authenticated context where relevant.
|
||||||
- Use Supabase console to inspect tables and audit logs.
|
- Use Supabase console to inspect tables and audit logs.
|
||||||
- For production, plan issuer key rotation via `aethex_issuer_keys`; rotation endpoints can be added similarly.
|
- For production, plan issuer key rotation via `aethex_issuer_keys`; rotation endpoints can be added similarly.
|
||||||
|
|
||||||
|
|
|
||||||
42
docs/FLASH_USB.md
Normal file
42
docs/FLASH_USB.md
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Flash AeThex OS ISO to USB
|
||||||
|
|
||||||
|
This guide shows how to write the AeThex OS ISO to a USB drive on Linux, macOS, and Windows.
|
||||||
|
|
||||||
|
## Linux/macOS (Script)
|
||||||
|
|
||||||
|
- Prereqs: `sudo`, optional `pv` for progress.
|
||||||
|
- File: [script/flash-usb.sh](script/flash-usb.sh)
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo ./script/flash-usb.sh -i artifacts/AeThex-Linux-amd64.iso
|
||||||
|
# Or specify the device
|
||||||
|
sudo ./script/flash-usb.sh -i artifacts/AeThex-Linux-amd64.iso -d /dev/sdX
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- The script lists removable drives and prompts for confirmation.
|
||||||
|
- It unmounts any partitions and writes the ISO with `dd` (progress shown when `pv` is installed).
|
||||||
|
|
||||||
|
## Windows (Rufus)
|
||||||
|
|
||||||
|
Windows does not include a native `dd`. Use Rufus:
|
||||||
|
- Download Rufus: https://rufus.ie
|
||||||
|
- Insert USB drive.
|
||||||
|
- Select the ISO: `AeThex-Linux-amd64.iso`.
|
||||||
|
- Partition scheme: `GPT` for UEFI, `MBR` for BIOS.
|
||||||
|
- Hit Start and confirm.
|
||||||
|
|
||||||
|
Optional PowerShell checks:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Get-Disk | Where-Object BusType -eq 'USB'
|
||||||
|
Get-Volume | Where-Object DriveType -eq 'Removable'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Boot Tips
|
||||||
|
|
||||||
|
- Prefer UEFI boot with Secure Boot disabled (or enroll keys if supported).
|
||||||
|
- If the system does not boot, try toggling CSM/Legacy mode.
|
||||||
|
- Use `F12/F10/ESC/DEL` (vendor dependent) to open the boot menu.
|
||||||
60
package-lock.json
generated
60
package-lock.json
generated
|
|
@ -4144,6 +4144,66 @@
|
||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
|
||||||
|
"version": "1.7.1",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@emnapi/wasi-threads": "1.1.0",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
|
||||||
|
"version": "1.7.1",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@emnapi/core": "^1.7.1",
|
||||||
|
"@emnapi/runtime": "^1.7.1",
|
||||||
|
"@tybys/wasm-util": "^0.10.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
|
||||||
|
"version": "0.10.1",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "0BSD",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
|
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
|
||||||
"version": "4.1.18",
|
"version": "4.1.18",
|
||||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz",
|
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz",
|
||||||
|
|
|
||||||
240
script/build-linux-iso.sh
Normal file
240
script/build-linux-iso.sh
Normal file
|
|
@ -0,0 +1,240 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# AeThex Linux ISO Builder - Full Desktop Edition
|
||||||
|
# Produces a bootable hybrid MBR/UEFI ISO with Ubuntu 24.04, Xfce desktop, and AeThex app
|
||||||
|
|
||||||
|
WORK_DIR="${1:-.}"
|
||||||
|
BUILD_DIR="$WORK_DIR/aethex-linux-build"
|
||||||
|
ISO_NAME="AeThex-Linux-amd64.iso"
|
||||||
|
ROOTFS_DIR="$BUILD_DIR/rootfs"
|
||||||
|
ISO_DIR="$BUILD_DIR/iso"
|
||||||
|
|
||||||
|
echo "[*] AeThex ISO Builder - Full Desktop Edition"
|
||||||
|
echo "[*] Build directory: $BUILD_DIR"
|
||||||
|
|
||||||
|
# Clean and prepare
|
||||||
|
rm -rf "$BUILD_DIR"
|
||||||
|
mkdir -p "$ROOTFS_DIR" "$ISO_DIR"/{boot/grub,casper,isolinux}
|
||||||
|
|
||||||
|
# Check critical dependencies
|
||||||
|
echo "[*] Checking dependencies..."
|
||||||
|
for cmd in debootstrap grub-mkrescue mksquashfs xorriso; do
|
||||||
|
if ! command -v "$cmd" &> /dev/null; then
|
||||||
|
echo "[!] Missing: $cmd"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "[+] Bootstrapping Ubuntu 24.04 (noble)..."
|
||||||
|
echo " (this may take 10-15 minutes, please wait...)"
|
||||||
|
debootstrap --arch=amd64 --variant=minbase noble "$ROOTFS_DIR" http://archive.ubuntu.com/ubuntu/ 2>&1 | tail -5
|
||||||
|
|
||||||
|
# Prepare chroot networking and mounts
|
||||||
|
cp -f /etc/resolv.conf "$ROOTFS_DIR/etc/resolv.conf" || true
|
||||||
|
mount -t proc /proc "$ROOTFS_DIR/proc" || true
|
||||||
|
mount -t sysfs /sys "$ROOTFS_DIR/sys" || true
|
||||||
|
mount --bind /dev "$ROOTFS_DIR/dev" || true
|
||||||
|
|
||||||
|
echo "[+] Installing Xfce desktop, Firefox, and system tools..."
|
||||||
|
echo " (packages installing, ~15-20 minutes...)"
|
||||||
|
chroot "$ROOTFS_DIR" bash -c '
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
# Enable universe repository
|
||||||
|
sed -i "s/^# deb/deb/" /etc/apt/sources.list
|
||||||
|
echo "deb http://archive.ubuntu.com/ubuntu noble universe" >> /etc/apt/sources.list
|
||||||
|
echo "deb http://archive.ubuntu.com/ubuntu noble-updates universe" >> /etc/apt/sources.list
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y \
|
||||||
|
linux-image-generic \
|
||||||
|
grub-pc-bin grub-efi-amd64-bin grub-common xorriso \
|
||||||
|
xorg xfce4 xfce4-goodies lightdm \
|
||||||
|
firefox network-manager \
|
||||||
|
sudo curl wget git ca-certificates gnupg \
|
||||||
|
pipewire-audio wireplumber \
|
||||||
|
file-roller thunar-archive-plugin \
|
||||||
|
xfce4-terminal mousepad ristretto \
|
||||||
|
dbus-x11
|
||||||
|
apt-get clean
|
||||||
|
' 2>&1 | tail -50
|
||||||
|
|
||||||
|
echo "[+] Installing Node.js 20.x from NodeSource..."
|
||||||
|
chroot "$ROOTFS_DIR" bash -c '
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
# Install ca-certificates first
|
||||||
|
apt-get install -y ca-certificates curl gnupg
|
||||||
|
|
||||||
|
mkdir -p /etc/apt/keyrings
|
||||||
|
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
|
||||||
|
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" > /etc/apt/sources.list.d/nodesource.list
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y nodejs
|
||||||
|
node --version || echo "Node install failed"
|
||||||
|
npm --version || echo "npm not found"
|
||||||
|
' 2>&1 | tail -10
|
||||||
|
|
||||||
|
echo "[+] Creating AeThex user with auto-login..."
|
||||||
|
chroot "$ROOTFS_DIR" bash -c '
|
||||||
|
useradd -m -s /bin/bash -G sudo aethex
|
||||||
|
echo "aethex:aethex" | chpasswd
|
||||||
|
echo "aethex ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
'
|
||||||
|
|
||||||
|
# Configure LightDM for auto-login
|
||||||
|
mkdir -p "$ROOTFS_DIR/etc/lightdm"
|
||||||
|
cat > "$ROOTFS_DIR/etc/lightdm/lightdm.conf" << 'LIGHTDM'
|
||||||
|
[Seat:*]
|
||||||
|
autologin-user=aethex
|
||||||
|
autologin-user-timeout=0
|
||||||
|
user-session=xfce
|
||||||
|
LIGHTDM
|
||||||
|
|
||||||
|
echo "[+] Setting up AeThex Desktop application..."
|
||||||
|
|
||||||
|
# Copy app files (if available, otherwise note for manual addition)
|
||||||
|
if [ -d "client" ] && [ -d "server" ]; then
|
||||||
|
echo " Copying AeThex Desktop files..."
|
||||||
|
mkdir -p "$ROOTFS_DIR/opt/aethex-desktop"
|
||||||
|
cp -r client "$ROOTFS_DIR/opt/aethex-desktop/"
|
||||||
|
cp -r server "$ROOTFS_DIR/opt/aethex-desktop/"
|
||||||
|
cp -r shared "$ROOTFS_DIR/opt/aethex-desktop/" 2>/dev/null || true
|
||||||
|
cp package*.json "$ROOTFS_DIR/opt/aethex-desktop/" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Install dependencies in chroot
|
||||||
|
chroot "$ROOTFS_DIR" bash -c 'cd /opt/aethex-desktop && npm install --production' 2>&1 | tail -10 || echo " npm install skipped"
|
||||||
|
else
|
||||||
|
echo " (client/server not found; skipping app copy)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create systemd service for AeThex server
|
||||||
|
cat > "$ROOTFS_DIR/etc/systemd/system/aethex-desktop.service" << 'SERVICEEOF'
|
||||||
|
[Unit]
|
||||||
|
Description=AeThex Desktop Server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=aethex
|
||||||
|
WorkingDirectory=/opt/aethex-desktop
|
||||||
|
ExecStart=/usr/bin/npm start
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
SERVICEEOF
|
||||||
|
|
||||||
|
# Enable AeThex service
|
||||||
|
chroot "$ROOTFS_DIR" systemctl enable aethex-desktop.service 2>/dev/null || echo " systemd service added"
|
||||||
|
|
||||||
|
# Create auto-start script for Firefox kiosk
|
||||||
|
mkdir -p "$ROOTFS_DIR/home/aethex/.config/autostart"
|
||||||
|
cat > "$ROOTFS_DIR/home/aethex/.config/autostart/aethex-kiosk.desktop" << 'KIOSK'
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name=AeThex Kiosk
|
||||||
|
Exec=firefox --kiosk http://localhost:5000
|
||||||
|
Hidden=false
|
||||||
|
NoDisplay=false
|
||||||
|
X-GNOME-Autostart-enabled=true
|
||||||
|
KIOSK
|
||||||
|
|
||||||
|
chroot "$ROOTFS_DIR" chown -R aethex:aethex /home/aethex
|
||||||
|
|
||||||
|
echo "[✓] AeThex Desktop integrated with Xfce auto-login and Firefox kiosk"
|
||||||
|
|
||||||
|
echo "[+] Extracting kernel and initrd..."
|
||||||
|
KERNEL="$(ls -1 $ROOTFS_DIR/boot/vmlinuz-* 2>/dev/null | head -n 1)"
|
||||||
|
INITRD="$(ls -1 $ROOTFS_DIR/boot/initrd.img-* 2>/dev/null | head -n 1)"
|
||||||
|
|
||||||
|
if [ -z "$KERNEL" ] || [ -z "$INITRD" ]; then
|
||||||
|
echo "[!] Kernel or initrd not found."
|
||||||
|
ls -la "$ROOTFS_DIR/boot/" || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp "$KERNEL" "$ISO_DIR/casper/vmlinuz"
|
||||||
|
cp "$INITRD" "$ISO_DIR/casper/initrd.img"
|
||||||
|
echo "[✓] Kernel: $(basename "$KERNEL")"
|
||||||
|
echo "[✓] Initrd: $(basename "$INITRD")"
|
||||||
|
echo "No kernel found in rootfs" > "$BUILD_DIR/README.txt"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp "$KERNEL" "$ISO_DIR/casper/vmlinuz"
|
||||||
|
cp "$INITRD" "$ISO_DIR/casper/initrd.i
|
||||||
|
|
||||||
|
# Unmount before squashfs
|
||||||
|
echo "[+] Unmounting chroot filesystems..."
|
||||||
|
umount -lf "$ROOTFS_DIR/procfilesystem..."
|
||||||
|
echo " (compressing ~2-3GB desktop, takes 10-15 minutes...)"
|
||||||
|
mksquashfs "$ROOTFS_DIR" "$ISO_DIR/casper/filesystem.squashfs" -b 1048576 -comp xz -Xdict-size 100% 2>&1 | tail -3mksquashfs "$ROOTFS_DIR" "$ISO_DIR/casper/filesystem.squashfs" -b 1048576 -comp xz 2>&1 | tail -3
|
||||||
|
else
|
||||||
|
echo "[!] mksquashfs not found; cannot create ISO."
|
||||||
|
mkdir -p "$BUILD_DIR"
|
||||||
|
echo "mksquashfs not available" > "$BUILD_DIR/README.txt"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[+] Setting up BIOS boot (isolinux)..."
|
||||||
|
cat > "$BUILD_DIR/isolinux.cfg" << 'EOF'
|
||||||
|
PROMPT 0
|
||||||
|
TIMEOUT 50
|
||||||
|
DEFAULT linux
|
||||||
|
|
||||||
|
LABEL linux
|
||||||
|
KERNELISO_DIR/isolinux/isolinux.cfg" << 'EOF'
|
||||||
|
PROMPT 0
|
||||||
|
TIMEOUT 50
|
||||||
|
DEFAULT linux
|
||||||
|
|
||||||
|
LABEL linux
|
||||||
|
MENU LABEL AeThex OS
|
||||||
|
KERNEL /casper/vmlinuz
|
||||||
|
APPEND initrd=/casper/initrd.img boot=casper quiet splash
|
||||||
|
EOF
|
||||||
|
cp /usr/lib/syslinux/isolinux.bin "$ISO_DIR/isolinux/" 2>/dev/null || \
|
||||||
|
cp /usr/share/syslinux/isolinux.bin "$ISO_DIR/isolinux/" 2>/dev/null || echo "[!] isolinux.bin missing"
|
||||||
|
cp /usr/lib/syslinux/ldlinux.c32 "$ISO_DIR/isolinux/" 2>/dev/null || \
|
||||||
|
cp /usr/share/syslinux/ldlinux.c32 "$ISO_DIR/isolinux/" 2>/dev/null || echo "[!] ldlinux.c32 missing"
|
||||||
|
|
||||||
|
echo "[+] Setting up UEFI boot (GRUB)..."
|
||||||
|
cat > "$ISO_DIR/boot/grub/grub.cfg" << 'EOF'
|
||||||
|
set timeout=10
|
||||||
|
set default=0
|
||||||
|
with grub-mkrescue..."
|
||||||
|
grub-mkrescue -o "$BUILD_DIR/$ISO_NAME" "$ISO_DIR" --verbose 2>&1 | tail -20
|
||||||
|
|
||||||
|
echo "[+] Computing SHA256 checksum..."
|
||||||
|
if [ -f "$BUILD_DIR/$ISO_NAME" ]; then
|
||||||
|
cd "$BUILD_DIR"
|
||||||
|
sha256sum "$ISO_NAME" > "$ISO_NAME.sha256"
|
||||||
|
echo "[✓] ISO ready:"
|
||||||
|
ls -lh "$ISO_NAME" | awk '{print " Size: " $5}'
|
||||||
|
cat "$ISO_NAME.sha256" | awk '{print " SHA256: " $1}'
|
||||||
|
echo "[✓] Location: $BUILD_DIR/$ISO_NAME"
|
||||||
|
else
|
||||||
|
echo "[!] ISO creation failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "[*] Cleaning up rootfs..."
|
||||||
|
rm -rf "$ROOTFS_DIR"
|
||||||
|
|
||||||
|
echo "[✓] Build complete!"
|
||||||
|
echo ""
|
||||||
|
echo "=== AeThex OS Full Desktop Edition ==="
|
||||||
|
echo "Features:"
|
||||||
|
echo " - Xfce desktop environment"
|
||||||
|
echo " - Firefox browser (auto-launches in kiosk mode)"
|
||||||
|
echo " - Node.js 20.x + npm"
|
||||||
|
echo " - AeThex Desktop app at /opt/aethex-desktop"
|
||||||
|
echo " - Auto-login as user 'aethex'"
|
||||||
|
echo " - NetworkManager for WiFi/Ethernet"
|
||||||
|
echo " - Audio support (PulseAudio)"
|
||||||
|
echo ""
|
||||||
|
echo "Flash to USB: sudo ./script/flash-usb.sh -i $BUILD_DIR/$ISO_NAME
|
||||||
|
echo "[✓] Done!"
|
||||||
110
script/flash-usb.sh
Executable file
110
script/flash-usb.sh
Executable file
|
|
@ -0,0 +1,110 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# AeThex OS USB flashing helper (Linux/macOS)
|
||||||
|
# Usage:
|
||||||
|
# sudo ./script/flash-usb.sh -i path/to/AeThex-Linux-amd64.iso -d /dev/sdX
|
||||||
|
# sudo ./script/flash-usb.sh -i path/to/AeThex-Linux-amd64.iso # will list devices and prompt
|
||||||
|
|
||||||
|
ISO=""
|
||||||
|
DEVICE=""
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: sudo $0 -i <iso_path> [-d <device>]" >&2
|
||||||
|
echo "Example: sudo $0 -i ./artifacts/AeThex-Linux-amd64.iso -d /dev/sdX" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
while getopts ":i:d:h" opt; do
|
||||||
|
case "$opt" in
|
||||||
|
i) ISO="$OPTARG" ;;
|
||||||
|
d) DEVICE="$OPTARG" ;;
|
||||||
|
h) usage; exit 0 ;;
|
||||||
|
*) usage; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo "This script must run as root (use sudo)." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$ISO" ]]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$ISO" ]]; then
|
||||||
|
echo "ISO not found: $ISO" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
OS_NAME="$(uname -s)"
|
||||||
|
|
||||||
|
list_devices_linux() {
|
||||||
|
lsblk -dpno NAME,SIZE,MODEL,TRAN | grep -E "/dev/" || true
|
||||||
|
}
|
||||||
|
|
||||||
|
list_devices_macos() {
|
||||||
|
diskutil list | sed -n '/(external, physical)/,/^$/p' || diskutil list
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "ISO: $ISO"
|
||||||
|
echo "Detecting removable drives..."
|
||||||
|
|
||||||
|
if [[ "$OS_NAME" == "Linux" ]]; then
|
||||||
|
list_devices_linux
|
||||||
|
elif [[ "$OS_NAME" == "Darwin" ]]; then
|
||||||
|
list_devices_macos
|
||||||
|
else
|
||||||
|
echo "Unsupported OS: $OS_NAME" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$DEVICE" ]]; then
|
||||||
|
read -r -p "Enter target device (e.g., /dev/sdX or /dev/diskN): " DEVICE
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$DEVICE" ]]; then
|
||||||
|
echo "No device specified." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "\nWARNING: This will ERASE ALL DATA on $DEVICE"
|
||||||
|
read -r -p "Type ERASE to continue: " CONFIRM
|
||||||
|
if [[ "$CONFIRM" != "ERASE" ]]; then
|
||||||
|
echo "Aborted." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Unmounting any mounted partitions from $DEVICE..."
|
||||||
|
if [[ "$OS_NAME" == "Linux" ]]; then
|
||||||
|
mapfile -t parts < <(lsblk -no NAME "$DEVICE" 2>/dev/null | tail -n +2)
|
||||||
|
for p in "${parts[@]}"; do
|
||||||
|
mountpoint="/dev/$p"
|
||||||
|
umount "$mountpoint" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
elif [[ "$OS_NAME" == "Darwin" ]]; then
|
||||||
|
diskutil unmountDisk force "$DEVICE" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Writing ISO to $DEVICE... this may take several minutes."
|
||||||
|
if [[ "$OS_NAME" == "Linux" ]]; then
|
||||||
|
if command -v pv >/dev/null 2>&1; then
|
||||||
|
pv "$ISO" | dd of="$DEVICE" bs=4M conv=fsync status=progress
|
||||||
|
else
|
||||||
|
dd if="$ISO" of="$DEVICE" bs=4M conv=fsync status=progress
|
||||||
|
fi
|
||||||
|
sync
|
||||||
|
elif [[ "$OS_NAME" == "Darwin" ]]; then
|
||||||
|
# On macOS, use raw disk for performance (/dev/rdiskN)
|
||||||
|
RAW_DEVICE="$DEVICE"
|
||||||
|
if [[ "$DEVICE" == /dev/disk* ]]; then
|
||||||
|
RAW_DEVICE="/dev/r$(basename "$DEVICE")"
|
||||||
|
fi
|
||||||
|
dd if="$ISO" of="$RAW_DEVICE" bs=4m
|
||||||
|
sync
|
||||||
|
diskutil eject "$DEVICE" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "\nDone. Safely remove the USB, plug into target PC, and boot."
|
||||||
|
echo "If boot fails on UEFI, ensure Secure Boot is disabled or keys enrolled."
|
||||||
90
script/gitlab-download-artifacts.sh
Executable file
90
script/gitlab-download-artifacts.sh
Executable file
|
|
@ -0,0 +1,90 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
GITLAB_HOST="${GITLAB_HOST:-https://gitlab.com}"
|
||||||
|
API_BASE="$GITLAB_HOST/api/v4"
|
||||||
|
|
||||||
|
PROJECT_PATH="${PROJECT_PATH:-}"
|
||||||
|
REF="${REF:-main}"
|
||||||
|
JOB_NAME="${JOB_NAME:-build_iso}"
|
||||||
|
PIPELINE_ID="${PIPELINE_ID:-}"
|
||||||
|
OUT_DIR="${OUT_DIR:-artifacts}"
|
||||||
|
|
||||||
|
if [[ -z "${GITLAB_TOKEN:-}" ]]; then
|
||||||
|
if [[ -n "${GITLAB_TOKEN_FILE:-}" && -r "$GITLAB_TOKEN_FILE" ]]; then
|
||||||
|
GITLAB_TOKEN=$(cat "$GITLAB_TOKEN_FILE")
|
||||||
|
else
|
||||||
|
echo "GITLAB_TOKEN is required. Set GITLAB_TOKEN or GITLAB_TOKEN_FILE." >&2
|
||||||
|
echo "Example: export GITLAB_TOKEN=... or export GITLAB_TOKEN_FILE=~/gitlab.token" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$PROJECT_PATH" ]]; then
|
||||||
|
echo "PROJECT_PATH is required (e.g., AeThex-Corporation/AeThex-OS)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
|
||||||
|
urlencode_project() {
|
||||||
|
echo -n "$PROJECT_PATH" | sed -e 's/\//%2F/g'
|
||||||
|
}
|
||||||
|
|
||||||
|
PROJECT_ENC="$(urlencode_project)"
|
||||||
|
|
||||||
|
auth() {
|
||||||
|
echo "PRIVATE-TOKEN: $GITLAB_TOKEN"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_json() {
|
||||||
|
local url="$1"
|
||||||
|
curl -sS -H "$(auth)" "$url"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_jq() {
|
||||||
|
if ! command -v jq >/dev/null 2>&1; then
|
||||||
|
echo "jq is required. Install with: sudo apt-get update && sudo apt-get install -y jq" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
require_jq
|
||||||
|
|
||||||
|
if [[ -z "$PIPELINE_ID" ]]; then
|
||||||
|
PIPELINE_ID=$(get_json "$API_BASE/projects/$PROJECT_ENC/pipelines?ref=$REF&status=success&order_by=updated_at&sort=desc&per_page=1" | jq -r '.[0].id')
|
||||||
|
if [[ -z "$PIPELINE_ID" || "$PIPELINE_ID" == "null" ]]; then
|
||||||
|
echo "No successful pipeline found for ref=$REF" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
JOBS_JSON=$(get_json "$API_BASE/projects/$PROJECT_ENC/pipelines/$PIPELINE_ID/jobs?scope=success")
|
||||||
|
JOB_ID=$(echo "$JOBS_JSON" | jq -r --arg name "$JOB_NAME" '[.[] | select(.name == $name and .artifacts_file and (.artifacts_file.filename != null))][0].id')
|
||||||
|
|
||||||
|
if [[ -z "$JOB_ID" || "$JOB_ID" == "null" ]]; then
|
||||||
|
echo "No job with artifacts found matching name=$JOB_NAME in pipeline=$PIPELINE_ID" >&2
|
||||||
|
echo "Available job names:" >&2
|
||||||
|
echo "$JOBS_JSON" | jq -r '.[].name' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ART_ZIP="$OUT_DIR/${PIPELINE_ID}-${JOB_NAME}.zip"
|
||||||
|
echo "Downloading artifacts from job $JOB_ID to $ART_ZIP"
|
||||||
|
curl -fSL -H "$(auth)" "$API_BASE/projects/$PROJECT_ENC/jobs/$JOB_ID/artifacts" -o "$ART_ZIP"
|
||||||
|
|
||||||
|
echo "Extracting $ART_ZIP"
|
||||||
|
unzip -o "$ART_ZIP" -d "$OUT_DIR" >/dev/null
|
||||||
|
|
||||||
|
ISO_PATH=$(find "$OUT_DIR" -type f -name '*.iso' | head -n 1 || true)
|
||||||
|
if [[ -n "$ISO_PATH" ]]; then
|
||||||
|
echo "Found ISO: $ISO_PATH"
|
||||||
|
if command -v sha256sum >/dev/null 2>&1; then
|
||||||
|
sha256sum "$ISO_PATH" | tee "$ISO_PATH.sha256.txt"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "No ISO file found in artifacts. Contents:" >&2
|
||||||
|
find "$OUT_DIR" -maxdepth 2 -type f -printf '%p\n' >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Done. Artifacts in $OUT_DIR"
|
||||||
36
trigger-gitlab-pipeline.sh
Executable file
36
trigger-gitlab-pipeline.sh
Executable file
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Trigger GitLab CI pipeline for AeThex-OS ISO build
|
||||||
|
# Usage: ./trigger-gitlab-pipeline.sh [branch] [token]
|
||||||
|
# Defaults: branch=main, token=$GITLAB_TOKEN
|
||||||
|
|
||||||
|
BRANCH="${1:-main}"
|
||||||
|
TOKEN="${2:-${GITLAB_TOKEN:-}}"
|
||||||
|
|
||||||
|
if [ -z "$TOKEN" ]; then
|
||||||
|
echo "❌ GITLAB_TOKEN not set and no token provided as argument."
|
||||||
|
echo "Usage: $0 [branch] [token]"
|
||||||
|
echo "Or export GITLAB_TOKEN=your_token_here"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PROJECT_ID="MrPiglr%2FAeThex-OS" # URL-encoded namespace/project
|
||||||
|
GITLAB_URL="https://gitlab.com/api/v4"
|
||||||
|
|
||||||
|
echo "🚀 Triggering GitLab pipeline on branch: $BRANCH"
|
||||||
|
|
||||||
|
RESPONSE=$(curl -s -X POST \
|
||||||
|
"${GITLAB_URL}/projects/${PROJECT_ID}/pipeline" \
|
||||||
|
-H "PRIVATE-TOKEN: $TOKEN" \
|
||||||
|
-d "ref=${BRANCH}")
|
||||||
|
|
||||||
|
echo "$RESPONSE" | jq . || echo "$RESPONSE"
|
||||||
|
|
||||||
|
PIPELINE_ID=$(echo "$RESPONSE" | jq -r '.id // empty')
|
||||||
|
if [ -n "$PIPELINE_ID" ]; then
|
||||||
|
echo "✅ Pipeline #$PIPELINE_ID created"
|
||||||
|
echo "📊 View at: https://gitlab.com/MrPiglr/AeThex-OS/-/pipelines/$PIPELINE_ID"
|
||||||
|
else
|
||||||
|
echo "⚠️ No pipeline ID returned; check your token and project access."
|
||||||
|
fi
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
"tsBuildInfoFile": "./node_modules/typescript/tsbuildinfo",
|
"tsBuildInfoFile": "./node_modules/typescript/tsbuildinfo",
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
|
"target": "ES2017",
|
||||||
|
"downlevelIteration": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"lib": ["esnext", "dom", "dom.iterable"],
|
"lib": ["esnext", "dom", "dom.iterable"],
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue