Add ISO installer image

This commit is contained in:
Qingsong Chen 2025-12-11 13:10:10 +00:00 committed by Tate, Hongliang Tian
parent e94546fef7
commit 12c364da32
20 changed files with 194 additions and 45 deletions

View File

@ -67,7 +67,7 @@ runs:
run: | run: |
CMD="" CMD=""
[[ "${{ matrix.id }}" == "lint" ]] && CMD+="make check" [[ "${{ matrix.id }}" == "lint" ]] && CMD+="make check"
[[ "${{ matrix.id }}" == "compile" ]] && CMD+="make build FEATURES=all" [[ "${{ matrix.id }}" == "compile" ]] && CMD+="make kernel FEATURES=all"
[[ "${{ matrix.id }}" == "usermode_test" ]] && CMD+="make test" [[ "${{ matrix.id }}" == "usermode_test" ]] && CMD+="make test"
[[ "${{ matrix.id }}" == "ktest" ]] && CMD+="make ktest NETDEV=tap" [[ "${{ matrix.id }}" == "ktest" ]] && CMD+="make ktest NETDEV=tap"
[[ -n "${{ inputs.arch }}" ]] && CMD+=" OSDK_TARGET_ARCH=${{ inputs.arch }}" [[ -n "${{ inputs.arch }}" ]] && CMD+=" OSDK_TARGET_ARCH=${{ inputs.arch }}"
@ -79,7 +79,7 @@ runs:
if: ${{ !(inputs.auto_test == 'general' || inputs.auto_test == 'osdk') }} if: ${{ !(inputs.auto_test == 'general' || inputs.auto_test == 'osdk') }}
shell: bash shell: bash
run: | run: |
CMD="make run AUTO_TEST=${{ inputs.auto_test }}" CMD="make run_kernel AUTO_TEST=${{ inputs.auto_test }}"
[[ "${{ inputs.intel_tdx }}" == "true" ]] && CMD+=" INTEL_TDX=1" [[ "${{ inputs.intel_tdx }}" == "true" ]] && CMD+=" INTEL_TDX=1"
[[ "${{ inputs.release }}" == "true" ]] && CMD+=" RELEASE=1" [[ "${{ inputs.release }}" == "true" ]] && CMD+=" RELEASE=1"
[[ "${{ inputs.enable_kvm }}" == "false" ]] && CMD+=" ENABLE_KVM=0" [[ "${{ inputs.enable_kvm }}" == "false" ]] && CMD+=" ENABLE_KVM=0"

View File

@ -24,7 +24,7 @@ jobs:
docker run \ docker run \
--privileged --network=host --device=/dev/kvm \ --privileged --network=host --device=/dev/kvm \
-v ./:/root/asterinas asterinas/asterinas:0.16.2-20251209 \ -v ./:/root/asterinas asterinas/asterinas:0.16.2-20251209 \
make run AUTO_TEST=vsock ENABLE_KVM=0 SCHEME=microvm RELEASE_MODE=1 & make run_kernel AUTO_TEST=vsock ENABLE_KVM=0 SCHEME=microvm RELEASE_MODE=1 &
- name: Run Vsock Client on Host - name: Run Vsock Client on Host
id: host_vsock_client id: host_vsock_client
run: | run: |

39
.github/workflows/test_iso_image.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: Test ISO image
on:
workflow_dispatch:
pull_request:
paths:
- distro/**
- .github/workflows/test_iso_image.yml
- tools/nixos/**
push:
branches:
- main
paths:
- distro/**
- .github/workflows/test_iso_image.yml
- tools/nixos/**
jobs:
iso-test:
runs-on: ubuntu-4-cores-150GB-ssd
container:
image: asterinas/asterinas:0.16.2-20251209
options: -v /dev:/dev --privileged
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- name: Build Asterinas NixOS ISO installer image
run: |
make iso NIXOS_TEST_COMMAND='hello-asterinas'
- name: Run ISO image and install Asterinas NixOS
run: |
make run_iso || true
tail --lines 10 qemu.log | grep -q "^Installation finished" || (echo "Test ISO failed" && exit 1)
echo "Test ISO succeeds!"
- name : Run Asterinas NixOS
run: |
make run_nixos || true
tail --lines 10 qemu.log | grep -q "^Hello Asterinas!" || (echo "Test NixOS failed" && exit 1)
echo "Test NixOS succeeds!"

View File

@ -33,12 +33,14 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Use nix-env to install and run the hello package - name: Use nix-env to install and run the hello package
run: | run: |
make run NIXOS=1 NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='nix-env -iA nixos.hello && hello' || true make nixos NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='nix-env -iA nixos.hello && hello' || true
make run_nixos || true
tail --lines 10 qemu.log | grep -q "^Hello, world!" || (echo "Test nix-env failed" && exit 1) tail --lines 10 qemu.log | grep -q "^Hello, world!" || (echo "Test nix-env failed" && exit 1)
echo "Test nix-env succeeds!" echo "Test nix-env succeeds!"
- name: Use nix-shell to install and run the hello package - name: Use nix-shell to install and run the hello package
run: | run: |
make run NIXOS=1 NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='nix-shell -p hello --command hello' || true make nixos NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='nix-shell -p hello --command hello' || true
make run_nixos || true
tail --lines 10 qemu.log | grep -q "^Hello, world!" || (echo "Test nix-shell failed" && exit 1) tail --lines 10 qemu.log | grep -q "^Hello, world!" || (echo "Test nix-shell failed" && exit 1)
echo "Test nix-shell succeeds!" echo "Test nix-shell succeeds!"
@ -56,6 +58,7 @@ jobs:
distro/etc_nixos/configuration.nix distro/etc_nixos/configuration.nix
- name: Run podman commands - name: Run podman commands
run: | run: |
make run NIXOS=1 NIXOS_DISK_SIZE_IN_MB=8192 NIXOS_TEST_COMMAND='podman run docker.io/library/alpine:latest ls /etc' || true make nixos NIXOS_DISK_SIZE_IN_MB=8192 NIXOS_TEST_COMMAND='podman run docker.io/library/alpine:latest ls /etc' || true
make run_nixos || true
tail --lines 50 qemu.log | grep -q "alpine-release" || (echo "Test podman failed" && exit 1) tail --lines 50 qemu.log | grep -q "alpine-release" || (echo "Test podman failed" && exit 1)
echo "Test podman succeeds!" echo "Test podman succeeds!"

View File

@ -37,7 +37,9 @@ jobs:
with: with:
image: asterinas/asterinas:0.16.2-20251209 image: asterinas/asterinas:0.16.2-20251209
options: --privileged -v /dev:/dev -v ${{ github.workspace }}:/root/asterinas options: --privileged -v /dev:/dev -v ${{ github.workspace }}:/root/asterinas
run: make run NIXOS=1 NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='hello-asterinas' || true run: |
make nixos NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='hello-asterinas' || true
make run_nixos || true
- name: Check results - name: Check results
run: | run: |
tail --lines 10 ${{ github.workspace }}/qemu.log | grep -q "^Hello Asterinas!" || (echo "Test NixOS failed" && exit 1) tail --lines 10 ${{ github.workspace }}/qemu.log | grep -q "^Hello Asterinas!" || (echo "Test NixOS failed" && exit 1)

View File

@ -55,7 +55,6 @@ DNS_SERVER ?= none
# End of network settings # End of network settings
# NixOS settings # NixOS settings
NIXOS ?= 0
NIXOS_DISK_SIZE_IN_MB ?= 8192 NIXOS_DISK_SIZE_IN_MB ?= 8192
NIXOS_DISABLE_SYSTEMD ?= false NIXOS_DISABLE_SYSTEMD ?= false
NIXOS_TEST_COMMAND ?= NIXOS_TEST_COMMAND ?=
@ -64,6 +63,10 @@ NIXOS_TEST_COMMAND ?=
NIXOS_STAGE_2_INIT ?= /bin/sh -l NIXOS_STAGE_2_INIT ?= /bin/sh -l
# End of NixOS settings # End of NixOS settings
# ISO installer settings
AUTO_INSTALL ?= true
# End of ISO installer settings
# ========================= End of Makefile options. ========================== # ========================= End of Makefile options. ==========================
SHELL := /bin/bash SHELL := /bin/bash
@ -158,11 +161,6 @@ ifeq ($(NO_DEFAULT_FEATURES), 1)
CARGO_OSDK_COMMON_ARGS += --no-default-features CARGO_OSDK_COMMON_ARGS += --no-default-features
endif endif
ifeq ($(NIXOS), 1)
BOOT_PROTOCOL = linux-efi-handover64
OVMF=off
endif
# To test the linux-efi-handover64 boot protocol, we need to use Debian's # To test the linux-efi-handover64 boot protocol, we need to use Debian's
# GRUB release, which is installed in /usr/bin in our Docker image. # GRUB release, which is installed in /usr/bin in our Docker image.
ifeq ($(BOOT_PROTOCOL), linux-efi-handover64) ifeq ($(BOOT_PROTOCOL), linux-efi-handover64)
@ -248,7 +246,7 @@ OSDK_SRC_FILES := \
$(shell find osdk/Cargo.toml osdk/Cargo.lock osdk/src -type f) $(shell find osdk/Cargo.toml osdk/Cargo.lock osdk/src -type f)
.PHONY: all .PHONY: all
all: build all: kernel
# Install or update OSDK from source # Install or update OSDK from source
# To uninstall, do `cargo uninstall cargo-osdk` # To uninstall, do `cargo uninstall cargo-osdk`
@ -288,22 +286,15 @@ check_vdso:
initramfs: check_vdso initramfs: check_vdso
@$(MAKE) --no-print-directory -C test @$(MAKE) --no-print-directory -C test
.PHONY: build # Build the kernel with an initramfs
build: initramfs $(CARGO_OSDK) .PHONY: kernel
kernel: initramfs $(CARGO_OSDK)
@cd kernel && cargo osdk build $(CARGO_OSDK_BUILD_ARGS) @cd kernel && cargo osdk build $(CARGO_OSDK_BUILD_ARGS)
ifeq ($(NIXOS),1)
@./tools/nixos/build_nixos.sh
endif
.PHONY: run # Build the kernel with an initramfs and then run it
run: initramfs $(CARGO_OSDK) .PHONY: run_kernel
ifeq ($(NIXOS),1) run_kernel: initramfs $(CARGO_OSDK)
@cd kernel && cargo osdk build $(CARGO_OSDK_BUILD_ARGS)
@./tools/nixos/build_nixos.sh
@./tools/nixos/run_nixos.sh target/nixos
else
@cd kernel && cargo osdk run $(CARGO_OSDK_BUILD_ARGS) @cd kernel && cargo osdk run $(CARGO_OSDK_BUILD_ARGS)
endif
# Check the running status of auto tests from the QEMU log # Check the running status of auto tests from the QEMU log
ifeq ($(AUTO_TEST), syscall) ifeq ($(AUTO_TEST), syscall)
@tail --lines 100 qemu.log | grep -q "^All syscall tests passed." \ @tail --lines 100 qemu.log | grep -q "^All syscall tests passed." \
@ -319,6 +310,29 @@ else ifeq ($(AUTO_TEST), vsock)
|| (echo "Vsock test failed" && exit 1) || (echo "Vsock test failed" && exit 1)
endif endif
# Build the Asterinas NixOS ISO installer image
iso: BOOT_PROTOCOL = linux-efi-handover64
iso:
@make kernel
@./tools/nixos/build_iso.sh
# Build the Asterinas NixOS ISO installer image and then do installation
run_iso: OVMF = off
run_iso:
@./tools/nixos/run_iso.sh
# Create an Asterinas NixOS installation on host
nixos: BOOT_PROTOCOL = linux-efi-handover64
nixos:
@make kernel
@./tools/nixos/build_nixos.sh
# After creating a Asterinas NixOS installation (via either the `run_iso` or `nixos` target),
# run the NixOS
run_nixos: OVMF = off
run_nixos:
@./tools/nixos/run_nixos.sh target/nixos
.PHONY: gdb_server .PHONY: gdb_server
gdb_server: initramfs $(CARGO_OSDK) gdb_server: initramfs $(CARGO_OSDK)
@cd kernel && cargo osdk run $(CARGO_OSDK_BUILD_ARGS) --gdb-server wait-client,vscode,addr=:$(GDB_TCP_PORT) @cd kernel && cargo osdk run $(CARGO_OSDK_BUILD_ARGS) --gdb-server wait-client,vscode,addr=:$(GDB_TCP_PORT)

View File

@ -78,8 +78,8 @@ docker run -it --privileged --network=host -v /dev:/dev -v $(pwd)/asterinas:/roo
3. Inside the container, go to the project folder to build and run Asterinas. 3. Inside the container, go to the project folder to build and run Asterinas.
```bash ```bash
make build make kernel
make run make run_kernel
``` ```
If everything goes well, Asterinas is now up and running inside a VM. If everything goes well, Asterinas is now up and running inside a VM.

View File

@ -62,8 +62,8 @@ docker run -it --privileged --network=host --device=/dev/kvm -v $(pwd)/asterinas
3. 在容器内,进入项目文件夹构建并运行星绽。 3. 在容器内,进入项目文件夹构建并运行星绽。
```bash ```bash
make build make kernel
make run make run_kernel
``` ```
如果一切顺利,星绽现在应该在一个虚拟机内运行起来了。 如果一切顺利,星绽现在应该在一个虚拟机内运行起来了。

View File

@ -57,8 +57,8 @@ docker run -it --privileged --network=host --device=/dev/kvm -v $(pwd)/asterinas
3. コンテナ内でプロジェクトフォルダに移動し、Asterinasをビルドして実行します。 3. コンテナ内でプロジェクトフォルダに移動し、Asterinasをビルドして実行します。
```bash ```bash
make build make kernel
make run make run_kernel
``` ```
すべてが順調に進めば、Asterinasは仮想マシン内で実行されます。 すべてが順調に進めば、Asterinasは仮想マシン内で実行されます。

View File

@ -54,8 +54,8 @@ docker run -it --privileged \
3. Inside the container, go to the project folder to build and run Asterinas. 3. Inside the container, go to the project folder to build and run Asterinas.
```bash ```bash
make build make kernel
make run make run_kernel
``` ```
If everything goes well, Asterinas is now up and running inside a VM. If everything goes well, Asterinas is now up and running inside a VM.

View File

@ -37,7 +37,7 @@ cargo osdk test
The following command builds and runs the test binaries in `test/src/apps` directory on Asterinas. The following command builds and runs the test binaries in `test/src/apps` directory on Asterinas.
```bash ```bash
make run AUTO_TEST=test make run_kernel AUTO_TEST=test
``` ```
### Syscall Test ### Syscall Test
@ -45,13 +45,13 @@ make run AUTO_TEST=test
The following command builds and runs the syscall test binaries on Asterinas. The following command builds and runs the syscall test binaries on Asterinas.
```bash ```bash
make run AUTO_TEST=syscall make run_kernel AUTO_TEST=syscall
``` ```
To run system call tests interactively, start an instance of Asterinas with the system call tests built and installed. To run system call tests interactively, start an instance of Asterinas with the system call tests built and installed.
```bash ```bash
make run BUILD_SYSCALL_TEST=1 make run_kernel BUILD_SYSCALL_TEST=1
``` ```
Then, in the interactive shell, run the following script to start the syscall tests. Then, in the interactive shell, run the following script to start the syscall tests.

View File

@ -73,7 +73,7 @@ docker run -it --privileged --network=host --device=/dev/kvm -v $(pwd)/asterinas
go to the project folder to build and run Asterinas. go to the project folder to build and run Asterinas.
```bash ```bash
make run INTEL_TDX=1 make run_kernel INTEL_TDX=1
``` ```
If everything goes well, If everything goes well,

View File

@ -33,6 +33,7 @@ in pkgs.stdenv.mkDerivation {
mkdir -p $out/{bin,etc_nixos} mkdir -p $out/{bin,etc_nixos}
cp ${install_aster_nixos} $out/bin/install_aster_nixos.sh cp ${install_aster_nixos} $out/bin/install_aster_nixos.sh
ln -s ${aster_configuration} $out/etc_nixos/aster_configuration.nix ln -s ${aster_configuration} $out/etc_nixos/aster_configuration.nix
ln -s ${etc-nixos}/configuration.nix $out/etc_nixos/configuration.nix
ln -s ${etc-nixos}/modules $out/etc_nixos/modules ln -s ${etc-nixos}/modules $out/etc_nixos/modules
ln -s ${etc-nixos}/overlays $out/etc_nixos/overlays ln -s ${etc-nixos}/overlays $out/etc_nixos/overlays
ln -s ${aster-kernel} $out/kernel ln -s ${aster-kernel} $out/kernel

View File

@ -82,8 +82,13 @@ fi
BUILD_DIR=$(mktemp -d -p /mnt) BUILD_DIR=$(mktemp -d -p /mnt)
BOOT_DEVICE=${DISK}p1 if [ "${DISK#/dev/loop}" != "$DISK" ]; then
ROOT_DEVICE=${DISK}p2 BOOT_DEVICE="${DISK}p1"
ROOT_DEVICE="${DISK}p2"
else
BOOT_DEVICE="${DISK}1"
ROOT_DEVICE="${DISK}2"
fi
if [ ! -b "${BOOT_DEVICE}" ] && [ ! -b "${ROOT_DEVICE}" ]; then if [ ! -b "${BOOT_DEVICE}" ] && [ ! -b "${ROOT_DEVICE}" ]; then
parted ${DISK} -- mklabel gpt parted ${DISK} -- mklabel gpt
parted ${DISK} -- mkpart ESP fat32 1MB 512MB parted ${DISK} -- mkpart ESP fat32 1MB 512MB

View File

@ -0,0 +1,28 @@
{ pkgs ? import <nixpkgs> { }, autoInstall ? false, test-command ? "", ... }:
let
installer =
pkgs.callPackage ../aster_nixos_installer { inherit test-command; };
configuration = {
imports = [
"${pkgs.path}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix"
"${pkgs.path}/nixos/modules/installer/cd-dvd/channel.nix"
];
services.getty.autologinUser = pkgs.lib.mkForce "root";
environment.systemPackages = [ installer ];
environment.loginShellInit = ''
if [ ! -e "$HOME/configuration.nix" ]; then
# Copy the default configuration.nix to user's home directory.
cp -L ${installer}/etc_nixos/configuration.nix $HOME
fi
${pkgs.lib.optionalString autoInstall ''
if [ "$(tty)" == "/dev/hvc0" ]; then
echo "The installer automatically runs on /dev/hvc0!"
install_aster_nixos.sh --config $HOME/configuration.nix --disk /dev/vda --force-format-disk || true
poweroff
fi
''}
'';
};
in (pkgs.nixos configuration).config.system.build.isoImage

View File

@ -38,9 +38,9 @@ While most tests rely on `Nix` for compilation, the `gvisor` syscall test suite
The test suite supports building for multiple architectures, including `x86_64` and `riscv64`. You can specify the desired architecture by running: The test suite supports building for multiple architectures, including `x86_64` and `riscv64`. You can specify the desired architecture by running:
```bash ```bash
make build OSDK_TARGET_ARCH=x86_64 make kernel OSDK_TARGET_ARCH=x86_64
# or # or
make build OSDK_TARGET_ARCH=riscv64 make kernel OSDK_TARGET_ARCH=riscv64
``` ```
The build artifacts (initramfs) can be found in the `test/build` directory after the compilation. The build artifacts (initramfs) can be found in the `test/build` directory after the compilation.

View File

@ -118,7 +118,7 @@ run_benchmark() {
done <<< "$runtime_configs_str" done <<< "$runtime_configs_str"
# Prepare commands for Asterinas and Linux using arrays # Prepare commands for Asterinas and Linux using arrays
local asterinas_cmd_arr=(make run "BENCHMARK=${benchmark}") local asterinas_cmd_arr=(make run_kernel "BENCHMARK=${benchmark}")
# Add scheme part only if it's not empty and the platform is not TDX (OSDK doesn't support multiple SCHEME) # Add scheme part only if it's not empty and the platform is not TDX (OSDK doesn't support multiple SCHEME)
[[ -n "$aster_scheme_cmd_part" && "$platform" != "tdx" ]] && asterinas_cmd_arr+=("$aster_scheme_cmd_part") [[ -n "$aster_scheme_cmd_part" && "$platform" != "tdx" ]] && asterinas_cmd_arr+=("$aster_scheme_cmd_part")
asterinas_cmd_arr+=( asterinas_cmd_arr+=(

View File

@ -50,7 +50,7 @@ for CRATE in $EXCLUDED_CRATES; do
continue continue
;; ;;
# `target/osdk/base` and `target/osdk/test-base` are generated by OSDK and does not need to be formatted. # `target/osdk/base` and `target/osdk/test-base` are generated by OSDK and does not need to be formatted.
# The directories do not exist before running `make build` or `make test`. # The directories do not exist before running `make kernel` or `make test`.
*target/osdk/base*) *target/osdk/base*)
continue continue
;; ;;

17
tools/nixos/build_iso.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
# SPDX-License-Identifier: MPL-2.0
set -e
SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
ASTERINAS_DIR=$(realpath ${SCRIPT_DIR}/../..)
DISTRO_DIR=$(realpath ${ASTERINAS_DIR}/distro)
TARGET_DIR=${ASTERINAS_DIR}/target/nixos
mkdir -p ${TARGET_DIR}
nix-build ${DISTRO_DIR}/iso_image \
--arg autoInstall ${AUTO_INSTALL} \
--argstr test-command "${NIXOS_TEST_COMMAND}" \
--out-link ${TARGET_DIR}/iso_image

40
tools/nixos/run_iso.sh Executable file
View File

@ -0,0 +1,40 @@
#!/bin/bash
# SPDX-License-Identifier: MPL-2.0
set -e
SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)
ASTERINAS_DIR=$(realpath ${SCRIPT_DIR}/../..)
ASTER_IMAGE_PATH=${ASTERINAS_DIR}/target/nixos/asterinas.img
NIXOS_DISK_SIZE_IN_MB=${NIXOS_DISK_SIZE_IN_MB:-8192}
ISO_IMAGE_PATH=$(realpath ${ASTERINAS_DIR}/target/nixos/iso_image/iso/*.iso)
if [ ! -f "$ISO_IMAGE_PATH" ]; then
echo "Error: ISO_IMAGE not found!"
exit 1
fi
rm -f ${ASTER_IMAGE_PATH}
echo "Creating image at ${ASTER_IMAGE_PATH} of size ${NIXOS_DISK_SIZE_IN_MB}MB......"
dd if=/dev/zero of=${ASTER_IMAGE_PATH} bs=1M count=${NIXOS_DISK_SIZE_IN_MB}
echo "Image created successfully!"
QEMU_ARGS="qemu-system-x86_64 \
-bios /root/ovmf/release/OVMF.fd \
-cdrom ${ISO_IMAGE_PATH} -boot d \
-drive if=none,format=raw,id=u0,file=${ASTER_IMAGE_PATH} \
-device virtio-blk-pci,drive=u0,disable-legacy=on,disable-modern=off \
"
if [ "${ENABLE_KVM}" = "1" ]; then
QEMU_ARGS="${QEMU_ARGS} -accel kvm"
fi
COMMON_QEMU_ARGS=$(${SCRIPT_DIR}/../qemu_args.sh common 2>/dev/null)
QEMU_ARGS="
${QEMU_ARGS} \
${COMMON_QEMU_ARGS} \
"
${QEMU_ARGS}