first commit
This commit is contained in:
commit
7584207f76
72 changed files with 12801 additions and 0 deletions
1125
docs/calmares-installer.md
Normal file
1125
docs/calmares-installer.md
Normal file
File diff suppressed because it is too large
Load diff
730
docs/calmares-plan.md
Normal file
730
docs/calmares-plan.md
Normal file
|
|
@ -0,0 +1,730 @@
|
|||
# Calamares Module for bootc install
|
||||
|
||||
## Overview
|
||||
|
||||
This document outlines a focused plan for creating a single Calamares module that handles `bootc install` operations. This is the simplest and most direct approach, following the official bootc documentation patterns.
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Goal**: Create a single Calamares module that executes `bootc install` commands with proper configuration and error handling.
|
||||
|
||||
**Timeline**: 2-3 months (focused, single-purpose implementation)
|
||||
**Complexity**: Low (direct tool integration)
|
||||
**Target**: Debian 13 (Trixie) with bootc support
|
||||
|
||||
## Real-World Analysis
|
||||
|
||||
### How bootc install Actually Works
|
||||
|
||||
Based on the [official bootc documentation](https://bootc-dev.github.io/bootc//bootc-install.html) and [Fedora's bare metal documentation](https://docs.fedoraproject.org/en-US/bootc/bare-metal/):
|
||||
|
||||
#### 1. Core Commands
|
||||
```bash
|
||||
bootc install to-disk /dev/sda
|
||||
bootc install to-filesystem /path/to/mounted/fs
|
||||
bootc install to-existing-root
|
||||
```
|
||||
|
||||
#### 2. Container Execution Pattern
|
||||
From [Fedora's official documentation](https://docs.fedoraproject.org/en-US/bootc/bare-metal/):
|
||||
```bash
|
||||
podman run \
|
||||
--rm --privileged \
|
||||
--pid=host \
|
||||
-v /dev:/dev \
|
||||
-v /var/lib/containers:/var/lib/containers \
|
||||
--security-opt label=type:unconfined_t \
|
||||
<image> \
|
||||
bootc install to-disk /path/to/disk
|
||||
```
|
||||
|
||||
#### 3. Key Differences from Anaconda Approach
|
||||
- **No kickstart files** - Direct container execution
|
||||
- **No network during install** - Container is already pulled
|
||||
- **Minimal configuration** - Basic installer built into bootc
|
||||
- **Live ISO environment** - Typically run from Fedora CoreOS Live ISO
|
||||
|
||||
#### 3. Key OSTree Filesystem Nuances
|
||||
|
||||
**Critical differences from traditional Linux installations:**
|
||||
|
||||
- **Composefs by default**: [Fedora bootc uses composefs](https://docs.fedoraproject.org/en-US/bootc/filesystem/) for the root filesystem
|
||||
- **Read-only root**: Filesystem is read-only at runtime (like `podman run --read-only`)
|
||||
- **Special mount points**: `/etc` and `/var` are persistent, mutable bind mounts
|
||||
- **Kernel location**: Kernel is in `/usr/lib/ostree-boot/` not `/boot/`
|
||||
- **3-way merge**: `/etc` changes are merged across upgrades
|
||||
- **Transient mountpoints**: Support for dynamic mountpoints with `transient-ro`
|
||||
|
||||
#### 4. Filesystem Layout
|
||||
```
|
||||
/usr/lib/ostree-boot/ # Kernel and initrd (not /boot/)
|
||||
/etc/ # Persistent, mutable (bind mount)
|
||||
/var/ # Persistent, mutable (bind mount)
|
||||
/usr/ # Read-only (composefs)
|
||||
/opt/ # Read-only (composefs)
|
||||
```
|
||||
|
||||
#### 5. Authentication Patterns
|
||||
From [Fedora's authentication documentation](https://docs.fedoraproject.org/en-US/bootc/authentication/):
|
||||
- **Registry auth**: `/etc/ostree/auth.json` for container registries
|
||||
- **SSH keys**: Via kickstart or bootc-image-builder config
|
||||
- **User management**: systemd-sysusers for local users
|
||||
- **nss-altfiles**: Static users in `/usr/lib/passwd` and `/usr/lib/group`
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Core Module Development (Month 1)
|
||||
|
||||
#### 1.1 Module Structure
|
||||
```cpp
|
||||
class BootcInstallModule : public Calamares::Module
|
||||
{
|
||||
public:
|
||||
void init() override;
|
||||
QList<Calamares::job_ptr> jobs() const override;
|
||||
|
||||
private:
|
||||
QString m_containerUrl;
|
||||
QString m_targetDevice;
|
||||
QString m_installType; // "to-disk", "to-filesystem", "to-existing-root"
|
||||
bool m_authRequired;
|
||||
QString m_authJson;
|
||||
};
|
||||
```
|
||||
|
||||
#### 1.2 Configuration Loading
|
||||
```cpp
|
||||
void BootcInstallModule::init()
|
||||
{
|
||||
auto config = Calamares::ModuleSystem::instance()->moduleConfiguration("bootc-install");
|
||||
|
||||
m_containerUrl = config.value("containerUrl").toString();
|
||||
m_targetDevice = config.value("targetDevice").toString();
|
||||
m_installType = config.value("installType", "to-disk").toString();
|
||||
m_authRequired = config.value("authRequired", false).toBool();
|
||||
m_authJson = config.value("authJson").toString();
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.3 Job Implementation
|
||||
```cpp
|
||||
QList<Calamares::job_ptr> BootcInstallModule::jobs() const
|
||||
{
|
||||
QList<Calamares::job_ptr> jobs;
|
||||
|
||||
// Registry authentication job
|
||||
if (m_authRequired) {
|
||||
jobs.append(Calamares::job_ptr(new RegistryAuthJob(m_authJson)));
|
||||
}
|
||||
|
||||
// Bootc installation job
|
||||
jobs.append(Calamares::job_ptr(new BootcInstallJob(m_containerUrl, m_targetDevice, m_installType)));
|
||||
|
||||
// Post-install configuration job
|
||||
jobs.append(Calamares::job_ptr(new BootcPostInstallJob(m_targetDevice, m_sshKey, m_username)));
|
||||
|
||||
return jobs;
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 2: Job Implementations (Month 1-2)
|
||||
|
||||
#### 2.1 Registry Authentication Job
|
||||
```cpp
|
||||
class RegistryAuthJob : public Calamares::Job
|
||||
{
|
||||
public:
|
||||
RegistryAuthJob(const QString& authJson) : m_authJson(authJson) {}
|
||||
|
||||
QString prettyName() const override { return "Configuring registry authentication"; }
|
||||
Calamares::JobResult exec() override;
|
||||
|
||||
private:
|
||||
QString m_authJson;
|
||||
};
|
||||
|
||||
Calamares::JobResult RegistryAuthJob::exec()
|
||||
{
|
||||
// Create /etc/ostree directory (persistent bind mount)
|
||||
if (!QDir("/etc/ostree").exists()) {
|
||||
if (!QDir().mkpath("/etc/ostree")) {
|
||||
return Calamares::JobResult::error("Failed to create /etc/ostree directory");
|
||||
}
|
||||
}
|
||||
|
||||
// Write auth.json (will persist across upgrades due to /etc bind mount)
|
||||
QFile authFile("/etc/ostree/auth.json");
|
||||
if (!authFile.open(QIODevice::WriteOnly)) {
|
||||
return Calamares::JobResult::error("Failed to open /etc/ostree/auth.json for writing");
|
||||
}
|
||||
|
||||
authFile.write(m_authJson.toUtf8());
|
||||
authFile.close();
|
||||
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2 Bootc Install Job
|
||||
```cpp
|
||||
class BootcInstallJob : public Calamares::Job
|
||||
{
|
||||
public:
|
||||
BootcInstallJob(const QString& containerUrl, const QString& targetDevice, const QString& installType)
|
||||
: m_containerUrl(containerUrl), m_targetDevice(targetDevice), m_installType(installType) {}
|
||||
|
||||
QString prettyName() const override { return "Installing bootc container"; }
|
||||
Calamares::JobResult exec() override;
|
||||
|
||||
private:
|
||||
QString m_containerUrl;
|
||||
QString m_targetDevice;
|
||||
QString m_installType;
|
||||
};
|
||||
|
||||
Calamares::JobResult BootcInstallJob::exec()
|
||||
{
|
||||
// Build podman command with OSTree-specific considerations
|
||||
QStringList args;
|
||||
args << "run" << "--rm" << "--privileged";
|
||||
args << "--pid=host";
|
||||
args << "-v" << "/dev:/dev";
|
||||
args << "-v" << "/var/lib/containers:/var/lib/containers";
|
||||
args << "--security-opt" << "label=type:unconfined_t";
|
||||
|
||||
// Add environment variables for OSTree filesystem
|
||||
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||
env.insert("OSTREE_NO_SIGNATURE_VERIFICATION", "1"); // For composefs unsigned mode
|
||||
env.insert("LIBMOUNT_FORCE_MOUNT2", "always"); // For transient-ro support
|
||||
|
||||
args << m_containerUrl;
|
||||
args << "bootc" << "install" << m_installType << m_targetDevice;
|
||||
|
||||
// Execute podman command
|
||||
QProcess process;
|
||||
process.setProcessEnvironment(env);
|
||||
process.start("podman", args);
|
||||
|
||||
if (!process.waitForFinished(-1)) {
|
||||
return Calamares::JobResult::error("bootc install command timed out");
|
||||
}
|
||||
|
||||
if (process.exitCode() != 0) {
|
||||
QString error = QString("bootc install failed: %1").arg(process.readAllStandardError());
|
||||
return Calamares::JobResult::error(error);
|
||||
}
|
||||
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.3 Post-Install Configuration Job
|
||||
```cpp
|
||||
class BootcPostInstallJob : public Calamares::Job
|
||||
{
|
||||
public:
|
||||
BootcPostInstallJob(const QString& targetDevice, const QString& sshKey, const QString& username)
|
||||
: m_targetDevice(targetDevice), m_sshKey(sshKey), m_username(username) {}
|
||||
|
||||
QString prettyName() const override { return "Configuring bootc system"; }
|
||||
Calamares::JobResult exec() override;
|
||||
|
||||
private:
|
||||
QString m_targetDevice;
|
||||
QString m_sshKey;
|
||||
QString m_username;
|
||||
|
||||
bool configureBootloader();
|
||||
bool createUserAccount();
|
||||
bool setupSshKey();
|
||||
};
|
||||
|
||||
Calamares::JobResult BootcPostInstallJob::exec()
|
||||
{
|
||||
// Mount the installed system
|
||||
QString mountPoint = "/mnt/bootc-install";
|
||||
if (!QDir().mkpath(mountPoint)) {
|
||||
return Calamares::JobResult::error("Failed to create mount point");
|
||||
}
|
||||
|
||||
// Mount the root partition
|
||||
QProcess mount;
|
||||
mount.start("mount", QStringList() << m_targetDevice << mountPoint);
|
||||
if (!mount.waitForFinished() || mount.exitCode() != 0) {
|
||||
return Calamares::JobResult::error("Failed to mount installed system");
|
||||
}
|
||||
|
||||
// Configure bootloader (GRUB2 for OSTree)
|
||||
if (!configureBootloader()) {
|
||||
return Calamares::JobResult::error("Failed to configure bootloader");
|
||||
}
|
||||
|
||||
// Create user account
|
||||
if (!createUserAccount()) {
|
||||
return Calamares::JobResult::error("Failed to create user account");
|
||||
}
|
||||
|
||||
// Setup SSH key
|
||||
if (!setupSshKey()) {
|
||||
return Calamares::JobResult::error("Failed to setup SSH key");
|
||||
}
|
||||
|
||||
// Unmount
|
||||
QProcess umount;
|
||||
umount.start("umount", QStringList() << mountPoint);
|
||||
umount.waitForFinished();
|
||||
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
bool BootcPostInstallJob::configureBootloader()
|
||||
{
|
||||
// OSTree systems use GRUB2 with specific configuration
|
||||
// Kernel is in /usr/lib/ostree-boot/, not /boot/
|
||||
QString grubConfig = QString("/mnt/bootc-install/boot/grub2/grub.cfg");
|
||||
|
||||
// Check if GRUB2 configuration exists
|
||||
if (!QFile::exists(grubConfig)) {
|
||||
// Run grub2-mkconfig to generate configuration
|
||||
QProcess grubMkconfig;
|
||||
grubMkconfig.start("grub2-mkconfig", QStringList() << "-o" << grubConfig);
|
||||
if (!grubMkconfig.waitForFinished() || grubMkconfig.exitCode() != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Install GRUB2 to the target device
|
||||
QProcess grubInstall;
|
||||
grubInstall.start("grub2-install", QStringList() << "--target=x86_64-efi" << m_targetDevice);
|
||||
if (!grubInstall.waitForFinished() || grubInstall.exitCode() != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BootcPostInstallJob::createUserAccount()
|
||||
{
|
||||
// OSTree systems use systemd-sysusers for user management
|
||||
// Users are defined in /usr/lib/sysusers.d/ or /etc/sysusers.d/
|
||||
QString sysusersConfig = "/mnt/bootc-install/etc/sysusers.d/calamares-user.conf";
|
||||
|
||||
QString userConfig = QString("u %1 1000 \"%1\" /home/%1\n").arg(m_username);
|
||||
userConfig += QString("g %1 1000\n").arg(m_username);
|
||||
userConfig += QString("m %1 %1\n").arg(m_username);
|
||||
|
||||
QFile file(sysusersConfig);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file.write(userConfig.toUtf8());
|
||||
file.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BootcPostInstallJob::setupSshKey()
|
||||
{
|
||||
if (m_sshKey.isEmpty()) return true;
|
||||
|
||||
// Create .ssh directory for root
|
||||
QString sshDir = "/mnt/bootc-install/root/.ssh";
|
||||
if (!QDir().mkpath(sshDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write SSH key
|
||||
QString keyFile = sshDir + "/authorized_keys";
|
||||
QFile file(keyFile);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file.write(m_sshKey.toUtf8());
|
||||
file.close();
|
||||
|
||||
// Set proper permissions
|
||||
QFile::setPermissions(keyFile, QFile::ReadOwner | QFile::WriteOwner);
|
||||
QFile::setPermissions(sshDir, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 3: OSTree Filesystem Considerations (Month 2)
|
||||
|
||||
#### 3.1 Filesystem Layout Validation
|
||||
```cpp
|
||||
class OstreeFilesystemValidator
|
||||
{
|
||||
public:
|
||||
static bool validateTargetDevice(const QString& device);
|
||||
static bool checkComposefsSupport();
|
||||
static bool validateMountPoints();
|
||||
|
||||
private:
|
||||
static bool isOstreeBootPath(const QString& path);
|
||||
static bool checkTransientRoSupport();
|
||||
};
|
||||
|
||||
bool OstreeFilesystemValidator::validateTargetDevice(const QString& device)
|
||||
{
|
||||
// Check if target device can support OSTree layout
|
||||
// - GPT partition table required
|
||||
// - EFI system partition for UEFI
|
||||
// - Root partition for OSTree deployment
|
||||
// - Boot partition for kernel/initrd (not /boot/ but /usr/lib/ostree-boot/)
|
||||
|
||||
QProcess sfdisk;
|
||||
sfdisk.start("sfdisk", QStringList() << "-l" << device);
|
||||
if (!sfdisk.waitForFinished()) return false;
|
||||
|
||||
QString output = sfdisk.readAllStandardOutput();
|
||||
return output.contains("GPT") && output.contains("EFI");
|
||||
}
|
||||
|
||||
bool OstreeFilesystemValidator::checkComposefsSupport()
|
||||
{
|
||||
// Check if composefs is available in the container
|
||||
QProcess composefs;
|
||||
composefs.start("composefs", QStringList() << "--help");
|
||||
return composefs.waitForFinished() && composefs.exitCode() == 0;
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2 Kernel and Initrd Handling
|
||||
```cpp
|
||||
class OstreeBootManager
|
||||
{
|
||||
public:
|
||||
static QString getKernelPath();
|
||||
static QString getInitrdPath();
|
||||
static bool setupBootloader(const QString& device);
|
||||
static bool regenerateInitramfs(const QString& mountPoint);
|
||||
|
||||
private:
|
||||
static const QString OSTREE_BOOT_PATH; // "/usr/lib/ostree-boot/"
|
||||
};
|
||||
|
||||
const QString OstreeBootManager::OSTREE_BOOT_PATH = "/usr/lib/ostree-boot/";
|
||||
|
||||
QString OstreeBootManager::getKernelPath()
|
||||
{
|
||||
// Kernel is in /usr/lib/ostree-boot/, not /boot/
|
||||
return OSTREE_BOOT_PATH + "vmlinuz";
|
||||
}
|
||||
|
||||
QString OstreeBootManager::getInitrdPath()
|
||||
{
|
||||
// Initrd is in /usr/lib/ostree-boot/, not /boot/
|
||||
return OSTREE_BOOT_PATH + "initramfs.img";
|
||||
}
|
||||
|
||||
bool OstreeBootManager::regenerateInitramfs(const QString& mountPoint)
|
||||
{
|
||||
// OSTree systems need initramfs regeneration after configuration changes
|
||||
// This is critical for filesystem configuration changes
|
||||
|
||||
QProcess dracut;
|
||||
dracut.start("dracut", QStringList()
|
||||
<< "--force"
|
||||
<< "--hostonly"
|
||||
<< "--kver" << "5.15.0" // Get actual kernel version
|
||||
<< mountPoint + "/boot/initramfs.img");
|
||||
|
||||
if (!dracut.waitForFinished()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return dracut.exitCode() == 0;
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.3 Persistent State Management
|
||||
```cpp
|
||||
class OstreeStateManager
|
||||
{
|
||||
public:
|
||||
static bool setupEtcBindMount();
|
||||
static bool setupVarBindMount();
|
||||
static bool configureTransientRo();
|
||||
|
||||
private:
|
||||
static bool createBindMount(const QString& source, const QString& target);
|
||||
};
|
||||
|
||||
bool OstreeStateManager::setupEtcBindMount()
|
||||
{
|
||||
// /etc is a persistent, mutable bind mount
|
||||
// Changes here persist across upgrades via 3-way merge
|
||||
return createBindMount("/etc", "/etc");
|
||||
}
|
||||
|
||||
bool OstreeStateManager::configureTransientRo()
|
||||
{
|
||||
// Enable transient-ro for dynamic mountpoints
|
||||
QString configPath = "/usr/lib/ostree/prepare-root.conf";
|
||||
QString config = "[root]\ntransient-ro = true\n";
|
||||
|
||||
QFile file(configPath);
|
||||
if (!file.open(QIODevice::WriteOnly)) return false;
|
||||
|
||||
file.write(config.toUtf8());
|
||||
file.close();
|
||||
|
||||
// Regenerate initramfs after config change
|
||||
QProcess dracut;
|
||||
dracut.start("dracut", QStringList() << "--force");
|
||||
return dracut.waitForFinished() && dracut.exitCode() == 0;
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 4: UI Integration (Month 2-3)
|
||||
|
||||
#### 4.1 Configuration Page
|
||||
```cpp
|
||||
class BootcInstallPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BootcInstallPage(QWidget* parent = nullptr);
|
||||
|
||||
QString containerUrl() const;
|
||||
QString targetDevice() const;
|
||||
QString installType() const;
|
||||
bool authRequired() const;
|
||||
QString authJson() const;
|
||||
bool enableTransientRo() const;
|
||||
|
||||
private slots:
|
||||
void onContainerUrlChanged();
|
||||
void onTargetDeviceChanged();
|
||||
void onInstallTypeChanged();
|
||||
void onAuthRequiredChanged();
|
||||
void validateOstreeRequirements();
|
||||
|
||||
private:
|
||||
QLineEdit* m_containerUrlEdit;
|
||||
QLineEdit* m_targetDeviceEdit;
|
||||
QComboBox* m_installTypeCombo;
|
||||
QCheckBox* m_authRequiredCheck;
|
||||
QTextEdit* m_authJsonEdit;
|
||||
QCheckBox* m_transientRoCheck;
|
||||
QLabel* m_ostreeStatusLabel;
|
||||
};
|
||||
```
|
||||
|
||||
#### 4.2 OSTree-Aware Validation
|
||||
```cpp
|
||||
bool BootcInstallPage::validate()
|
||||
{
|
||||
if (m_containerUrlEdit->text().isEmpty()) {
|
||||
Calamares::Branding::instance()->setValidationError("Container URL is required");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_targetDeviceEdit->text().isEmpty()) {
|
||||
Calamares::Branding::instance()->setValidationError("Target device is required");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate OSTree filesystem requirements
|
||||
if (!OstreeFilesystemValidator::validateTargetDevice(m_targetDeviceEdit->text())) {
|
||||
Calamares::Branding::instance()->setValidationError("Target device must have GPT partition table and EFI support");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!OstreeFilesystemValidator::checkComposefsSupport()) {
|
||||
Calamares::Branding::instance()->setValidationError("Composefs support not available in container");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_authRequiredCheck->isChecked() && m_authJsonEdit->toPlainText().isEmpty()) {
|
||||
Calamares::Branding::instance()->setValidationError("Authentication JSON is required");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BootcInstallPage::validateOstreeRequirements()
|
||||
{
|
||||
// Real-time validation of OSTree requirements
|
||||
bool deviceValid = OstreeFilesystemValidator::validateTargetDevice(m_targetDeviceEdit->text());
|
||||
bool composefsValid = OstreeFilesystemValidator::checkComposefsSupport();
|
||||
|
||||
QString status;
|
||||
if (deviceValid && composefsValid) {
|
||||
status = "✓ OSTree requirements satisfied";
|
||||
m_ostreeStatusLabel->setStyleSheet("color: green;");
|
||||
} else {
|
||||
status = "✗ OSTree requirements not met";
|
||||
m_ostreeStatusLabel->setStyleSheet("color: red;");
|
||||
}
|
||||
|
||||
m_ostreeStatusLabel->setText(status);
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 4: Testing and Polish (Month 2-3)
|
||||
|
||||
#### 4.1 Unit Tests
|
||||
```cpp
|
||||
class BootcInstallModuleTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void testModuleInitialization();
|
||||
void testJobCreation();
|
||||
void testRegistryAuthJob();
|
||||
void testBootcInstallJob();
|
||||
void testValidation();
|
||||
};
|
||||
```
|
||||
|
||||
#### 4.2 Integration Tests
|
||||
- [ ] Test with real bootc containers
|
||||
- [ ] Test registry authentication
|
||||
- [ ] Test different install types
|
||||
- [ ] Test error handling
|
||||
|
||||
## Configuration
|
||||
|
||||
### Module Configuration
|
||||
```yaml
|
||||
# bootc-install.conf
|
||||
module: bootc-install
|
||||
config:
|
||||
containerUrl: "quay.io/centos-bootc/centos-bootc:stream9"
|
||||
targetDevice: "/dev/sda"
|
||||
installType: "to-disk" # to-disk, to-filesystem, to-existing-root
|
||||
authRequired: false
|
||||
authJson: ""
|
||||
|
||||
# User account configuration
|
||||
username: "admin"
|
||||
sshKey: "" # SSH public key for root access
|
||||
|
||||
# OSTree-specific configuration
|
||||
ostree:
|
||||
enableComposefs: true
|
||||
enableTransientRo: false
|
||||
kernelPath: "/usr/lib/ostree-boot/vmlinuz"
|
||||
initrdPath: "/usr/lib/ostree-boot/initramfs.img"
|
||||
bootPath: "/usr/lib/ostree-boot/"
|
||||
|
||||
# Bootloader configuration
|
||||
bootloader:
|
||||
type: "grub2"
|
||||
target: "x86_64-efi"
|
||||
regenerateInitramfs: true
|
||||
|
||||
# Filesystem validation
|
||||
validation:
|
||||
requireGpt: true
|
||||
requireEfi: true
|
||||
checkComposefs: true
|
||||
validateMountPoints: true
|
||||
```
|
||||
|
||||
### Calamares Integration
|
||||
```yaml
|
||||
# calamares.conf
|
||||
modules:
|
||||
- bootc-install
|
||||
|
||||
bootc-install:
|
||||
containerUrl: "quay.io/centos-bootc/centos-bootc:stream9"
|
||||
targetDevice: "/dev/sda"
|
||||
installType: "to-disk"
|
||||
authRequired: false
|
||||
|
||||
# OSTree filesystem settings
|
||||
ostree:
|
||||
enableComposefs: true
|
||||
enableTransientRo: false
|
||||
```
|
||||
|
||||
## Technical Architecture
|
||||
|
||||
### File Structure
|
||||
```
|
||||
calamares-bootc-install/
|
||||
├── src/
|
||||
│ ├── BootcInstallModule.cpp
|
||||
│ ├── BootcInstallJob.cpp
|
||||
│ ├── RegistryAuthJob.cpp
|
||||
│ ├── BootcInstallPage.cpp
|
||||
│ └── BootcInstallPage.ui
|
||||
├── config/
|
||||
│ └── bootc-install.conf
|
||||
├── tests/
|
||||
│ ├── BootcInstallModuleTest.cpp
|
||||
│ └── testdata/
|
||||
└── CMakeLists.txt
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
- **Calamares**: Module framework
|
||||
- **Qt**: UI and core functionality
|
||||
- **podman**: Container runtime
|
||||
- **bootc**: Container installation tool
|
||||
|
||||
## Key Implementation Details
|
||||
|
||||
### 1. Simple and Focused
|
||||
- **Single purpose**: Only handles `bootc install`
|
||||
- **Direct integration**: Calls podman and bootc directly
|
||||
- **Minimal complexity**: No pattern switching or hybrid approaches
|
||||
|
||||
### 2. Follow Official Patterns
|
||||
- **Use exact podman command** from Fedora documentation
|
||||
- **Follow bootc install syntax** from official docs
|
||||
- **Handle registry auth** via `/etc/ostree/auth.json`
|
||||
|
||||
### 3. Error Handling
|
||||
- **Validate inputs** before execution
|
||||
- **Handle podman failures** gracefully
|
||||
- **Provide clear error messages** to users
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### Technical Metrics
|
||||
- [ ] Module loads and initializes correctly
|
||||
- [ ] Jobs execute successfully
|
||||
- [ ] Registry authentication works
|
||||
- [ ] bootc install completes successfully
|
||||
|
||||
### User Experience Metrics
|
||||
- [ ] Clear configuration UI
|
||||
- [ ] Proper validation and error messages
|
||||
- [ ] Progress reporting during installation
|
||||
- [ ] Integration with Calamares workflow
|
||||
|
||||
## Conclusion
|
||||
|
||||
This focused plan creates a single, purpose-built Calamares module for `bootc install` operations that properly accounts for the unique OSTree filesystem characteristics and the specific nuances of direct container installation. By following the [official bootc bare metal documentation](https://docs.fedoraproject.org/en-US/bootc/bare-metal/) exactly and incorporating the specific requirements for bootloader configuration, initramfs handling, and user account creation, we can create a reliable, maintainable solution.
|
||||
|
||||
### Key bootc install Considerations Addressed:
|
||||
|
||||
1. **Direct Container Execution** - Uses [podman run with privileged mode](https://docs.fedoraproject.org/en-US/bootc/bare-metal/) for installation
|
||||
2. **Post-Install Configuration** - Handles bootloader setup, user creation, and SSH key configuration
|
||||
3. **OSTree Filesystem Layout** - Kernel in `/usr/lib/ostree-boot/` not `/boot/`
|
||||
4. **GRUB2 Configuration** - Proper bootloader setup for OSTree systems
|
||||
5. **Initramfs Regeneration** - Critical for filesystem configuration changes
|
||||
6. **User Account Management** - Uses systemd-sysusers for OSTree-compatible user creation
|
||||
7. **SSH Key Setup** - Proper permissions and directory structure for root access
|
||||
|
||||
### Key Advantages:
|
||||
|
||||
1. **bootc install Native** - Follows the [official bootc install approach](https://docs.fedoraproject.org/en-US/bootc/bare-metal/) exactly
|
||||
2. **Complete Installation** - Handles both installation and post-install configuration
|
||||
3. **OSTree-Aware** - Properly manages filesystem layout and bootloader configuration
|
||||
4. **User-Friendly** - Provides familiar Calamares interface for bootc installation
|
||||
5. **Validation** - Real-time checking of OSTree and bootc requirements
|
||||
6. **Extensibility** - Can be enhanced with additional features over time
|
||||
|
||||
This approach ensures that the Calamares module provides a complete, user-friendly interface for `bootc install` operations while properly handling all the OSTree-specific requirements for bootloader configuration, initramfs management, and user account creation.
|
||||
300
docs/debian-installer.md
Normal file
300
docs/debian-installer.md
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
# Debian Installer Integration
|
||||
|
||||
## Overview
|
||||
|
||||
This document explores how to integrate debian-installer (d-i) support into the debian-bootc-image-builder project, examining the traditional debian-installer build process and potential integration approaches.
|
||||
|
||||
## Traditional Debian Installer Build Process
|
||||
|
||||
### Core Toolchain
|
||||
|
||||
The official debian-installer is built using a structured toolchain:
|
||||
|
||||
- **Primary Tool**: `Makefile` in `debian-installer/build/` directory
|
||||
- **Build System**: Make-based with structured targets and dependencies
|
||||
- **Dependencies**: Listed in `installer/debian/control` file
|
||||
- **Environment**: Requires Debian unstable (sid) or sid chroot
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
debian-installer/
|
||||
├── build/
|
||||
│ ├── Makefile # Main build orchestrator
|
||||
│ ├── util/ # Helper scripts
|
||||
│ ├── config/ # Build targets per architecture
|
||||
│ ├── pkg-lists/ # udeb packages for each image type
|
||||
│ ├── boot/ # Boot configuration files
|
||||
│ └── localudebs/ # Custom udebs not in standard mirror
|
||||
```
|
||||
|
||||
### Key Components
|
||||
|
||||
- **udebs**: Debian Installer packages (specialized for installer environment)
|
||||
- **pkg-lists**: Define which udebs are included in each image type
|
||||
- **config**: Architecture-specific build targets and supported media types
|
||||
- **boot**: Bootloader configuration for different boot methods
|
||||
|
||||
### Build Process
|
||||
|
||||
1. **Setup**: Ensure build dependencies are satisfied
|
||||
2. **Targets**: Use make commands like `build_cdrom_isolinux`, `build_netboot`
|
||||
3. **Cleanup**: Run `make reallyclean` between builds
|
||||
|
||||
## Alternative Tools
|
||||
|
||||
### simple-cdd
|
||||
- **Purpose**: Create custom Debian installation CDs
|
||||
- **Approach**: Configuration-driven, uses debian-installer as base
|
||||
- **Use Case**: Custom distributions, pre-configured installs
|
||||
- **Advantage**: Simpler than full d-i build system
|
||||
|
||||
### debian-cd
|
||||
- **Purpose**: Official Debian CD/DVD creation
|
||||
- **Approach**: Complex build system for official releases
|
||||
- **Use Case**: Official Debian releases
|
||||
- **Complexity**: High, designed for official distribution
|
||||
|
||||
## Integration Approaches
|
||||
|
||||
### Option 1: Hybrid Approach (Recommended)
|
||||
- **Disk Images**: Use OSBuild (qcow2, ami, vmdk, raw)
|
||||
- **debian-installer**: Use simple-cdd integration
|
||||
- **Shared Configuration**: Leverage existing `.config/registry.yaml` system
|
||||
|
||||
**Advantages:**
|
||||
- Uses each tool for its intended purpose
|
||||
- OSBuild excels at disk images
|
||||
- simple-cdd is proven for installer creation
|
||||
- Maintains project focus and simplicity
|
||||
|
||||
### Option 2: OSBuild Extension
|
||||
- **Approach**: Extend OSBuild with debian-installer stages
|
||||
- **Complexity**: High - requires OSBuild modifications
|
||||
- **Maintenance**: Ongoing OSBuild integration work
|
||||
|
||||
### Option 3: Focus on Disk Images Only
|
||||
- **Approach**: Remove installer support entirely
|
||||
- **Focus**: Pure disk image creation with OSBuild
|
||||
- **Simplicity**: Maximum focus and maintainability
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
### Recommended: simple-cdd Integration
|
||||
|
||||
1. **Add debian-installer command**:
|
||||
```bash
|
||||
debian-bootc-image-builder installer --type debian-installer
|
||||
```
|
||||
|
||||
2. **Configuration Integration**:
|
||||
- Extend `.config/registry.yaml` with installer settings
|
||||
- Support debian-installer specific configurations
|
||||
- Maintain consistency with existing config system
|
||||
|
||||
3. **Build Process**:
|
||||
- Use simple-cdd for installer creation
|
||||
- Integrate with existing container workflow
|
||||
- Leverage existing APT integration
|
||||
|
||||
4. **Package Management**:
|
||||
- Use existing APT solver for udeb resolution
|
||||
- Extend package definitions for installer packages
|
||||
- Maintain consistency with disk image approach
|
||||
|
||||
## Comparison: Fedora vs Debian Approach
|
||||
|
||||
### Fedora (anaconda)
|
||||
- **OSBuild Integration**: Native support via `org.osbuild.anaconda` stage
|
||||
- **Package-Based**: Uses RPM packages in YAML definitions
|
||||
- **Pipeline**: Multi-stage OSBuild pipeline (build → anaconda-tree → bootiso)
|
||||
- **Configuration**: Blueprint format with anaconda module support
|
||||
|
||||
### Debian (debian-installer)
|
||||
- **Traditional Toolchain**: Make-based build system
|
||||
- **Package-Based**: Uses udeb packages (installer-specific)
|
||||
- **Alternative Tools**: simple-cdd, debian-cd
|
||||
- **Configuration**: Various formats (simple-cdd config, debian-cd config)
|
||||
|
||||
## Recommendation
|
||||
|
||||
**Use the Hybrid Approach** with simple-cdd integration:
|
||||
|
||||
1. **Keep OSBuild for disk images** - it's designed for this purpose
|
||||
2. **Use simple-cdd for debian-installer** - proven, maintained tool
|
||||
3. **Share configuration system** - extend `.config/registry.yaml`
|
||||
4. **Maintain consistency** - use existing APT integration
|
||||
|
||||
This approach provides:
|
||||
- ✅ **Best tool for each job**
|
||||
- ✅ **Proven, maintained tools**
|
||||
- ✅ **Consistent user experience**
|
||||
- ✅ **Manageable complexity**
|
||||
- ✅ **Clear separation of concerns**
|
||||
|
||||
## Technical Hurdles and Challenges
|
||||
|
||||
### Understanding the Installation Flow
|
||||
|
||||
#### How Anaconda Integrates with Bootc
|
||||
The Fedora anaconda approach provides a clear model for understanding the technical challenges:
|
||||
|
||||
1. **Anaconda ISO Creation**: OSBuild generates an anaconda ISO with embedded kickstart configuration
|
||||
2. **Kickstart Integration**: The `ostreecontainer --url <container-image>` directive tells anaconda to install the bootc container
|
||||
3. **Installation Process**: Anaconda downloads the container and calls `bootc install` internally
|
||||
4. **System Configuration**: The installed system boots into the OSTree-based bootc environment
|
||||
|
||||
#### Key Technical Challenge: Preseed vs Kickstart
|
||||
- **Fedora**: Uses kickstart with `ostreecontainer` directive
|
||||
- **Debian**: Uses preseed configuration system
|
||||
- **Challenge**: No equivalent `ostreecontainer` directive exists in debian-installer preseed
|
||||
|
||||
### Major Technical Hurdles
|
||||
|
||||
#### 1. Preseed Integration Challenge
|
||||
**Problem**: Debian-installer uses preseed, not kickstart
|
||||
- **Preseed limitations**: No built-in support for container installation
|
||||
- **Custom integration needed**: Must create custom preseed hooks or scripts
|
||||
- **Complexity**: Requires deep understanding of debian-installer internals
|
||||
|
||||
**Potential Solutions**:
|
||||
- **Custom preseed script**: Create preseed hook that downloads and installs bootc container
|
||||
- **Modified debian-installer**: Extend debian-installer with bootc support
|
||||
- **Post-installation script**: Install bootc after base system installation
|
||||
|
||||
#### 2. Bootc Installation Integration
|
||||
**Problem**: How to integrate `bootc install` into debian-installer workflow
|
||||
- **Timing**: When during installation should bootc install run?
|
||||
- **Dependencies**: bootc must be available in the installer environment
|
||||
- **Partitioning**: Must align with debian-installer's partitioning scheme
|
||||
|
||||
**Technical Requirements**:
|
||||
- **bootc package**: Must be available in installer environment (udeb)
|
||||
- **Container download**: Network access during installation
|
||||
- **Installation order**: Partition → Format → bootc install → Configure bootloader
|
||||
|
||||
#### 3. Package Management Complexity
|
||||
**Problem**: Different package systems between installer and target
|
||||
- **Installer packages**: udebs (debian-installer packages)
|
||||
- **Target packages**: Regular .deb packages
|
||||
- **bootc package**: Must be available as both udeb and .deb
|
||||
|
||||
**Challenges**:
|
||||
- **Package availability**: bootc may not be available as udeb
|
||||
- **Dependency resolution**: Different dependency trees for installer vs target
|
||||
- **Repository management**: Different repositories for installer vs target
|
||||
|
||||
#### 4. Bootloader Configuration
|
||||
**Problem**: Bootloader setup for bootc systems
|
||||
- **GRUB configuration**: Must support OSTree-based booting
|
||||
- **Kernel parameters**: Special parameters for bootc/OSTree systems
|
||||
- **UEFI/BIOS support**: Different bootloader requirements
|
||||
|
||||
**Technical Details**:
|
||||
- **OSTree integration**: GRUB must understand OSTree deployments
|
||||
- **Kernel selection**: Must boot correct kernel from OSTree deployment
|
||||
- **Initramfs**: May need custom initramfs for bootc systems
|
||||
|
||||
#### 5. Network and Container Access
|
||||
**Problem**: Container registry access during installation
|
||||
- **Network configuration**: Must have network access during installation
|
||||
- **Registry authentication**: May need credentials for private registries
|
||||
- **Container download**: Large container images during installation
|
||||
|
||||
**Challenges**:
|
||||
- **Offline installation**: How to handle offline scenarios?
|
||||
- **Bandwidth**: Large container downloads during installation
|
||||
- **Authentication**: Registry credentials management
|
||||
|
||||
### Implementation Complexity Analysis
|
||||
|
||||
#### Simple-cdd Integration Challenges
|
||||
**Advantages**:
|
||||
- ✅ **Proven tool**: Well-maintained and documented
|
||||
- ✅ **Configuration-driven**: Fits existing config system
|
||||
- ✅ **Debian-native**: Designed for Debian systems
|
||||
|
||||
**Challenges**:
|
||||
- ❌ **Learning curve**: Complex configuration system
|
||||
- ❌ **bootc integration**: No built-in bootc support
|
||||
- ❌ **Customization needed**: Significant modification required
|
||||
|
||||
#### OSBuild Extension Challenges
|
||||
**Advantages**:
|
||||
- ✅ **Consistent approach**: Same tool for disk images and installers
|
||||
- ✅ **Existing integration**: Already integrated with project
|
||||
|
||||
**Challenges**:
|
||||
- ❌ **No debian-installer support**: OSBuild doesn't support debian-installer
|
||||
- ❌ **Major development**: Would require significant OSBuild modifications
|
||||
- ❌ **Maintenance burden**: Ongoing OSBuild integration work
|
||||
|
||||
#### Direct debian-installer Modification
|
||||
**Advantages**:
|
||||
- ✅ **Native integration**: Built into debian-installer
|
||||
- ✅ **Clean approach**: No external tool dependencies
|
||||
|
||||
**Challenges**:
|
||||
- ❌ **Complex development**: Requires deep debian-installer knowledge
|
||||
- ❌ **Upstream integration**: Changes need to be accepted upstream
|
||||
- ❌ **Maintenance**: Ongoing debian-installer integration
|
||||
|
||||
### Risk Assessment
|
||||
|
||||
#### High Risk Factors
|
||||
1. **Preseed limitations**: No proven way to integrate bootc installation
|
||||
2. **Package availability**: bootc may not be available as udeb
|
||||
3. **Bootloader complexity**: OSTree bootloader configuration is complex
|
||||
4. **Network dependencies**: Container download during installation
|
||||
|
||||
#### Medium Risk Factors
|
||||
1. **simple-cdd learning curve**: Complex configuration system
|
||||
2. **Testing complexity**: Difficult to test installer integration
|
||||
3. **Documentation gaps**: Limited documentation for custom installer creation
|
||||
|
||||
#### Low Risk Factors
|
||||
1. **Existing APT integration**: Can leverage existing package resolution
|
||||
2. **Configuration system**: Existing config system can be extended
|
||||
3. **Container workflow**: Existing container handling can be reused
|
||||
|
||||
### Recommended Approach: Phased Implementation
|
||||
|
||||
#### Phase 1: Research and Prototype
|
||||
1. **Investigate preseed hooks**: Research custom preseed script capabilities
|
||||
2. **Test bootc availability**: Check if bootc is available as udeb
|
||||
3. **Prototype simple-cdd**: Create basic simple-cdd configuration
|
||||
4. **Test container download**: Verify network access during installation
|
||||
|
||||
#### Phase 2: Basic Integration
|
||||
1. **Create preseed script**: Develop custom preseed hook for bootc installation
|
||||
2. **Integrate with simple-cdd**: Add bootc support to simple-cdd configuration
|
||||
3. **Test basic workflow**: Verify end-to-end installation process
|
||||
|
||||
#### Phase 3: Production Ready
|
||||
1. **Error handling**: Add comprehensive error handling and recovery
|
||||
2. **Documentation**: Create user documentation and examples
|
||||
3. **Testing**: Comprehensive testing across different scenarios
|
||||
|
||||
### Alternative: Focus on Disk Images Only
|
||||
|
||||
Given the technical complexity, consider **removing installer support entirely**:
|
||||
|
||||
**Advantages**:
|
||||
- ✅ **Simplified project**: Focus on core disk image functionality
|
||||
- ✅ **Reduced complexity**: No installer integration challenges
|
||||
- ✅ **Faster development**: Can focus on disk image improvements
|
||||
- ✅ **Clear scope**: Well-defined project boundaries
|
||||
|
||||
**Disadvantages**:
|
||||
- ❌ **Limited use cases**: No installer-based deployment
|
||||
- ❌ **User expectations**: Users may expect installer support
|
||||
- ❌ **Feature parity**: Less feature-complete than Fedora version
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Research preseed hooks** and custom script capabilities
|
||||
2. **Investigate bootc udeb availability** in Debian repositories
|
||||
3. **Prototype simple-cdd integration** with basic bootc support
|
||||
4. **Test container download** during installation process
|
||||
5. **Evaluate complexity** vs. benefit of installer support
|
||||
6. **Consider focusing on disk images only** if complexity is too high
|
||||
348
docs/fedora-ignition.md
Normal file
348
docs/fedora-ignition.md
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
# Fedora Ignition Approach for Bootc Installation
|
||||
|
||||
## Overview
|
||||
|
||||
Fedora CoreOS uses **Ignition** instead of traditional kickstart for system configuration and bootc installation. Ignition is a modern, JSON-based configuration system designed for immutable infrastructure and container-first deployments.
|
||||
|
||||
## Key Technical Concepts
|
||||
|
||||
### 1. Ignition vs Kickstart
|
||||
|
||||
| Aspect | Ignition | Kickstart |
|
||||
|--------|----------|-----------|
|
||||
| **Format** | JSON | Shell-like syntax |
|
||||
| **Purpose** | Immutable infrastructure | Package-based installation |
|
||||
| **Configuration** | Declarative | Imperative |
|
||||
| **Container Support** | Native | Via `ostreecontainer` directive |
|
||||
| **Modernity** | Modern, cloud-native | Traditional, legacy |
|
||||
|
||||
### 2. Ignition Configuration Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"ignition": {
|
||||
"version": "3.4.0"
|
||||
},
|
||||
"storage": {
|
||||
"disks": [
|
||||
{
|
||||
"device": "/dev/sda",
|
||||
"partitions": [
|
||||
{
|
||||
"label": "BIOS-BOOT",
|
||||
"number": 1,
|
||||
"size": 1024
|
||||
},
|
||||
{
|
||||
"label": "EFI-SYSTEM",
|
||||
"number": 2,
|
||||
"size": 268435456
|
||||
},
|
||||
{
|
||||
"label": "ROOT",
|
||||
"number": 3,
|
||||
"size": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"filesystems": [
|
||||
{
|
||||
"device": "/dev/disk/by-partlabel/ROOT",
|
||||
"format": "xfs",
|
||||
"path": "/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"systemd": {
|
||||
"units": [
|
||||
{
|
||||
"name": "bootc-install.service",
|
||||
"enabled": true,
|
||||
"contents": "[Unit]\nDescription=Install bootc container\n[Service]\nType=oneshot\nExecStart=/usr/bin/bootc install to-disk /dev/sda\n[Install]\nWantedBy=multi-user.target"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Container Installation via Ignition
|
||||
|
||||
#### Method 1: Systemd Service
|
||||
```json
|
||||
{
|
||||
"systemd": {
|
||||
"units": [
|
||||
{
|
||||
"name": "bootc-install.service",
|
||||
"enabled": true,
|
||||
"contents": "[Unit]\nDescription=Install bootc container\n[Service]\nType=oneshot\nExecStart=/usr/bin/bootc install to-disk /dev/sda\n[Install]\nWantedBy=multi-user.target"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Method 2: Direct Container Pull
|
||||
```json
|
||||
{
|
||||
"storage": {
|
||||
"files": [
|
||||
{
|
||||
"path": "/etc/containers/registries.conf.d/bootc.conf",
|
||||
"mode": 420,
|
||||
"contents": {
|
||||
"source": "data:text/plain;base64,W1JlZ2lzdHJ5XQpsb2NhdGlvbj0icXVheS5pbyIKc2VjdXJlPWZhbHNlCg=="
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Fedora CoreOS ISO Analysis
|
||||
|
||||
### ISO Structure
|
||||
```
|
||||
fedora-coreos-42.20250803.3.0-live-iso.x86_64.iso
|
||||
├── coreos/
|
||||
│ ├── features.json # Installer capabilities
|
||||
│ ├── igninfo.json # Points to ignition.img
|
||||
│ ├── kargs.json # Kernel arguments
|
||||
│ └── miniso.dat # Minimal ISO data
|
||||
├── images/
|
||||
│ ├── ignition.img # Ignition configuration
|
||||
│ ├── initrd.img # Initial ramdisk
|
||||
│ ├── rootfs.img # Root filesystem
|
||||
│ └── vmlinuz # Kernel
|
||||
├── EFI/fedora/grub.cfg # EFI boot configuration
|
||||
└── isolinux/isolinux.cfg # BIOS boot configuration
|
||||
```
|
||||
|
||||
### Boot Configuration
|
||||
- **Kernel arguments**: `coreos.liveiso=fedora-coreos-42.20250803.3.0 ignition.firstboot ignition.platform.id=metal`
|
||||
- **Ignition integration**: `ignition.img` loaded as initrd
|
||||
- **No kickstart references** in boot configuration
|
||||
|
||||
### Features Capabilities
|
||||
```json
|
||||
{
|
||||
"installer-config": true,
|
||||
"installer-config-directives": {
|
||||
"append-karg": true,
|
||||
"architecture": true,
|
||||
"console": true,
|
||||
"copy-network": true,
|
||||
"delete-karg": true,
|
||||
"dest-device": true,
|
||||
"fetch-retries": true,
|
||||
"ignition-file": true,
|
||||
"ignition-hash": true,
|
||||
"ignition-url": true,
|
||||
"image-file": true,
|
||||
"image-url": true,
|
||||
"insecure": true,
|
||||
"insecure-ignition": true,
|
||||
"network-dir": true,
|
||||
"offline": true,
|
||||
"platform": true,
|
||||
"preserve-on-error": true,
|
||||
"save-partindex": true,
|
||||
"save-partlabel": true,
|
||||
"secure-ipl": true,
|
||||
"stream": true,
|
||||
"stream-base-url": true
|
||||
},
|
||||
"live-initrd-network": true
|
||||
}
|
||||
```
|
||||
|
||||
## Ignition Configuration Examples
|
||||
|
||||
### 1. Basic Bootc Installation
|
||||
```json
|
||||
{
|
||||
"ignition": {
|
||||
"version": "3.4.0"
|
||||
},
|
||||
"storage": {
|
||||
"disks": [
|
||||
{
|
||||
"device": "/dev/sda",
|
||||
"wipeTable": true,
|
||||
"partitions": [
|
||||
{
|
||||
"label": "BIOS-BOOT",
|
||||
"number": 1,
|
||||
"size": 1024,
|
||||
"typeGuid": "21686148-6449-6E6F-744E-656564454649"
|
||||
},
|
||||
{
|
||||
"label": "EFI-SYSTEM",
|
||||
"number": 2,
|
||||
"size": 268435456,
|
||||
"typeGuid": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
|
||||
},
|
||||
{
|
||||
"label": "ROOT",
|
||||
"number": 3,
|
||||
"size": 0,
|
||||
"typeGuid": "4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"filesystems": [
|
||||
{
|
||||
"device": "/dev/disk/by-partlabel/ROOT",
|
||||
"format": "xfs",
|
||||
"path": "/"
|
||||
}
|
||||
]
|
||||
},
|
||||
"systemd": {
|
||||
"units": [
|
||||
{
|
||||
"name": "bootc-install.service",
|
||||
"enabled": true,
|
||||
"contents": "[Unit]\nDescription=Install bootc container\n[Service]\nType=oneshot\nExecStart=/usr/bin/bootc install to-disk /dev/sda\n[Install]\nWantedBy=multi-user.target"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Registry Authentication
|
||||
```json
|
||||
{
|
||||
"ignition": {
|
||||
"version": "3.4.0"
|
||||
},
|
||||
"storage": {
|
||||
"files": [
|
||||
{
|
||||
"path": "/etc/ostree/auth.json",
|
||||
"mode": 420,
|
||||
"contents": {
|
||||
"source": "data:text/plain;base64,ewogICJhdXRocyI6IHsKICAgICJxdWF5LmlvIjogewogICAgICAiYXV0aCI6ICI8eW91ciBzZWNyZXQgaGVyZT4iCiAgICB9CiAgfQp9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "/etc/containers/registries.conf.d/bootc.conf",
|
||||
"mode": 420,
|
||||
"contents": {
|
||||
"source": "data:text/plain;base64,W1JlZ2lzdHJ5XQpsb2NhdGlvbj0icXVheS5pbyIKc2VjdXJlPWZhbHNlCg=="
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Network Configuration
|
||||
```json
|
||||
{
|
||||
"ignition": {
|
||||
"version": "3.4.0"
|
||||
},
|
||||
"networkd": {
|
||||
"units": [
|
||||
{
|
||||
"name": "00-eth0.network",
|
||||
"contents": "[Match]\nName=eth0\n[Network]\nDHCP=yes"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Advantages of Ignition Approach
|
||||
|
||||
### 1. Modern Design
|
||||
- **JSON-based** - easy to generate programmatically
|
||||
- **Declarative** - describes desired state, not steps
|
||||
- **Immutable** - configuration is applied once
|
||||
- **Cloud-native** - designed for modern infrastructure
|
||||
|
||||
### 2. Container Integration
|
||||
- **Native container support** - no special directives needed
|
||||
- **Registry authentication** - built-in support
|
||||
- **Container runtime** - integrated by default
|
||||
- **Bootc compatibility** - works seamlessly with bootc
|
||||
|
||||
### 3. Flexibility
|
||||
- **Modular** - can combine different configuration sources
|
||||
- **Extensible** - easy to add new configuration types
|
||||
- **Versioned** - configuration format is versioned
|
||||
- **Validated** - JSON schema validation
|
||||
|
||||
## Implementation for Debian
|
||||
|
||||
### Calamares Integration
|
||||
1. **Generate Ignition JSON** from Calamares configuration
|
||||
2. **Create custom module** for container installation
|
||||
3. **Handle registry authentication** via Ignition
|
||||
4. **Integrate with bootc** installation process
|
||||
|
||||
### debian-installer Integration
|
||||
1. **Replace preseed** with Ignition configuration
|
||||
2. **Add container runtime** to installer environment
|
||||
3. **Implement Ignition parser** in installer
|
||||
4. **Handle container installation** via systemd units
|
||||
|
||||
### Key Implementation Steps
|
||||
1. **Study Ignition specification** and examples
|
||||
2. **Design JSON generation** from user input
|
||||
3. **Implement container installation** logic
|
||||
4. **Handle registry authentication** and configuration
|
||||
5. **Test with real bootc containers**
|
||||
|
||||
## Comparison: Ignition vs Kickstart vs Preseed
|
||||
|
||||
| Feature | Ignition | Kickstart | Preseed |
|
||||
|---------|----------|-----------|---------|
|
||||
| **Format** | JSON | Shell-like | Debian-specific |
|
||||
| **Container Support** | Native | Via directive | None |
|
||||
| **Modernity** | High | Medium | Low |
|
||||
| **Flexibility** | High | Medium | Low |
|
||||
| **Validation** | Schema-based | Runtime | Limited |
|
||||
| **Cloud Integration** | Excellent | Good | Poor |
|
||||
| **Immutable Design** | Yes | No | No |
|
||||
|
||||
## Tools and Resources
|
||||
|
||||
### CoreOS Installer
|
||||
- **`coreos-installer`** - tool for creating custom ISOs
|
||||
- **`butane`** - YAML to Ignition converter
|
||||
- **`ignition-validate`** - configuration validator
|
||||
|
||||
### Configuration Examples
|
||||
- **Fedora CoreOS examples** - official configuration samples
|
||||
- **Butane configs** - YAML-based Ignition generation
|
||||
- **Container installation** - bootc integration patterns
|
||||
|
||||
### Documentation
|
||||
- [Ignition specification](https://coreos.github.io/ignition/)
|
||||
- [Butane documentation](https://coreos.github.io/butane/)
|
||||
- [CoreOS installer](https://coreos.github.io/coreos-installer/)
|
||||
|
||||
## Next Steps for Implementation
|
||||
|
||||
1. **Study Ignition examples** for container installation
|
||||
2. **Design JSON generation** from user configuration
|
||||
3. **Implement Calamares module** for Ignition support
|
||||
4. **Create debian-installer** Ignition integration
|
||||
5. **Test with real bootc containers** and registries
|
||||
|
||||
## Conclusion
|
||||
|
||||
The Ignition approach used by Fedora CoreOS is **more modern and suitable** for our Debian bootc-image-builder than traditional kickstart or preseed. Its JSON-based configuration, native container support, and immutable design make it ideal for container-first deployments.
|
||||
|
||||
Key advantages:
|
||||
- **Easier to generate** programmatically
|
||||
- **More flexible** than kickstart/preseed
|
||||
- **Container-native** by design
|
||||
- **Better suited** for modern infrastructure
|
||||
- **Future-proof** approach
|
||||
|
||||
This makes Ignition the recommended approach for both Calamares and debian-installer integration in our Debian bootc-image-builder project.
|
||||
283
docs/fedora-kickstart.md
Normal file
283
docs/fedora-kickstart.md
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
# Fedora Kickstart Approach for Bootc Installation
|
||||
|
||||
## Overview
|
||||
|
||||
Fedora uses a sophisticated kickstart-based approach for bootc installation that is fundamentally different from traditional package-based installations. The key insight is that **bootc installations are container-first, not package-first**.
|
||||
|
||||
## Key Technical Concepts
|
||||
|
||||
### 1. The `ostreecontainer` Directive
|
||||
|
||||
The `ostreecontainer` kickstart directive is the core mechanism for bootc installation:
|
||||
|
||||
```kickstart
|
||||
ostreecontainer --url quay.io/centos-bootc/centos-bootc:stream9
|
||||
```
|
||||
|
||||
**Key characteristics:**
|
||||
- **No `%packages` section** - the entire system is container-based
|
||||
- **Registry URL** specifies the container image to install
|
||||
- **Authentication** handled separately via registry configuration
|
||||
- **Partitioning** still required, but no package management
|
||||
|
||||
### 1.1. Complete `ostreecontainer` Parameters
|
||||
|
||||
Based on analysis of the Fedora COSMIC Atomic ISO, the full parameter set is:
|
||||
|
||||
```kickstart
|
||||
ostreecontainer --url="quay.io/exampleos/foo:latest" \
|
||||
--stateroot="default" \
|
||||
--remote="default" \
|
||||
--transport="registry" \
|
||||
--no-signature-verification
|
||||
```
|
||||
|
||||
**Parameter details:**
|
||||
- **`--url`** (required): Container image URL (e.g., `quay.io/exampleos/foo:latest`)
|
||||
- **`--stateroot`**: Name for the state directory (default: `default`)
|
||||
- **`--remote`**: Name of the OSTree remote (default: same as stateroot)
|
||||
- **`--transport`**: Transport method (default: `registry`)
|
||||
- **`--no-signature-verification`**: Disable signature verification (optional)
|
||||
|
||||
### 1.2. Implementation Details
|
||||
|
||||
**Python-based implementation** in PyKickstart:
|
||||
- **File**: `/usr/lib/python3.13/site-packages/pykickstart/commands/ostreecontainer.py`
|
||||
- **Class**: `F38_OSTreeContainer` (available in Fedora 38+)
|
||||
- **Conflicts**: Cannot be used with `ostreesetup` directive
|
||||
- **Experimental**: Marked as experimental in documentation
|
||||
|
||||
### 2. Kickstart Infrastructure
|
||||
|
||||
Based on analysis of the Fedora COSMIC Atomic ISO, the kickstart system includes:
|
||||
|
||||
#### 2.1. Dracut Hooks
|
||||
- **`50-kickstart-genrules.sh`**: Generates udev rules for fetching kickstarts
|
||||
- **`11-fetch-kickstart-net.sh`**: Fetches kickstart files from network
|
||||
- **`26-parse-anaconda-kickstart.sh`**: Handles kickstart command line parsing
|
||||
|
||||
#### 2.2. Anaconda Integration
|
||||
- **PyKickstart library**: Python-based kickstart parsing
|
||||
- **Command handlers**: Including `ostreecontainer` and `ostreesetup`
|
||||
- **Version support**: Fedora 38+ includes `ostreecontainer` support
|
||||
|
||||
#### 2.3. Kickstart Fetching Methods
|
||||
- **Network**: HTTP, HTTPS, FTP, NFS
|
||||
- **Local**: CDROM, hard disk
|
||||
- **Multiple URLs**: Support for fallback kickstart locations
|
||||
|
||||
### 3. Registry Authentication
|
||||
|
||||
Fedora handles registry access through kickstart `%pre` sections:
|
||||
|
||||
#### Basic Authentication
|
||||
```kickstart
|
||||
%pre
|
||||
mkdir -p /etc/ostree
|
||||
cat > /etc/ostree/auth.json << 'EOF'
|
||||
{
|
||||
"auths": {
|
||||
"quay.io": {
|
||||
"auth": "<your secret here>"
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
%end
|
||||
```
|
||||
|
||||
#### Insecure Registry Support
|
||||
```kickstart
|
||||
%pre
|
||||
mkdir -p /etc/containers/registries.conf.d/
|
||||
cat > /etc/containers/registries.conf.d/local-registry.conf << 'EOF'
|
||||
[[registry]]
|
||||
location="[IP_Address]:5000"
|
||||
insecure=true
|
||||
EOF
|
||||
%end
|
||||
```
|
||||
|
||||
### 4. Complete Kickstart Example
|
||||
|
||||
```kickstart
|
||||
# Basic setup
|
||||
text
|
||||
network --bootproto=dhcp --device=link --activate
|
||||
|
||||
# Basic partitioning
|
||||
clearpart --all --initlabel --disklabel=gpt
|
||||
reqpart --add-boot
|
||||
part / --grow --fstype xfs
|
||||
|
||||
# Container installation - NO %packages section!
|
||||
ostreecontainer --url quay.io/centos-bootc/centos-bootc:stream9
|
||||
|
||||
# System configuration
|
||||
firewall --disabled
|
||||
services --enabled=sshd
|
||||
rootpw --iscrypted locked
|
||||
sshkey --username root "<your key here>"
|
||||
reboot
|
||||
```
|
||||
|
||||
## Installation Methods Analysis
|
||||
|
||||
### Fedora COSMIC Atomic vs Fedora CoreOS
|
||||
|
||||
**Key Discovery**: Different Fedora variants use different approaches:
|
||||
|
||||
| Variant | Configuration System | Container Support | Use Case |
|
||||
|---------|---------------------|-------------------|----------|
|
||||
| **Fedora COSMIC Atomic** | Kickstart + `ostreecontainer` | Native | Traditional server/workstation |
|
||||
| **Fedora CoreOS** | Ignition | Native | Container-first, immutable |
|
||||
| **Fedora Server/Workstation** | Kickstart + `ostreecontainer` | Native | Traditional Linux |
|
||||
|
||||
## Three Installation Methods
|
||||
|
||||
### 1. Stock Anaconda ISO/PXE (Network-based)
|
||||
- Uses standard Fedora installer with custom kickstart
|
||||
- Requires network access during installation
|
||||
- Container image fetched from registry
|
||||
- **Advantage**: Uses existing installer infrastructure
|
||||
- **Disadvantage**: Requires network connectivity
|
||||
|
||||
### 2. Custom Installer ISO (bootc-image-builder generated)
|
||||
- Uses `anaconda-iso` type in bootc-image-builder
|
||||
- Container image **embedded in the ISO**
|
||||
- No network access needed during installation
|
||||
- **Advantage**: Air-gapped installation possible
|
||||
- **Disadvantage**: Larger ISO size
|
||||
|
||||
### 3. Direct Container Installation (`bootc install`)
|
||||
- Uses `bootc install to-disk` or `bootc install to-filesystem`
|
||||
- Container image is the "source of truth"
|
||||
- Can be run from any Linux environment
|
||||
- **Advantage**: Most flexible, container-native
|
||||
- **Disadvantage**: Requires existing Linux environment
|
||||
|
||||
## Technical Implementation Details
|
||||
|
||||
### Container Runtime Requirements
|
||||
- **Podman** or **containerd** must be available in installer environment
|
||||
- **Registry access** configured via `/etc/containers/registries.conf.d/`
|
||||
- **Authentication** handled via `/etc/ostree/auth.json`
|
||||
|
||||
### Partitioning Strategy
|
||||
- **GPT partition table** required
|
||||
- **Boot partition** for EFI/BIOS boot
|
||||
- **Root partition** for container installation
|
||||
- **No package management** - all content from container
|
||||
|
||||
### Network Configuration
|
||||
- **DHCP** for basic network access
|
||||
- **Registry connectivity** for container pull
|
||||
- **Optional**: Static IP configuration
|
||||
|
||||
## Implications for Debian Implementation
|
||||
|
||||
### Calamares Integration
|
||||
1. **Custom module needed** to handle `ostreecontainer` equivalent
|
||||
2. **Registry authentication** must be implemented
|
||||
3. **Container runtime** must be available
|
||||
4. **Partitioning** handled before container installation
|
||||
|
||||
### debian-installer Integration
|
||||
1. **Preseed extension** needed for container support
|
||||
2. **Container runtime** added to installer environment
|
||||
3. **Registry configuration** in installer
|
||||
4. **Major architectural change** from package-based to container-based
|
||||
|
||||
### Key Differences from Traditional Installation
|
||||
- **No package management** during installation
|
||||
- **Container-first** approach
|
||||
- **Registry authentication** required
|
||||
- **Partitioning** still needed but simpler
|
||||
- **System configuration** via kickstart/preseed
|
||||
|
||||
## Registry Handling Patterns
|
||||
|
||||
### Authentication Methods
|
||||
1. **Username/password** via auth.json
|
||||
2. **Token-based** authentication
|
||||
3. **Certificate-based** authentication
|
||||
4. **Insecure registry** support for development
|
||||
|
||||
### Configuration Locations
|
||||
- **`/etc/ostree/auth.json`** - authentication credentials
|
||||
- **`/etc/containers/registries.conf.d/`** - registry configuration
|
||||
- **`/etc/pki/ca-trust/source/anchors/`** - certificate authorities
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Registry Security
|
||||
- **TLS verification** by default
|
||||
- **Insecure registries** only for development
|
||||
- **Certificate management** for custom CAs
|
||||
- **Authentication** required for private registries
|
||||
|
||||
### Container Security
|
||||
- **Image verification** via signatures
|
||||
- **Content trust** mechanisms
|
||||
- **Runtime security** via container runtime
|
||||
|
||||
## Advantages of This Approach
|
||||
|
||||
1. **Container-native** - aligns with modern deployment patterns
|
||||
2. **Atomic updates** - via ostree/bootc upgrade
|
||||
3. **Immutable systems** - reduces configuration drift
|
||||
4. **Registry integration** - leverages existing container infrastructure
|
||||
5. **Air-gapped support** - via embedded ISO approach
|
||||
|
||||
## Challenges for Debian
|
||||
|
||||
1. **Preseed lacks `ostreecontainer` equivalent** - major technical hurdle
|
||||
2. **Container runtime** not standard in debian-installer
|
||||
3. **Registry authentication** not built into installer
|
||||
4. **Architectural shift** from package-based to container-based
|
||||
5. **Tooling gaps** - need custom modules/extensions
|
||||
|
||||
## Real-World Implementation Analysis
|
||||
|
||||
### Fedora COSMIC Atomic ISO Structure
|
||||
```
|
||||
Fedora-COSMIC-Atomic-ostree-x86_64-42-1.1.iso
|
||||
├── boot/grub2/grub.cfg # BIOS boot configuration
|
||||
├── EFI/BOOT/grub.cfg # EFI boot configuration
|
||||
├── images/
|
||||
│ ├── install.img # Anaconda installer image
|
||||
│ ├── pxeboot/
|
||||
│ │ ├── initrd.img # XZ-compressed initrd
|
||||
│ │ └── vmlinuz # Kernel
|
||||
│ └── eltorito.img # El Torito boot image
|
||||
└── Fedora-Legal-README.txt # Legal information
|
||||
```
|
||||
|
||||
### Kickstart Processing Pipeline
|
||||
1. **Boot**: Kernel loads with kickstart parameters
|
||||
2. **Dracut**: Hooks process kickstart fetching
|
||||
3. **Anaconda**: PyKickstart parses configuration
|
||||
4. **Installation**: `ostreecontainer` directive triggers container installation
|
||||
5. **Configuration**: System setup via kickstart commands
|
||||
|
||||
### Key Implementation Files
|
||||
- **`ostreecontainer.py`**: Core directive implementation
|
||||
- **`f42.py`**: Fedora 42 handler with `ostreecontainer` support
|
||||
- **Dracut hooks**: Network and disk kickstart fetching
|
||||
- **Anaconda modules**: Integration with installer
|
||||
|
||||
## Next Steps for Implementation
|
||||
|
||||
1. **Study `ostreecontainer` implementation** in Anaconda
|
||||
2. **Design Calamares module** for container installation
|
||||
3. **Extend preseed** for container support
|
||||
4. **Implement registry handling** in both approaches
|
||||
5. **Test container installation** workflows
|
||||
6. **Choose approach**: Kickstart (traditional) vs Ignition (modern)
|
||||
|
||||
## References
|
||||
|
||||
- [Fedora bootc bare metal installation guide](https://docs.fedoraproject.org/en-US/bootc/bare-metal/)
|
||||
- [Kickstart ostreecontainer documentation](https://pykickstart.readthedocs.io/en/latest/kickstart-docs.html#ostreecontainer)
|
||||
- [bootc-image-builder documentation](https://github.com/osbuild/bootc-image-builder)
|
||||
- [bib-kickstart-demo repository](https://github.com/osbuild/bib-kickstart-demo)
|
||||
369
docs/ignition-vs-calamares.md
Normal file
369
docs/ignition-vs-calamares.md
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
# Ignition vs Calamares: Comparison for Debian Bootc-Image-Builder
|
||||
|
||||
## Overview
|
||||
|
||||
This document compares Ignition and Calamares as potential approaches for implementing installer support in our Debian bootc-image-builder project. Both offer different advantages and trade-offs for container-first installation.
|
||||
|
||||
## Executive Summary
|
||||
|
||||
| Aspect | Winner | Reasoning |
|
||||
|--------|--------|-----------|
|
||||
| **Container Integration** | Ignition | Native container support, designed for immutable infrastructure |
|
||||
| **Modern Architecture** | Ignition | JSON-based, declarative, cloud-native |
|
||||
| **User Experience** | Calamares | Graphical interface, familiar to users |
|
||||
| **Debian Integration** | Calamares | Already used in Debian, better ecosystem fit |
|
||||
| **Development Complexity** | Calamares | Existing framework, less custom development |
|
||||
| **Flexibility** | Ignition | More modular, easier to extend |
|
||||
|
||||
## Detailed Comparison
|
||||
|
||||
### 1. Architecture and Design Philosophy
|
||||
|
||||
#### Ignition
|
||||
- **Declarative**: Describes desired system state
|
||||
- **Immutable**: Configuration applied once, system remains unchanged
|
||||
- **Container-first**: Designed for modern container workloads
|
||||
- **JSON-based**: Easy to generate programmatically
|
||||
- **Cloud-native**: Optimized for infrastructure automation
|
||||
|
||||
#### Calamares
|
||||
- **Interactive**: User-driven configuration process
|
||||
- **Mutable**: Allows system modifications after installation
|
||||
- **Distribution-agnostic**: Works across different Linux distributions
|
||||
- **C++/Python**: Mixed language implementation
|
||||
- **Desktop-focused**: Originally designed for desktop installations
|
||||
|
||||
### 2. Container Integration
|
||||
|
||||
Based on analysis of Fedora's approaches, both Ignition and Calamares can effectively handle bootc installation:
|
||||
|
||||
#### Ignition (Fedora CoreOS Pattern)
|
||||
```json
|
||||
{
|
||||
"systemd": {
|
||||
"units": [
|
||||
{
|
||||
"name": "bootc-install.service",
|
||||
"enabled": true,
|
||||
"contents": "[Unit]\nDescription=Install bootc container\n[Service]\nType=oneshot\nExecStart=/usr/bin/bootc install to-disk /dev/sda\n[Install]\nWantedBy=multi-user.target"
|
||||
}
|
||||
]
|
||||
},
|
||||
"storage": {
|
||||
"files": [
|
||||
{
|
||||
"path": "/etc/ostree/auth.json",
|
||||
"mode": 420,
|
||||
"contents": {
|
||||
"source": "data:text/plain;base64,ewogICJhdXRocyI6IHsKICAgICJxdWF5LmlvIjogewogICAgICAiYXV0aCI6ICI8eW91ciBzZWNyZXQgaGVyZT4iCiAgICB9CiAgfQp9"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Advantages:**
|
||||
- **Native container support** - no special directives needed
|
||||
- **Systemd integration** - seamless service management
|
||||
- **Registry authentication** - built-in support via JSON config
|
||||
- **Immutable design** - configuration applied once
|
||||
|
||||
#### Calamares (Hybrid Approach)
|
||||
```python
|
||||
# Can implement multiple patterns from Fedora analysis
|
||||
class BootcInstaller:
|
||||
def __init__(self, config):
|
||||
self.approach = config.get("installationApproach", "systemd")
|
||||
# Supports: "kickstart", "ignition", "systemd"
|
||||
|
||||
def run(self):
|
||||
if self.approach == "kickstart":
|
||||
return self.install_via_kickstart() # Fedora COSMIC Atomic pattern
|
||||
elif self.approach == "ignition":
|
||||
return self.install_via_ignition() # Fedora CoreOS pattern
|
||||
else:
|
||||
return self.install_via_systemd() # Direct systemd approach
|
||||
```
|
||||
|
||||
**Advantages:**
|
||||
- **Multiple patterns** - can use kickstart, Ignition, or systemd approaches
|
||||
- **User interface** - graphical configuration for all patterns
|
||||
- **Fedora compatibility** - leverages proven Fedora patterns
|
||||
- **Flexible implementation** - choose best approach per use case
|
||||
|
||||
### 3. User Experience
|
||||
|
||||
#### Ignition
|
||||
- **No GUI** - configuration file only
|
||||
- **Technical users** - requires JSON knowledge
|
||||
- **Automation-friendly** - perfect for infrastructure as code
|
||||
- **Learning curve** - steep for non-technical users
|
||||
|
||||
#### Calamares
|
||||
- **Graphical interface** - familiar installation experience
|
||||
- **User-friendly** - guided configuration process
|
||||
- **Progress indicators** - visual feedback
|
||||
- **Error handling** - user-friendly error messages
|
||||
|
||||
### 4. Development Complexity
|
||||
|
||||
Based on Fedora pattern analysis, the complexity assessment has changed:
|
||||
|
||||
#### Ignition
|
||||
**Implementation Requirements:**
|
||||
1. **JSON generation** - create Ignition configs from user input
|
||||
2. **Container integration** - systemd services for bootc installation
|
||||
3. **Registry handling** - authentication and configuration
|
||||
4. **Validation** - JSON schema validation
|
||||
5. **Testing** - container installation workflows
|
||||
|
||||
**Estimated Effort:** High (3-6 months)
|
||||
- Custom JSON generation logic
|
||||
- Container installation integration
|
||||
- Registry authentication handling
|
||||
- Comprehensive testing
|
||||
- **Limited Debian ecosystem support**
|
||||
|
||||
#### Calamares (Updated Assessment)
|
||||
**Implementation Requirements:**
|
||||
1. **Hybrid module** - Support kickstart, Ignition, and systemd patterns
|
||||
2. **UI components** - configuration screens for all approaches
|
||||
3. **Pattern integration** - leverage proven Fedora patterns
|
||||
4. **Framework integration** - with existing Calamares ecosystem
|
||||
5. **Testing** - comprehensive pattern testing
|
||||
|
||||
**Estimated Effort:** Medium (2-4 months) - **Reduced due to Fedora patterns**
|
||||
- **Leverage Fedora patterns** - proven `ostreecontainer` and Ignition approaches
|
||||
- **Existing framework** - Calamares module system
|
||||
- **Reuse Fedora code** - adapt PyKickstart and Ignition patterns
|
||||
- **Standard testing** - Calamares testing approach
|
||||
- **Better Debian integration** - native ecosystem support
|
||||
|
||||
### 5. Debian Ecosystem Integration
|
||||
|
||||
#### Ignition
|
||||
**Challenges:**
|
||||
- **Not native to Debian** - primarily used in Fedora CoreOS
|
||||
- **Limited adoption** - few Debian-based distributions use it
|
||||
- **Tooling gaps** - limited Debian-specific tooling
|
||||
- **Community support** - smaller Debian community
|
||||
|
||||
**Advantages:**
|
||||
- **Modern approach** - future-proof design
|
||||
- **Cloud integration** - works well with modern infrastructure
|
||||
- **Immutable design** - aligns with container philosophy
|
||||
|
||||
#### Calamares
|
||||
**Advantages:**
|
||||
- **Debian native** - used in Debian and derivatives
|
||||
- **Mature ecosystem** - extensive module library
|
||||
- **Community support** - active Debian community
|
||||
- **Documentation** - well-documented for Debian
|
||||
|
||||
**Challenges:**
|
||||
- **Package-based focus** - originally designed for traditional installations
|
||||
- **Container adaptation** - requires significant customization
|
||||
- **Legacy design** - not originally container-focused
|
||||
|
||||
### 6. Technical Implementation
|
||||
|
||||
Based on Fedora analysis, both approaches can leverage proven patterns:
|
||||
|
||||
#### Ignition Approach (Fedora CoreOS Pattern)
|
||||
```json
|
||||
{
|
||||
"ignition": {
|
||||
"version": "3.4.0"
|
||||
},
|
||||
"storage": {
|
||||
"disks": [disk_config],
|
||||
"filesystems": [fs_config],
|
||||
"files": [
|
||||
{
|
||||
"path": "/etc/ostree/auth.json",
|
||||
"mode": 420,
|
||||
"contents": {
|
||||
"source": "data:text/plain;base64,{{ auth_data }}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"systemd": {
|
||||
"units": [
|
||||
{
|
||||
"name": "bootc-install.service",
|
||||
"enabled": true,
|
||||
"contents": "[Unit]\nDescription=Install bootc container\n[Service]\nType=oneshot\nExecStart=/usr/bin/bootc install to-disk /dev/sda\n[Install]\nWantedBy=multi-user.target"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation Steps:**
|
||||
1. **Create Ignition generator** - convert user input to JSON
|
||||
2. **Implement container installation** - systemd service approach
|
||||
3. **Handle registry auth** - authentication configuration
|
||||
4. **Add validation** - JSON schema validation
|
||||
5. **Integrate with bootc** - container installation logic
|
||||
|
||||
#### Calamares Approach (Hybrid Pattern)
|
||||
```python
|
||||
# Can implement all three Fedora patterns
|
||||
class HybridBootcInstaller:
|
||||
def __init__(self, config):
|
||||
self.approach = config.get("installationApproach", "systemd")
|
||||
# Supports: "kickstart", "ignition", "systemd"
|
||||
|
||||
def run(self):
|
||||
if self.approach == "kickstart":
|
||||
return self.install_via_kickstart() # Fedora COSMIC Atomic
|
||||
elif self.approach == "ignition":
|
||||
return self.install_via_ignition() # Fedora CoreOS
|
||||
else:
|
||||
return self.install_via_systemd() # Direct approach
|
||||
|
||||
def install_via_kickstart(self):
|
||||
# Generate ostreecontainer directive
|
||||
kickstart = f"""ostreecontainer --url="{self.container_url}" \\
|
||||
--stateroot="{self.stateroot}" \\
|
||||
--remote="{self.remote}" \\
|
||||
--transport="{self.transport}"
|
||||
"""
|
||||
# Execute via anaconda
|
||||
subprocess.run(["anaconda", "--kickstart", "/tmp/bootc.ks"])
|
||||
|
||||
def install_via_ignition(self):
|
||||
# Generate Ignition JSON
|
||||
ignition_config = self.generate_ignition_config()
|
||||
# Execute via ignition
|
||||
subprocess.run(["ignition", "apply", "/tmp/bootc.ign"])
|
||||
```
|
||||
|
||||
**Implementation Steps:**
|
||||
1. **Create hybrid module** - support all Fedora patterns
|
||||
2. **Design UI screens** - configuration for all approaches
|
||||
3. **Implement pattern switching** - kickstart, Ignition, systemd
|
||||
4. **Leverage Fedora code** - adapt PyKickstart and Ignition patterns
|
||||
5. **Integrate with Calamares** - module registration and execution
|
||||
|
||||
### 7. Maintenance and Support
|
||||
|
||||
#### Ignition
|
||||
**Maintenance:**
|
||||
- **Custom implementation** - full control over code
|
||||
- **Upstream dependencies** - Ignition specification changes
|
||||
- **Container integration** - bootc compatibility
|
||||
- **Testing** - comprehensive test suite needed
|
||||
|
||||
**Support:**
|
||||
- **Limited community** - smaller Debian user base
|
||||
- **Documentation** - need to create Debian-specific docs
|
||||
- **Troubleshooting** - custom implementation issues
|
||||
|
||||
#### Calamares
|
||||
**Maintenance:**
|
||||
- **Framework updates** - follow Calamares development
|
||||
- **Module compatibility** - ensure module works with new versions
|
||||
- **Debian integration** - follow Debian packaging changes
|
||||
- **Testing** - standard Calamares testing approach
|
||||
|
||||
**Support:**
|
||||
- **Active community** - large Debian and Calamares community
|
||||
- **Existing documentation** - extensive Calamares docs
|
||||
- **Module ecosystem** - can leverage existing modules
|
||||
|
||||
### 8. Use Case Analysis
|
||||
|
||||
#### Ignition Best For:
|
||||
- **Infrastructure automation** - GitOps, CI/CD pipelines
|
||||
- **Cloud deployments** - AWS, GCP, Azure
|
||||
- **Immutable infrastructure** - container-first systems
|
||||
- **Technical users** - developers, system administrators
|
||||
- **Large-scale deployments** - hundreds of systems
|
||||
|
||||
#### Calamares Best For:
|
||||
- **Desktop installations** - user-friendly setup
|
||||
- **Mixed environments** - traditional and container systems
|
||||
- **End users** - non-technical users
|
||||
- **Small to medium deployments** - individual systems
|
||||
- **Debian ecosystem** - existing Debian users
|
||||
|
||||
### 9. Risk Assessment
|
||||
|
||||
#### Ignition Risks
|
||||
- **High complexity** - significant development effort
|
||||
- **Limited adoption** - smaller user base
|
||||
- **Learning curve** - steep for users
|
||||
- **Maintenance burden** - custom implementation
|
||||
- **Debian integration** - potential compatibility issues
|
||||
|
||||
#### Calamares Risks
|
||||
- **Container adaptation** - requires significant customization
|
||||
- **Legacy design** - not originally container-focused
|
||||
- **Framework dependency** - tied to Calamares development
|
||||
- **Performance** - may be slower than Ignition
|
||||
- **Complexity** - module development can be complex
|
||||
|
||||
### 10. Recommendation
|
||||
|
||||
## **Recommended Approach: Calamares with Hybrid Pattern Support**
|
||||
|
||||
### **Updated Reasoning (Based on Fedora Analysis):**
|
||||
1. **Debian ecosystem fit** - already used in Debian
|
||||
2. **User experience** - graphical interface for end users
|
||||
3. **Development efficiency** - leverage existing framework + Fedora patterns
|
||||
4. **Community support** - active Debian community
|
||||
5. **Flexibility** - can implement kickstart, Ignition, AND systemd approaches
|
||||
6. **Proven patterns** - leverage Fedora's `ostreecontainer` and Ignition implementations
|
||||
7. **Future-proof** - support multiple installation paradigms
|
||||
|
||||
### **Enhanced Implementation Strategy:**
|
||||
1. **Phase 1**: Create hybrid BootcModule supporting all Fedora patterns
|
||||
2. **Phase 2**: Implement kickstart pattern (Fedora COSMIC Atomic approach)
|
||||
3. **Phase 3**: Add Ignition pattern (Fedora CoreOS approach)
|
||||
4. **Phase 4**: Integrate systemd direct approach
|
||||
5. **Phase 5**: UI polish and comprehensive testing
|
||||
|
||||
### **Hybrid Pattern Benefits:**
|
||||
- **Kickstart compatibility** - works with existing Fedora tooling
|
||||
- **Ignition modernity** - JSON-based, cloud-native approach
|
||||
- **Systemd flexibility** - direct container installation
|
||||
- **User choice** - select best approach per use case
|
||||
- **Fedora compatibility** - leverage proven implementations
|
||||
|
||||
### **Key Implementation Insights:**
|
||||
- **Leverage PyKickstart** - adapt Fedora's `ostreecontainer` implementation
|
||||
- **Reuse Ignition patterns** - systemd services and JSON config
|
||||
- **Registry authentication** - use Fedora's `/etc/ostree/auth.json` approach
|
||||
- **Modular design** - easy to add new patterns in future
|
||||
|
||||
## Conclusion
|
||||
|
||||
Based on comprehensive analysis of Fedora's kickstart and Ignition approaches, **Calamares with hybrid pattern support is the optimal choice** for our Debian bootc-image-builder project:
|
||||
|
||||
### **Why Calamares Wins:**
|
||||
1. **Better Debian integration** - native ecosystem support
|
||||
2. **Superior user experience** - graphical interface for all patterns
|
||||
3. **Reduced development complexity** - leverage existing framework + Fedora patterns
|
||||
4. **Active community** - better support and documentation
|
||||
5. **Maximum flexibility** - support kickstart, Ignition, AND systemd approaches
|
||||
6. **Proven patterns** - leverage Fedora's production implementations
|
||||
7. **Future-proof** - easy to add new installation patterns
|
||||
|
||||
### **Key Innovation:**
|
||||
The hybrid approach allows Calamares to **combine the best of all worlds**:
|
||||
- **Kickstart compatibility** - works with existing Fedora tooling
|
||||
- **Ignition modernity** - JSON-based, cloud-native configuration
|
||||
- **Systemd flexibility** - direct container installation
|
||||
- **User choice** - select optimal approach per use case
|
||||
|
||||
### **Implementation Advantage:**
|
||||
By leveraging Fedora's proven patterns (`ostreecontainer` directive, Ignition JSON configs, systemd services), we can:
|
||||
- **Reduce development time** - reuse existing, tested code
|
||||
- **Ensure compatibility** - work with existing Fedora tooling
|
||||
- **Provide flexibility** - support multiple installation paradigms
|
||||
- **Future-proof** - easy to adapt to new patterns
|
||||
|
||||
The key is to implement Calamares with a **hybrid, container-first mindset**, creating a modern installation experience that bridges traditional package-based and container-based installations while leveraging the best patterns from both Fedora approaches.
|
||||
206
docs/process.md
Normal file
206
docs/process.md
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
# Fedora bootc-image-builder Complete Workflow Analysis
|
||||
|
||||
## Overview
|
||||
|
||||
The Fedora bootc-image-builder is a sophisticated containerized tool that creates bootable disk images from bootc (bootable container) inputs. It's specifically designed for Fedora/CentOS/RHEL systems using DNF/RPM package management and supports various output formats including QCOW2, AMI, VMDK, VHD, GCE, and ISO images.
|
||||
|
||||
## Complete Workflow Flowchart
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[User runs bootc-image-builder] --> B[Parse CLI Arguments]
|
||||
B --> C[Validate Container Storage Mount]
|
||||
C --> D[Load Configuration & Blueprint]
|
||||
D --> E[Validate Container Tags]
|
||||
E --> F[Get Container Size]
|
||||
F --> G[Create Podman Container Instance]
|
||||
G --> H[Extract OS Info from Container]
|
||||
H --> I[Initialize DNF in Container]
|
||||
I --> J[Create DNF Solver]
|
||||
J --> K[Generate OSBuild Manifest]
|
||||
|
||||
K --> L[Load Distribution Definitions]
|
||||
L --> M[Create Package Set Chains]
|
||||
M --> N[DNF Dependency Resolution]
|
||||
N --> O[Resolve Container Specs]
|
||||
O --> P[Serialize Manifest]
|
||||
P --> Q[Execute OSBuild Pipeline]
|
||||
|
||||
Q --> R{Image Type?}
|
||||
R -->|Disk Images| S[Create Partition Table]
|
||||
R -->|ISO Images| T[Create ISO Structure]
|
||||
|
||||
S --> U[Generate Filesystem Layout]
|
||||
U --> V[Install GRUB2 Bootloader]
|
||||
V --> W[Copy Container Contents]
|
||||
W --> X[Apply Customizations]
|
||||
X --> Y[Generate Final Image]
|
||||
|
||||
T --> Z[Create Installer Structure]
|
||||
Z --> AA[Package Installer Components]
|
||||
AA --> BB[Generate ISO Image]
|
||||
|
||||
Y --> CC{Upload to Cloud?}
|
||||
BB --> CC
|
||||
CC -->|Yes| DD[AWS/GCP Upload]
|
||||
CC -->|No| EE[Save to Output Directory]
|
||||
DD --> EE
|
||||
EE --> FF[Complete]
|
||||
|
||||
style A fill:#e1f5fe
|
||||
style FF fill:#c8e6c9
|
||||
style K fill:#fff3e0
|
||||
style Q fill:#f3e5f5
|
||||
style R fill:#fce4ec
|
||||
```
|
||||
|
||||
## Detailed Component Analysis
|
||||
|
||||
### 1. **Container Orchestration Layer**
|
||||
- **Podman Container**: Manages the bootc container lifecycle
|
||||
- **Container Storage**: Mounts `/var/lib/containers/storage` for image access
|
||||
- **Container Inspection**: Extracts OS information, kernel details, and customization data
|
||||
- **Cross-Architecture Support**: Uses qemu-user for cross-arch builds
|
||||
|
||||
### 2. **Package Management System**
|
||||
- **DNF Solver**: Resolves package dependencies using `dnfjson.Solver`
|
||||
- **RPM Metadata Cache**: Caches RPM metadata in `/rpmmd` volume
|
||||
- **Librepo Backend**: Optional faster download backend
|
||||
- **Repository Configuration**: Uses Fedora/CentOS/RHEL repositories
|
||||
|
||||
### 3. **Distribution Definition System**
|
||||
- **YAML Definitions**: Loads package lists from `data/defs/*.yaml` files
|
||||
- **Version Matching**: Supports exact and fuzzy version matching
|
||||
- **Image Type Specific**: Different package sets for different image types
|
||||
- **Multi-Directory Support**: Searches multiple definition directories
|
||||
|
||||
### 4. **OSBuild Integration**
|
||||
- **Manifest Generation**: Creates comprehensive OSBuild manifests
|
||||
- **Pipeline Definition**: Defines build, target, and export pipelines
|
||||
- **Stage Management**: Orchestrates multiple build stages
|
||||
- **Serialization**: Converts manifests to OSBuild-compatible format
|
||||
|
||||
### 5. **Image Building Pipeline**
|
||||
|
||||
#### **Disk Image Generation**:
|
||||
1. **Partition Table Creation**: GPT/MBR partition layouts
|
||||
2. **Filesystem Setup**: ext4/xfs/btrfs filesystem creation
|
||||
3. **Bootloader Installation**: GRUB2 configuration and installation
|
||||
4. **Container Content Copy**: Transfers bootc container contents
|
||||
5. **Customization Application**: Applies user customizations
|
||||
6. **Final Assembly**: Creates bootable disk image
|
||||
|
||||
#### **ISO Image Generation**:
|
||||
1. **Installer Structure**: Creates Anaconda installer layout
|
||||
2. **Package Integration**: Includes installer-specific packages
|
||||
3. **Boot Configuration**: Sets up ISO boot parameters
|
||||
4. **Media Creation**: Generates bootable ISO image
|
||||
|
||||
### 6. **Cloud Integration**
|
||||
- **AWS Upload**: Direct AMI upload to AWS
|
||||
- **GCP Support**: Google Cloud Platform integration
|
||||
- **Multi-Region**: Support for multiple cloud regions
|
||||
- **Authentication**: Handles cloud credentials and permissions
|
||||
|
||||
## Key Tools and Dependencies
|
||||
|
||||
### **Core Tools**:
|
||||
- **osbuild**: Primary image building engine
|
||||
- **osbuild-ostree**: OSTree integration for atomic updates
|
||||
- **osbuild-depsolve-dnf**: DNF-based dependency resolution
|
||||
- **osbuild-lvm2**: LVM2 support for advanced partitioning
|
||||
- **podman**: Container runtime and management
|
||||
- **qemu-img**: Image format conversion and manipulation
|
||||
|
||||
### **Package Management**:
|
||||
- **dnf**: Package manager for dependency resolution
|
||||
- **rpm**: Package format handling
|
||||
- **librepo**: Optional high-performance download backend
|
||||
- **subscription-manager**: RHEL subscription handling
|
||||
|
||||
### **System Components**:
|
||||
- **selinux-policy-targeted**: SELinux policy enforcement
|
||||
- **distribution-gpg-keys**: Package signature verification
|
||||
- **qemu-user**: Cross-architecture emulation support
|
||||
|
||||
## Configuration System
|
||||
|
||||
### **Blueprint Format**:
|
||||
- **TOML/JSON Configuration**: User customization files
|
||||
- **Container Metadata**: Extracts configuration from container images
|
||||
- **Environment Variables**: AWS credentials and other settings
|
||||
- **Command-line Flags**: Extensive CLI options for fine-tuning
|
||||
|
||||
### **Hardcoded Defaults**:
|
||||
- **Container Size Multiplier**: `containerSizeToDiskSizeMultiplier = 2`
|
||||
- **Default Image Size**: `DEFAULT_SIZE = 10 * GibiByte`
|
||||
- **Kernel Options**: `"rw"`, `"console=tty0"`, `"console=ttyS0"`
|
||||
- **Distribution Paths**: Multiple fallback paths for definitions
|
||||
|
||||
## Build Process Stages
|
||||
|
||||
### **Stage 1: Initialization**
|
||||
1. Parse CLI arguments and validate inputs
|
||||
2. Mount container storage and validate access
|
||||
3. Load configuration and blueprint files
|
||||
4. Validate container image tags and accessibility
|
||||
|
||||
### **Stage 2: Container Analysis**
|
||||
1. Get container size for disk sizing calculations
|
||||
2. Create Podman container instance
|
||||
3. Extract OS information (distro, version, kernel)
|
||||
4. Initialize DNF package manager in container
|
||||
5. Create DNF solver for dependency resolution
|
||||
|
||||
### **Stage 3: Manifest Generation**
|
||||
1. Load distribution-specific package definitions
|
||||
2. Create package set chains for different image types
|
||||
3. Resolve package dependencies using DNF solver
|
||||
4. Resolve container specifications and architectures
|
||||
5. Serialize manifest for OSBuild execution
|
||||
|
||||
### **Stage 4: Image Building**
|
||||
1. Execute OSBuild pipeline based on manifest
|
||||
2. Create partition tables and filesystem layouts
|
||||
3. Install bootloader and configure boot parameters
|
||||
4. Copy container contents to target filesystem
|
||||
5. Apply user customizations and configurations
|
||||
6. Generate final bootable image
|
||||
|
||||
### **Stage 5: Output and Upload**
|
||||
1. Save images to output directory
|
||||
2. Optionally upload to cloud providers (AWS/GCP)
|
||||
3. Clean up temporary files and containers
|
||||
4. Report build status and results
|
||||
|
||||
## Supported Image Types
|
||||
|
||||
### **Disk Images**:
|
||||
- **QCOW2**: KVM/QEMU virtual machine images
|
||||
- **AMI**: Amazon Machine Images for AWS
|
||||
- **VMDK**: VMware virtual machine images
|
||||
- **VHD**: Microsoft Hyper-V virtual machine images
|
||||
- **GCE**: Google Compute Engine images
|
||||
- **Raw**: Raw disk images for direct hardware deployment
|
||||
|
||||
### **ISO Images**:
|
||||
- **Anaconda ISO**: Fedora/CentOS/RHEL installer images
|
||||
- **Custom ISO**: User-defined ISO configurations
|
||||
|
||||
## Architecture Support
|
||||
|
||||
- **x86_64**: Primary architecture
|
||||
- **aarch64**: ARM64 support
|
||||
- **ppc64le**: PowerPC 64-bit little-endian
|
||||
- **s390x**: IBM Z architecture
|
||||
- **riscv64**: RISC-V 64-bit architecture
|
||||
|
||||
## Testing Infrastructure
|
||||
|
||||
- **Python-based Tests**: Integration and functional testing
|
||||
- **Go Unit Tests**: Component-level testing
|
||||
- **Container Testing**: Tests run in isolated containers
|
||||
- **VM Testing**: Can test resulting images in virtual machines
|
||||
- **Test Plans**: FMF-based test organization and execution
|
||||
|
||||
This comprehensive workflow demonstrates the sophisticated orchestration of multiple tools and systems to create production-ready bootable images from container inputs, making it a powerful tool for modern container-native operating system deployment.
|
||||
516
docs/simple-installer.md
Normal file
516
docs/simple-installer.md
Normal file
|
|
@ -0,0 +1,516 @@
|
|||
# Simple Bootc Installer
|
||||
|
||||
## Overview
|
||||
|
||||
A minimal, web-based installer for bootc that follows the standard "curl | sh" pattern. This approach works with bootc's design rather than against it, providing a simple way to install bootc containers on bare metal.
|
||||
|
||||
## Concept
|
||||
|
||||
```bash
|
||||
# Simple one-liner installation
|
||||
curl -fsSL https://install.bootc.dev | sh
|
||||
|
||||
# Or with specific container
|
||||
curl -fsSL https://install.bootc.dev | sh -s -- quay.io/centos-bootc/centos-bootc:stream9
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### 1. Web-Based Installer Script
|
||||
- **Single shell script** hosted on a website
|
||||
- **Self-contained** - no external dependencies beyond curl
|
||||
- **Interactive prompts** for configuration
|
||||
- **Validation** of system requirements
|
||||
|
||||
### 2. Live CD Environment
|
||||
- **Minimal live environment** (Debian-based)
|
||||
- **Pre-installed tools**: podman, bootc, curl
|
||||
- **Network connectivity** for container pulling
|
||||
- **No complex installer** - just a shell script
|
||||
|
||||
### 3. Installation Flow
|
||||
```
|
||||
1. Boot live CD
|
||||
2. Run: curl -fsSL https://install.bootc.dev | sh
|
||||
3. Follow interactive prompts
|
||||
4. Install completes automatically
|
||||
5. Reboot into installed system
|
||||
```
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Core Installer Script (Week 1-2)
|
||||
|
||||
#### 1.1 Basic Script Structure
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# bootc-installer.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Configuration
|
||||
CONTAINER_URL="${1:-quay.io/centos-bootc/centos-bootc:stream9}"
|
||||
TARGET_DEVICE=""
|
||||
USERNAME=""
|
||||
SSH_KEY=""
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Main installer function
|
||||
main() {
|
||||
log_info "Bootc Installer v1.0"
|
||||
log_info "Installing container: $CONTAINER_URL"
|
||||
|
||||
check_requirements
|
||||
detect_target_device
|
||||
prompt_user_config
|
||||
install_bootc
|
||||
configure_system
|
||||
finalize_installation
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.2 System Requirements Check
|
||||
```bash
|
||||
check_requirements() {
|
||||
log_info "Checking system requirements..."
|
||||
|
||||
# Check if running as root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log_error "This script must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for required tools
|
||||
local required_tools=("podman" "bootc" "curl" "parted" "mkfs.ext4")
|
||||
for tool in "${required_tools[@]}"; do
|
||||
if ! command -v "$tool" &> /dev/null; then
|
||||
log_error "Required tool '$tool' not found"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Check for internet connectivity
|
||||
if ! curl -s --connect-timeout 5 https://quay.io > /dev/null; then
|
||||
log_error "No internet connectivity. Required for container pulling."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "System requirements satisfied"
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.3 Device Detection and Selection
|
||||
```bash
|
||||
detect_target_device() {
|
||||
log_info "Detecting available storage devices..."
|
||||
|
||||
# List available block devices
|
||||
local devices=($(lsblk -d -n -o NAME | grep -E '^[sv]d[a-z]$'))
|
||||
|
||||
if [[ ${#devices[@]} -eq 0 ]]; then
|
||||
log_error "No suitable storage devices found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Display available devices
|
||||
echo "Available storage devices:"
|
||||
for i in "${!devices[@]}"; do
|
||||
local device="/dev/${devices[$i]}"
|
||||
local size=$(lsblk -d -n -o SIZE "$device")
|
||||
local model=$(lsblk -d -n -o MODEL "$device" | head -1)
|
||||
echo " $((i+1)). $device ($size) - $model"
|
||||
done
|
||||
|
||||
# Prompt user for selection
|
||||
while true; do
|
||||
read -p "Select device number (1-${#devices[@]}): " choice
|
||||
if [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le "${#devices[@]}" ]]; then
|
||||
TARGET_DEVICE="/dev/${devices[$((choice-1))]}"
|
||||
break
|
||||
else
|
||||
log_warn "Invalid selection. Please try again."
|
||||
fi
|
||||
done
|
||||
|
||||
log_info "Selected device: $TARGET_DEVICE"
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.4 User Configuration Prompts
|
||||
```bash
|
||||
prompt_user_config() {
|
||||
log_info "Configuring user account..."
|
||||
|
||||
# Get username
|
||||
while true; do
|
||||
read -p "Enter username for the system: " USERNAME
|
||||
if [[ -n "$USERNAME" ]] && [[ "$USERNAME" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
||||
break
|
||||
else
|
||||
log_warn "Invalid username. Use only letters, numbers, underscores, and hyphens."
|
||||
fi
|
||||
done
|
||||
|
||||
# Get SSH key
|
||||
echo "Enter SSH public key for root access (optional):"
|
||||
echo "You can paste your public key here (it will be hidden):"
|
||||
read -s SSH_KEY
|
||||
echo
|
||||
|
||||
log_info "User configuration complete"
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 2: Bootc Installation (Week 2-3)
|
||||
|
||||
#### 2.1 Container Installation
|
||||
```bash
|
||||
install_bootc() {
|
||||
log_info "Installing bootc container..."
|
||||
|
||||
# Pull the container image
|
||||
log_info "Pulling container image: $CONTAINER_URL"
|
||||
if ! podman pull "$CONTAINER_URL"; then
|
||||
log_error "Failed to pull container image"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install bootc to disk
|
||||
log_info "Installing to device: $TARGET_DEVICE"
|
||||
if ! podman run \
|
||||
--rm \
|
||||
--privileged \
|
||||
--pid=host \
|
||||
-v /dev:/dev \
|
||||
-v /var/lib/containers:/var/lib/containers \
|
||||
--security-opt label=type:unconfined_t \
|
||||
"$CONTAINER_URL" \
|
||||
bootc install to-disk "$TARGET_DEVICE"; then
|
||||
log_error "Bootc installation failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Bootc installation completed successfully"
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2 Post-Install Configuration
|
||||
```bash
|
||||
configure_system() {
|
||||
log_info "Configuring installed system..."
|
||||
|
||||
# Mount the installed system
|
||||
local mount_point="/mnt/bootc-install"
|
||||
mkdir -p "$mount_point"
|
||||
|
||||
# Find the root partition
|
||||
local root_partition=$(find_root_partition)
|
||||
if [[ -z "$root_partition" ]]; then
|
||||
log_error "Could not find root partition"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Mount root partition
|
||||
if ! mount "$root_partition" "$mount_point"; then
|
||||
log_error "Failed to mount root partition"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Configure user account
|
||||
configure_user_account "$mount_point"
|
||||
|
||||
# Configure SSH access
|
||||
if [[ -n "$SSH_KEY" ]]; then
|
||||
configure_ssh_access "$mount_point"
|
||||
fi
|
||||
|
||||
# Unmount
|
||||
umount "$mount_point"
|
||||
|
||||
log_info "System configuration completed"
|
||||
}
|
||||
|
||||
find_root_partition() {
|
||||
# Look for the root partition on the target device
|
||||
local partitions=($(lsblk -n -o NAME "$TARGET_DEVICE" | tail -n +2))
|
||||
|
||||
for partition in "${partitions[@]}"; do
|
||||
local part_path="/dev/$partition"
|
||||
# Check if this looks like a root partition
|
||||
if mount "$part_path" /mnt 2>/dev/null; then
|
||||
if [[ -d "/mnt/usr" ]] && [[ -d "/mnt/etc" ]]; then
|
||||
umount /mnt
|
||||
echo "$part_path"
|
||||
return
|
||||
fi
|
||||
umount /mnt
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
configure_user_account() {
|
||||
local mount_point="$1"
|
||||
|
||||
# Create user configuration for systemd-sysusers
|
||||
local sysusers_config="$mount_point/etc/sysusers.d/installer-user.conf"
|
||||
cat > "$sysusers_config" << EOF
|
||||
u $USERNAME 1000 "$USERNAME" /home/$USERNAME
|
||||
g $USERNAME 1000
|
||||
m $USERNAME $USERNAME
|
||||
EOF
|
||||
|
||||
log_info "User account '$USERNAME' configured"
|
||||
}
|
||||
|
||||
configure_ssh_access() {
|
||||
local mount_point="$1"
|
||||
|
||||
# Create .ssh directory for root
|
||||
local ssh_dir="$mount_point/root/.ssh"
|
||||
mkdir -p "$ssh_dir"
|
||||
|
||||
# Add SSH key
|
||||
echo "$SSH_KEY" > "$ssh_dir/authorized_keys"
|
||||
|
||||
# Set proper permissions
|
||||
chmod 700 "$ssh_dir"
|
||||
chmod 600 "$ssh_dir/authorized_keys"
|
||||
|
||||
log_info "SSH access configured for root"
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 3: Live CD Creation (Week 3-4)
|
||||
|
||||
#### 3.1 Live CD Build Script
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# build-live-cd.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Configuration
|
||||
LIVE_CD_NAME="bootc-installer-live"
|
||||
LIVE_CD_VERSION="1.0"
|
||||
OUTPUT_DIR="./live-cd-build"
|
||||
|
||||
# Create build directory
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
cd "$OUTPUT_DIR"
|
||||
|
||||
# Create live CD structure
|
||||
mkdir -p {live,chroot}
|
||||
|
||||
# Install debootstrap
|
||||
apt-get update
|
||||
apt-get install -y debootstrap
|
||||
|
||||
# Bootstrap minimal Debian system
|
||||
debootstrap --arch=amd64 trixie chroot/
|
||||
|
||||
# Install required packages
|
||||
chroot chroot/ apt-get update
|
||||
chroot chroot/ apt-get install -y \
|
||||
podman \
|
||||
bootc \
|
||||
curl \
|
||||
parted \
|
||||
e2fsprogs \
|
||||
grub-efi-amd64 \
|
||||
systemd \
|
||||
openssh-server \
|
||||
vim \
|
||||
nano
|
||||
|
||||
# Create installer script
|
||||
cat > chroot/usr/local/bin/bootc-installer << 'EOF'
|
||||
#!/bin/bash
|
||||
# ... (installer script content)
|
||||
EOF
|
||||
|
||||
chmod +x chroot/usr/local/bin/bootc-installer
|
||||
|
||||
# Create auto-run script
|
||||
cat > chroot/etc/profile.d/bootc-installer.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
if [[ -z "$BOOTC_INSTALLER_RUN" ]]; then
|
||||
export BOOTC_INSTALLER_RUN=1
|
||||
echo "Bootc Installer Live CD"
|
||||
echo "Run: bootc-installer"
|
||||
echo "Or: curl -fsSL https://install.bootc.dev | sh"
|
||||
fi
|
||||
EOF
|
||||
|
||||
# Build ISO
|
||||
apt-get install -y live-build
|
||||
lb config --binary-images iso-hybrid
|
||||
lb build
|
||||
```
|
||||
|
||||
#### 3.2 Live CD Features
|
||||
- **Minimal Debian Trixie** base
|
||||
- **Pre-installed tools**: podman, bootc, curl, parted
|
||||
- **Network configuration** via DHCP
|
||||
- **Auto-mount** of installer script
|
||||
- **GRUB2 bootloader** with UEFI support
|
||||
|
||||
### Phase 4: Web Hosting and Distribution (Week 4)
|
||||
|
||||
#### 4.1 Web Server Setup
|
||||
```nginx
|
||||
# nginx configuration for install.bootc.dev
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name install.bootc.dev;
|
||||
|
||||
ssl_certificate /path/to/cert.pem;
|
||||
ssl_certificate_key /path/to/key.pem;
|
||||
|
||||
location / {
|
||||
add_header Content-Type text/plain;
|
||||
add_header Cache-Control no-cache;
|
||||
return 200 "$(cat /var/www/install.bootc.dev/installer.sh)";
|
||||
}
|
||||
|
||||
location /latest {
|
||||
return 302 https://install.bootc.dev/;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2 Installer Script Hosting
|
||||
```bash
|
||||
# Simple script to serve the installer
|
||||
#!/bin/bash
|
||||
# serve-installer.sh
|
||||
|
||||
while true; do
|
||||
echo "Serving installer script..."
|
||||
cat installer.sh | nc -l 8080
|
||||
done
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Installation
|
||||
```bash
|
||||
# Boot from live CD, then:
|
||||
curl -fsSL https://install.bootc.dev | sh
|
||||
```
|
||||
|
||||
### Install Specific Container
|
||||
```bash
|
||||
curl -fsSL https://install.bootc.dev | sh -s -- quay.io/myorg/my-bootc:latest
|
||||
```
|
||||
|
||||
### Install with Pre-configured Settings
|
||||
```bash
|
||||
# Set environment variables
|
||||
export BOOTC_USERNAME="admin"
|
||||
export BOOTC_SSH_KEY="ssh-rsa AAAAB3NzaC1yc2E..."
|
||||
export BOOTC_DEVICE="/dev/sda"
|
||||
|
||||
curl -fsSL https://install.bootc.dev | sh
|
||||
```
|
||||
|
||||
## Advantages of This Approach
|
||||
|
||||
### 1. **Simplicity**
|
||||
- Single shell script
|
||||
- No complex dependencies
|
||||
- Easy to understand and modify
|
||||
|
||||
### 2. **Compatibility**
|
||||
- Works with bootc's design
|
||||
- No fighting against OSTree internals
|
||||
- Uses standard Linux tools
|
||||
|
||||
### 3. **Flexibility**
|
||||
- Easy to customize for different containers
|
||||
- Can be extended with additional features
|
||||
- Works with any bootc-compatible container
|
||||
|
||||
### 4. **Reliability**
|
||||
- Minimal failure points
|
||||
- Easy to debug and troubleshoot
|
||||
- Can be tested in virtual machines
|
||||
|
||||
### 5. **User Experience**
|
||||
- Familiar "curl | sh" pattern
|
||||
- Interactive prompts for configuration
|
||||
- Clear progress indicators
|
||||
|
||||
## Implementation Timeline
|
||||
|
||||
- **Week 1-2**: Core installer script development
|
||||
- **Week 2-3**: Bootc integration and testing
|
||||
- **Week 3-4**: Live CD creation and testing
|
||||
- **Week 4**: Web hosting and distribution setup
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### 1. **Virtual Machine Testing**
|
||||
- Test with different container images
|
||||
- Test with various disk configurations
|
||||
- Test error handling and recovery
|
||||
|
||||
### 2. **Hardware Testing**
|
||||
- Test on different hardware configurations
|
||||
- Test with UEFI and legacy BIOS
|
||||
- Test with different storage devices
|
||||
|
||||
### 3. **Network Testing**
|
||||
- Test with different network configurations
|
||||
- Test with proxy/firewall environments
|
||||
- Test with slow/unreliable connections
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### 1. **Advanced Features**
|
||||
- Multiple container selection
|
||||
- Custom partitioning options
|
||||
- Network configuration
|
||||
- Timezone and locale settings
|
||||
|
||||
### 2. **Enterprise Features**
|
||||
- Corporate registry integration
|
||||
- Signed installer verification
|
||||
- Audit logging
|
||||
- Remote management integration
|
||||
|
||||
### 3. **UI Improvements**
|
||||
- Web-based configuration interface
|
||||
- Progress bars and better feedback
|
||||
- Error recovery suggestions
|
||||
- Installation validation
|
||||
|
||||
## Conclusion
|
||||
|
||||
This simple installer approach provides a practical, reliable way to install bootc containers while working with the tools rather than against them. The "curl | sh" pattern is familiar to users and the implementation is straightforward and maintainable.
|
||||
|
||||
The key advantages are:
|
||||
- **Simplicity**: Easy to understand and modify
|
||||
- **Compatibility**: Works with bootc's design
|
||||
- **Reliability**: Minimal failure points
|
||||
- **Flexibility**: Easy to extend and customize
|
||||
- **User Experience**: Familiar and intuitive
|
||||
|
||||
This approach can be implemented quickly and provides a solid foundation for more advanced features in the future.
|
||||
Loading…
Add table
Add a link
Reference in a new issue