ABRoot

core

import "github.com/vanilla-os/abroot/core"

Overview

Index

Package files

atomic-io.go checks.go chroot.go diff.go disk-manager.go grub.go image-recipe.go image.go integrity.go kargs.go logging.go oci.go package-diff.go packages.go registry.go root.go rsync.go specs.go system.go utils.go

Constants

const (
    DefaultKargs = "quiet splash bgrt_disable $vt_handoff"
    KargsTmpFile = "/tmp/kargs-temp"
)
const (
    PackagesBaseDir       = "/etc/abroot"
    DryRunPackagesBaseDir = "/tmp/abroot"
    PackagesAddFile       = "packages.add"
    PackagesRemoveFile    = "packages.remove"
    PackagesUnstagedFile  = "packages.unstaged"
)
const (
    ADD    = "+"
    REMOVE = "-"
)
const (
    // ABSystem operations
    UPGRADE           = "upgrade"
    FORCE_UPGRADE     = "force-upgrade"
    DRY_RUN_UPGRADE   = "dry-run-upgrade"
    APPLY             = "package-apply"
    DRY_RUN_APPLY     = "dry-run-package-apply"
    INITRAMFS         = "initramfs"
    DRY_RUN_INITRAMFS = "dry-run-initramfs"

    // ABSystem rollback response
    ROLLBACK_UNNECESSARY = "rollback-unnecessary"
    ROLLBACK_SUCCESS     = "rollback-success"
    ROLLBACK_FAILED      = "rollback-failed"
)

Supported ABSystemOperation types

Variables

var (

    // Errors
    ErrNoUpdate error = errors.New("no update available")
)

Common variables and errors used by the ABSystem

var KargsPath = "/etc/abroot/kargs"
var ReservedMounts = []string{
    "/dev",
    "/dev/pts",
    "/proc",
    "/run",
    "/sys",
}

ReservedMounts is a list of mount points from host which should be mounted inside the chroot environment to ensure it works properly in some cases, such as grub-mkconfig

func AtomicRsync

func AtomicRsync(src, dst string, transitionalPath string, finalPath string, excluded []string, keepUnwanted bool) error

AtomicRsync executes the rsync command in an atomic-like manner. It does so by dry-running the rsync, and if it succeeds, it runs the rsync again performing changes. If the keepUnwanted option is set to true, it will omit the –delete option, so that the already existing and unwanted files will not be deleted. To ensure the changes are applied atomically, we rsync on a _new directory first, and use atomicSwap to replace the _new with the dst directory.

func AtomicSwap

func AtomicSwap(src, dst string) error

atomicSwap allows swapping 2 files or directories in-place and atomically, using the renameat2 syscall. This should be used instead of os.Rename, which is not atomic at all

func BaseImagePackageDiff

func BaseImagePackageDiff(currentDigest, newDigest string) (
    added, upgraded, downgraded, removed []diff.PackageDiff,
    err error,
)

BaseImagePackageDiff retrieves the added, removed, upgraded and downgraded base packages (the ones bundled with the image).

func CopyFile

func CopyFile(source, dest string) error

CopyFile copies a file from source to dest

func DeleteImageForRoot

func DeleteImageForRoot(root string) error

DeleteImageForRoot deletes the image created for the provided root

func DiffFiles

func DiffFiles(sourceFile, destFile string) ([]byte, error)

DiffFiles returns the diff lines between source and dest files using the diff command (assuming it is installed). If no diff is found, nil is returned. If any errors occur, they are returned.

func FindImageWithLabel

func FindImageWithLabel(key, value string) (string, error)

FindImageWithLabel returns the name of the first image containing the provided key-value pair or an empty string if none was found

func GetLogFile

func GetLogFile() *os.File

GetLogFile returns the log file handle

func GetRepoContentsForPkg

func GetRepoContentsForPkg(pkg string) (map[string]interface{}, error)

GetRepoContentsForPkg retrieves package information from the repository API

func GetToken

func GetToken() (string, error)

GetToken generates a token using the provided tokenURL and returns it

func IsVerbose

func IsVerbose() bool

IsVerbose checks if verbose mode is enabled

func KargsBackup

func KargsBackup() error

KargsBackup makes a backup of the current kargs file

func KargsEdit

func KargsEdit() (bool, error)

KargsEdit copies the kargs file to a temporary file and opens it in the user’s preferred editor by querying the $EDITOR environment variable. Once closed, its contents are written back to the main kargs file. This function returns a boolean parameter indicating whether any changes were made to the kargs file.

func KargsFormat

func KargsFormat(content string) (string, error)

KargsFormat formats the contents of the kargs file, ensuring that there are no duplicate entries, multiple spaces or trailing newline

func KargsRead

func KargsRead() (string, error)

KargsRead reads the content of the kargs file

func KargsWrite

func KargsWrite(content string) error

KargsWrite makes a backup of the current kargs file and then writes the new content to it

func LogToFile

func LogToFile(msg string, args ...interface{}) error

LogToFile writes messages to the log file

func MergeDiff

func MergeDiff(firstFile, secondFile, destination string) error

MergeDiff merges the diff lines between the first and second files into the destination file. If any errors occur, they are returned.

func OciExportRootFs

func OciExportRootFs(buildImageName string, imageRecipe *ImageRecipe, transDir string, dest string) error

OciExportRootFs generates a rootfs from an image recipe file

func OverlayPackageDiff

func OverlayPackageDiff() (
    added, upgraded, downgraded, removed []diff.PackageDiff,
    err error,
)

OverlayPackageDiff retrieves the added, removed, upgraded and downgraded overlay packages (the ones added manually via abroot pkg add).

func PrintVerbose

func PrintVerbose(prefix, level string, depth float32, args ...interface{})

PrintVerbose prints verbose messages and logs to the file if enabled

func PrintVerboseErr

func PrintVerboseErr(prefix string, depth float32, args ...interface{})

PrintVerboseErr prints verbose error messages and logs to the file if enabled

func PrintVerboseErrNoLog

func PrintVerboseErrNoLog(prefix string, depth float32, args ...interface{})

PrintVerboseErrNoLog prints verbose error messages without logging to the file

func PrintVerboseInfo

func PrintVerboseInfo(prefix string, args ...interface{})

PrintVerboseInfo prints verbose info messages and logs to the file if enabled

func PrintVerboseInfoNoLog

func PrintVerboseInfoNoLog(prefix string, args ...interface{})

PrintVerboseInfoNoLog prints verbose info messages without logging to the file

func PrintVerboseNoLog

func PrintVerboseNoLog(prefix, level string, depth float32, args ...interface{})

PrintVerboseNoLog prints verbose messages without logging to the file

func PrintVerboseSimple

func PrintVerboseSimple(args ...interface{})

PrintVerboseSimple prints simple verbose messages and logs to the file if enabled

func PrintVerboseSimpleNoLog

func PrintVerboseSimpleNoLog(args ...interface{})

PrintVerboseSimpleNoLog prints simple verbose messages without logging to the file

func PrintVerboseWarn

func PrintVerboseWarn(prefix string, depth float32, args ...interface{})

PrintVerboseWarn prints verbose warning messages and logs to the file if enabled

func PrintVerboseWarnNoLog

func PrintVerboseWarnNoLog(prefix string, depth float32, args ...interface{})

PrintVerboseWarnNoLog prints verbose warning messages without logging to the file

func RetrieveImageForRoot

func RetrieveImageForRoot(root string) (string, error)

RetrieveImageForRoot retrieves the image created for the provided root based on the label. Note for distro maintainers: labels must follow those defined in the ABRoot config file

func RootCheck

func RootCheck(display bool) bool

func WriteDiff

func WriteDiff(destFile string, diffLines []byte) error

WriteDiff applies the diff lines to the destination file using the patch command (assuming it is installed). If any errors occur, they are returned.

type ABImage

type ABImage struct {
    Digest    string    `json:"digest"`
    Timestamp time.Time `json:"timestamp"`
    Image     string    `json:"image"`
}

The ABImage is the representation of an OCI image used by ABRoot, it contains the digest, the timestamp and the image name. If you need to investigate the current ABImage on an ABRoot system, you can find it at /abimage.abr

func NewABImage

func NewABImage(digest string, image string) (*ABImage, error)

NewABImage creates a new ABImage instance and returns a pointer to it, if the digest is empty, it returns an error

func NewABImageFromRoot

func NewABImageFromRoot() (*ABImage, error)

NewABImageFromRoot returns the current ABImage by parsing /abimage.abr, if it fails, it returns an error (e.g. if the file doesn’t exist). Note for distro maintainers: if the /abimage.abr is not present, it could mean that the user is running an older version of ABRoot (pre v2) or the root state is corrupted. In the latter case, generating a new ABImage should fix the issue, Digest and Timestamp can be random, but Image should reflect an existing image on the configured Docker registry. Anyway, support on this is not guaranteed, so please don’t open issues about this.

func (*ABImage) WriteTo

func (a *ABImage) WriteTo(dest string, suffix string) error

WriteTo writes the json to a destination path, if the suffix is not empty, it will be appended to the filename

type ABRollbackResponse

type ABRollbackResponse string

ABRollbackResponse represents the response of a rollback operation

type ABRootManager

type ABRootManager struct {
    // Partitions is a list of partitions managed by ABRoot
    Partitions []ABRootPartition

    // VarPartition is the partition where /var is mounted
    VarPartition Partition
}

ABRootManager exposes methods to manage ABRoot partitions, this includes getting the present and future partitions, the boot partition, the init volume (when using LVM Thin-Provisioning), and the other partition. If you need to operate on an ABRoot partition, you should use this struct, each partition is a pointer to a Partition struct, which contains methods to operate on the partition itself

func NewABRootManager

func NewABRootManager() *ABRootManager

NewABRootManager creates a new ABRootManager

func (*ABRootManager) GetBoot

func (a *ABRootManager) GetBoot() (partition Partition, err error)

GetBoot gets the boot partition from the current device

func (*ABRootManager) GetFuture

func (a *ABRootManager) GetFuture() (partition ABRootPartition, err error)

GetFuture gets the future partition

func (*ABRootManager) GetInit

func (a *ABRootManager) GetInit() (partition Partition, err error)

GetInit gets the init volume when using LVM Thin-Provisioning

func (*ABRootManager) GetOther

func (a *ABRootManager) GetOther() (partition ABRootPartition, err error)

GetOther gets the other partition

func (*ABRootManager) GetPartition

func (a *ABRootManager) GetPartition(label string) (partition ABRootPartition, err error)

GetPartition gets a partition by label

func (*ABRootManager) GetPartitions

func (a *ABRootManager) GetPartitions() error

GetPartitions gets the root partitions from the current device

func (*ABRootManager) GetPresent

func (a *ABRootManager) GetPresent() (partition ABRootPartition, err error)

GetPresent gets the present partition

func (*ABRootManager) IdentifyPartition

func (a *ABRootManager) IdentifyPartition(partition Partition) (identifiedAs string, err error)

IdentifyPartition identifies a partition

func (*ABRootManager) IsCurrent

func (a *ABRootManager) IsCurrent(partition Partition) bool

IsCurrent checks if a partition is the current one

type ABRootPartition

type ABRootPartition struct {
    Label        string // Matches `partLabelA` and `partLabelB` settings entries
    IdentifiedAs string // Either `present` or `future`
    Partition    Partition
    MountPoint   string
    MountOptions string
    Uuid         string
    FsType       string
    Current      bool
}

ABRootPartition represents a partition managed by ABRoot

type ABSystem

type ABSystem struct {
    // Checks contains an instance of Checks which allows to perform
    // compatibility checks on the system such as filesystem compatibility,
    // connectivity and root check.
    Checks *Checks

    // RootM contains an instance of the ABRootManager which allows to
    // manage the ABRoot partition scheme.
    RootM *ABRootManager

    // Registry contains an instance of the Registry used to retrieve resources
    // from the configured Docker registry.
    Registry *Registry

    // CurImage contains an instance of ABImage which represents the current
    // image used by the system (abimage.abr).
    CurImage *ABImage
}

An ABSystem allows to perform system operations such as upgrades, package changes and rollback on an ABRoot-compliant system.

func NewABSystem

func NewABSystem() (*ABSystem, error)

NewABSystem initializes a new ABSystem, which contains all the functions to perform system operations such as upgrades, package changes and rollback. It returns a pointer to the initialized ABSystem and an error, if any.

func (*ABSystem) AddToCleanUpQueue

func (s *ABSystem) AddToCleanUpQueue(name string, priority int, values ...interface{})

AddToCleanUpQueue adds a function to the queue

func (*ABSystem) CheckAll

func (s *ABSystem) CheckAll() error

CheckAll performs all checks from the Checks struct

func (*ABSystem) CheckUpdate

func (s *ABSystem) CheckUpdate() (string, bool)

CheckUpdate checks if there is an update available

func (*ABSystem) CreateStageFile

func (s *ABSystem) CreateStageFile() error

CreateStageFile creates the stage file, which is used to determine if the upgrade can be interrupted or not. If the stage file is present, it means that the upgrade is in a state where it is still possible to interrupt it, otherwise it is not. This is useful for third-party applications like update managers.

func (*ABSystem) GenerateCrypttab

func (s *ABSystem) GenerateCrypttab(rootPath string) error

GenerateCrypttab identifies which devices are encrypted and generates the /etc/crypttab file for the specified root

func (*ABSystem) GenerateFstab

func (s *ABSystem) GenerateFstab(rootPath string, root ABRootPartition) error

GenerateFstab generates a fstab file for the future root

func (*ABSystem) GenerateSystemdUnits

func (s *ABSystem) GenerateSystemdUnits(rootPath string, root ABRootPartition) error

GenerateSystemdUnits generates systemd units that mount the mutable parts of the system to their respective mountpoints

func (*ABSystem) LockUpgrade

func (s *ABSystem) LockUpgrade() error

LockUpgrade creates a lock file, preventing upgrades from proceeding

func (*ABSystem) RemoveFromCleanUpQueue

func (s *ABSystem) RemoveFromCleanUpQueue(name string)

RemoveFromCleanUpQueue removes a function from the queue

func (*ABSystem) RemoveStageFile

func (s *ABSystem) RemoveStageFile() error

RemoveStageFile removes the stage file disabling the ability to interrupt the upgrade process

func (*ABSystem) ResetQueue

func (s *ABSystem) ResetQueue()

ResetQueue resets the queue

func (*ABSystem) Rollback

func (s *ABSystem) Rollback() (response ABRollbackResponse, err error)

Rollback swaps the master grub files if the current root is not the default

func (*ABSystem) RunCleanUpQueue

func (s *ABSystem) RunCleanUpQueue(fnName string) error

RunCleanUpQueue runs the functions in the queue or only the specified one

func (*ABSystem) RunOperation

func (s *ABSystem) RunOperation(operation ABSystemOperation) error

RunOperation executes a root-switching operation from the options below:

UPGRADE:
	Upgrades to a new image, if available,
FORCE_UPGRADE:
	Forces the upgrade operation, even if no new image is available,
APPLY:
	Applies package changes, but doesn't update the system.
INITRAMFS:
	Updates the initramfs for the future root, but doesn't update the system.

func (*ABSystem) UnlockUpgrade

func (s *ABSystem) UnlockUpgrade() error

UnlockUpgrade removes the lock file, allowing upgrades to proceed

func (*ABSystem) UpgradeLockExists

func (s *ABSystem) UpgradeLockExists() bool

UpgradeLockExists checks if the lock file exists and returns a boolean

func (*ABSystem) UserLockRequested

func (s *ABSystem) UserLockRequested() bool

UserLockRequested checks if the user lock file exists and returns a boolean note that if the user lock file exists, it means that the user explicitly requested the upgrade to be locked (using an update manager for example)

type ABSystemOperation

type ABSystemOperation string

ABSystemOperation represents a system operation to be performed by the ABSystem, must be given as a parameter to the RunOperation function.

type Checks

type Checks struct{}

Represents a Checks struct which contains all the checks which can be performed one by one or all at once using PerformAllChecks()

func NewChecks

func NewChecks() *Checks

NewChecks returns a new Checks struct

func (*Checks) CheckCompatibilityFS

func (c *Checks) CheckCompatibilityFS() error

CheckCompatibilityFS checks if the filesystem is compatible with ABRoot v2 if not, it returns an error. Note that currently only ext4, btrfs and xfs are supported/tested. Here we assume some utilities are installed, such as findmnt and lsblk

func (*Checks) CheckConnectivity

func (c *Checks) CheckConnectivity() error

CheckConnectivity checks if the system is connected to the internet

func (*Checks) CheckRoot

func (c *Checks) CheckRoot() error

CheckRoot checks if the user is root and returns an error if not

func (*Checks) PerformAllChecks

func (c *Checks) PerformAllChecks() error

PerformAllChecks performs all checks

type Children

type Children struct {
    MountPoint   string     `json:"mountpoint"`
    FsType       string     `json:"fstype"`
    Label        string     `json:"label"`
    Uuid         string     `json:"uuid"`
    LogicalName  string     `json:"name"`
    Size         string     `json:"size"`
    MountOptions string     `json:"mountopts"`
    Children     []Children `json:"children"`
}

The children a block device or partition may have

type Chroot

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

Chroot represents a chroot instance, which can be used to run commands inside a chroot environment

func NewChroot

func NewChroot(root string, rootUuid string, rootDevice string) (*Chroot, error)

NewChroot creates a new chroot environment from the given root path and returns its Chroot instance or an error if something went wrong

func (*Chroot) Close

func (c *Chroot) Close() error

Close unmounts all the bind mounts and closes the chroot environment

func (*Chroot) Execute

func (c *Chroot) Execute(cmd string, args []string) error

Execute runs a command in the chroot environment, the command is a string and the arguments are a list of strings. If an error occurs it is returned.

func (*Chroot) ExecuteCmds

func (c *Chroot) ExecuteCmds(cmds []string) error

ExecuteCmds runs a list of commands in the chroot environment, stops at the first error

type DiskManager

type DiskManager struct{}

DiskManager exposes functions to interact with the system’s disks and partitions (e.g. mount, unmount, get partitions, etc.)

func NewDiskManager

func NewDiskManager() *DiskManager

NewDiskManager creates and returns a pointer to a new DiskManager instance from which you can interact with the system’s disks and partitions

func (*DiskManager) GetPartitionByLabel

func (d *DiskManager) GetPartitionByLabel(label string) (Partition, error)

GetPartitionByLabel finds a partition by searching for its label. If no partition can be found with the given label, returns error.

type GPUInfo

type GPUInfo struct {
    Address     string
    Description string
}

type Grub

type Grub struct {
    PresentRoot string
    FutureRoot  string
}

Grub represents a grub instance, it exposes methods to generate a new grub config compatible with ABRoot, and to check if the system is booted into the present root or the future root

func NewGrub

func NewGrub(bootPart Partition) (*Grub, error)

NewGrub creates a new Grub instance

func (*Grub) IsBootedIntoPresentRoot

func (g *Grub) IsBootedIntoPresentRoot() (bool, error)

type ImageRecipe

type ImageRecipe struct {
    From    string
    Labels  map[string]string
    Args    map[string]string
    Content string
}

An ImageRecipe represents a Dockerfile/Containerfile-like recipe

func NewImageRecipe

func NewImageRecipe(image string, labels map[string]string, args map[string]string, content string) *ImageRecipe

NewImageRecipe creates a new ImageRecipe instance and returns a pointer to it

func (*ImageRecipe) Write

func (c *ImageRecipe) Write(path string) error

Write writes a ImageRecipe to the given path, returning an error if any

type IntegrityCheck

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

func NewIntegrityCheck

func NewIntegrityCheck(root ABRootPartition, repair bool) (*IntegrityCheck, error)

NewIntegrityCheck creates a new IntegrityCheck instance for the given root partition, and returns a pointer to it or an error if something went wrong

func (*IntegrityCheck) Repair

func (ic *IntegrityCheck) Repair() error

Repair repairs the system

type Manifest

type Manifest struct {
    Manifest []byte
    Digest   string
    Layers   []string
}

Manifest is the struct used to parse the manifest response from the registry it contains the manifest itself, the digest and the list of layers. This should be compatible with most registries, but it’s not guaranteed

type PCSpecs

type PCSpecs struct {
    CPU    string
    GPU    []string
    Memory string
}

func GetPCSpecs

func GetPCSpecs() PCSpecs

type PackageManager

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

PackageManager struct

func NewPackageManager

func NewPackageManager(dryRun bool) *PackageManager

NewPackageManager returns a new PackageManager struct

func (*PackageManager) Add

func (p *PackageManager) Add(pkg string) error

Add adds a package to the packages.add file

func (*PackageManager) ClearUnstagedPackages

func (p *PackageManager) ClearUnstagedPackages() error

ClearUnstagedPackages removes all packages from the unstaged list

func (*PackageManager) ExistsInRepo

func (p *PackageManager) ExistsInRepo(pkg string) error

func (*PackageManager) GetAddPackages

func (p *PackageManager) GetAddPackages() ([]string, error)

GetAddPackages returns the packages in the packages.add file

func (*PackageManager) GetAddPackagesString

func (p *PackageManager) GetAddPackagesString(sep string) (string, error)

GetAddPackagesString returns the packages in the packages.add file as a string

func (*PackageManager) GetFinalCmd

func (p *PackageManager) GetFinalCmd(operation ABSystemOperation) string

func (*PackageManager) GetRemovePackages

func (p *PackageManager) GetRemovePackages() ([]string, error)

GetRemovePackages returns the packages in the packages.remove file

func (*PackageManager) GetRemovePackagesString

func (p *PackageManager) GetRemovePackagesString(sep string) (string, error)

GetRemovePackagesString returns the packages in the packages.remove file as a string

func (*PackageManager) GetUnstagedPackages

func (p *PackageManager) GetUnstagedPackages() ([]UnstagedPackage, error)

GetUnstagedPackages returns the package changes that are yet to be applied

func (*PackageManager) GetUnstagedPackagesPlain

func (p *PackageManager) GetUnstagedPackagesPlain() ([]string, error)

GetUnstagedPackagesPlain returns the package changes that are yet to be applied as strings

func (*PackageManager) Remove

func (p *PackageManager) Remove(pkg string) error

Remove removes a package from the packages.add file

type Partition

type Partition struct {
    Label        string
    MountPoint   string
    MountOptions string
    Uuid         string
    FsType       string

    // If standard partition, Device will be the partition's name (e.g. sda1, nvme0n1p1).
    // If LUKS-encrypted or LVM volume, Device will be the name in device-mapper.
    Device string

    // If the partition is LUKS-encrypted or an LVM volume, the logical volume
    // opened in /dev/mapper will be a child of the physical partition in /dev.
    // Otherwise, the partition will be a direct child of the block device, and
    // Parent will be nil.
    //
    // The same logic applies for encrypted LVM volumes. When this is the case,
    // the filesystem hirearchy is as follows:
    //
    //         NAME               FSTYPE
    //   -- sda1                LVM2_member
    //    |-- myVG-myLV         crypto_LUKS
    //      |-- luks-volume     btrfs
    //
    // In this case, the parent of "luks-volume" is "myVG-myLV", which,
    // in turn, has "sda1" as parent. Since "sda1" is a physical partition,
    // its parent is nil.
    Parent *Partition
}

Partition represents either a standard partition or a device-mapper partition, such as an LVM volume

func (*Partition) IsDevMapper

func (p *Partition) IsDevMapper() bool

Returns whether the partition is a device-mapper virtual partition

func (*Partition) IsEncrypted

func (p *Partition) IsEncrypted() bool

IsEncrypted returns whether the partition is encrypted

func (*Partition) Mount

func (p *Partition) Mount(destination string) error

Mount mounts a partition to a directory, returning an error if any occurs

func (*Partition) Unmount

func (p *Partition) Unmount() error

Unmount unmounts a partition

type QueuedFunction

type QueuedFunction struct {
    // The name of the function to be executed, which must match one of the
    // supported functions in the RunCleanUpQueue function.
    Name string

    // The values to be passed to the function.
    Values []interface{}

    // The priority of the function. Functions with lower numbers will be
    // executed first.
    Priority int
}

QueuedFunction represents a function to be executed in the clean up queue

type Registry

type Registry struct {
    API string
}

A Registry instance exposes functions to interact with the configured Docker registry

func NewRegistry

func NewRegistry() *Registry

NewRegistry returns a new Registry instance, exposing functions to interact with the configured Docker registry

func (*Registry) GetManifest

func (r *Registry) GetManifest(token string) (*Manifest, error)

GetManifest returns the manifest of the image, a token is required to perform the request and is generated using GetToken()

func (*Registry) HasUpdate

func (r *Registry) HasUpdate(digest string) (string, bool)

HasUpdate checks if the image/tag from the registry has a different digest it returns the new digest and a boolean indicating if an update is available

type UnstagedPackage

type UnstagedPackage struct {
    Name, Status string
}

An unstaged package is a package that is waiting to be applied to the next root.

Every time a pkg apply or upgrade operation is executed, all unstaged packages are consumed and added/removed in the next root.


Generated by godoc2md