feat: Select operating systems (#204)
This commit is contained in:
parent
120171e826
commit
1abc636ede
7 changed files with 234 additions and 73 deletions
|
@ -3,7 +3,7 @@ services:
|
|||
container_name: qemu
|
||||
image: qemux/qemu-arm
|
||||
environment:
|
||||
BOOT: "https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/aarch64/alpine-virt-3.19.1-aarch64.iso"
|
||||
BOOT: "alpine"
|
||||
devices:
|
||||
- /dev/kvm
|
||||
- /dev/net/tun
|
||||
|
|
|
@ -31,7 +31,7 @@ spec:
|
|||
image: qemux/qemu-arm
|
||||
env:
|
||||
- name: BOOT
|
||||
value: "https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/aarch64/alpine-virt-3.19.1-aarch64.iso"
|
||||
value: "alpine"
|
||||
- name: DISK_SIZE
|
||||
value: "16G"
|
||||
ports:
|
||||
|
|
120
readme.md
120
readme.md
|
@ -32,7 +32,7 @@ services:
|
|||
container_name: qemu
|
||||
image: qemux/qemu-arm
|
||||
environment:
|
||||
BOOT: "https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/aarch64/alpine-virt-3.19.1-aarch64.iso"
|
||||
BOOT: "alpine"
|
||||
devices:
|
||||
- /dev/kvm
|
||||
- /dev/net/tun
|
||||
|
@ -49,7 +49,7 @@ services:
|
|||
Via Docker CLI:
|
||||
|
||||
```bash
|
||||
docker run -it --rm --name qemu -e "BOOT=http://example.com/image.iso" -p 8006:8006 --device=/dev/kvm --device=/dev/net/tun --cap-add NET_ADMIN -v ${PWD:-.}/qemu:/storage --stop-timeout 120 qemux/qemu-arm
|
||||
docker run -it --rm --name qemu -e "BOOT=alpine" -p 8006:8006 --device=/dev/kvm --device=/dev/net/tun --cap-add NET_ADMIN -v ${PWD:-.}/qemu:/storage --stop-timeout 120 qemux/qemu-arm
|
||||
```
|
||||
|
||||
Via Kubernetes:
|
||||
|
@ -72,7 +72,7 @@ kubectl apply -f https://raw.githubusercontent.com/qemus/qemu-arm/refs/heads/mas
|
|||
|
||||
Very simple! These are the steps:
|
||||
|
||||
- Set the `BOOT` environment variable to the URL of any [disk image](#what-image-formats-are-supported) you want to install.
|
||||
- Set the `BOOT` variable to the [operating system](#how-do-i-select-the-operating-system) you want to install.
|
||||
|
||||
- Start the container and connect to [port 8006](http://localhost:8006) using your web browser.
|
||||
|
||||
|
@ -80,23 +80,63 @@ kubectl apply -f https://raw.githubusercontent.com/qemus/qemu-arm/refs/heads/mas
|
|||
|
||||
Enjoy your brand new machine, and don't forget to star this repo!
|
||||
|
||||
### What image formats are supported?
|
||||
### How do I select the operating system?
|
||||
|
||||
You can use the `BOOT` environment variable in order to specify the operating system to be installed:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
BOOT: "alpine"
|
||||
```
|
||||
Select from the values below:
|
||||
|
||||
| **Value** | **Operating System** | **Size** |
|
||||
|---|---|---|
|
||||
| `alma` | Alma Linux | 1.7 GB |
|
||||
| `alpine` | Alpine Linux | 60 MB |
|
||||
| `centos` | CentOS Stream | 6.4 GB |
|
||||
| `debian` | Debian | 3.7 GB |
|
||||
| `fedora` | Fedora | 2.9 GB |
|
||||
| `gentoo` | Gentoo | 1.3 GB |
|
||||
| `kali` | Kali Linux | 3.4 GB |
|
||||
| `nixos` | NixOS | 2.4 GB |
|
||||
| `oracle` | Oracle Linux | 1.0 GB |
|
||||
| `rocky` | Rocky Linux | 1.9 GB |
|
||||
| `ubuntu` | Ubuntu Desktop | 3.3 GB |
|
||||
| `ubuntus` | Ubuntu Server | 2.7 GB |
|
||||
|
||||
### How can I use my own image?
|
||||
|
||||
If you want to boot an operating system that is not in the list, you can set the `BOOT` variable to the URL of the image:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
BOOT: "https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/aarch64/alpine-virt-3.19.1-aarch64.iso"
|
||||
```
|
||||
|
||||
The `BOOT` URL accepts files in any of the following formats:
|
||||
|
||||
| **Extension** | **Format** |
|
||||
| **Extension** | **Format** |
|
||||
|---|---|
|
||||
| `.img` | Raw |
|
||||
| `.raw` | Raw |
|
||||
| `.iso` | Optical |
|
||||
| `.qcow2` | QEMU |
|
||||
| `.vmdk` | VMware |
|
||||
| `.vhd` | VirtualPC |
|
||||
| `.vhdx` | Hyper-V |
|
||||
| `.vdi` | VirtualBox |
|
||||
| `.img` | Raw |
|
||||
| `.raw` | Raw |
|
||||
| `.iso` | Optical |
|
||||
| `.qcow2` | QEMU |
|
||||
| `.vmdk` | VMware |
|
||||
| `.vhd` | VirtualPC |
|
||||
| `.vhdx` | Hyper-V |
|
||||
| `.vdi` | VirtualBox |
|
||||
|
||||
> [!TIP]
|
||||
> It will also accept `.img.gz`, `.qcow2.xz`, `.iso.zip` and many more, as it automaticly extracts compressed files.
|
||||
It will also accept `.img.gz`, `.qcow2.xz`, `.iso.zip` and many more, as it automaticly extracts compressed files.
|
||||
|
||||
You can also use a local image file directly, and skip the download altogether, by binding it in your compose file like this:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- ./example.iso:/boot.iso
|
||||
```
|
||||
|
||||
This way you can supply a `/boot.iso`, `/boot.img` or a `/boot.qcow2` file. The value of `BOOT` will be ignored in this case.
|
||||
|
||||
### How do I change the storage location?
|
||||
|
||||
|
@ -121,6 +161,18 @@ kubectl apply -f https://raw.githubusercontent.com/qemus/qemu-arm/refs/heads/mas
|
|||
> [!TIP]
|
||||
> This can also be used to resize the existing disk to a larger capacity without any data loss.
|
||||
|
||||
### How do I change the amount of CPU or RAM?
|
||||
|
||||
By default, the container will be allowed to use a maximum of 1 CPU core and 1 GB of RAM.
|
||||
|
||||
If you want to adjust this, you can specify the desired amount using the following environment variables:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
RAM_SIZE: "4G"
|
||||
CPU_CORES: "4"
|
||||
```
|
||||
|
||||
### How do I increase the display resolution?
|
||||
|
||||
For maximum compatibility, the display output will be a simple framebuffer by default. While this isn't the most optimal, it doesn't require any drivers.
|
||||
|
@ -137,50 +189,14 @@ kubectl apply -f https://raw.githubusercontent.com/qemus/qemu-arm/refs/heads/mas
|
|||
> [!NOTE]
|
||||
> Using this method your screen will stay black during the boot process, until the point where the driver is actually loaded.
|
||||
|
||||
### How do I boot a local image?
|
||||
|
||||
You can use a local image file directly, and skip the download altogether, by binding it in your compose file:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- ./example.iso:/boot.iso
|
||||
```
|
||||
|
||||
You can supply a `boot.iso`, `boot.img` or `boot.qcow2` file by replacing the example path `./example.iso` with the filename of your desired image. The value of `BOOT` will be ignored in this case.
|
||||
|
||||
### How do I boot Windows?
|
||||
|
||||
Use [dockur/windows-arm](https://github.com/dockur/windows-arm) instead, as it includes all the drivers required during installation, amongst many other features.
|
||||
|
||||
### How do I boot a x86 image?
|
||||
### How do I boot x86/x64 images?
|
||||
|
||||
You can use the [qemu](https://github.com/qemus/qemu/) container to run x86 and x64 images on ARM.
|
||||
|
||||
### How do I boot without SCSI drivers?
|
||||
|
||||
By default, the machine makes use of `virtio-scsi` drives for performance reasons, and even though most Linux kernels bundle the necessary driver for this device, that may not always be the case for other operating systems.
|
||||
|
||||
If your machine fails to detect the hard drive, you can modify your compose file to use `virtio-blk` instead:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
DISK_TYPE: "blk"
|
||||
```
|
||||
|
||||
If it still fails to boot, you can set the value to `usb` to emulate a USB drive, which is slower but requires no drivers and is compatible with almost every system.
|
||||
|
||||
### How do I change the amount of CPU or RAM?
|
||||
|
||||
By default, the container will be allowed to use a maximum of 1 CPU core and 1 GB of RAM.
|
||||
|
||||
If you want to adjust this, you can specify the desired amount using the following environment variables:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
RAM_SIZE: "4G"
|
||||
CPU_CORES: "4"
|
||||
```
|
||||
|
||||
### How do I verify if my system supports KVM?
|
||||
|
||||
Only Linux and Windows 11 support KVM virtualization, macOS and Windows 10 do not unfortunately.
|
||||
|
|
97
src/define.sh
Normal file
97
src/define.sh
Normal file
|
@ -0,0 +1,97 @@
|
|||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
getURL() {
|
||||
local id="${1/ /}"
|
||||
local ret="$2"
|
||||
local url=""
|
||||
local name=""
|
||||
|
||||
case "${id,,}" in
|
||||
"alma" )
|
||||
name="AlmaLinux"
|
||||
url="https://repo.almalinux.org/almalinux/9/live/aarch64/AlmaLinux-9.5-aarch64-Live-GNOME.iso" ;;
|
||||
"alpine" )
|
||||
name="Alpine Linux"
|
||||
url="https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/aarch64/alpine-virt-3.19.1-aarch64.iso" ;;
|
||||
"arch" )
|
||||
name="Arch Linux"
|
||||
error "No image for $name is available for ARM64 yet! " && return 1 ;;
|
||||
"cachy" | "cachyos" )
|
||||
name="CachyOS"
|
||||
error "No image for $name is available for ARM64 yet! " && return 1 ;;
|
||||
"centos" )
|
||||
name="CentOS Stream"
|
||||
url="https://mirrors.xtom.de/centos-stream/10-stream/BaseOS/aarch64/iso/CentOS-Stream-10-latest-aarch64-dvd1.iso" ;;
|
||||
"debian" )
|
||||
name="Debian"
|
||||
url="https://cdimage.debian.org/debian-cd/current/arm64/iso-dvd/debian-12.9.0-arm64-DVD-1.iso" ;;
|
||||
"endeavour" | "endeavouros" )
|
||||
name="EndeavourOS"
|
||||
error "No image for $name is available for ARM64 yet! " && return 1 ;;
|
||||
"fedora" )
|
||||
name="Fedora Linux"
|
||||
url="https://eu.edge.kernel.org/fedora/releases/41/Workstation/aarch64/images/Fedora-Workstation-41-1.4.aarch64.raw.xz" ;;
|
||||
"gentoo" )
|
||||
name="Gentoo Linux"
|
||||
url="https://distfiles.gentoo.org/releases/arm64/autobuilds/20250309T234826Z/di-arm64-cloudinit-20250309T234826Z.qcow2" ;;
|
||||
"kali" )
|
||||
name="Kali Linux"
|
||||
url="https://cdimage.kali.org/kali-2024.4/kali-linux-2024.4-live-arm64.iso" ;;
|
||||
"kubuntu" )
|
||||
name="Kubuntu"
|
||||
error "No image for $name is available for ARM64 yet! " && return 1 ;;
|
||||
"macos" | "osx" )
|
||||
name="macOS"
|
||||
error "To install $name use: https://github.com/dockur/macos" && return 1 ;;
|
||||
"mint" | "linuxmint" )
|
||||
name="Linux Mint"
|
||||
error "No image for $name is available for ARM64 yet! " && return 1 ;;
|
||||
"manjaro" )
|
||||
name="Manjaro"
|
||||
error "No image for $name is available for ARM64 yet! " && return 1 ;;
|
||||
"mx" )
|
||||
name="MX Linux"
|
||||
error "No image for $name is available for ARM64 yet! " && return 1 ;;
|
||||
"nixos" )
|
||||
name="NixOS"
|
||||
url="https://channels.nixos.org/nixos-24.11/latest-nixos-gnome-aarch64-linux.iso" ;;
|
||||
"opensuse" | "suse" )
|
||||
name="OpenSUSE"
|
||||
error "No image for $name is available for ARM64 yet! " && return 1 ;;
|
||||
"oracle" )
|
||||
name="Oracle Linux"
|
||||
url="https://yum.oracle.com/ISOS/OracleLinux/OL9/u5/aarch64/OracleLinux-R9-U5-aarch64-boot-uek.iso" ;;
|
||||
"rocky" )
|
||||
name="Rocky Linux"
|
||||
url="https://dl.rockylinux.org/pub/rocky/9/live/aarch64/Rocky-9-Workstation-aarch64-latest.iso" ;;
|
||||
"slack" | "slackware" )
|
||||
name="Slackware"
|
||||
error "No image for $name is available for ARM64 yet! " && return 1 ;;
|
||||
"tails" )
|
||||
name="Tails"
|
||||
error "No image for $name is available for ARM64 yet! " && return 1 ;;
|
||||
"ubuntu" )
|
||||
name="Ubuntu Desktop"
|
||||
url="https://cdimage.ubuntu.com/ubuntu/releases/24.10/release/ubuntu-24.10-desktop-arm64.iso" ;;
|
||||
"ubuntus" )
|
||||
name="Ubuntu Server"
|
||||
url="https://cdimage.ubuntu.com/releases/24.04/release/ubuntu-24.04.2-live-server-arm64.iso" ;;
|
||||
"windows" )
|
||||
name="Windows"
|
||||
error "To install $name use: https://github.com/dockur/windows" && return 1 ;;
|
||||
"xubuntu" )
|
||||
name="Xubuntu"
|
||||
error "No image for $name is available for ARM64 yet! " && return 1 ;;
|
||||
esac
|
||||
|
||||
case "${ret,,}" in
|
||||
"test" ) ;;
|
||||
"name" ) echo "$name" ;;
|
||||
*) echo "$url";;
|
||||
esac
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
return 0
|
|
@ -611,7 +611,11 @@ if [ -z "$DISK_FMT" ]; then
|
|||
if [ -f "$DISK1_FILE.qcow2" ]; then
|
||||
DISK_FMT="qcow2"
|
||||
else
|
||||
DISK_FMT="raw"
|
||||
if [[ "$BOOT" == *".qcow2" ]] && [ ! -f "$DISK1_FILE.img" ]; then
|
||||
DISK_FMT="qcow2"
|
||||
else
|
||||
DISK_FMT="raw"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ set -Eeuo pipefail
|
|||
cd /run
|
||||
|
||||
. reset.sh # Initialize system
|
||||
. install.sh # Get bootdisk
|
||||
. define.sh # Define images
|
||||
. install.sh # Download image
|
||||
. disk.sh # Initialize disks
|
||||
. display.sh # Initialize graphics
|
||||
. network.sh # Initialize network
|
||||
|
|
|
@ -1,6 +1,26 @@
|
|||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
moveFile() {
|
||||
|
||||
local file="$1"
|
||||
local ext="${file##*.}"
|
||||
local dest="$STORAGE/boot.$ext"
|
||||
|
||||
if [[ "$file" == "$dest" ]] || [[ "$file" == "/boot.$ext" ]]; then
|
||||
BOOT="$file"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! mv -f "$file" "$dest"; then
|
||||
error "Failed to move $file to $dest !"
|
||||
return 1
|
||||
fi
|
||||
|
||||
BOOT="$dest"
|
||||
return 0
|
||||
}
|
||||
|
||||
detectType() {
|
||||
|
||||
local dir=""
|
||||
|
@ -10,25 +30,26 @@ detectType() {
|
|||
[ ! -s "$file" ] && return 1
|
||||
|
||||
case "${file,,}" in
|
||||
*".iso" | *".img" | *".raw" | *".qcow2" )
|
||||
BOOT="$file" ;;
|
||||
*".iso" | *".img" | *".raw" | *".qcow2" ) ;;
|
||||
* ) return 1 ;;
|
||||
esac
|
||||
|
||||
[ -n "$BOOT_MODE" ] && return 0
|
||||
[[ "${file,,}" != *".iso" ]] && return 0
|
||||
if [ -n "$BOOT_MODE" ] || [[ "${file,,}" != *".iso" ]]; then
|
||||
! moveFile "$file" && return 1
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Automaticly detect UEFI-compatible ISO's
|
||||
dir=$(isoinfo -f -i "$file")
|
||||
|
||||
if [ -z "$dir" ]; then
|
||||
BOOT=""
|
||||
error "Failed to read ISO file, invalid format!" && return 1
|
||||
if [ -n "$dir" ]; then
|
||||
dir=$(echo "${dir^^}" | grep "^/EFI")
|
||||
[ -z "$dir" ] && BOOT_MODE="legacy"
|
||||
else
|
||||
error "Failed to read ISO file, invalid format!"
|
||||
fi
|
||||
|
||||
dir=$(echo "${dir^^}" | grep "^/EFI")
|
||||
[ -z "$dir" ] && BOOT_MODE="legacy"
|
||||
|
||||
! moveFile "$file" && return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -36,7 +57,8 @@ downloadFile() {
|
|||
|
||||
local url="$1"
|
||||
local base="$2"
|
||||
local msg rc total total_mb progress
|
||||
local name="$3"
|
||||
local msg rc total total_mb progress name
|
||||
|
||||
local dest="$STORAGE/$base.tmp"
|
||||
rm -f "$dest"
|
||||
|
@ -48,8 +70,14 @@ downloadFile() {
|
|||
progress="--progress=dot:giga"
|
||||
fi
|
||||
|
||||
msg="Downloading image"
|
||||
info "Downloading $base..."
|
||||
if [ -z "$name" ]; then
|
||||
name="$base"
|
||||
msg="Downloading image"
|
||||
else
|
||||
msg="Downloading $name"
|
||||
fi
|
||||
|
||||
info "Downloading $name..."
|
||||
html "$msg..."
|
||||
|
||||
/run/progress.sh "$dest" "0" "$msg ([P])..." &
|
||||
|
@ -189,7 +217,22 @@ findFile "qcow2" && return 0
|
|||
|
||||
if [ -z "$BOOT" ] || [[ "$BOOT" == *"example.com/image.iso" ]]; then
|
||||
hasDisk && return 0
|
||||
error "No boot disk specified, set BOOT= to the URL of a disk image file." && exit 64
|
||||
error "No value specified for the BOOT variable." && exit 64
|
||||
fi
|
||||
|
||||
! getURL "$BOOT" "test" && exit 34
|
||||
|
||||
url=$(getURL "$BOOT" "url")
|
||||
name=$(getURL "$BOOT" "name")
|
||||
|
||||
[ -n "$url" ] && BOOT="$url"
|
||||
|
||||
if [[ "$BOOT" != *"."* ]]; then
|
||||
error "Invalid BOOT value specified, shortcut \"$BOOT\" is not recognized!" && exit 64
|
||||
fi
|
||||
|
||||
if [[ "${BOOT,,}" != "http"* ]]; then
|
||||
error "Invalid BOOT value specified, \"$BOOT\" is not a valid URL!" && exit 64
|
||||
fi
|
||||
|
||||
base=$(basename "${BOOT%%\?*}")
|
||||
|
@ -227,7 +270,7 @@ case "${base,,}" in
|
|||
* ) error "Unknown file extension, type \".${base/*./}\" is not recognized!" && exit 33 ;;
|
||||
esac
|
||||
|
||||
if ! downloadFile "$BOOT" "$base"; then
|
||||
if ! downloadFile "$BOOT" "$base" "$name"; then
|
||||
rm -f "$STORAGE/$base.tmp" && exit 60
|
||||
fi
|
||||
|
||||
|
@ -298,4 +341,4 @@ dst="$STORAGE/${base%.*}.$target_ext"
|
|||
|
||||
base=$(basename "$dst")
|
||||
detectType "$STORAGE/$base" && return 0
|
||||
error "Cannot read file \"${base}\"" && exit 36
|
||||
error "Cannot convert file \"${base}\"" && exit 36
|
||||
|
|
Loading…
Reference in a new issue