pkg

package
v0.13.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 7, 2026 License: MIT Imports: 29 Imported by: 0

Documentation

Index

Constants

View Source
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"
)
View Source
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"
)
View Source
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"
)
View Source
const (
	SeverityError   = types.SeverityError
	SeverityWarning = types.SeverityWarning
)

Re-export constants for backward compatibility

View Source
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"
)
View Source
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
)
View Source
const (
	EventTypeStep     = types.EventTypeStep
	EventTypeProgress = types.EventTypeProgress
	EventTypeMessage  = types.EventTypeMessage
	EventTypeWarning  = types.EventTypeWarning
	EventTypeError    = types.EventTypeError
	EventTypeComplete = types.EventTypeComplete
)

Re-export constants for backward compatibility

Variables

View Source
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

func AttachLoopback(imagePath string) (string, error)

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

func CheckUpdateNeeded(installedDigest, remoteDigest string) bool

CheckUpdateNeeded compares the installed image digest with the remote image digest Returns true if an update is needed (digests differ), false otherwise

func ChrootCommand

func ChrootCommand(targetDir string, command string, args ...string) error

ChrootCommand runs a command in a chroot environment

func CloseLUKS added in v0.6.0

func CloseLUKS(mapperName string, progress *ProgressReporter) error

CloseLUKS closes a LUKS container

func CreateFstab

func CreateFstab(targetDir string, scheme *PartitionScheme) error

CreateFstab creates an /etc/fstab file with the proper mount points

func CreateLUKSContainer added in v0.6.0

func CreateLUKSContainer(partition, passphrase string, progress *ProgressReporter) error

CreateLUKSContainer creates a LUKS2 container on the given partition

func CreateLoopbackFile added in v0.13.0

func CreateLoopbackFile(imagePath string, sizeGB int, force bool) error

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

func DetachLoopback(device string) error

DetachLoopback detaches a loopback device.

func EnrollTPM2 added in v0.6.0

func EnrollTPM2(partition string, config *LUKSConfig) error

EnrollTPM2 enrolls a TPM2 key for automatic unlock with no PCRs

func EnsureCriticalFilesInOverlay added in v0.8.5

func EnsureCriticalFilesInOverlay(dryRun bool, progress *ProgressReporter) error

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 FormatPartitions

func FormatPartitions(scheme *PartitionScheme, dryRun bool) error

FormatPartitions formats the partitions with appropriate filesystems

func FormatSize

func FormatSize(bytes uint64) string

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

func GetActiveRootPartition() (string, error)

GetActiveRootPartition determines which root partition is currently active

func GetBootDeviceFromPartition

func GetBootDeviceFromPartition(partition string) (string, error)

GetBootDeviceFromPartition extracts the parent disk device from a partition path Example: /dev/sda3 -> /dev/sda, /dev/nvme0n1p3 -> /dev/nvme0n1

func GetCurrentBootDevice

func GetCurrentBootDevice() (string, error)

GetCurrentBootDevice determines the disk device that the system booted from

func GetCurrentBootDeviceInfo

func GetCurrentBootDeviceInfo(verbose bool) (string, error)

GetCurrentBootDeviceInfo returns detailed information about the boot device

func GetDiskByPath

func GetDiskByPath(path string) (string, error)

GetDiskByPath resolves a disk path (handles by-id, by-uuid, etc.)

func GetDiskID added in v0.13.0

func GetDiskID(device string) (string, error)

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) (string, bool, error)

GetInactiveRootPartition returns the inactive root partition given a partition scheme

func GetLUKSUUID added in v0.6.0

func GetLUKSUUID(partition string) (string, error)

GetLUKSUUID retrieves the LUKS container UUID (not filesystem UUID)

func GetPartitionUUID

func GetPartitionUUID(partition string) (string, error)

GetPartitionUUID returns the UUID of a partition

func GetRemoteImageDigest

func GetRemoteImageDigest(imageRef string) (string, error)

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

func InitramfsHasEtcOverlay(initramfsPath string) (bool, error)

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(targetDir string, dryRun bool) 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(targetDir string, dryRun bool, progress *ProgressReporter) 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(targetDir string, dryRun bool, progress *ProgressReporter) 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

func IsBlockDevice(path string) bool

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 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

func LoadImageFromOCILayout(layoutPath string) (v1.Image, error)

LoadImageFromOCILayout loads a container image from an OCI layout directory

func MergeEtcFromActive

func MergeEtcFromActive(targetDir string, activeRootPartition string, dryRun bool, progress *ProgressReporter) 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(scheme *PartitionScheme, mountPoint string, dryRun bool) error

MountPartitions mounts the partitions to a temporary directory

func ParseDeviceName

func ParseDeviceName(device string) (string, error)

ParseDeviceName extracts the base device name without partition number

func ParseOSRelease

func ParseOSRelease(targetDir string) string

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

func ParseSizeGB(sizeStr string) (int, error)

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

func PopulateEtcLower(targetDir string, dryRun bool, progress *ProgressReporter) error

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

func PrepareMachineID(targetDir string, progress *ProgressReporter) error

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 RegenerateInitramfs added in v0.8.0

func RegenerateInitramfs(targetDir string, dryRun bool, verbose bool) 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

func SavePristineEtc(targetDir string, dryRun bool, progress *ProgressReporter) error

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(targetDir, password string, dryRun bool) 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

func SetupEtcOverlay(targetDir string, dryRun bool, progress *ProgressReporter) error

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(targetDir string, dryRun bool, progress *ProgressReporter) 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(scheme *PartitionScheme, passphrase string, dryRun bool, progress *ProgressReporter) error

SetupLUKS creates LUKS containers on root and var partitions Returns the opened LUKS devices (must be closed during cleanup)

func SetupSystemDirectories

func SetupSystemDirectories(targetDir string, progress *ProgressReporter) error

SetupSystemDirectories creates necessary system directories

func SystemLockPath added in v0.13.0

func SystemLockPath() string

SystemLockPath returns the full path to the system lock file

func UnmountPartitions

func UnmountPartitions(mountPoint string, dryRun bool) error

UnmountPartitions unmounts all partitions

func UpdateSystemConfigImageRef

func UpdateSystemConfigImageRef(imageRef, imageDigest string, dryRun bool, progress *ProgressReporter) error

UpdateSystemConfigImageRef updates the image reference and digest in the system config

func ValidateDisk

func ValidateDisk(device string, minSize uint64) error

ValidateDisk checks if a disk is suitable for installation

func ValidateInitramfsSupport added in v0.6.0

func ValidateInitramfsSupport(targetDir string, tpm2Enabled bool) []string

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

func VerifyDiskID(device, expectedDiskID string) (bool, error)

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(targetDir string, dryRun bool) 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

func VerifyExtraction(targetDir string) error

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 WipeDisk

func WipeDisk(device string, dryRun bool) error

WipeDisk securely wipes a disk's partition table

func WriteSystemConfig

func WriteSystemConfig(config *SystemConfig, dryRun bool, progress *ProgressReporter) 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(varMountPoint string, config *SystemConfig, dryRun bool, progress *ProgressReporter) 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 BootcInstaller

type BootcInstaller struct {
	ImageRef        string
	Device          string
	Verbose         bool
	DryRun          bool
	JSONOutput      bool
	KernelArgs      []string
	MountPoint      string
	FilesystemType  string // ext4 or btrfs
	Progress        *ProgressReporter
	Encryption      *LUKSConfig          // Encryption configuration
	LocalLayoutPath string               // Path to OCI layout directory for local image
	LocalMetadata   *CachedImageMetadata // Metadata from cached image
	RootPassword    string               // Root password to set (optional)
}

BootcInstaller handles bootc container installation

func NewBootcInstaller

func NewBootcInstaller(imageRef, device string) *BootcInstaller

NewBootcInstaller creates a new BootcInstaller

func (*BootcInstaller) AddKernelArg

func (b *BootcInstaller) AddKernelArg(arg string)

AddKernelArg adds a kernel argument

func (*BootcInstaller) Install

func (b *BootcInstaller) Install() error

Install performs the bootc installation to the target disk

func (*BootcInstaller) InstallComplete

func (b *BootcInstaller) InstallComplete(skipPull bool) error

InstallComplete performs the complete installation workflow

func (*BootcInstaller) PullImage

func (b *BootcInstaller) 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 (*BootcInstaller) SetDryRun

func (b *BootcInstaller) SetDryRun(dryRun bool)

SetDryRun enables dry run mode

func (*BootcInstaller) SetEncryption added in v0.6.0

func (b *BootcInstaller) SetEncryption(passphrase, keyfile string, tpm2 bool)

SetEncryption enables LUKS encryption with the given passphrase/keyfile and optional TPM2

func (*BootcInstaller) SetFilesystemType

func (b *BootcInstaller) SetFilesystemType(fsType string)

SetFilesystemType sets the filesystem type for root and var partitions

func (*BootcInstaller) SetJSONOutput added in v0.2.0

func (b *BootcInstaller) SetJSONOutput(jsonOutput bool)

SetJSONOutput enables JSON output mode

func (*BootcInstaller) SetLocalImage added in v0.12.0

func (b *BootcInstaller) SetLocalImage(layoutPath string, metadata *CachedImageMetadata)

SetLocalImage sets the local OCI layout path and metadata for offline installation

func (*BootcInstaller) SetMountPoint

func (b *BootcInstaller) SetMountPoint(mountPoint string)

SetMountPoint sets the temporary mount point for installation

func (*BootcInstaller) SetRootPassword added in v0.13.0

func (b *BootcInstaller) SetRootPassword(password string)

SetRootPassword sets the root password to configure during installation

func (*BootcInstaller) SetVerbose

func (b *BootcInstaller) SetVerbose(verbose bool)

SetVerbose enables verbose output

func (*BootcInstaller) Verify

func (b *BootcInstaller) Verify() error

Verify performs post-installation verification

type BootloaderInstaller

type BootloaderInstaller struct {
	Type       BootloaderType
	TargetDir  string
	Device     string
	Scheme     *PartitionScheme
	KernelArgs []string
	OSName     string
	Verbose    bool
	Encryption *LUKSConfig // Encryption configuration
}

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() 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) 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        *ProgressReporter
}

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() 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) 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

func ListDisks

func ListDisks() ([]DiskInfo, error)

ListDisks returns a list of available physical disks

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 EventType added in v0.2.0

type EventType = types.EventType

Type aliases for backward compatibility

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

func AcquireCacheLock() (*FileLock, error)

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

func AcquireCacheLockShared() (*FileLock, error)

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

func AcquireExclusive(lockPath string) (*FileLock, error)

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

func AcquireShared(lockPath string) (*FileLock, error)

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

func AcquireSystemLock() (*FileLock, error)

AcquireSystemLock acquires an exclusive lock for system operations (install/update). Returns a user-friendly error if the lock is already held.

func (*FileLock) Path added in v0.13.0

func (l *FileLock) Path() string

Path returns the path of the lock file

func (*FileLock) Release added in v0.13.0

func (l *FileLock) Release() error

Release releases the lock and closes the underlying file. It is safe to call Release multiple times.

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

type ImageCache struct {
	CacheDir string
	Verbose  bool
}

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() error

Clear removes all cached images

func (*ImageCache) Download added in v0.12.0

func (c *ImageCache) Download(imageRef string) (*CachedImageMetadata, error)

Download pulls a container image and saves it to the cache in OCI layout format

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

func (c *ImageCache) Remove(digestOrPrefix string) error

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 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(partition, mapperName, passphrase string, progress *ProgressReporter) (*LUKSDevice, error)

OpenLUKS opens a LUKS container and returns the device info

func TryTPM2Unlock added in v0.8.4

func TryTPM2Unlock(partition, mapperName string, progress *ProgressReporter) (*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

type LintCheck func(rootDir string, fix bool) []LintIssue

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

type LintIssue = types.LintIssue

func CheckMachineID added in v0.9.0

func CheckMachineID(rootDir string, fix bool) []LintIssue

CheckMachineID checks for a non-empty machine-id

func CheckRandomSeed added in v0.9.0

func CheckRandomSeed(rootDir string, fix bool) []LintIssue

CheckRandomSeed checks for random seed files that should not be in the image

func CheckSSHHostKeys added in v0.9.0

func CheckSSHHostKeys(rootDir string, fix bool) []LintIssue

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

func (l *Linter) RegisterCheck(check LintCheck)

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) SetFix added in v0.10.0

func (l *Linter) SetFix(fix bool)

SetFix enables automatic fixing of issues

func (*Linter) SetQuiet added in v0.9.0

func (l *Linter) SetQuiet(quiet bool)

SetQuiet suppresses all stdout output (for JSON mode)

func (*Linter) SetVerbose added in v0.9.0

func (l *Linter) SetVerbose(verbose bool)

SetVerbose enables verbose output

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(imagePath string, sizeGB int, force bool) (*LoopbackDevice, error)

SetupLoopbackInstall creates a loopback image file and attaches it. Returns the LoopbackDevice for cleanup and the device path for installation.

func (*LoopbackDevice) Cleanup added in v0.13.0

func (l *LoopbackDevice) Cleanup() error

Cleanup detaches the loopback device.

type PartitionInfo

type PartitionInfo struct {
	Device     string
	Size       uint64
	MountPoint string
	FileSystem string
}

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(device string, dryRun bool, progress *ProgressReporter) (*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()

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 ProgressEvent added in v0.2.0

type ProgressEvent = types.ProgressEvent

type ProgressReporter added in v0.2.0

type ProgressReporter struct {
	// contains filtered or unexported fields
}

ProgressReporter handles streaming JSON Lines output for progress updates

func NewProgressReporter added in v0.2.0

func NewProgressReporter(jsonEnabled bool, totalSteps int) *ProgressReporter

NewProgressReporter creates a new progress reporter

func (*ProgressReporter) Complete added in v0.2.0

func (p *ProgressReporter) Complete(message string, details any)

Complete reports successful completion with optional result details

func (*ProgressReporter) Error added in v0.2.0

func (p *ProgressReporter) Error(err error, message string)

Error reports an error

func (*ProgressReporter) IsJSON added in v0.2.0

func (p *ProgressReporter) IsJSON() bool

IsJSON returns true if JSON output is enabled

func (*ProgressReporter) Message added in v0.2.0

func (p *ProgressReporter) Message(format string, args ...any)

Message reports an informational message

func (*ProgressReporter) MessagePlain added in v0.2.0

func (p *ProgressReporter) MessagePlain(format string, args ...any)

MessagePlain reports an informational message without indentation (for non-JSON)

func (*ProgressReporter) Progress added in v0.2.0

func (p *ProgressReporter) Progress(percent int, message string)

Progress reports progress within a step (0-100 percent)

func (*ProgressReporter) Step added in v0.2.0

func (p *ProgressReporter) Step(step int, name string)

Step reports the start of a new step

func (*ProgressReporter) Warning added in v0.2.0

func (p *ProgressReporter) Warning(format string, args ...any)

Warning reports a warning message

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         *ProgressReporter
	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 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

Directories

Path Synopsis
Package types provides JSON output types for nbc commands.
Package types provides JSON output types for nbc commands.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL