# openkylin-server-installer **Repository Path**: healthly/openkylin-server-installer ## Basic Information - **Project Name**: openkylin-server-installer - **Description**: openkylin-server-installer - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-09 - **Last Updated**: 2026-09-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # openKylin Server Installer ## Installed APT sources The image must include `openkylin-keyring` and `openkylin-archive-anything`. Preflight checks both keyring files before disk writes; installation is offline and does not download keys or bypass signature verification. Image builds must separately verify repository signatures with these keys and disable the old anything2.0/nile source before updating package indexes. During installation only, all flat files and symlinks in the **target system's** `/etc/apt/sources.list.d/` are removed (including third-party sources and backups). The installer writes exactly two deb822 files, each with an explicit `Signed-By`: - `openkylin.sources`: `http://archive.build.openkylin.top/openkylin/`, suites `huanghe huanghe-security huanghe-updates huanghe-proposed`, components `main cross pty`. - `openkylin-anything.sources`: `http://ppa.build.openkylin.top/kylinsoft/anything3.0/openkylin/`, suite `huanghe`, component `main`. `/etc/apt/sources.list` contains only migration comments. Enabling proposed is intentional Server release policy. No software source is added. This operation does not run on installer package upgrades or modify the Live system's sources. Later source-package upgrades should be checked for reintroduced legacy entries. ## Storage engine 0.4 / LVM The installation-method page offers **Use an entire disk** (default) and **Custom partitions**. Whole-disk installation defaults to **Ordinary partitions**; select **Use LVM** in its Disk layout field for LVM. This creates an ESP (UEFI) or BIOS Boot partition, a separate 2048 MiB ext4 `/boot`, and a new PV/VG with an ext4 root LV. For a VG of at least 20 GiB, root initially uses about 80% and the rest is visibly reserved; smaller VGs use all capacity. The root LV and reserve can be adjusted in the plan before installation. Custom layouts support new PVs in unallocated GPT space, one or more new VGs, and new filesystem/swap LVs. Start from the disk overview, open a disk and select a **Free region**, then choose **LVM physical volume (PV)**. Select a planned PV to create a VG; open that VG to create LVs from **VG free** space. The overview separates physical disk unallocated space from capacity inside existing/new VGs. There is no global Create LVM shortcut competing with the free-region workflow. The the first PV on the boot disk reserves 2048 MiB for `/boot` if it is missing; this is shown in the form. Otherwise create `/boot` on the boot disk first. LV sizes are multiples of 4 MiB. PVs can span multiple disks only by explicit membership selection; this is linear LVM, not RAID. Root uses ext4; data LVs support ext4/XFS, and swap has no mount directory. Existing ordinary linear VGs can be explicitly retired as a complete group, including **every LV and every member PV partition**. The review lists each destructive change. An individual old PV cannot be deleted independently. Mounted/open LVs, incomplete/shared/complex VGs, thin pools, snapshots, encryption and LVM RAID are protected. A cross-disk VG cannot be implicitly destroyed by choosing to erase one disk: review and retire its complete membership first. Unallocated disk space remains available alongside safely inventoried old LVM. Reuse/resizing of old LVs is unsupported. All changes use the same reviewed plan and Undo workflow. Use JSON plan version 2 for LVM; version 1 ordinary plans and legacy CLI layout options remain supported. Both Live and target image need `lvm2` and initramfs LVM activation support. The installer checks actual generated initramfs contents, uses an ordinary `/boot`, and sets the target's LVM autoactivation list to this installation's VGs. Its original image lvm.conf is saved as lvm.conf.pre-installer. Commands restrict their device set; cleanup only deactivates recorded VG UUIDs with matching PV membership. Existing VG retirement is separately scoped by recorded VG/PV UUIDs and exact member devices, after backups and re-probe. It never performs a global VG purge or an automatic destructive retry. LVM validation: `python3 tests/lvm_storage.py`; destructive integration testing is limited to newly allocated disposable loops (`sudo python3 tests/lvm_integration.py`). The integration test currently uses the local ISO build root as installation source. ## Ordinary storage layouts The **Disks & partitions** page uses a reviewed JSON plan shared with the backend. Default installation erases one selected disk and creates GPT plus an ESP (UEFI) or a 2 MiB BIOS Boot partition (BIOS), followed by an ext4 root filesystem. Custom installation can create filesystems in multiple unallocated regions on multiple disks. A unique suitable ESP on an unambiguous target is reused automatically; otherwise the installer reserves a new boot partition in free space when the target is clear. **Use as boot disk** in each disk's menu automatically reuses a suitable ESP without formatting or reserves a new boot partition. Multiple suitable ESPs require explicit selection. **Boot partition properties** allows advanced size and boot-order configuration. Existing BIOS Boot layouts are not taken over. No existing filesystem is shrunk; insufficient space requires changing the plan. Then select a free region marked **Enter: CREATE PARTITION**. Mount points include `/`, `/boot`, `/home`, `/var`, `/var/log`, `/srv`, `/data` and user-entered absolute paths. ext4 is supported for all ordinary mount points; XFS is optional for data partitions. TUI sizes accept whole numbers in MiB only; **Use entire free region** is a separate checkbox. The CLI/plan size parser retains its compatibility syntax. Swap has no mount point. An existing GPT/FAT32 ESP may be selected explicitly and is never formatted. New ESPs default to 512 MiB with adjustable size. Existing files and firmware entries are preserved; each openKylin instance has its own EFI directory. Recognized ESP dirty flags are warnings, not installation blockers. Read-only diagnostics retain their complete output; other reported errors still block. No automatic repair is performed. ESP access/capacity are checked before writes, and write access is tested after final consent but before deleting old partitions. Root and `/boot` use ext4. The image must boot in the desired firmware mode. All edits remain pending until the final confirmation. Undo, reset and back do not write disks. **Clear this disk** is an explicit planned operation. Existing GPT data partitions can also be individually marked for deletion by selecting the partition and choosing Delete (no typed path). Freed space replaces deleted partitions in the physically ordered planned layout. **Pending changes** lists deletions and allows cancelling them. Before Identity, a disk-stage review lists each DELETE, ERASE, new filesystem and unformatted ESP reuse. Accepting this review does not write disks; the final Summary still requires separate write authorization. Existing ESP/BIOS Boot/MSR/Windows Recovery partitions are protected from individual deletion. Undo or cancel the deletion before installing; remove any overlapping new partitions first when restoring. Long lists scroll. Required boot/root partitions, overlaps, stale device identities, occupied disks, source capacity and mount conflicts are checked before writing. Supported: GPT ordinary partitions, x86 BIOS/UEFI, multi-disk mounts, preserved ESP multiboot. Not supported: MBR-preserving custom installation, resizing, existing LV reuse/resizing, RAID/encryption/subvolumes, separate early-boot directories such as `/usr` and `/etc`, arbitrary submounts under `/boot`, signed Secure Boot installation. On a preserved BIOS boot disk already containing bios_grub, this version refuses to risk overwriting another GRUB core image; choose a separate boot disk. Other architectures need their own ISO boot acceptance before release. Backend integration: `openkylin-install --storage-plan /run/.../plan.json`. Plans must be owner-only regular files and contain a matching reviewed digest. The old CLI options below are compatibility inputs, converted into this same storage model for real installation; they do not expose every TUI capability. Validation: `make smoke` includes shared-model and UI behavior tests. `sudo python3 tests/storage_integration.py` uses temporary loop devices only. `sudo python3 tests/storage_replacement_integration.py` verifies replacement of two old Linux partitions with a dirty shared ESP and byte-preserved NTFS data. See [replacement design](docs/STORAGE-REPLACEMENT-0.2.3.md) for scope and safeguards. `tests/qemu_acceptance.py` performs actual installs and boots disposable disks. Never run disk tests against production disks. No tests are run at ISO startup. ## Multiboot safety and diagnostics Each EFI instance uses its own directory. The generated chainloader searches the selected ESP UUID and sets GRUB's **root device** before launching Windows or another loader. `update-grub` refreshes this menu from the mounted ESP; it does not mount arbitrary foreign filesystems. Other ESPs remain reachable through their firmware entries. Stale EFI files/entries are never auto-deleted. Existing EFI files are hashed before and after bootloader setup. Only after GRUB config validation are the new NVRAM entry and requested BootOrder published. An unsuccessful BootOrder update attempts to restore the previous order. Only recognized dirty-flag and internally consistent FAT32 FSInfo count-only diagnostics are warnings. Unknown diagnostics or structural damage still stop installation; the installer never automatically repairs a shared ESP. Full installation logs and storage/NVRAM evidence are copied before target unmount to `/var/log/installer/` (directory 0700, files 0600, password redaction). The main file is `openkylin-installer.log`; its stated cutoff excludes subsequent Live shutdown/reboot messages. Failure archives are best effort only when the installation target is still safely mounted. Live service diagnostics include `nvmf-autoconnect` to distinguish image-layer defects from disk failures. See [0.4 safety and test report](docs/SAFETY-0.4.0.md) for tested boundaries and manual recovery of a lost NVRAM entry. Secure Boot remains unsupported. `openkylin-server-installer` is a full-screen terminal installer for an openKylin live ISO. Its Python `curses` frontend builds an installation plan; the existing shell backend validates and applies that plan. The package provides: - `/usr/sbin/openkylin-installer-tui` (default interactive frontend) - `/usr/sbin/openkylin-install` - `/usr/lib/openkylin-server-installer/lib/*.sh` - `/usr/lib/openkylin-server-installer/steps/*.sh` - `/usr/lib/systemd/system/openkylin-server-installer.service` The TUI presents five stages, each with a main page and explicit bottom actions: 1. Disks & partitions: whole-disk installation is the default; Custom is advanced. Erasure authorization remains unchecked until explicitly selected. Confirm and continue opens a changes review before advancing to Identity. 2. Identity: hostname, username, password confirmation, and optional local root password in one form. Enabling a root password does not enable root SSH. 3. Locale: timezone and system language in one form, English by default. 4. Network: interface and addressing mode, with static IPv4 fields expanded inline. 5. Summary: review all non-secret settings and disk changes; Start installation opens a separate unchecked write acknowledgment and Install now button. The disk stage owns the installation-method, boot-setup and partition child forms. Existing data partitions may be explicitly deleted in the plan; an ESP can be reused without formatting. Pending partitions can be edited or deleted without writing disks. Deleting an old OS does not remove its EFI files or firmware entry; that stale entry may no longer boot. Back up old data first. Size inputs show disk free total, selected region, minimum and suggested size. The `/boot` minimum is 256 MiB; its suggested size is 2048 MiB for kernel updates. Actual source contents plus filesystem reserve must still fit before writing. Occupied mount points are excluded from new partitions and manually typed paths are validated immediately. The interface uses an openKylin-specific blue/yellow visual system, a five-step progress header, planned-filesystem and disk-map sections, and highlighted input cards. Arrows or Tab/Shift+Tab move between content and bottom actions; Left/Right or Space change selections. Enter toggles checkboxes, while in text fields it moves to another field without submitting the stage. Select **Confirm and continue** explicitly to advance. Press Esc twice within 0.8 seconds to return; a single Esc only displays a reminder. Bottom Back/Cancel buttons remain directly usable. Returning from a stage retains input drafts; returning from a child editor discards its uncommitted changes without crossing stages. On the disk map, **Back: method** / double Esc opens the method form. Ctrl+C is ignored without flushing queued input. Terminals smaller than 64x20 pause with an enlargement prompt. There is no UI exit to a shell; an unexpected frontend failure is restarted by systemd. Installation stays inside the TUI with stage messages and scrolling command output. The managed backend uses a separate event pipe for unmount retry and completion; success requires both the completion event and exit status zero. Only then does Enter request a reboot. Failures preserve the log screen without automatically retrying partitioning; recovery reboot requires confirmation. The shell CLI retains its existing console/completion behavior. `python3 tests/terminal_interaction.py` runs the real curses frontend in an 80x24 PTY with synthetic disks and a disabled backend (requires pexpect). Use `--columns 64 --rows 20` for the minimum-size regression. The shell backend remains available for scripted installs. ## Partitioning modes The default `whole` mode recreates a GPT partition table and installs the standard EFI (or BIOS boot) plus root layout. It is destructive and requires explicit confirmation of the target disk. When `--mode` is omitted in an interactive install, the installer presents this choice explicitly; command-line `--mode` is intended for automation. Use `--mode custom` to install alongside existing systems. Custom mode never repartitions the disk or resizes an existing partition: it creates a new root partition in a user-selected unallocated gap. Existing partitions are preserved. On UEFI systems an existing EFI System Partition can be chosen with `--efi-partition`; it is mounted at `/boot/efi` and is not formatted. If no ESP exists, a 512 MiB FAT32 ESP is created in the selected gap. Examples: ```text openkylin-install --mode custom --disk /dev/nvme0n1 \ --efi-partition /dev/nvme0n1p1 ``` `--root-size-mib` optionally limits the new root partition (minimum 10240 MiB). `--home-size-mib` and `--swap-size-mib` optionally reserve separate `/home` and swap partitions (minimum 1024 MiB and 512 MiB). Any remaining gap (`0` disables either partition) is left untouched. In an interactive custom install, the installer asks for these optional sizes when they are not supplied. Custom mode does not shrink existing Windows/Linux partitions; the disk must already contain enough unallocated space. Supported installation architectures: - `x86_64`: UEFI and BIOS - `riscv64`: UEFI only - `aarch64`: UEFI only - `loongarch64`: UEFI only ARM64 uses the `arm64-efi` GRUB target. LoongArch uses `loongarch64-efi`. The systemd service starts only when the kernel command line contains: ```text installer=1 ``` With that parameter present, the ISO starts `/usr/sbin/openkylin-installer-tui`. The storage page first shows available disks, then asks whether the selected disk should use the default whole-disk layout or custom installation into unallocated space. For live-build, install this deb into the live rootfs and add `installer=1` to the default GRUB menu entry. ## Installation source The installer copies the read-only live rootfs, normally mounted at `/rofs`. It intentionally refuses to copy the merged `/`, because that view includes the live writable layer and runtime state. An alternate source can be supplied with `--source-root`, but it must be a complete rootfs and must not resolve to `/`. The live image builder should clean build state before creating `filesystem.squashfs`. For a standard live-build tree, add a chroot hook such as `config/hooks/normal/999-clean-rootfs.chroot` (use the equivalent hook stage if the platform wraps live-build): ```sh #!/bin/sh set -eu find /var/lib/apt/lists -mindepth 1 -delete 2>/dev/null || true find /var/cache/apt/archives -mindepth 1 -delete 2>/dev/null || true find /var/log -mindepth 1 -delete 2>/dev/null || true rm -rf /etc/apt/live-build rm -f \ /etc/apt/apt.conf.d/00recommends \ /etc/apt/apt.conf.d/00secure \ /etc/kylin-build \ /etc/machine-id \ /var/lib/dbus/machine-id \ /var/lib/systemd/random-seed \ /var/lib/systemd/timesync/clock ``` This hook must not remove `casper` or `openkylin-server-installer`; those are needed while the ISO is running. The installer purges those live-only packages from the target when they are registered in the target dpkg database.