Documentation
¶
Overview ¶
Package pkg provides the public API for nbc (bootc container installation).
The primary entry point is the Installer type, which handles installation of bootc container images to physical disks or loopback devices.
Example usage:
cfg := &pkg.InstallConfig{
ImageRef: "quay.io/example/myimage:latest",
Device: "/dev/sda",
FilesystemType: "btrfs",
}
installer, err := pkg.NewInstaller(cfg)
if err != nil {
log.Fatal(err)
}
result, err := installer.Install(context.Background())
if err != nil {
log.Fatal(err)
}
if result != nil && result.Cleanup != nil {
defer result.Cleanup()
}
Index ¶
- Constants
- Variables
- func AttachLoopback(imagePath string) (string, error)
- func CacheLockPath() string
- func CheckRequiredTools() error
- func CheckUpdateNeeded(installedDigest, remoteDigest string) bool
- func ChrootCommand(targetDir string, command string, args ...string) error
- func CloseLUKS(ctx context.Context, mapperName string, progress Reporter) error
- func CreateFstab(ctx context.Context, targetDir string, scheme *PartitionScheme, ...) error
- func CreateLUKSContainer(ctx context.Context, partition, passphrase string, progress Reporter) error
- func CreateLoopbackFile(imagePath string, sizeGB int, force bool) error
- func DetachLoopback(device string) error
- func EnrollTPM2(ctx context.Context, partition string, config *LUKSConfig, progress Reporter) error
- func EnsureCriticalFilesInOverlay(ctx context.Context, dryRun bool, progress Reporter) error
- func ExtractAndVerifyContainer(ctx context.Context, imageRef, localLayoutPath, mountPoint string, ...) error
- func FormatPartitions(ctx context.Context, scheme *PartitionScheme, dryRun bool, progress Reporter) error
- func FormatSize(bytes uint64) string
- func GenerateCrypttab(devices []*LUKSDevice, tpm2Enabled bool) string
- func GetActiveRootPartition() (string, error)
- func GetBootDeviceFromPartition(partition string) (string, error)
- func GetCurrentBootDevice(progress Reporter) (string, error)
- func GetCurrentBootDeviceInfo(ctx context.Context, verbose bool, progress Reporter) (string, error)
- func GetDiskByPath(path string) (string, error)
- func GetDiskID(device string) (string, error)
- func GetInactiveRootPartition(scheme *PartitionScheme, progress Reporter) (string, bool, error)
- func GetLUKSUUID(ctx context.Context, partition string) (string, error)
- func GetPartitionUUID(ctx context.Context, partition string) (string, error)
- func GetRemoteImageDigest(imageRef string) (string, error)
- func InitramfsHasEtcOverlay(initramfsPath string) (bool, error)
- func InstallDracutEtcOverlay(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
- func InstallEtcMountUnit(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
- func InstallTmpfilesConfig(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
- func IsBlockDevice(path string) bool
- func IsNBCBooted() bool
- func IsRebootRequired() bool
- func IsRootMountedReadOnly() string
- func IsRunningInContainer() bool
- func IsTPMAvailable() bool
- func LoadImageFromOCILayout(layoutPath string) (v1.Image, error)
- func MergeEtcFromActive(ctx context.Context, targetDir string, activeRootPartition string, dryRun bool, ...) error
- func MountPartitions(ctx context.Context, scheme *PartitionScheme, mountPoint string, dryRun bool, ...) error
- func ParseDeviceName(device string) (string, error)
- func ParseOSRelease(targetDir string) string
- func ParseSizeGB(sizeStr string) (int, error)
- func PopulateEtcLower(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
- func PrepareMachineID(ctx context.Context, targetDir string, progress Reporter) error
- func PullImage(ctx context.Context, imageRef string, verbose bool, progress Reporter) error
- func ReadRebootRequiredMarker() (*types.RebootPendingInfo, error)
- func RegenerateInitramfs(ctx context.Context, targetDir string, dryRun bool, verbose bool, ...) error
- func SavePristineEtc(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
- func SetRootPasswordInTarget(ctx context.Context, targetDir, password string, dryRun bool, ...) error
- func SetupEtcOverlay(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
- func SetupEtcPersistence(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
- func SetupLUKS(ctx context.Context, scheme *PartitionScheme, passphrase string, dryRun bool, ...) error
- func SetupSystemDirectories(ctx context.Context, targetDir string, progress Reporter) error
- func SetupTargetSystem(ctx context.Context, mountPoint string, dryRun, verbose bool, ...) error
- func SystemLockPath() string
- func UnmountPartitions(ctx context.Context, mountPoint string, dryRun bool, progress Reporter) error
- func UpdateSystemConfigImageRef(ctx context.Context, imageRef, imageDigest string, dryRun bool, ...) error
- func ValidateDisk(device string, minSize uint64) error
- func ValidateInitramfsSupport(targetDir string, tpm2Enabled bool) []string
- func VerifyDiskID(device, expectedDiskID string) (bool, error)
- func VerifyDracutEtcOverlay(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
- func VerifyExtraction(targetDir string) error
- func WipeDisk(ctx context.Context, device string, dryRun bool, progress Reporter) error
- func WriteRebootRequiredMarker(info *types.RebootPendingInfo) error
- func WriteSystemConfig(ctx context.Context, config *SystemConfig, dryRun bool, progress Reporter) error
- func WriteSystemConfigToVar(ctx context.Context, varMountPoint string, config *SystemConfig, dryRun bool, ...) error
- type BootloaderInstaller
- func (b *BootloaderInstaller) AddKernelArg(arg string)
- func (b *BootloaderInstaller) Install(ctx context.Context) error
- func (b *BootloaderInstaller) SetEncryption(config *LUKSConfig)
- func (b *BootloaderInstaller) SetProgress(p Reporter)
- func (b *BootloaderInstaller) SetType(t BootloaderType)
- func (b *BootloaderInstaller) SetVerbose(verbose bool)
- type BootloaderType
- type CachedImageMetadata
- type ContainerExtractor
- type DiskInfo
- type EncryptionConfig
- type EncryptionOptions
- type FileLock
- type FilesystemType
- type ImageCache
- func (c *ImageCache) Clear(ctx context.Context, progress Reporter) error
- func (c *ImageCache) Download(ctx context.Context, imageRef string, progress Reporter) (*CachedImageMetadata, error)
- func (c *ImageCache) GetImage(digestOrRef string) (v1.Image, *CachedImageMetadata, error)
- func (c *ImageCache) GetLayoutPath(digest string) string
- func (c *ImageCache) GetSingle() (*CachedImageMetadata, error)
- func (c *ImageCache) IsCached(digest string) (bool, error)
- func (c *ImageCache) List() ([]CachedImageMetadata, error)
- func (c *ImageCache) Remove(ctx context.Context, digestOrPrefix string, progress Reporter) error
- func (c *ImageCache) SetVerbose(verbose bool)
- type InstallConfig
- type InstallResult
- type Installer
- type JSONReporter
- func (r *JSONReporter) Complete(message string, details any)
- func (r *JSONReporter) Error(err error, message string)
- func (r *JSONReporter) IsJSON() bool
- func (r *JSONReporter) Message(format string, args ...any)
- func (r *JSONReporter) MessagePlain(format string, args ...any)
- func (r *JSONReporter) Progress(percent int, message string)
- func (r *JSONReporter) Step(step, total int, name string)
- func (r *JSONReporter) Warning(format string, args ...any)
- type LUKSConfig
- type LUKSDevice
- type LintCheck
- type LintIssue
- type LintResult
- type LintSeverity
- type Linter
- func (l *Linter) Lint(rootDir string) *LintResult
- func (l *Linter) LintContainerImage(imageRef string) (*LintResult, error)
- func (l *Linter) RegisterCheck(check LintCheck)
- func (l *Linter) RegisterDefaultChecks()
- func (l *Linter) SetFix(fix bool)
- func (l *Linter) SetQuiet(quiet bool)
- func (l *Linter) SetVerbose(verbose bool)
- type LocalImageSource
- type LoopbackDevice
- type LoopbackOptions
- type NoopReporter
- func (NoopReporter) Complete(string, any)
- func (NoopReporter) Error(error, string)
- func (NoopReporter) IsJSON() bool
- func (NoopReporter) Message(string, ...any)
- func (NoopReporter) MessagePlain(string, ...any)
- func (NoopReporter) Progress(int, string)
- func (NoopReporter) Step(int, int, string)
- func (NoopReporter) Warning(string, ...any)
- type PartitionInfo
- type PartitionScheme
- type Reporter
- type StepFunc
- type SystemConfig
- type SystemUpdater
- func (u *SystemUpdater) AddKernelArg(arg string)
- func (u *SystemUpdater) InstallKernelAndInitramfs() error
- func (u *SystemUpdater) IsUpdateNeeded(short bool) (bool, string, error)
- func (u *SystemUpdater) PerformUpdate(skipPull bool) error
- func (u *SystemUpdater) PrepareUpdate() error
- func (u *SystemUpdater) PullImage() error
- func (u *SystemUpdater) SetDryRun(dryRun bool)
- func (u *SystemUpdater) SetForce(force bool)
- func (u *SystemUpdater) SetJSONOutput(jsonOutput bool)
- func (u *SystemUpdater) SetLocalImage(layoutPath string, metadata *CachedImageMetadata)
- func (u *SystemUpdater) SetVerbose(verbose bool)
- func (u *SystemUpdater) Update() error
- func (u *SystemUpdater) UpdateBootloader() error
- type TextReporter
- func (r *TextReporter) Complete(message string, _ any)
- func (r *TextReporter) Error(err error, message string)
- func (r *TextReporter) IsJSON() bool
- func (r *TextReporter) Message(format string, args ...any)
- func (r *TextReporter) MessagePlain(format string, args ...any)
- func (r *TextReporter) Progress(_ int, message string)
- func (r *TextReporter) Step(step, total int, name string)
- func (r *TextReporter) Warning(format string, args ...any)
- type UpdaterConfig
- type Workflow
- type WorkflowState
Constants ¶
const ( // StagedInstallDir is the directory for pre-staged installation images (e.g., on ISO) StagedInstallDir = "/var/cache/nbc/staged-install" // StagedUpdateDir is the directory for pre-downloaded update images StagedUpdateDir = "/var/cache/nbc/staged-update" // MetadataFileName is the name of the metadata file in each cached image directory MetadataFileName = "metadata.json" )
const ( // SystemConfigDir is the directory for nbc system configuration // Stored in /var/lib/nbc/state/ to avoid /etc overlay complications SystemConfigDir = "/var/lib/nbc/state" // SystemConfigFile is the main configuration file SystemConfigFile = "/var/lib/nbc/state/config.json" // LegacySystemConfigDir is the old location (for migration) LegacySystemConfigDir = "/etc/nbc" // LegacySystemConfigFile is the old config file location (for migration) LegacySystemConfigFile = "/etc/nbc/config.json" // LegacyOverlayUpperNbc is the old config location in overlay upper layer LegacyOverlayUpperNbc = "/var/lib/nbc/etc-overlay/upper/nbc" // NBCBootedMarker is the runtime marker file indicating nbc-managed boot // Created by tmpfiles.d during boot, similar to /run/ostree-booted NBCBootedMarker = "/run/nbc-booted" // NBCTmpfilesConfig is the tmpfiles.d config that creates the marker NBCTmpfilesConfig = "/usr/lib/tmpfiles.d/nbc.conf" // RebootRequiredMarker indicates a system update is pending reboot // Written to /run after update completes, automatically cleared on reboot (tmpfs) RebootRequiredMarker = "/run/nbc-reboot-required" )
const ( // PristineEtcPath is where we store the pristine /etc from installation PristineEtcPath = "/var/lib/nbc/etc.pristine" // EtcOverlayPath is where we store the overlay upper/work directories EtcOverlayPath = "/var/lib/nbc/etc-overlay" // VarEtcPath is DEPRECATED - we no longer use /var/etc for boot-time bind mount // Kept for documentation purposes VarEtcPath = "/var/etc.backup" )
const ( SeverityError = types.SeverityError SeverityWarning = types.SeverityWarning )
Re-export constants for backward compatibility
const ( // LockDir is the directory where lock files are stored LockDir = "/var/run/nbc" // CacheLockFile is the lock file for cache operations CacheLockFile = "cache.lock" // SystemLockFile is the lock file for system operations (install/update) SystemLockFile = "system.lock" )
const ( // MinLoopbackSizeGB is the minimum size for a loopback image (35GB) // This accounts for: 2GB boot + 2x12GB roots + var space MinLoopbackSizeGB = 35 // DefaultLoopbackSizeGB is the default size when not specified DefaultLoopbackSizeGB = 35 )
Variables ¶
var ( // ErrLockHeld is returned when a lock cannot be acquired because another process holds it ErrLockHeld = errors.New("lock held by another process") )
Functions ¶
func AttachLoopback ¶ added in v0.13.0
AttachLoopback attaches an image file as a loopback device. Returns the loop device path (e.g., /dev/loop0).
func CacheLockPath ¶ added in v0.13.0
func CacheLockPath() string
CacheLockPath returns the full path to the cache lock file
func CheckRequiredTools ¶
func CheckRequiredTools() error
CheckRequiredTools checks if required tools are available
func CheckUpdateNeeded ¶
CheckUpdateNeeded compares the installed image digest with the remote image digest Returns true if an update is needed (digests differ), false otherwise
func ChrootCommand ¶
ChrootCommand runs a command in a chroot environment
func CreateFstab ¶
func CreateFstab(ctx context.Context, targetDir string, scheme *PartitionScheme, progress Reporter) error
CreateFstab creates an /etc/fstab file with the proper mount points
func CreateLUKSContainer ¶ added in v0.6.0
func CreateLUKSContainer(ctx context.Context, partition, passphrase string, progress Reporter) error
CreateLUKSContainer creates a LUKS2 container on the given partition
func CreateLoopbackFile ¶ added in v0.13.0
CreateLoopbackFile creates a sparse image file of the specified size. If the file already exists, it returns an error unless force is true.
func DetachLoopback ¶ added in v0.13.0
DetachLoopback detaches a loopback device.
func EnrollTPM2 ¶ added in v0.6.0
EnrollTPM2 enrolls a TPM2 key for automatic unlock with no PCRs
func EnsureCriticalFilesInOverlay ¶ added in v0.8.5
EnsureCriticalFilesInOverlay ensures critical files that should persist across updates are captured in the overlay upper layer. This is necessary because some files (like SSH host keys) may exist in the container image from build time, meaning they never get written to the overlay upper layer during normal operation.
When an A/B update happens with a new container image, the lower layer changes to the new container's /etc, and any files not in the overlay upper will show the new container's version instead of the running system's version.
This function copies critical files from the running system's /etc to the overlay upper layer if they don't already exist there.
func ExtractAndVerifyContainer ¶ added in v0.16.0
func ExtractAndVerifyContainer(ctx context.Context, imageRef, localLayoutPath, mountPoint string, verbose bool, progress Reporter) error
ExtractAndVerifyContainer creates and runs a container extractor, then verifies the extraction succeeded. Used by both install and update flows.
func FormatPartitions ¶
func FormatPartitions(ctx context.Context, scheme *PartitionScheme, dryRun bool, progress Reporter) error
FormatPartitions formats the partitions with appropriate filesystems
func FormatSize ¶
FormatSize formats a byte size as human-readable string
func GenerateCrypttab ¶ added in v0.6.0
func GenerateCrypttab(devices []*LUKSDevice, tpm2Enabled bool) string
GenerateCrypttab generates /etc/crypttab entries for the LUKS devices
func GetActiveRootPartition ¶
GetActiveRootPartition determines which root partition is currently active
func GetBootDeviceFromPartition ¶
GetBootDeviceFromPartition extracts the parent disk device from a partition path Example: /dev/sda3 -> /dev/sda, /dev/nvme0n1p3 -> /dev/nvme0n1
func GetCurrentBootDevice ¶
GetCurrentBootDevice determines the disk device that the system booted from
func GetCurrentBootDeviceInfo ¶
GetCurrentBootDeviceInfo returns detailed information about the boot device
func GetDiskByPath ¶
GetDiskByPath resolves a disk path (handles by-id, by-uuid, etc.)
func GetDiskID ¶ added in v0.13.0
GetDiskID returns the stable disk identifier from /dev/disk/by-id for a given device Returns the by-id path (e.g., "nvme-Samsung_SSD_980_PRO_2TB_S1234567890") or empty string if not found
func GetInactiveRootPartition ¶
func GetInactiveRootPartition(scheme *PartitionScheme, progress Reporter) (string, bool, error)
GetInactiveRootPartition returns the inactive root partition given a partition scheme
func GetLUKSUUID ¶ added in v0.6.0
GetLUKSUUID retrieves the LUKS container UUID (not filesystem UUID)
func GetPartitionUUID ¶
GetPartitionUUID returns the UUID of a partition
func GetRemoteImageDigest ¶
GetRemoteImageDigest fetches the digest of a remote container image without downloading layers. Returns the digest in the format "sha256:..."
func InitramfsHasEtcOverlay ¶ added in v0.11.0
InitramfsHasEtcOverlay checks if the initramfs at the given path contains the etc-overlay dracut module. This is used to skip regenerating the initramfs if it already has the module.
The function uses lsinitrd (Fedora/RHEL) or lsinitramfs (Debian/Ubuntu) to list the initramfs contents and searches for the etc-overlay hook script.
func InstallDracutEtcOverlay ¶ added in v0.13.0
func InstallDracutEtcOverlay(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
InstallDracutEtcOverlay installs the embedded etc-overlay dracut module to the target filesystem. This overwrites any existing module from the container image to ensure the nbc binary's version is used (which may have fixes not yet in the published container image).
func InstallEtcMountUnit ¶
func InstallEtcMountUnit(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
InstallEtcMountUnit is DEPRECATED - use SetupEtcPersistence instead. This function now just calls SetupEtcPersistence for backwards compatibility.
func InstallTmpfilesConfig ¶ added in v0.8.1
func InstallTmpfilesConfig(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
InstallTmpfilesConfig installs a tmpfiles.d config to create /run/nbc-booted marker. This marker is created by systemd-tmpfiles during boot, after /run is mounted. Unlike the dracut approach, this ensures the marker exists after switch_root when systemd mounts a fresh tmpfs on /run.
func IsBlockDevice ¶
IsBlockDevice checks if a path is a block device
func IsNBCBooted ¶ added in v0.8.0
func IsNBCBooted() bool
IsNBCBooted checks if the current system was booted via nbc. Returns true if /run/nbc-booted exists (created by tmpfiles.d during boot).
func IsRebootRequired ¶ added in v0.15.0
func IsRebootRequired() bool
IsRebootRequired checks if a reboot is pending (marker exists)
func IsRootMountedReadOnly ¶ added in v0.13.0
func IsRootMountedReadOnly() string
IsRootMountedReadOnly checks if the root partition is mounted read-only Returns "ro" for read-only, "rw" for read-write, or empty string if unable to determine
func IsRunningInContainer ¶ added in v0.10.0
func IsRunningInContainer() bool
IsRunningInContainer checks if the current process is running inside a container. It looks for common marker files created by container runtimes:
- /.dockerenv (Docker)
- /run/.containerenv (Podman)
This is used as a safety check before applying --fix in --local mode.
func IsTPMAvailable ¶ added in v0.13.0
func IsTPMAvailable() bool
IsTPMAvailable checks if a TPM device is available on the system
func LoadImageFromOCILayout ¶ added in v0.12.0
LoadImageFromOCILayout loads a container image from an OCI layout directory
func MergeEtcFromActive ¶
func MergeEtcFromActive(ctx context.Context, targetDir string, activeRootPartition string, dryRun bool, progress Reporter) error
MergeEtcFromActive handles /etc configuration during A/B updates with overlay persistence.
With the overlay-based persistence model, user modifications to /etc are stored in /var/lib/nbc/etc-overlay/upper and automatically apply to whichever root is active. This function no longer needs to copy files between roots.
The main task now is to: 1. Ensure the overlay directories exist on the new root 2. Optionally detect conflicts where both the container and user modified the same file
Parameters:
- targetDir: mount point of the NEW root partition (e.g., /tmp/nbc-update)
- activeRootPartition: the CURRENT root partition device (not used with overlay)
- dryRun: if true, don't make changes
- progress: progress reporter for output
func MountPartitions ¶
func MountPartitions(ctx context.Context, scheme *PartitionScheme, mountPoint string, dryRun bool, progress Reporter) error
MountPartitions mounts the partitions to a temporary directory
func ParseDeviceName ¶
ParseDeviceName extracts the base device name without partition number
func ParseOSRelease ¶
ParseOSRelease reads and parses /etc/os-release from the target directory Returns PRETTY_NAME if available, otherwise NAME, otherwise ID, or "Linux" as fallback
func ParseSizeGB ¶ added in v0.13.0
ParseSizeGB parses a size string and returns the size in GB. Accepts plain integers (assumed GB) or values with G/GB suffix. Enforces minimum size of MinLoopbackSizeGB.
func PopulateEtcLower ¶ added in v0.13.0
PopulateEtcLower copies the container's /etc to /.etc.lower for use as the overlay lower layer. This must be called after container extraction to ensure the dracut etc-overlay module finds a populated /.etc.lower directory on first boot.
The dracut module checks if /.etc.lower exists and has content: - If it exists with content: uses it as the overlay lowerdir - If it's empty or missing: moves /etc to /.etc.lower and uses it
By populating /.etc.lower during install/update, we ensure consistent behavior and the container's /etc is preserved as the read-only base layer.
func PrepareMachineID ¶ added in v0.13.0
PrepareMachineID ensures /etc/machine-id contains "uninitialized" for first-boot detection. This is required for read-only root filesystems where systemd cannot create the file at boot. systemd will detect "uninitialized" and properly initialize the machine-id on first boot.
func PullImage ¶ added in v0.14.0
PullImage validates an image reference and checks if it's accessible. This is a standalone function for use by Installer. The actual image pull happens during Extract() to avoid duplicate work.
func ReadRebootRequiredMarker ¶ added in v0.15.0
func ReadRebootRequiredMarker() (*types.RebootPendingInfo, error)
ReadRebootRequiredMarker reads the marker if it exists, returns nil if not present
func RegenerateInitramfs ¶ added in v0.8.0
func RegenerateInitramfs(ctx context.Context, targetDir string, dryRun bool, verbose bool, progress Reporter) error
RegenerateInitramfs regenerates the initramfs using dracut in a chroot environment. This is necessary to include the etc-overlay module in the initramfs. If the initramfs already contains the etc-overlay module, regeneration is skipped.
func SavePristineEtc ¶
SavePristineEtc saves a copy of the pristine /etc after installation This is used to detect user modifications during updates
func SetRootPasswordInTarget ¶ added in v0.13.0
func SetRootPasswordInTarget(ctx context.Context, targetDir, password string, dryRun bool, progress Reporter) error
SetRootPasswordInTarget sets the root password in the installed system using chpasswd The password is passed via stdin for security (not visible in process list)
func SetupEtcOverlay ¶ added in v0.8.0
SetupEtcOverlay creates the overlay directories for /etc persistence.
The overlay approach works as follows: 1. The root filesystem's /etc is the read-only lower layer (from container image) 2. User modifications persist in /var/lib/nbc/etc-overlay/upper (writable layer) 3. A dracut module (95etc-overlay) mounts the overlay during early boot
This allows user changes to /etc to persist across A/B updates while keeping the base /etc from the container image.
func SetupEtcPersistence ¶
func SetupEtcPersistence(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
SetupEtcPersistence ensures /etc is properly configured for persistence across A/B updates.
IMPORTANT: This function now sets up overlay-based persistence. A dracut module mounts an overlayfs for /etc during early boot: - lowerdir: /etc from root filesystem (read-only, from container image) - upperdir: /var/lib/nbc/etc-overlay/upper (writable, user modifications) - workdir: /var/lib/nbc/etc-overlay/work (required by overlayfs)
This approach solves the timing issues that plagued bind-mount approaches, because the dracut hook runs before pivot_root when /etc is not yet in use.
func SetupLUKS ¶ added in v0.6.0
func SetupLUKS(ctx context.Context, scheme *PartitionScheme, passphrase string, dryRun bool, progress Reporter) error
SetupLUKS creates LUKS containers on root and var partitions Returns the opened LUKS devices (must be closed during cleanup)
func SetupSystemDirectories ¶
SetupSystemDirectories creates necessary system directories
func SetupTargetSystem ¶ added in v0.16.0
func SetupTargetSystem(ctx context.Context, mountPoint string, dryRun, verbose bool, progress Reporter) error
SetupTargetSystem performs the common post-extraction system setup sequence shared between install and update flows. This includes: - Installing dracut etc-overlay module (with optional regeneration) - Setting up system directories - Preparing machine-id for first boot - Populating /.etc.lower for overlay - Installing tmpfiles.d config for /run/nbc-booted marker
Operations specific to install (InstallEtcMountUnit, SavePristineEtc) or update (MergeEtcFromActive) must be called separately.
func SystemLockPath ¶ added in v0.13.0
func SystemLockPath() string
SystemLockPath returns the full path to the system lock file
func UnmountPartitions ¶
func UnmountPartitions(ctx context.Context, mountPoint string, dryRun bool, progress Reporter) error
UnmountPartitions unmounts all partitions
func UpdateSystemConfigImageRef ¶
func UpdateSystemConfigImageRef(ctx context.Context, imageRef, imageDigest string, dryRun bool, progress Reporter) error
UpdateSystemConfigImageRef updates the image reference and digest in the system config
func ValidateDisk ¶
ValidateDisk checks if a disk is suitable for installation
func ValidateInitramfsSupport ¶ added in v0.6.0
ValidateInitramfsSupport checks if the extracted container has LUKS/TPM2 support Returns warnings (not errors) since initramfs contents vary by distro
func VerifyDiskID ¶ added in v0.13.0
VerifyDiskID checks if a device matches the expected disk ID Returns true if they match, false otherwise
func VerifyDracutEtcOverlay ¶ added in v0.8.0
func VerifyDracutEtcOverlay(ctx context.Context, targetDir string, dryRun bool, progress Reporter) error
VerifyDracutEtcOverlay verifies that the etc-overlay dracut module exists in the target filesystem. The module is installed via the nbc deb/rpm package to /usr/lib/dracut/modules.d/95etc-overlay/. This function checks that the container/host has nbc installed with the dracut module.
func VerifyExtraction ¶ added in v0.11.1
VerifyExtraction checks that the extracted filesystem has essential directories and files, returning an error if the extraction appears incomplete or failed. This helps catch silent extraction failures before proceeding with the update.
func WriteRebootRequiredMarker ¶ added in v0.15.0
func WriteRebootRequiredMarker(info *types.RebootPendingInfo) error
WriteRebootRequiredMarker creates the reboot-required marker with pending update info
func WriteSystemConfig ¶
func WriteSystemConfig(ctx context.Context, config *SystemConfig, dryRun bool, progress Reporter) error
WriteSystemConfig writes system configuration to /var/lib/nbc/state/config.json If legacy config exists at /etc/nbc/config.json, it will be cleaned up after successful write and verification.
func WriteSystemConfigToVar ¶ added in v0.13.0
func WriteSystemConfigToVar(ctx context.Context, varMountPoint string, config *SystemConfig, dryRun bool, progress Reporter) error
WriteSystemConfigToVar writes system configuration to the mounted /var partition varMountPoint is the path where the var partition is mounted (e.g., /mnt/var or /mnt/root/var)
Types ¶
type BootloaderInstaller ¶
type BootloaderInstaller struct {
Type BootloaderType
TargetDir string
Device string
Scheme *PartitionScheme
KernelArgs []string
OSName string
Verbose bool
Encryption *LUKSConfig // Encryption configuration
Progress Reporter // Progress reporter for output
}
BootloaderInstaller handles bootloader installation
func NewBootloaderInstaller ¶
func NewBootloaderInstaller(targetDir, device string, scheme *PartitionScheme, osName string) *BootloaderInstaller
NewBootloaderInstaller creates a new BootloaderInstaller
func (*BootloaderInstaller) AddKernelArg ¶
func (b *BootloaderInstaller) AddKernelArg(arg string)
AddKernelArg adds a kernel argument
func (*BootloaderInstaller) Install ¶
func (b *BootloaderInstaller) Install(ctx context.Context) error
Install installs the bootloader
func (*BootloaderInstaller) SetEncryption ¶ added in v0.6.0
func (b *BootloaderInstaller) SetEncryption(config *LUKSConfig)
SetEncryption sets the encryption configuration
func (*BootloaderInstaller) SetProgress ¶ added in v0.14.0
func (b *BootloaderInstaller) SetProgress(p Reporter)
SetProgress sets the progress reporter
func (*BootloaderInstaller) SetType ¶
func (b *BootloaderInstaller) SetType(t BootloaderType)
SetType sets the bootloader type
func (*BootloaderInstaller) SetVerbose ¶
func (b *BootloaderInstaller) SetVerbose(verbose bool)
SetVerbose enables verbose output
type BootloaderType ¶
type BootloaderType string
BootloaderType represents the type of bootloader to install
const ( BootloaderGRUB2 BootloaderType = "grub2" BootloaderSystemdBoot BootloaderType = "systemd-boot" )
func DetectBootloader ¶
func DetectBootloader(targetDir string) BootloaderType
DetectBootloader detects which bootloader should be used based on the container
type CachedImageMetadata ¶ added in v0.12.0
type CachedImageMetadata = types.CachedImageMetadata
Type alias for backward compatibility
func GetImageByPath ¶ added in v0.12.0
func GetImageByPath(layoutPath string) (v1.Image, *CachedImageMetadata, error)
GetImageByPath loads an image from an OCI layout directory path
type ContainerExtractor ¶
type ContainerExtractor struct {
ImageRef string
TargetDir string
Verbose bool
JSONOutput bool
LocalLayoutPath string // Path to OCI layout directory for local image
Progress Reporter
}
ContainerExtractor handles extracting container images to disk
func NewContainerExtractor ¶
func NewContainerExtractor(imageRef, targetDir string) *ContainerExtractor
NewContainerExtractor creates a new ContainerExtractor
func NewContainerExtractorFromLocal ¶ added in v0.12.0
func NewContainerExtractorFromLocal(layoutPath, targetDir string) *ContainerExtractor
NewContainerExtractorFromLocal creates a ContainerExtractor for a local OCI layout
func (*ContainerExtractor) Extract ¶
func (c *ContainerExtractor) Extract(ctx context.Context) error
Extract extracts the container filesystem to the target directory using go-containerregistry
func (*ContainerExtractor) SetJSONOutput ¶ added in v0.13.0
func (c *ContainerExtractor) SetJSONOutput(jsonOutput bool)
SetJSONOutput enables JSON output mode
func (*ContainerExtractor) SetProgress ¶ added in v0.14.0
func (c *ContainerExtractor) SetProgress(p Reporter)
SetProgress sets the progress reporter directly
func (*ContainerExtractor) SetVerbose ¶
func (c *ContainerExtractor) SetVerbose(verbose bool)
SetVerbose enables verbose output
type DiskInfo ¶
type DiskInfo struct {
Device string
Size uint64
Model string
IsRemovable bool
Partitions []PartitionInfo
}
DiskInfo represents information about a physical disk
type EncryptionConfig ¶ added in v0.7.3
type EncryptionConfig struct {
Enabled bool `json:"enabled"` // Whether LUKS encryption is enabled
TPM2 bool `json:"tpm2"` // Whether TPM2 auto-unlock is enabled
Root1LUKSUUID string `json:"root1_luks_uuid"` // LUKS UUID for root1 partition
Root2LUKSUUID string `json:"root2_luks_uuid"` // LUKS UUID for root2 partition
VarLUKSUUID string `json:"var_luks_uuid"` // LUKS UUID for var partition
}
EncryptionConfig stores LUKS encryption configuration for A/B updates
type EncryptionOptions ¶ added in v0.14.0
type EncryptionOptions struct {
// Passphrase is the LUKS encryption passphrase.
// Required for encryption.
Passphrase string
// TPM2 enables automatic unlock via TPM2 (no PCR binding).
TPM2 bool
}
EncryptionOptions configures LUKS encryption for the installation.
type FileLock ¶ added in v0.13.0
type FileLock struct {
// contains filtered or unexported fields
}
FileLock represents a file-based lock using flock
func AcquireCacheLock ¶ added in v0.13.0
AcquireCacheLock acquires an exclusive lock for cache write operations. Returns a user-friendly error if the lock is already held.
func AcquireCacheLockShared ¶ added in v0.13.0
AcquireCacheLockShared acquires a shared lock for cache read operations. Returns a user-friendly error if an exclusive lock is held.
func AcquireExclusive ¶ added in v0.13.0
AcquireExclusive acquires an exclusive (write) lock on the given path. Returns ErrLockHeld if the lock is already held by another process. The lock is automatically released when Release() is called or the process exits.
func AcquireShared ¶ added in v0.13.0
AcquireShared acquires a shared (read) lock on the given path. Multiple processes can hold shared locks simultaneously. Returns ErrLockHeld if an exclusive lock is held by another process. The lock is automatically released when Release() is called or the process exits.
func AcquireSystemLock ¶ added in v0.13.0
AcquireSystemLock acquires an exclusive lock for system operations (install/update). Returns a user-friendly error if the lock is already held.
type FilesystemType ¶
type FilesystemType string
FilesystemType represents the supported filesystem types
const ( FilesystemExt4 FilesystemType = "ext4" FilesystemBtrfs FilesystemType = "btrfs" )
type ImageCache ¶ added in v0.12.0
ImageCache manages cached container images in OCI layout format
func NewImageCache ¶ added in v0.12.0
func NewImageCache(cacheDir string) *ImageCache
NewImageCache creates a new ImageCache for the specified directory
func NewStagedInstallCache ¶ added in v0.12.0
func NewStagedInstallCache() *ImageCache
NewStagedInstallCache creates an ImageCache for staged installation images
func NewStagedUpdateCache ¶ added in v0.12.0
func NewStagedUpdateCache() *ImageCache
NewStagedUpdateCache creates an ImageCache for staged update images
func (*ImageCache) Clear ¶ added in v0.12.0
func (c *ImageCache) Clear(ctx context.Context, progress Reporter) error
Clear removes all cached images
func (*ImageCache) Download ¶ added in v0.12.0
func (c *ImageCache) Download(ctx context.Context, imageRef string, progress Reporter) (*CachedImageMetadata, error)
Download pulls a container image and saves it to the cache in OCI layout format Download pulls a container image and saves it to the cache in OCI layout format. If progress is non-nil and set to JSON mode, interactive spinners are skipped.
func (*ImageCache) GetImage ¶ added in v0.12.0
func (c *ImageCache) GetImage(digestOrRef string) (v1.Image, *CachedImageMetadata, error)
GetImage loads an image from the cache by digest or image reference
func (*ImageCache) GetLayoutPath ¶ added in v0.12.0
func (c *ImageCache) GetLayoutPath(digest string) string
GetLayoutPath returns the full path to an image's OCI layout directory given its digest
func (*ImageCache) GetSingle ¶ added in v0.12.0
func (c *ImageCache) GetSingle() (*CachedImageMetadata, error)
GetSingle returns the single cached image (for staged-update where only one is expected) Returns nil if no image is cached, error if multiple images exist
func (*ImageCache) IsCached ¶ added in v0.12.0
func (c *ImageCache) IsCached(digest string) (bool, error)
IsCached checks if an image is in the cache by digest
func (*ImageCache) List ¶ added in v0.12.0
func (c *ImageCache) List() ([]CachedImageMetadata, error)
List returns all cached images with their metadata
func (*ImageCache) Remove ¶ added in v0.12.0
Remove removes a cached image by digest or digest prefix
func (*ImageCache) SetVerbose ¶ added in v0.12.0
func (c *ImageCache) SetVerbose(verbose bool)
SetVerbose enables verbose output
type InstallConfig ¶ added in v0.14.0
type InstallConfig struct {
// ImageRef is the container image reference (e.g., "quay.io/example/myimage:latest").
// Required unless LocalImage is provided.
ImageRef string
// Device is the target disk device (e.g., "/dev/sda").
// Required unless Loopback is provided.
Device string
// FilesystemType is the filesystem for root and var partitions.
// Supported: "ext4", "btrfs". Default: "btrfs".
FilesystemType string
// KernelArgs are additional kernel command line arguments.
KernelArgs []string
// MountPoint is the temporary mount point for installation.
// Default: "/tmp/nbc-install".
MountPoint string
// Encryption configures LUKS full disk encryption.
// Optional; if nil, no encryption is used.
Encryption *EncryptionOptions
// LocalImage specifies a pre-staged local image to use instead of pulling.
// Optional; mutually exclusive with ImageRef.
LocalImage *LocalImageSource
// Loopback configures installation to a loopback image file.
// Optional; mutually exclusive with Device.
Loopback *LoopbackOptions
// RootPassword sets the root password during installation.
// Optional; if empty, no password is set.
RootPassword string
// Verbose enables verbose output.
Verbose bool
// DryRun simulates the installation without making changes.
DryRun bool
// JSONOutput enables JSON Lines output format.
JSONOutput bool
// SkipPull skips pulling the image (assumes it's already available).
SkipPull bool
}
InstallConfig holds all configuration options for an installation. Either ImageRef or LocalImage must be provided. Either Device or Loopback must be provided, but not both.
func (*InstallConfig) Validate ¶ added in v0.14.0
func (c *InstallConfig) Validate() error
Validate checks the InstallConfig for errors.
type InstallResult ¶ added in v0.14.0
type InstallResult struct {
// ImageRef is the container image that was installed.
ImageRef string
// ImageDigest is the digest of the installed image.
ImageDigest string
// Device is the device that was installed to.
Device string
// FilesystemType is the filesystem used for root and var partitions.
FilesystemType string
// BootloaderType is the type of bootloader installed ("grub2" or "systemd-boot").
BootloaderType BootloaderType
// LoopbackPath is set if loopback installation was used.
LoopbackPath string
// Duration is the total time taken for installation.
Duration time.Duration
// Cleanup releases resources (e.g., loopback device).
// Always non-nil if loopback was used, even on error or cancellation.
// Caller decides whether to call it based on error handling strategy.
Cleanup func() error
}
InstallResult contains the results of a successful installation.
type Installer ¶ added in v0.14.0
type Installer struct {
// contains filtered or unexported fields
}
Installer performs bootc container installation.
func NewInstaller ¶ added in v0.14.0
func NewInstaller(cfg *InstallConfig) (*Installer, error)
NewInstaller creates a new Installer with the given configuration. Returns an error if the configuration is invalid.
func (*Installer) Install ¶ added in v0.14.0
func (i *Installer) Install(ctx context.Context) (*InstallResult, error)
Install performs the bootc installation. The context can be used to cancel the operation. Returns a result with cleanup function even on error/cancellation if resources were allocated.
type JSONReporter ¶ added in v0.16.0
type JSONReporter struct {
// contains filtered or unexported fields
}
JSONReporter writes JSON Lines (one types.ProgressEvent per line) to an io.Writer. All writes are serialized with a mutex for thread safety.
func NewJSONReporter ¶ added in v0.16.0
func NewJSONReporter(w io.Writer) *JSONReporter
NewJSONReporter returns a JSONReporter that writes to w.
func (*JSONReporter) Complete ¶ added in v0.16.0
func (r *JSONReporter) Complete(message string, details any)
func (*JSONReporter) Error ¶ added in v0.16.0
func (r *JSONReporter) Error(err error, message string)
func (*JSONReporter) IsJSON ¶ added in v0.16.0
func (r *JSONReporter) IsJSON() bool
func (*JSONReporter) Message ¶ added in v0.16.0
func (r *JSONReporter) Message(format string, args ...any)
func (*JSONReporter) MessagePlain ¶ added in v0.16.0
func (r *JSONReporter) MessagePlain(format string, args ...any)
func (*JSONReporter) Progress ¶ added in v0.16.0
func (r *JSONReporter) Progress(percent int, message string)
func (*JSONReporter) Step ¶ added in v0.16.0
func (r *JSONReporter) Step(step, total int, name string)
func (*JSONReporter) Warning ¶ added in v0.16.0
func (r *JSONReporter) Warning(format string, args ...any)
type LUKSConfig ¶ added in v0.6.0
type LUKSConfig struct {
Enabled bool
Passphrase string // Passphrase for LUKS (mutually exclusive with Keyfile)
Keyfile string // Path to keyfile containing passphrase (mutually exclusive with Passphrase)
TPM2 bool
}
LUKSConfig holds encryption configuration
type LUKSDevice ¶ added in v0.6.0
type LUKSDevice struct {
Partition string // Raw partition (e.g., /dev/sda2)
MapperName string // Device mapper name (e.g., root1)
MapperPath string // Full path (e.g., /dev/mapper/root1)
LUKSUUID string // LUKS container UUID
}
LUKSDevice represents an opened LUKS container
func OpenLUKS ¶ added in v0.6.0
func OpenLUKS(ctx context.Context, partition, mapperName, passphrase string, progress Reporter) (*LUKSDevice, error)
OpenLUKS opens a LUKS container and returns the device info
func TryTPM2Unlock ¶ added in v0.8.4
func TryTPM2Unlock(ctx context.Context, partition, mapperName string, progress Reporter) (*LUKSDevice, error)
TryTPM2Unlock attempts to open a LUKS container using TPM2 token Returns the LUKSDevice on success, or an error if TPM2 unlock failed
type LintCheck ¶ added in v0.9.0
LintCheck is a function that performs a lint check on a container filesystem. If fix is true, the check should attempt to fix the issue and set Fixed=true on the issue. It returns a list of issues found (including fixed ones).
type LintIssue ¶ added in v0.9.0
func CheckMachineID ¶ added in v0.9.0
CheckMachineID checks for a non-empty machine-id
func CheckRandomSeed ¶ added in v0.9.0
CheckRandomSeed checks for random seed files that should not be in the image
func CheckSSHHostKeys ¶ added in v0.9.0
CheckSSHHostKeys checks for SSH host keys that should not be in the image
type LintResult ¶ added in v0.9.0
type LintResult = types.LintResult
type LintSeverity ¶ added in v0.9.0
type LintSeverity = types.LintSeverity
Type aliases for backward compatibility
type Linter ¶ added in v0.9.0
type Linter struct {
// contains filtered or unexported fields
}
Linter performs lint checks on container images
func NewLinter ¶ added in v0.9.0
func NewLinter() *Linter
NewLinter creates a new Linter with default checks
func (*Linter) Lint ¶ added in v0.9.0
func (l *Linter) Lint(rootDir string) *LintResult
Lint runs all registered checks on the given directory
func (*Linter) LintContainerImage ¶ added in v0.9.0
func (l *Linter) LintContainerImage(imageRef string) (*LintResult, error)
LintContainerImage extracts and lints a container image
func (*Linter) RegisterCheck ¶ added in v0.9.0
RegisterCheck adds a new lint check
func (*Linter) RegisterDefaultChecks ¶ added in v0.9.0
func (l *Linter) RegisterDefaultChecks()
RegisterDefaultChecks registers all built-in lint checks
func (*Linter) SetVerbose ¶ added in v0.9.0
SetVerbose enables verbose output
type LocalImageSource ¶ added in v0.14.0
type LocalImageSource struct {
// LayoutPath is the path to the OCI layout directory.
LayoutPath string
// Metadata contains information about the cached image.
Metadata *CachedImageMetadata
}
LocalImageSource specifies a pre-staged local image.
type LoopbackDevice ¶ added in v0.13.0
type LoopbackDevice struct {
ImagePath string // Path to the image file
Device string // Loop device path (e.g., /dev/loop0)
SizeGB int // Size of the image in GB
}
LoopbackDevice represents an attached loopback device
func SetupLoopbackInstall ¶ added in v0.13.0
func SetupLoopbackInstall(ctx context.Context, imagePath string, sizeGB int, force bool, progress Reporter) (*LoopbackDevice, error)
SetupLoopbackInstall creates a loopback image file and attaches it. Returns the LoopbackDevice for cleanup and the device path for installation.
type LoopbackOptions ¶ added in v0.14.0
type LoopbackOptions struct {
// ImagePath is the path to create the loopback image file.
ImagePath string
// SizeGB is the size of the loopback image in gigabytes.
// Minimum: 35GB.
SizeGB int
// Force overwrites an existing image file.
Force bool
}
LoopbackOptions configures installation to a loopback image file.
type NoopReporter ¶ added in v0.16.0
type NoopReporter struct{}
NoopReporter silently discards all output. Useful for tests and contexts where no progress reporting is needed.
func (NoopReporter) Complete ¶ added in v0.16.0
func (NoopReporter) Complete(string, any)
func (NoopReporter) Error ¶ added in v0.16.0
func (NoopReporter) Error(error, string)
func (NoopReporter) IsJSON ¶ added in v0.16.0
func (NoopReporter) IsJSON() bool
func (NoopReporter) Message ¶ added in v0.16.0
func (NoopReporter) Message(string, ...any)
func (NoopReporter) MessagePlain ¶ added in v0.16.0
func (NoopReporter) MessagePlain(string, ...any)
func (NoopReporter) Progress ¶ added in v0.16.0
func (NoopReporter) Progress(int, string)
func (NoopReporter) Warning ¶ added in v0.16.0
func (NoopReporter) Warning(string, ...any)
type PartitionInfo ¶
PartitionInfo represents information about a disk partition
type PartitionScheme ¶
type PartitionScheme struct {
BootPartition string // Boot partition (EFI System Partition, FAT32, 2GB) - holds EFI binaries + kernel/initramfs
Root1Partition string // First root filesystem partition (12GB)
Root2Partition string // Second root filesystem partition (12GB)
VarPartition string // /var partition (remaining space)
FilesystemType string // Filesystem type for root/var partitions (ext4, btrfs)
// LUKS encryption (optional)
Encrypted bool // Whether partitions are LUKS encrypted
LUKSDevices []*LUKSDevice // Opened LUKS devices (for cleanup)
}
PartitionScheme defines the disk partitioning layout
func CreatePartitions ¶
func CreatePartitions(ctx context.Context, device string, dryRun bool, progress Reporter) (*PartitionScheme, error)
CreatePartitions creates a GPT partition table with EFI, boot, and root partitions
func DetectExistingPartitionScheme ¶
func DetectExistingPartitionScheme(device string) (*PartitionScheme, error)
DetectExistingPartitionScheme detects the partition scheme of an existing installation
func (*PartitionScheme) CloseLUKSDevices ¶ added in v0.6.0
func (s *PartitionScheme) CloseLUKSDevices(ctx context.Context)
CloseLUKSDevices closes all open LUKS containers
func (*PartitionScheme) GetLUKSDevice ¶ added in v0.6.0
func (s *PartitionScheme) GetLUKSDevice(mapperName string) *LUKSDevice
GetLUKSDevice returns the LUKS device for a given mapper name
func (*PartitionScheme) GetRoot1Device ¶ added in v0.6.0
func (s *PartitionScheme) GetRoot1Device() string
GetRoot1Device returns the device path to use for root1 (mapper or raw partition)
func (*PartitionScheme) GetRoot2Device ¶ added in v0.6.0
func (s *PartitionScheme) GetRoot2Device() string
GetRoot2Device returns the device path to use for root2 (mapper or raw partition)
func (*PartitionScheme) GetVarDevice ¶ added in v0.6.0
func (s *PartitionScheme) GetVarDevice() string
GetVarDevice returns the device path to use for var (mapper or raw partition)
type Reporter ¶ added in v0.16.0
type Reporter interface {
Step(step, total int, name string)
Progress(percent int, message string)
Message(format string, args ...any)
MessagePlain(format string, args ...any)
Warning(format string, args ...any)
Error(err error, message string)
Complete(message string, details any)
IsJSON() bool
}
Reporter is the interface for reporting progress and messages during install and update operations. It has three implementations:
- TextReporter: human-readable text output
- JSONReporter: machine-readable JSON Lines output
- NoopReporter: silently discards all output
type StepFunc ¶ added in v0.16.0
type StepFunc func(ctx context.Context, state *WorkflowState) error
StepFunc is a single step in a workflow.
type SystemConfig ¶
type SystemConfig struct {
ImageRef string `json:"image_ref"` // Container image reference
ImageDigest string `json:"image_digest"` // Container image digest (sha256:...)
Device string `json:"device"` // Installation device (e.g. /dev/sda, /dev/nvme0n1)
DiskID string `json:"disk_id,omitempty"` // Stable disk identifier from /dev/disk/by-id
InstallDate string `json:"install_date"` // Installation timestamp
KernelArgs []string `json:"kernel_args"` // Custom kernel arguments
BootloaderType string `json:"bootloader_type"` // Bootloader type (grub2, systemd-boot)
FilesystemType string `json:"filesystem_type"` // Filesystem type (ext4, btrfs)
Encryption *EncryptionConfig `json:"encryption,omitempty"` // Encryption configuration (nil if not encrypted)
}
SystemConfig represents the system configuration stored in /var/lib/nbc/state/
func ReadSystemConfig ¶
func ReadSystemConfig() (*SystemConfig, error)
ReadSystemConfig reads system configuration from /var/lib/nbc/state/config.json Falls back to legacy location /etc/nbc/config.json for older installations
type SystemUpdater ¶
type SystemUpdater struct {
Config UpdaterConfig
Scheme *PartitionScheme
Active bool // true if root1 is active, false if root2 is active
Target string
TargetMapperName string // For encrypted systems: "root1" or "root2"
TargetMapperPath string // For encrypted systems: "/dev/mapper/root1" or "/dev/mapper/root2"
Progress Reporter
Encryption *EncryptionConfig // Encryption configuration (loaded from system config)
LocalLayoutPath string // Path to OCI layout directory for local image
LocalMetadata *CachedImageMetadata // Metadata from cached image
}
SystemUpdater handles A/B system updates
func NewSystemUpdater ¶
func NewSystemUpdater(device, imageRef string) *SystemUpdater
NewSystemUpdater creates a new SystemUpdater
func (*SystemUpdater) AddKernelArg ¶
func (u *SystemUpdater) AddKernelArg(arg string)
AddKernelArg adds a kernel argument
func (*SystemUpdater) InstallKernelAndInitramfs ¶
func (u *SystemUpdater) InstallKernelAndInitramfs() error
InstallKernelAndInitramfs checks for new kernel and initramfs in the updated root and copies them to the boot partition (which is the combined EFI/boot partition)
func (*SystemUpdater) IsUpdateNeeded ¶
func (u *SystemUpdater) IsUpdateNeeded(short bool) (bool, string, error)
IsUpdateNeeded checks if the remote image differs from the currently installed image. Returns true if an update is needed, false if the system is already up-to-date. Also returns the remote digest for use during the update process.
func (*SystemUpdater) PerformUpdate ¶
func (u *SystemUpdater) PerformUpdate(skipPull bool) error
PerformUpdate performs the complete update workflow
func (*SystemUpdater) PrepareUpdate ¶
func (u *SystemUpdater) PrepareUpdate() error
PrepareUpdate prepares for an update by detecting partitions and determining target
func (*SystemUpdater) PullImage ¶
func (u *SystemUpdater) PullImage() error
PullImage validates the image reference and checks if it's accessible The actual image pull happens during Extract() to avoid duplicate work
func (*SystemUpdater) SetDryRun ¶
func (u *SystemUpdater) SetDryRun(dryRun bool)
SetDryRun enables dry run mode
func (*SystemUpdater) SetForce ¶
func (u *SystemUpdater) SetForce(force bool)
SetForce enables non-interactive mode (skips confirmation)
func (*SystemUpdater) SetJSONOutput ¶ added in v0.2.0
func (u *SystemUpdater) SetJSONOutput(jsonOutput bool)
SetJSONOutput enables JSON output mode
func (*SystemUpdater) SetLocalImage ¶ added in v0.12.0
func (u *SystemUpdater) SetLocalImage(layoutPath string, metadata *CachedImageMetadata)
SetLocalImage sets the local OCI layout path and metadata for offline updates
func (*SystemUpdater) SetVerbose ¶
func (u *SystemUpdater) SetVerbose(verbose bool)
SetVerbose enables verbose output
func (*SystemUpdater) Update ¶
func (u *SystemUpdater) Update() error
Update performs the system update
func (*SystemUpdater) UpdateBootloader ¶
func (u *SystemUpdater) UpdateBootloader() error
UpdateBootloader updates the bootloader to boot from the new partition
type TextReporter ¶ added in v0.16.0
type TextReporter struct {
// contains filtered or unexported fields
}
TextReporter writes human-readable progress text to an io.Writer.
func NewTextReporter ¶ added in v0.16.0
func NewTextReporter(w io.Writer) *TextReporter
NewTextReporter returns a TextReporter that writes to w.
func (*TextReporter) Complete ¶ added in v0.16.0
func (r *TextReporter) Complete(message string, _ any)
func (*TextReporter) Error ¶ added in v0.16.0
func (r *TextReporter) Error(err error, message string)
func (*TextReporter) IsJSON ¶ added in v0.16.0
func (r *TextReporter) IsJSON() bool
func (*TextReporter) Message ¶ added in v0.16.0
func (r *TextReporter) Message(format string, args ...any)
func (*TextReporter) MessagePlain ¶ added in v0.16.0
func (r *TextReporter) MessagePlain(format string, args ...any)
func (*TextReporter) Progress ¶ added in v0.16.0
func (r *TextReporter) Progress(_ int, message string)
func (*TextReporter) Step ¶ added in v0.16.0
func (r *TextReporter) Step(step, total int, name string)
func (*TextReporter) Warning ¶ added in v0.16.0
func (r *TextReporter) Warning(format string, args ...any)
type UpdaterConfig ¶
type UpdaterConfig struct {
Device string
ImageRef string
ImageDigest string // Digest of the remote image (set by IsUpdateNeeded)
FilesystemType string // Filesystem type (ext4, btrfs)
Verbose bool
DryRun bool
Force bool // Skip interactive confirmation
JSONOutput bool
KernelArgs []string
MountPoint string
BootMountPoint string
}
UpdaterConfig holds configuration for system updates
type Workflow ¶ added in v0.16.0
type Workflow struct {
// contains filtered or unexported fields
}
Workflow orchestrates a sequence of named steps with progress reporting and context cancellation.
func NewWorkflow ¶ added in v0.16.0
NewWorkflow creates a Workflow that reports progress via the given Reporter.
type WorkflowState ¶ added in v0.16.0
type WorkflowState struct {
// Device is the target block device path.
Device string
// MountPoint is the temporary mount point for the target filesystem.
MountPoint string
// Scheme holds partition layout information.
Scheme *PartitionScheme
// ImageRef is the container image reference.
ImageRef string
// ImageDigest is the digest of the image being installed/updated.
ImageDigest string
// FilesystemType is "ext4" or "btrfs".
FilesystemType string
// KernelArgs holds additional kernel command line arguments.
KernelArgs []string
// DryRun indicates whether to simulate operations.
DryRun bool
// Verbose enables additional output.
Verbose bool
// Reporter is the output reporter for the workflow.
Reporter Reporter
// Encrypted indicates whether LUKS encryption is enabled.
Encrypted bool
// Passphrase is the LUKS passphrase (if encrypted).
Passphrase string
// TPM2 indicates whether TPM2 auto-unlock is enabled.
TPM2 bool
}
WorkflowState holds shared mutable state passed between workflow steps.