mirror of
https://github.com/AeThex-Corporation/AeThex-OS.git
synced 2026-04-17 22:27:19 +00:00
tools: add USB flash script and GitLab artifact downloader; docs: quick flashing guide; gitignore artifacts/ and ISO files
This commit is contained in:
parent
f80f1fed36
commit
adf1de6747
4 changed files with 250 additions and 0 deletions
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
|
||||||
|
|
|
||||||
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.
|
||||||
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."
|
||||||
87
script/gitlab-download-artifacts.sh
Executable file
87
script/gitlab-download-artifacts.sh
Executable file
|
|
@ -0,0 +1,87 @@
|
||||||
|
#!/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
|
||||||
|
echo "GITLAB_TOKEN is required" >&2
|
||||||
|
exit 1
|
||||||
|
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"
|
||||||
Loading…
Reference in a new issue