From e07546cf2bad63646867706c1e60c2b0fb475ca9 Mon Sep 17 00:00:00 2001 From: Mateus Melchiades Date: Sat, 4 Nov 2023 16:44:54 -0300 Subject: [PATCH] feat: Lvm support --- .github/workflows/go.yml | 21 +- .gitignore | 2 + README.md | 18 ++ RECIPE.md | 114 +++++++++ core/disk.go | 19 +- core/lvm/lv.go | 324 ++++++++++++++++++++++++++ core/lvm/lvm.go | 482 +++++++++++++++++++++++++++++++++++++++ core/lvm/pv.go | 74 ++++++ core/lvm/vg.go | 152 ++++++++++++ core/lvm_test.go | 287 +++++++++++++++++++++++ core/post_install.go | 9 +- core/recipe.go | 409 ++++++++++++++++++++++++++------- debian/control | 1 + go.sum | 146 ++++++++++++ utils/create_test_env.sh | 5 + 15 files changed, 1966 insertions(+), 97 deletions(-) create mode 100644 core/lvm/lv.go create mode 100644 core/lvm/lvm.go create mode 100644 core/lvm/pv.go create mode 100644 core/lvm/vg.go create mode 100644 core/lvm_test.go create mode 100755 utils/create_test_env.sh diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 68fa7ca5..1ce73800 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -1,4 +1,4 @@ -name: Build +name: Build and Test on: push: @@ -7,11 +7,10 @@ on: branches: [ "main" ] jobs: - build: runs-on: ubuntu-latest container: ghcr.io/vanilla-os/pico:main - + steps: - uses: actions/checkout@v4 @@ -23,10 +22,22 @@ jobs: - name: Install build dependencies run: | apt-get update - apt-get install -y gcc pkg-config libbtrfs-dev libdevmapper-dev libgpgme-dev + apt-get install -y gcc pkg-config libbtrfs-dev libdevmapper-dev libgpgme-dev lvm2 - name: Build run: go build -v ./... + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install test dependencies + run: | + curl -s https://raw.githubusercontent.com/89luca89/distrobox/main/install | sudo sh + ./utils/create_test_env.sh + - name: Test - run: go test -v ./... + run: | + distrobox enter -r albius_test -- sudo go test -v ./... diff --git a/.gitignore b/.gitignore index fbf69ba9..3f9e137f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .buildconfig albius + +.vscode/ \ No newline at end of file diff --git a/README.md b/README.md index a96488d2..9554c841 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,8 @@ Some system dependencies are required for building Albius: - `libbtrfs-dev` - `libdevmapper-dev` - `libgpgme-dev` +- `lvm2` +- A C compiler supported by CGo (`gcc`, for example) After the packages listed above have been installed, all that's left to do is run: @@ -141,6 +143,22 @@ run: $ go build ``` +## Testing + +Writing unit tests for new functionality is encouraged to make sure everything +still works. All tests are executed in a loop device created before the +tests are started. To execute the test suite, simply run: + +```sh +$ sudo go test ./... -v +``` + +Sudo is necessary in order to mount the loop device, as well as run some of the +operations. If you're in an immutable base distribution like Vanilla OS and wish +to run the tests in an isolated environment, keep in mind that **the tests need +to be executed in a rootful container**. You can find a script in `utils/create_test_env.sh` +that automatically sets up a container for running Albius by using Distrobox. + ## Running Albius accepts only one positional argument, which is the path for the recipe diff --git a/RECIPE.md b/RECIPE.md index 3bf9b69e..ecb068d2 100644 --- a/RECIPE.md +++ b/RECIPE.md @@ -76,6 +76,120 @@ Same as `format` but encrypts the partition with LUKS2. - *FsType* (`string`): The filesystem for the partition. Can be either `btrfs`, `ext[2,3,4]`, `linux-swap`, `ntfs`\*, `reiserfs`\*, `udf`\*, or `xfs`\*. - *Password* (`string`): The password used to encrypt the partition. +### pvcreate + +Creates a new LVM physical volume from a partition. + +**Accepts**: +- *Partition* (`string`): The partition to use as PV. + +### pvresize + +Resizes an LVM physical volume. + +**Accepts**: +- *PV* (`string`): The physical volume path. +- *Size* (optional `float`): The PV's desired size in MiB. If not provided, the PV will expand to the size of the underlying partition. + +### pvremove + +Remove LVM labels from a partition. + +**Accepts**: +- *PV* (`string`): The physical volume path. + +### vgcreate + +Creates a new LVM volume group. + +**Accepts**: +- *Name* (`string`): The VG name. +- *PVs* (optional `[string]`): List containing paths for PVs to add to the newly created VG. + +### vgrename + +Renames an LVM volume group. + +**Accepts**: +- *OldName* (`string`): The VG's current name. +- *NewName* (`string`): The VG's new name. + +### vgextend + +Adds PVs to an LVM volume group. + +**Accepts**: +- *Name* (`string`): The target VG's name. +- *PVs* (`[string]`): A list containing the paths of the PVs to be included. + +### vgreduce + +Removes PVs to an LVM volume group. + +**Accepts**: +- *Name* (`string`): The target VG's name. +- *PVs* (`[string]`): A list containing the paths of the PVs to be removed. + +### vgremove + +Deletes LVM volume group. + +**Accepts**: +- *Name* (`string`): The volume group name. + +### lvcreate + +Create LVM logical volume. + +**Accepts**: +- *Name* (`string`): Logical volume name. +- *VG* (`string`): Volume group name. +- *Type* (`string`): Logical volume type. See lvcreate(8) for available types. If unsure, use `linear`. +- *Size* (`float` or `string`): Logical volume size in MiB or a string containing a relative size (e.g. "100%FREE"). + +### lvrename + +Renames an LVM logical volume. + +**Accepts**: +- *OldName* (`string`): The LV's current name. +- *NewName* (`string`): The LV's new name. +- *VG* (`string`): Volume group the LV belongs to. + +### lvremove + +Deletes LVM logical volume. + +**Accepts**: +- *Name* (`string`): The logical volume name. + +### make-thin-pool + +Creates a new LVM thin pool from two LVs: one for metadata and another one for the data itself. + +**Accepts**: +- *ThinDataLV* (`string`): The LV for storing data (in format `vg_name/lv_name`). +- *ThinMetaLV* (`string`): The LV for storing pool metadata (in format `vg_name/lv_name`). + +### lvcreate-thin + +Same as `lvcreate`, but creates a thin LV instead. + +**Accepts**: +- *Name* (`string`): Thin logical volume name. +- *VG* (`string`): Volume group name. +- *Size* (`float`): Volume group size in MiB. +- *Thinpool* (`string`): Name of the thin pool to create the LV from. + +### lvm-format + +Same as `format`, but formats an LVM logical volume. + +**Accepts**: +- *Name* (`string`): Thin logical volume name (in format `vg_name/lv_name`). +- *FsType* (`string`): The filesystem for the partition. Can be either `btrfs`, `ext[2,3,4]`, `linux-swap`, `ntfs`\*, `reiserfs`\*, `udf`\*, or `xfs`\*. +- *Label* (optional `string`): An optional filesystem label. If not given, no label will be set. + --- ## Post-Installation diff --git a/core/disk.go b/core/disk.go index 2f421178..e5dccee6 100644 --- a/core/disk.go +++ b/core/disk.go @@ -146,8 +146,8 @@ func (disk *Disk) LabelDisk(label DiskLabel) error { // If fsType is an empty string, the function will skip creating the filesystem. // This can be useful when creating LUKS-encrypted partitions, where the format // operation needs to be executed first. -func (target *Disk) NewPartition(name string, fsType PartitionFs, start, end int64) (*Partition, error) { - createPartCmd := "parted -s %s unit MiB mkpart%s \"%s\" %s %d %s" +func (target *Disk) NewPartition(name string, fsType PartitionFs, start, end int) (*Partition, error) { + createPartCmd := "parted -s %s unit MiB mkpart%s%s %s %d %s" var partType string if target.Label == MSDOS { @@ -163,7 +163,12 @@ func (target *Disk) NewPartition(name string, fsType PartitionFs, start, end int endStr = fmt.Sprint(end) } - err := RunCommand(fmt.Sprintf(createPartCmd, target.Path, partType, name, fsType, start, endStr)) + partName := "" + if name != "" { + partName = fmt.Sprintf(" \"%s\"", name) + } + + err := RunCommand(fmt.Sprintf(createPartCmd, target.Path, partType, partName, fsType, start, endStr)) if err != nil { return nil, fmt.Errorf("Failed to create partition: %s", err) } @@ -192,9 +197,11 @@ func (target *Disk) NewPartition(name string, fsType PartitionFs, start, end int } } - err = newPartition.NamePartition(name) - if err != nil { - return nil, err + if name != "" { + err = newPartition.NamePartition(name) + if err != nil { + return nil, err + } } return newPartition, nil diff --git a/core/lvm/lv.go b/core/lvm/lv.go new file mode 100644 index 00000000..37f1d8a0 --- /dev/null +++ b/core/lvm/lv.go @@ -0,0 +1,324 @@ +package lvm + +import "fmt" + +type Lv struct { + Name, VgName, Pool string + AttrVolType int + AttrPermissions int + AttrAllocPolicy int + AttrFixed int + AttrState int + AttrDevice int + AttrTargetType int + AttrBlocks int + AttrHealth int + AttrSkip int + Size float64 +} + +type LVType string +type LVResizeMode int + +const ( + LV_TYPE_LINEAR = "linear" + LV_TYPE_STRIPED = "striped" + LV_TYPE_SNAPSHOT = "snapshot" + LV_TYPE_RAID = "raid" + LV_TYPE_MIRROR = "mirror" + LV_TYPE_THIN = "thin" + LV_TYPE_THIN_POOL = "thin-pool" + LV_TYPE_VDO = "vdo" + LV_TYPE_VDO_POOL = "vdo-pool" + LV_TYPE_CACHE = "cache" + LV_TYPE_CACHE_POOL = "cache-pool" + LV_TYPE_WRITECACHE = "writecache" +) + +const ( + LV_RESIZE_EXTEND = iota + LV_RESIZE_SHRINK = iota +) + +const ( + LV_ATTR_VOL_TYPE_CACHE = 1 << iota + LV_ATTR_VOL_TYPE_MIRRORED = 1 << iota + LV_ATTR_VOL_TYPE_MIRRORED_NO_INITIAL_SYNC = 1 << iota + LV_ATTR_VOL_TYPE_ORIGIN = 1 << iota + LV_ATTR_VOL_TYPE_ORIGIN_MERGING_SNAPSHOT = 1 << iota + LV_ATTR_VOL_TYPE_RAID = 1 << iota + LV_ATTR_VOL_TYPE_RAID_NO_INITIAL_SYNC = 1 << iota + LV_ATTR_VOL_TYPE_SNAPSHOT = 1 << iota + LV_ATTR_VOL_TYPE_MERGING_SNAPSHOT = 1 << iota + LV_ATTR_VOL_TYPE_PVMOVE = 1 << iota + LV_ATTR_VOL_TYPE_VIRTUAL = 1 << iota + LV_ATTR_VOL_TYPE_IMAGE = 1 << iota + LV_ATTR_VOL_TYPE_IMAGE_OUT_OF_SYNC = 1 << iota + LV_ATTR_VOL_TYPE_MIRROR_LOG_DEVICE = 1 << iota + LV_ATTR_VOL_TYPE_UNDER_CONVERSION = 1 << iota + LV_ATTR_VOL_TYPE_THIN_VOLUME = 1 << iota + LV_ATTR_VOL_TYPE_THIN_POOL = 1 << iota + LV_ATTR_VOL_TYPE_THIN_POOL_DATA = 1 << iota + LV_ATTR_VOL_TYPE_VDO_POOL = 1 << iota + LV_ATTR_VOL_TYPE_VDO_POOL_DATA = 1 << iota + LV_ATTR_VOL_TYPE_METADATA = 1 << iota +) + +const ( + LV_ATTR_PERMISSIONS_WRITEABLE = 1 << iota + LV_ATTR_PERMISSIONS_READONLY = 1 << iota + LV_ATTR_PERMISSIONS_READONLY_NON_RO_VOLUME = 1 << iota +) + +const ( + LV_ATTR_ALLOC_POLICY_ANYWHERE = 1 << iota + LV_ATTR_ALLOC_POLICY_CONTIGUOUS = 1 << iota + LV_ATTR_ALLOC_POLICY_INHERITED = 1 << iota + LV_ATTR_ALLOC_POLICY_CLING = 1 << iota + LV_ATTR_ALLOC_POLICY_NORMAL = 1 << iota +) + +const ( + LV_ATTR_FIXED_MINOR = 1 << iota +) + +const ( + LV_ATTR_STATE_ACTIVE = 1 << iota + LV_ATTR_STATE_HISTORICAL = 1 << iota + LV_ATTR_STATE_SUSPENDED = 1 << iota + LV_ATTR_STATE_INVALID_SNAPSHOT = 1 << iota + LV_ATTR_STATE_INVALID_SUSPENDED_SNAPSHOT = 1 << iota + LV_ATTR_STATE_SNAPSHOT_MERGE_FAILED = 1 << iota + LV_ATTR_STATE_SUSPENDED_SNAPSHOT_MERGE_FAILED = 1 << iota + LV_ATTR_STATE_MAPPED_DEVICE_PRESENT_WITHOUT_TABLES = 1 << iota + LV_ATTR_STATE_MAPPED_DEVICE_PRESENT_WITH_INACTIVE_TABLE = 1 << iota + LV_ATTR_STATE_THIN_POOL_CHECK_NEEDED = 1 << iota + LV_ATTR_STATE_SUSPENDED_THIN_POOL_CHECK_NEEDED = 1 << iota + LV_ATTR_STATE_UNKNOWN = 1 << iota +) + +const ( + LV_ATTR_DEVICE_OPEN = 1 << iota + LV_ATTR_DEVICE_UNKNOWN = 1 << iota +) + +const ( + LV_ATTR_TARGET_TYPE_CACHE = 1 << iota + LV_ATTR_TARGET_TYPE_MIRROR = 1 << iota + LV_ATTR_TARGET_TYPE_RAID = 1 << iota + LV_ATTR_TARGET_TYPE_SNAPSHOT = 1 << iota + LV_ATTR_TARGET_TYPE_THIN = 1 << iota + LV_ATTR_TARGET_TYPE_UNKNOWN = 1 << iota + LV_ATTR_TARGET_TYPE_VIRTUAL = 1 << iota +) + +const ( + LV_ATTR_BLOCKS_ARE_OVERWRITTEN_WITH_ZEROES_BEFORE_USE = 1 << iota +) + +const ( + LV_ATTR_HEALTH_PARTIAL = 1 << iota + LV_ATTR_HEALTH_UNKNOWN = 1 << iota + LV_ATTR_HEALTH_RAID_REFRESH_NEEDED = 1 << iota + LV_ATTR_HEALTH_RAID_MISMATCHES_EXIST = 1 << iota + LV_ATTR_HEALTH_RAID_WRITEMOSTLY = 1 << iota + LV_ATTR_HEALTH_THIN_FAILED = 1 << iota + LV_ATTR_HEALTH_THIN_POOL_OUT_OF_DATA_SPACE = 1 << iota + LV_ATTR_HEALTH_THIN_POOL_METADATA_READ_ONLY = 1 << iota + LV_ATTR_HEALTH_WRITECACHE_ERROR = 1 << iota +) + +const ( + LV_ATTR_SKIP_ACTIVATION = 1 << iota +) + +var ( + AttrVolTypeMap = map[byte]int{ + 'C': LV_ATTR_VOL_TYPE_CACHE, + 'm': LV_ATTR_VOL_TYPE_MIRRORED, + 'M': LV_ATTR_VOL_TYPE_MIRRORED_NO_INITIAL_SYNC, + 'o': LV_ATTR_VOL_TYPE_ORIGIN, + 'O': LV_ATTR_VOL_TYPE_ORIGIN_MERGING_SNAPSHOT, + 'r': LV_ATTR_VOL_TYPE_RAID, + 'R': LV_ATTR_VOL_TYPE_RAID_NO_INITIAL_SYNC, + 's': LV_ATTR_VOL_TYPE_SNAPSHOT, + 'S': LV_ATTR_VOL_TYPE_MERGING_SNAPSHOT, + 'p': LV_ATTR_VOL_TYPE_PVMOVE, + 'v': LV_ATTR_VOL_TYPE_VIRTUAL, + 'i': LV_ATTR_VOL_TYPE_IMAGE, + 'I': LV_ATTR_VOL_TYPE_IMAGE_OUT_OF_SYNC, + 'l': LV_ATTR_VOL_TYPE_MIRROR_LOG_DEVICE, + 'c': LV_ATTR_VOL_TYPE_UNDER_CONVERSION, + 'V': LV_ATTR_VOL_TYPE_THIN_VOLUME, + 't': LV_ATTR_VOL_TYPE_THIN_POOL, + 'T': LV_ATTR_VOL_TYPE_THIN_POOL_DATA, + 'd': LV_ATTR_VOL_TYPE_VDO_POOL, + 'D': LV_ATTR_VOL_TYPE_VDO_POOL_DATA, + 'e': LV_ATTR_VOL_TYPE_METADATA, + '-': 0, + } + + AttrPermissionsMap = map[byte]int{ + 'w': LV_ATTR_PERMISSIONS_WRITEABLE, + 'r': LV_ATTR_PERMISSIONS_READONLY, + 'R': LV_ATTR_PERMISSIONS_READONLY_NON_RO_VOLUME, + '-': 0, + } + + AttrAllocPolicyMap = map[byte]int{ + 'a': LV_ATTR_ALLOC_POLICY_ANYWHERE, + 'c': LV_ATTR_ALLOC_POLICY_CONTIGUOUS, + 'i': LV_ATTR_ALLOC_POLICY_INHERITED, + 'l': LV_ATTR_ALLOC_POLICY_CLING, + 'n': LV_ATTR_ALLOC_POLICY_NORMAL, + '-': 0, + } + + AttrStateMap = map[byte]int{ + 'a': LV_ATTR_STATE_ACTIVE, + 'h': LV_ATTR_STATE_HISTORICAL, + 's': LV_ATTR_STATE_SUSPENDED, + 'I': LV_ATTR_STATE_INVALID_SNAPSHOT, + 'S': LV_ATTR_STATE_INVALID_SUSPENDED_SNAPSHOT, + 'm': LV_ATTR_STATE_SNAPSHOT_MERGE_FAILED, + 'M': LV_ATTR_STATE_SUSPENDED_SNAPSHOT_MERGE_FAILED, + 'd': LV_ATTR_STATE_MAPPED_DEVICE_PRESENT_WITHOUT_TABLES, + 'i': LV_ATTR_STATE_MAPPED_DEVICE_PRESENT_WITH_INACTIVE_TABLE, + 'c': LV_ATTR_STATE_THIN_POOL_CHECK_NEEDED, + 'C': LV_ATTR_STATE_SUSPENDED_THIN_POOL_CHECK_NEEDED, + 'X': LV_ATTR_STATE_UNKNOWN, + '-': 0, + } + + AttrDeviceMap = map[byte]int{ + 'o': LV_ATTR_DEVICE_OPEN, + 'X': LV_ATTR_DEVICE_UNKNOWN, + '-': 0, + } + + AttrTargetTypeMap = map[byte]int{ + 'C': LV_ATTR_TARGET_TYPE_CACHE, + 'm': LV_ATTR_TARGET_TYPE_MIRROR, + 'r': LV_ATTR_TARGET_TYPE_RAID, + 's': LV_ATTR_TARGET_TYPE_SNAPSHOT, + 't': LV_ATTR_TARGET_TYPE_THIN, + 'u': LV_ATTR_TARGET_TYPE_UNKNOWN, + 'v': LV_ATTR_TARGET_TYPE_VIRTUAL, + '-': 0, + } + + AttrHealthMap = map[byte]int{ + 'p': LV_ATTR_HEALTH_PARTIAL, + 'X': LV_ATTR_HEALTH_UNKNOWN, + 'r': LV_ATTR_HEALTH_RAID_REFRESH_NEEDED, + 'm': LV_ATTR_HEALTH_RAID_MISMATCHES_EXIST, + 'w': LV_ATTR_HEALTH_RAID_WRITEMOSTLY, + 'F': LV_ATTR_HEALTH_THIN_FAILED, + 'D': LV_ATTR_HEALTH_THIN_POOL_OUT_OF_DATA_SPACE, + 'M': LV_ATTR_HEALTH_THIN_POOL_METADATA_READ_ONLY, + 'E': LV_ATTR_HEALTH_WRITECACHE_ERROR, + '-': 0, + } +) + +func parseLvAttrs(attrStr string) ([10]int, error) { + attrVolType, ok := AttrVolTypeMap[attrStr[0]] + if !ok { + return [10]int{}, fmt.Errorf("invalid lv_attr: %s", attrStr) + } + attrPermissions, ok := AttrPermissionsMap[attrStr[1]] + if !ok { + return [10]int{}, fmt.Errorf("invalid lv_attr: %s", attrStr) + } + attrAllocPolicy, ok := AttrAllocPolicyMap[attrStr[2]] + if !ok { + return [10]int{}, fmt.Errorf("invalid lv_attr: %s", attrStr) + } + attrFixed := 0 + if attrStr[3] == 'm' { + attrFixed += LV_ATTR_FIXED_MINOR + } else if attrStr[3] != '-' { + return [10]int{}, fmt.Errorf("invalid lv_attr: %s", attrStr) + } + attrState, ok := AttrStateMap[attrStr[4]] + if !ok { + return [10]int{}, fmt.Errorf("invalid lv_attr: %s", attrStr) + } + attrDevice, ok := AttrDeviceMap[attrStr[5]] + if !ok { + return [10]int{}, fmt.Errorf("invalid lv_attr: %s", attrStr) + } + attrTargetType, ok := AttrTargetTypeMap[attrStr[6]] + if !ok { + return [10]int{}, fmt.Errorf("invalid lv_attr: %s", attrStr) + } + attrBlocks := 0 + if attrStr[7] == 'z' { + attrFixed += LV_ATTR_BLOCKS_ARE_OVERWRITTEN_WITH_ZEROES_BEFORE_USE + } else if attrStr[7] != '-' { + return [10]int{}, fmt.Errorf("invalid lv_attr: %s", attrStr) + } + attrHealth, ok := AttrHealthMap[attrStr[8]] + if !ok { + return [10]int{}, fmt.Errorf("invalid lv_attr: %s", attrStr) + } + attrSkip := 0 + if attrStr[9] == 'k' { + attrFixed += LV_ATTR_SKIP_ACTIVATION + } else if attrStr[9] != '-' { + return [10]int{}, fmt.Errorf("invalid lv_attr: %s", attrStr) + } + + return [10]int{attrVolType, attrPermissions, attrAllocPolicy, attrFixed, attrState, attrDevice, attrTargetType, attrBlocks, attrHealth, attrSkip}, nil +} + +// FindLv fetches an LVM logical volume by its name. You can pass the name +// either as a single string (as in `vg_name/lv_name`) or as two separate +// variables, where the first is the VG name and, the second, the LV name. +func FindLv(name string, lvName ...string) (Lv, error) { + var fullName string + if len(lvName) == 0 { + fullName = name + } else { + fullName = name + "/" + lvName[0] + } + + lvs, err := Lvs(fullName) + if err != nil { + return Lv{}, fmt.Errorf("findLv: %v", err) + } + + return lvs[0], nil +} + +func MakeThinPool(poolMetadata, pool interface{}) error { + poolMetadataName, err := extractNameFromLv(poolMetadata) + if err != nil { + return err + } + poolName, err := extractNameFromLv(pool) + if err != nil { + return err + } + + _, err = RunCommand("lvconvert -y --type thin-pool --poolmetadata %s %s", poolMetadataName, poolName) + if err != nil { + return err + } + + return nil +} + +func (l *Lv) Rename(newName string) error { + newLv, err := Lvrename(l.Name, newName, l.VgName) + if err != nil { + return err + } + *l = newLv + + return nil +} + +func (l *Lv) Remove() error { + return Lvremove(l) +} diff --git a/core/lvm/lvm.go b/core/lvm/lvm.go new file mode 100644 index 00000000..ca83b2ba --- /dev/null +++ b/core/lvm/lvm.go @@ -0,0 +1,482 @@ +package lvm + +import ( + "errors" + "fmt" + "os/exec" + "reflect" + "strconv" + "strings" +) + +// LVM command return codes +const ( + ECMD_PROCESSED = iota + 1 + ENO_SUCH_CMD = iota + 1 + EINVALID_CMD_LINE = iota + 1 + EINIT_FAILED = iota + 1 + ECMD_FAILED = iota + 1 +) + +func RunCommand(command string, args ...interface{}) (string, error) { + cmd := exec.Command("sh", "-c", fmt.Sprintf(command, args...)) + out, err := cmd.Output() + + exitErr, ok := err.(*exec.ExitError) + if err != nil && ok { + return strings.TrimSpace(string(out)), fmt.Errorf("lvm.RunCommand: \n%s", string(exitErr.Stderr)) + } + + return strings.TrimSpace(string(out)), err +} + +// pvcreate (create pv) +func Pvcreate(diskLabel string) error { + _, err := RunCommand("pvcreate -y %s", diskLabel) + if err != nil { + return fmt.Errorf("pvcreate: %v", err) + } + + return nil +} + +// pvs (list pvs) +func Pvs(filter ...string) ([]Pv, error) { + filterStr := "" + if len(filter) > 0 { + filterStr = strings.Join(filter, " ") + } + + output, err := RunCommand("pvs --noheadings --units m --nosuffix --separator , %s", filterStr) + if err != nil { + return []Pv{}, fmt.Errorf("pvs: %v", err) + } + + pvList := []Pv{} + pvs := strings.Split(output, "\n") + for _, pv := range pvs { + if !strings.HasPrefix(pv, "/") { + continue + } + + vals := strings.Split(pv, ",") + attrVal, err := parsePvAttrs(vals[3]) + if err != nil { + return []Pv{}, fmt.Errorf("pvs: %v", err) + } + size, err := strconv.ParseFloat(vals[4], 64) + if err != nil { + return []Pv{}, fmt.Errorf("pvs: could not convert %s to float", vals[4]) + } + free, err := strconv.ParseFloat(vals[5], 64) + if err != nil { + return []Pv{}, fmt.Errorf("pvs: could not convert %s to float", vals[5]) + } + + pvList = append(pvList, Pv{ + Path: vals[0], + VgName: vals[1], + PvFmt: vals[2], + Attr: attrVal, + Size: size, + Free: free, + }) + } + + return pvList, nil +} + +// pvresize (resize pv) +func Pvresize(pv interface{}, setPvSize ...float64) error { + pvPaths, err := extractPathsFromPvs(pv) + if err != nil { + return fmt.Errorf("pvresize: %v", err) + } + + setPvSizeOpt := "" + if len(setPvSize) > 0 { + setPvSizeOpt = fmt.Sprintf("--setphysicalvolumesize %fm", setPvSize[0]) + } + + _, err = RunCommand("pvresize -y %s %s", setPvSizeOpt, pvPaths[0]) + if err != nil { + return fmt.Errorf("pvresize: %v", err) + } + + return nil +} + +// pvmove (move phisical extents) +// TODO + +// pvremove (make partition stop being a pv) +func Pvremove(pv interface{}) error { + pvPaths, err := extractPathsFromPvs(pv) + if err != nil { + return fmt.Errorf("pvremove: %v", err) + } + + _, err = RunCommand("pvremove -y %s", pvPaths[0]) + if err != nil { + return fmt.Errorf("pvremove: %v", err) + } + + return nil +} + +// vgcreate (create vg) +func Vgcreate(name string, pvs ...interface{}) error { + pvPaths, err := extractPathsFromPvs(pvs...) + if err != nil { + return fmt.Errorf("vgcreate: %v", err) + } + + _, err = RunCommand("vgcreate %s %s", name, strings.Join(pvPaths, " ")) + if err != nil { + return fmt.Errorf("vgcreate: %v", err) + } + + return nil +} + +// vgs (list vgs) +func Vgs(filter ...string) ([]Vg, error) { + filterStr := "" + if len(filter) > 0 { + filterStr = strings.Join(filter, " ") + } + + output, err := RunCommand("vgs --noheadings --units m --nosuffix --separator , %s", filterStr) + if err != nil { + return []Vg{}, fmt.Errorf("vgs: %v", err) + } + + vgList := []Vg{} + vgs := strings.Split(output, "\n") + for _, vg := range vgs { + if vg == "" { + continue + } + + vals := strings.Split(vg, ",") + attrVal, err := parseVgAttrs(vals[4]) + if err != nil { + return []Vg{}, fmt.Errorf("vgs: %v", err) + } + size, err := strconv.ParseFloat(vals[5], 64) + if err != nil { + return []Vg{}, fmt.Errorf("vgs: could not convert %s to float", vals[4]) + } + free, err := strconv.ParseFloat(vals[6], 64) + if err != nil { + return []Vg{}, fmt.Errorf("vgs: could not convert %s to float", vals[5]) + } + + // Filter Pvs matching Vg + pvs, err := Pvs() + if err != nil { + return []Vg{}, fmt.Errorf("vgs: could not get list of pvs: %v", err) + } + matchedPvs := []Pv{} + for _, pv := range pvs { + if pv.VgName == vals[0] { + matchedPvs = append(matchedPvs, pv) + } + } + + // Filter LVs matching Vg + lvs, err := Lvs() + if err != nil { + return []Vg{}, fmt.Errorf("vgs: could not get list of lvs: %v", err) + } + matchedLvs := []Lv{} + for _, lv := range lvs { + if lv.VgName == vals[0] { + matchedLvs = append(matchedLvs, lv) + } + } + + vgList = append(vgList, Vg{ + Name: vals[0], + Pvs: matchedPvs, + Lvs: matchedLvs, + Attr: attrVal, + Size: size, + Free: free, + }) + } + + return vgList, nil +} + +// vgrename (rename vg) +func Vgrename(oldName, newName string) (Vg, error) { + _, err := RunCommand("vgrename %s %s", oldName, newName) + if err != nil { + return Vg{}, fmt.Errorf("vgrename: %v", err) + } + + newVg, err := Vgs(newName) + if err != nil { + return Vg{}, fmt.Errorf("vgrename: %v", err) + } + + return newVg[0], nil +} + +// vgextend (add pv to vg) +func Vgextend(vg interface{}, pvs ...interface{}) error { + if len(pvs) == 0 { + return errors.New("vgextend: No PVs were provided") + } + + vgName, err := extractNameFromVg(vg) + if err != nil { + return fmt.Errorf("vgextend: %v", err) + } + pvPaths, err := extractPathsFromPvs(pvs...) + if err != nil { + return fmt.Errorf("vgextend: %v", err) + } + + _, err = RunCommand("vgextend %s %s", vgName, strings.Join(pvPaths, " ")) + if err != nil { + return fmt.Errorf("vgextend: %v", err) + } + + return nil +} + +// vgreduce (remove pv from vg) +func Vgreduce(vg interface{}, pvs ...interface{}) error { + if len(pvs) == 0 { + return errors.New("vgreduce: No PVs were provided") + } + + vgName, err := extractNameFromVg(vg) + if err != nil { + return fmt.Errorf("vgreduce: %v", err) + } + pvPaths, err := extractPathsFromPvs(pvs...) + if err != nil { + return fmt.Errorf("vgreduce: %v", err) + } + + _, err = RunCommand("vgreduce %s %s", vgName, strings.Join(pvPaths, " ")) + if err != nil { + return fmt.Errorf("vgreduce: %v", err) + } + + return nil +} + +// vgremove (remove vg) +func Vgremove(vg interface{}) error { + vgName, err := extractNameFromVg(vg) + if err != nil { + return fmt.Errorf("vgremove: %v", err) + } + + _, err = RunCommand("vgremove -y %s", vgName) + if err != nil { + return fmt.Errorf("vgremove: %v", err) + } + + return nil +} + +// lvcreate (create lv) +func Lvcreate(name string, vg interface{}, lvType LVType, size interface{}) error { + vgName, err := extractNameFromVg(vg) + if err != nil { + return fmt.Errorf("lvcreate: %v", err) + } + + sizeStr := "" + switch sizeVar := size.(type) { + case string: + sizeStr = "-l" + sizeVar + case float64: + sizeStr = fmt.Sprintf("-L %.2fm", sizeVar) + case int: + sizeStr = fmt.Sprintf("-L %dm", sizeVar) + default: + return fmt.Errorf("lvcreate: expected either string, int, or float64 for size, got %s", reflect.TypeOf(size)) + } + + _, err = RunCommand("lvcreate -y --type %s %s %s -n %s", lvType, sizeStr, vgName, name) + if err != nil { + return fmt.Errorf("lvcreate: %v", err) + } + + return nil +} + +func LvThinCreate(name string, vg, pool interface{}, size float64) error { + vgName, err := extractNameFromVg(vg) + if err != nil { + return fmt.Errorf("lvmThinCreate: %v", err) + } + + poolName, err := extractNameFromPool(pool) + if err != nil { + return fmt.Errorf("lvmThinCreate: %v", err) + } + + _, err = RunCommand("lvcreate -y -n %s -V %.2fm --thinpool %s %s", name, size, poolName, vgName) + if err != nil { + return fmt.Errorf("lvmThinCreate: %v", err) + } + + return nil +} + +// lvs (list lvs) +func Lvs(filter ...string) ([]Lv, error) { + filterStr := "" + if len(filter) > 0 { + filterStr = strings.Join(filter, " ") + } + + output, err := RunCommand("lvs --noheadings --units m --nosuffix --separator , %s", filterStr) + if err != nil { + return []Lv{}, fmt.Errorf("lvs: %v", err) + } + + lvList := []Lv{} + lvs := strings.Split(output, "\n") + for _, lv := range lvs { + if lv == "" { + continue + } + + vals := strings.Split(lv, ",") + attrs, err := parseLvAttrs(vals[2]) + if err != nil { + return []Lv{}, fmt.Errorf("lvs: %v", err) + } + + size, err := strconv.ParseFloat(vals[3], 64) + if err != nil { + return []Lv{}, fmt.Errorf("lvs: could not convert %s to float", vals[5]) + } + + lvList = append(lvList, Lv{ + Name: vals[0], + VgName: vals[1], + Pool: vals[4], + AttrVolType: attrs[0], + AttrPermissions: attrs[1], + AttrAllocPolicy: attrs[2], + AttrFixed: attrs[3], + AttrState: attrs[4], + AttrDevice: attrs[5], + AttrTargetType: attrs[6], + AttrBlocks: attrs[7], + AttrHealth: attrs[8], + AttrSkip: attrs[9], + Size: size, + }) + } + + return lvList, nil +} + +// lvrename (rename lv) +func Lvrename(oldName, newName string, vg interface{}) (Lv, error) { + vgName, err := extractNameFromVg(vg) + if err != nil { + return Lv{}, fmt.Errorf("lvrename: %v", err) + } + + _, err = RunCommand("lvrename %s %s %s", vgName, oldName, newName) + if err != nil { + return Lv{}, fmt.Errorf("lvrename: %v", err) + } + + newLv, err := Lvs(vgName + "/" + newName) + if err != nil { + return Lv{}, fmt.Errorf("lvrename: %v", err) + } + + return newLv[0], nil +} + +// lvresize (resize lv and fs) +// TODO: Need to implement a function to resize filesystems first +// func Lvresize(lv interface{}, mode LVResizeMode, sizeOffset float64) error { +// return nil +// } + +// lvremove (remove lv) +func Lvremove(lv interface{}) error { + lvName, err := extractNameFromLv(lv) + if err != nil { + return fmt.Errorf("lvremove: %v", err) + } + + _, err = RunCommand("lvremove -y %s", lvName) + if err != nil { + return fmt.Errorf("lvremove: %v", err) + } + + return nil +} + +func extractPathsFromPvs(pvs ...interface{}) ([]string, error) { + pvPaths := []string{} + for _, pv := range pvs { + switch pvar := pv.(type) { + case string: + pvPaths = append(pvPaths, pvar) + case *Pv: + pvPaths = append(pvPaths, pvar.Path) + default: + return nil, errors.New("invalid type for pv. Must be either a string with the PV's path or a pointer to a PV struct") + } + } + + return pvPaths, nil +} + +func extractNameFromVg(vg interface{}) (string, error) { + var vgName string + switch vgvar := vg.(type) { + case string: + vgName = vgvar + case *Vg: + vgName = vgvar.Name + default: + return "", errors.New("invalid type for vg. Must be either a string with the VG's name or a pointer to a VG struct") + } + + return vgName, nil +} + +func extractNameFromLv(lv interface{}) (string, error) { + var lvName string + switch lvar := lv.(type) { + case string: + lvName = lvar + case *Lv: + lvName = lvar.VgName + "/" + lvar.Name + default: + return "", errors.New("invalid type for lv. Must be either a string with the LV's path ([group_name]/[lv_name]) or a pointer to a LV struct") + } + + return lvName, nil +} + +func extractNameFromPool(pool interface{}) (string, error) { + var poolName string + switch lvar := pool.(type) { + case string: + poolName = lvar + case *Lv: + poolName = lvar.Name + default: + return "", errors.New("invalid type for pool. Must be either a string with the pool's name or a pointer to a LV struct") + } + + return poolName, nil +} diff --git a/core/lvm/pv.go b/core/lvm/pv.go new file mode 100644 index 00000000..5315253f --- /dev/null +++ b/core/lvm/pv.go @@ -0,0 +1,74 @@ +package lvm + +import "fmt" + +type Pv struct { + Path, VgName, PvFmt string + Attr int + Size, Free float64 +} + +// PV attributes +const ( + PV_ATTR_MISSING = 1 << iota + PV_ATTR_EXPORTED = 1 << iota + PV_ATTR_DUPLICATE = 1 << iota + PV_ATTR_ALLOCATABLE = 1 << iota + PV_ATTR_USED = 1 << iota +) + +func parsePvAttrs(attrStr string) (int, error) { + attrVal := 0 + if attrStr[2] != '-' { + attrVal += PV_ATTR_MISSING + } + if attrStr[1] != '-' { + attrVal += PV_ATTR_EXPORTED + } + switch attrStr[0] { + case 'd': + attrVal += PV_ATTR_DUPLICATE + case 'a': + attrVal += PV_ATTR_ALLOCATABLE + case 'u': + attrVal += PV_ATTR_USED + case '-': + default: + return -1, fmt.Errorf("invalid pv_attr: %s", attrStr) + } + + return attrVal, nil +} + +func FindPv(path string) (Pv, error) { + pvs, err := Pvs(path) + if err != nil { + return Pv{}, fmt.Errorf("findPv: %v", err) + } + + return pvs[0], nil +} + +func (p *Pv) Remove() error { + return Pvremove(p) +} + +func (p *Pv) IsMissing() bool { + return p.Attr&PV_ATTR_MISSING > 0 +} + +func (p *Pv) IsExported() bool { + return p.Attr&PV_ATTR_EXPORTED > 0 +} + +func (p *Pv) IsDuplicate() bool { + return p.Attr&PV_ATTR_DUPLICATE > 0 +} + +func (p *Pv) IsAllocatable() bool { + return p.Attr&PV_ATTR_ALLOCATABLE > 0 +} + +func (p *Pv) IsUsed() bool { + return p.Attr&PV_ATTR_USED > 0 +} diff --git a/core/lvm/vg.go b/core/lvm/vg.go new file mode 100644 index 00000000..d60d7e3e --- /dev/null +++ b/core/lvm/vg.go @@ -0,0 +1,152 @@ +package lvm + +import "fmt" + +type Vg struct { + Name string + Pvs []Pv + Lvs []Lv + Attr int + Size, Free float64 +} + +// VG attributes +const ( + VG_ATTR_WRITABLE = 1 << iota + VG_ATTR_READONLY = 1 << iota + VG_ATTR_RESIZABLE = 1 << iota + VG_ATTR_EXPORTED = 1 << iota + VG_ATTR_PARTIAL = 1 << iota + VG_ATTR_CONTIGUOUS = 1 << iota + VG_ATTR_CLING = 1 << iota + VG_ATTR_NORMAL = 1 << iota + VG_ATTR_ANYWHERE = 1 << iota + VG_ATTR_CLUSTERED = 1 << iota + VG_ATTR_SHARED = 1 << iota +) + +func parseVgAttrs(attrStr string) (int, error) { + attrVal := 0 + switch attrStr[5] { + case 'c': + attrVal += VG_ATTR_CLUSTERED + case 's': + attrVal += VG_ATTR_SHARED + case '-': + default: + return -1, fmt.Errorf("invalid vg_attr: %s", attrStr) + } + switch attrStr[4] { + case 'c': + attrVal += VG_ATTR_CONTIGUOUS + case 'l': + attrVal += VG_ATTR_CLING + case 'n': + attrVal += VG_ATTR_NORMAL + case 'a': + attrVal += VG_ATTR_ANYWHERE + default: + return -1, fmt.Errorf("invalid vg_attr: %s", attrStr) + } + if attrStr[3] != '-' { + attrVal += VG_ATTR_PARTIAL + } + if attrStr[2] != '-' { + attrVal += VG_ATTR_EXPORTED + } + if attrStr[1] != '-' { + attrVal += VG_ATTR_RESIZABLE + } + switch attrStr[0] { + case 'w': + attrVal += VG_ATTR_WRITABLE + case 'r': + attrVal += VG_ATTR_READONLY + default: + return -1, fmt.Errorf("invalid vg_attr: %s", attrStr) + } + + return attrVal, nil +} + +func FindVg(name string) (Vg, error) { + vgs, err := Vgs(name) + if err != nil { + return Vg{}, fmt.Errorf("findVg: %v", err) + } + + return vgs[0], nil +} + +// TODO: Add vgchange commands: +// (de)activate (-a), +// max logical volumes (-l), +// max phisical volumes (-p) +// set resizable (-x) +// autobackup (-A) + +func (v *Vg) Rename(newName string) error { + newVg, err := Vgrename(v.Name, newName) + if err != nil { + return err + } + *v = newVg + + return nil +} + +func (v *Vg) Extend(pvs ...interface{}) error { + return Vgextend(v, pvs...) +} + +func (v *Vg) Reduce(pvs ...interface{}) error { + return Vgreduce(v, pvs...) +} + +func (v *Vg) Remove() error { + return Vgremove(v) +} + +func (v *Vg) IsWritable() bool { + return v.Attr&VG_ATTR_WRITABLE > 0 +} + +func (v *Vg) IsReadonly() bool { + return v.Attr&VG_ATTR_READONLY > 0 +} + +func (v *Vg) IsResizable() bool { + return v.Attr&VG_ATTR_RESIZABLE > 0 +} + +func (v *Vg) IsExported() bool { + return v.Attr&VG_ATTR_EXPORTED > 0 +} + +func (v *Vg) IsPartial() bool { + return v.Attr&VG_ATTR_PARTIAL > 0 +} + +func (v *Vg) IsContiguous() bool { + return v.Attr&VG_ATTR_CONTIGUOUS > 0 +} + +func (v *Vg) IsCling() bool { + return v.Attr&VG_ATTR_CLING > 0 +} + +func (v *Vg) IsNormal() bool { + return v.Attr&VG_ATTR_NORMAL > 0 +} + +func (v *Vg) IsAnywhere() bool { + return v.Attr&VG_ATTR_ANYWHERE > 0 +} + +func (v *Vg) IsClustered() bool { + return v.Attr&VG_ATTR_CLUSTERED > 0 +} + +func (v *Vg) IsShared() bool { + return v.Attr&VG_ATTR_SHARED > 0 +} diff --git a/core/lvm_test.go b/core/lvm_test.go new file mode 100644 index 00000000..36c9ac5c --- /dev/null +++ b/core/lvm_test.go @@ -0,0 +1,287 @@ +package albius + +import ( + "fmt" + "os" + "os/exec" + "testing" + + "github.com/vanilla-os/albius/core/lvm" +) + +var ( + device string + lvmpart string +) + +func TestMain(m *testing.M) { + // Setup testing device + // Create dummy image + cmd := exec.Command("dd", "if=/dev/zero", "of=test.img", "count=102400") + if err := cmd.Run(); err != nil { + panic("error while creating testing device image: " + err.Error()) + } + // Mount dummy image as loop device + cmd = exec.Command("losetup", "--find", "--show", "test.img") + cmd.Stderr = os.Stderr + ret, err := cmd.Output() + if err != nil { + panic("error while mounting loop device: " + err.Error()) + } + device = string(ret) + device = device[:len(device)-1] + + // Create device label and add some partitions + albiusDevice, err := LocateDisk(device) + if err != nil { + panic("error finding loop device: " + err.Error()) + } + err = albiusDevice.LabelDisk(GPT) + if err != nil { + panic("error adding label to loop device: " + err.Error()) + } + _, err = albiusDevice.NewPartition("", EXT4, 1, 25) + if err != nil { + panic("error creating partition A in loop device: " + err.Error()) + } + _, err = albiusDevice.NewPartition("", EXT4, 26, -1) + if err != nil { + panic("error creating partition B in loop device: " + err.Error()) + } + lvmpart = device + "p" + + // Run tests + status := m.Run() + + // Remove testing device + cmd = exec.Command("losetup", "-d", device) + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + panic("error while detaching testing device: " + err.Error()) + } + err = os.Remove("test.img") + if err != nil { + panic("error while removing testing device image: " + err.Error()) + } + + // Cleanup + os.Exit(status) +} + +func TestPvcreate(t *testing.T) { + err := lvm.Pvcreate(lvmpart + "1") + if err != nil { + t.Error(err) + } +} + +func TestPvs(t *testing.T) { + pvs, err := lvm.Pvs() + fmt.Printf(" -> Returned: %v\n", pvs) + if err != nil { + t.Error(err) + } +} + +func TestPvResize(t *testing.T) { + pvs, err := lvm.Pvs() + if err != nil { + t.Error(err) + } + err = lvm.Pvresize(&pvs[0]) + if err != nil { + t.Error(err) + } +} + +func TestPvShrink(t *testing.T) { + pvs, err := lvm.Pvs() + if err != nil { + t.Error(err) + } + err = lvm.Pvresize(&pvs[0], 10.0) + if err != nil { + t.Error(err) + } + + pvs, err = lvm.Pvs() + fmt.Printf(" -> New size: %v\n", pvs) + if err != nil { + t.Error(err) + } +} + +func TestPvRemoveStr(t *testing.T) { + err := lvm.Pvremove(lvmpart + "1") + if err != nil { + t.Error(err) + } +} + +func TestPvRemoveStruct(t *testing.T) { + // Recreate PV removed by previous test + err := lvm.Pvcreate(lvmpart + "1") + if err != nil { + t.Error(err) + } + + pvs, err := lvm.Pvs(lvmpart + "1") + if err != nil { + t.Error(err) + } + + err = lvm.Pvremove(&pvs[0]) + if err != nil { + t.Error(err) + } +} + +func TestVgCreate(t *testing.T) { + // Create two testing PVs + err := lvm.Pvcreate(lvmpart + "1") + if err != nil { + t.Error(err) + } + err = lvm.Pvcreate(lvmpart + "2") + if err != nil { + t.Error(err) + } + + // Pass one PV as struct and another as string + pvs, err := lvm.Pvs(lvmpart + "1") + if err != nil { + t.Error(err) + } + + err = lvm.Vgcreate("MyTestingVG", &pvs[0], lvmpart+"2") + if err != nil { + t.Error(err) + } +} + +func TestVgs(t *testing.T) { + vgs, err := lvm.Vgs() + fmt.Printf(" -> Returned: %v\n", vgs) + if err != nil { + t.Error(err) + } +} + +func TestVgrename(t *testing.T) { + // Retrieve Vg + vgs, err := lvm.Vgs() + if err != nil { + t.Error(err) + } + + err = vgs[0].Rename("MyTestingVG1") + if err != nil { + t.Error(err) + } + + vgs, err = lvm.Vgs("MyTestingVG1") + fmt.Printf(" -> Returned: %v\n", vgs) + if err != nil { + t.Error(err) + } +} + +func TestVgReduce(t *testing.T) { + // Retrieve Vg + vgs, err := lvm.Vgs() + if err != nil { + t.Error(err) + } + + err = vgs[0].Reduce(lvmpart + "2") + if err != nil { + t.Error(err) + } + + // Retrieve Vg + vgs, err = lvm.Vgs() + fmt.Printf(" -> Returned: %v\n", vgs) + if err != nil { + t.Error(err) + } +} + +func TestVgExtend(t *testing.T) { + // Retrieve Vg + vgs, err := lvm.Vgs() + if err != nil { + t.Error(err) + } + + err = vgs[0].Extend(lvmpart + "2") + if err != nil { + t.Error(err) + } + + // Retrieve Vg + vgs, err = lvm.Vgs() + fmt.Printf(" -> Returned: %v\n", vgs) + if err != nil { + t.Error(err) + } +} + +func TestLvCreate(t *testing.T) { + err := lvm.Lvcreate("MyLv0", "MyTestingVG1", lvm.LV_TYPE_LINEAR, 30) + if err != nil { + t.Error(err) + } +} + +func TestLvs(t *testing.T) { + lvs, err := lvm.Lvs() + fmt.Printf(" -> Returned: %v\n", lvs) + if err != nil { + t.Error(err) + } +} + +func TestLvrename(t *testing.T) { + // Retrieve Lv + lv, err := lvm.FindLv("MyTestingVG1", "MyLv0") + if err != nil { + t.Error(err) + } + + err = lv.Rename("MyLv1") + if err != nil { + t.Error(err) + } + + lv, err = lvm.FindLv("MyTestingVG1", "MyLv1") + fmt.Printf(" -> Returned: %v\n", lv) + if err != nil { + t.Error(err) + } +} + +func TestLvRemove(t *testing.T) { + // Retrieve Lv + lv, err := lvm.FindLv("MyTestingVG1", "MyLv1") + if err != nil { + t.Error(err) + } + + err = lv.Remove() + if err != nil { + t.Error(err) + } +} + +func TestVgRemove(t *testing.T) { + // Retrieve Vg + vg, err := lvm.FindVg("MyTestingVG1") + if err != nil { + t.Error(err) + } + + err = vg.Remove() + if err != nil { + t.Error(err) + } +} diff --git a/core/post_install.go b/core/post_install.go index 38059f5e..8666eb02 100644 --- a/core/post_install.go +++ b/core/post_install.go @@ -9,7 +9,7 @@ import ( ) func SetTimezone(targetRoot, tz string) error { - tzPath := targetRoot + "/etc/timezone\n" + tzPath := targetRoot + "/etc/timezone" err := os.WriteFile(tzPath, []byte(tz), 0644) if err != nil { @@ -30,14 +30,13 @@ func SetTimezone(targetRoot, tz string) error { } func AddUser(targetRoot, username, fullname string, groups []string, withPassword bool, password ...string) error { - // TODO: "adduser" isn't distro agnostic. Change to "useradd"? - adduserCmd := "adduser --quiet --disabled-password --shell /bin/bash --gecos \"%s\" %s" + adduserCmd := "useradd --shell /bin/bash %s && usermod -c \"%s\" %s" var err error if targetRoot != "" { - err = RunInChroot(targetRoot, fmt.Sprintf(adduserCmd, fullname, username)) + err = RunInChroot(targetRoot, fmt.Sprintf(adduserCmd, username, fullname, username)) } else { - err = RunCommand(fmt.Sprintf(adduserCmd, fullname, username)) + err = RunCommand(fmt.Sprintf(adduserCmd, username, fullname, username)) } if err != nil { return fmt.Errorf("Failed to create user: %s", err) diff --git a/core/recipe.go b/core/recipe.go index 169226e2..560588ec 100644 --- a/core/recipe.go +++ b/core/recipe.go @@ -5,10 +5,11 @@ import ( "fmt" "os" "path/filepath" - "reflect" "regexp" "strconv" "strings" + + "github.com/vanilla-os/albius/core/lvm" ) const ( @@ -55,36 +56,13 @@ type PostStep struct { func ReadRecipe(path string) (*Recipe, error) { content, err := os.ReadFile(path) if err != nil { - return nil, fmt.Errorf("Failed to read recipe: %s", err) + return nil, fmt.Errorf("failed to read recipe: %s", err) } var recipe Recipe - dec := json.NewDecoder(strings.NewReader(string(content))) - dec.DisallowUnknownFields() - dec.UseNumber() - err = dec.Decode(&recipe) + err = json.Unmarshal(content, &recipe) if err != nil { - return nil, fmt.Errorf("Failed to read recipe: %s", err) - } - - // Convert json.Number to int64 - for i := 0; i < len(recipe.Setup); i++ { - step := &recipe.Setup[i] - formattedParams := []interface{}{} - for _, param := range step.Params { - var dummy json.Number - dummy = "1" - if reflect.TypeOf(param) == reflect.TypeOf(dummy) { - convertedParam, err := param.(json.Number).Int64() - if err != nil { - return nil, fmt.Errorf("Failed to convert recipe parameter: %s", err) - } - formattedParams = append(formattedParams, convertedParam) - } else { - formattedParams = append(formattedParams, param) - } - } - step.Params = formattedParams + return nil, fmt.Errorf("failed to read recipe: %s", err) } return &recipe, nil @@ -109,7 +87,7 @@ func runSetupOperation(diskLabel, operation string, args []interface{}) error { label := DiskLabel(args[0].(string)) err = disk.LabelDisk(label) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } /* !! ### mkpart * @@ -131,17 +109,17 @@ func runSetupOperation(diskLabel, operation string, args []interface{}) error { case "mkpart": name := args[0].(string) fsType := PartitionFs(args[1].(string)) - start := args[2].(int64) - end := args[3].(int64) + start := int(args[2].(float64)) + end := int(args[3].(float64)) if len(args) > 4 && strings.HasPrefix(string(fsType), "luks-") { luksPassword := args[4].(string) part, err := disk.NewPartition(name, "", start, end) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } err = LuksFormat(part, luksPassword) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } // lsblk seems to take a few milliseconds to update the partition's // UUID, so we loop until it gives us one @@ -150,25 +128,25 @@ func runSetupOperation(diskLabel, operation string, args []interface{}) error { uuid, err = part.GetUUID() } if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } err = LuksOpen(part, fmt.Sprintf("luks-%s", uuid), luksPassword) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } part.Filesystem = PartitionFs(strings.TrimPrefix(string(fsType), "luks-")) err = LUKSMakeFs(part) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } err = LUKSSetLabel(part, name) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } } else { _, err := disk.NewPartition(name, fsType, start, end) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } } /* !! ### rm @@ -181,11 +159,11 @@ func runSetupOperation(diskLabel, operation string, args []interface{}) error { case "rm": partNum, err := strconv.Atoi(args[0].(string)) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } err = disk.Partitions[partNum-1].RemovePartition() if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } /* !! ### resizepart * @@ -198,15 +176,15 @@ func runSetupOperation(diskLabel, operation string, args []interface{}) error { case "resizepart": partNum, err := strconv.Atoi(args[0].(string)) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } partNewSize, err := strconv.Atoi(args[1].(string)) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } err = disk.Partitions[partNum-1].ResizePartition(partNewSize) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } /* !! ### namepart * @@ -219,19 +197,19 @@ func runSetupOperation(diskLabel, operation string, args []interface{}) error { case "namepart": partNum, err := strconv.Atoi(args[0].(string)) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } partNewName := args[1].(string) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } err = disk.Partitions[partNum-1].SetLabel(partNewName) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } err = disk.Partitions[partNum-1].NamePartition(partNewName) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } /* !! ### setflag * @@ -246,11 +224,11 @@ func runSetupOperation(diskLabel, operation string, args []interface{}) error { case "setflag": partNum, err := strconv.Atoi(args[0].(string)) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } err = disk.Partitions[partNum-1].SetPartitionFlag(args[1].(string), args[2].(bool)) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } /* !! ### format * @@ -263,13 +241,13 @@ func runSetupOperation(diskLabel, operation string, args []interface{}) error { case "format": partNum, err := strconv.Atoi(args[0].(string)) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } filesystem := args[1].(string) disk.Partitions[partNum-1].Filesystem = PartitionFs(filesystem) err = MakeFs(&disk.Partitions[partNum-1]) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } /* !! ### luks-format * @@ -283,7 +261,7 @@ func runSetupOperation(diskLabel, operation string, args []interface{}) error { case "luks-format": partNum, err := strconv.Atoi(args[0].(string)) if err != nil { - return fmt.Errorf("Failed to execute operation %s: %s", operation, err) + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } filesystem := args[1].(string) password := args[2].(string) @@ -291,15 +269,271 @@ func runSetupOperation(diskLabel, operation string, args []interface{}) error { part.Filesystem = PartitionFs(filesystem) err = LuksFormat(&part, password) if err != nil { - return err + return fmt.Errorf("failed to execute operation %s: %s", operation, err) } err = LUKSMakeFs(&part) if err != nil { - return err + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### pvcreate + * + * Creates a new LVM physical volume from a partition. + * + * **Accepts**: + * - *Partition* (`string`): The partition to use as PV. + */ + case "pvcreate": + part := args[0].(string) + err := lvm.Pvcreate(part) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### pvresize + * + * Resizes an LVM physical volume. + * + * **Accepts**: + * - *PV* (`string`): The physical volume path. + * - *Size* (optional `float`): The PV's desired size in MiB. If not provided, the PV will expand to the size of the underlying partition. + */ + case "pvresize": + part := args[0].(string) + var err error + if len(args) > 1 { + size := args[1].(float64) + err = lvm.Pvresize(part, size) + } else { + err = lvm.Pvresize(part) + } + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### pvremove + * + * Remove LVM labels from a partition. + * + * **Accepts**: + * - *PV* (`string`): The physical volume path. + */ + case "pvremove": + part := args[0].(string) + err := lvm.Pvremove(part) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### vgcreate + * + * Creates a new LVM volume group. + * + * **Accepts**: + * - *Name* (`string`): The VG name. + * - *PVs* (optional `[string]`): List containing paths for PVs to add to the newly created VG. + */ + case "vgcreate": + name := args[0].(string) + pvs := []string{} + if len(args) > 1 { + for _, pv := range args[1].([]interface{}) { + pvs = append(pvs, pv.(string)) + } + } + pvList := make([]interface{}, len(pvs)) + for i, p := range pvs { + pvList[i] = p + } + err := lvm.Vgcreate(name, pvList...) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### vgrename + * + * Renames an LVM volume group. + * + * **Accepts**: + * - *OldName* (`string`): The VG's current name. + * - *NewName* (`string`): The VG's new name. + */ + case "vgrename": + oldName := args[0].(string) + newName := args[1].(string) + _, err := lvm.Vgrename(oldName, newName) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### vgextend + * + * Adds PVs to an LVM volume group. + * + * **Accepts**: + * - *Name* (`string`): The target VG's name. + * - *PVs* (`[string]`): A list containing the paths of the PVs to be included. + */ + case "vgextend": + name := args[0].(string) + pvs := []string{} + for _, pv := range args[1].([]interface{}) { + pvs = append(pvs, pv.(string)) + } + pvList := make([]interface{}, len(pvs)) + for i, p := range pvs { + pvList[i] = p + } + err := lvm.Vgextend(name, pvList...) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### vgreduce + * + * Removes PVs to an LVM volume group. + * + * **Accepts**: + * - *Name* (`string`): The target VG's name. + * - *PVs* (`[string]`): A list containing the paths of the PVs to be removed. + */ + case "vgreduce": + name := args[0].(string) + pvs := []string{} + for _, pv := range args[1].([]interface{}) { + pvs = append(pvs, pv.(string)) + } + pvList := make([]interface{}, len(pvs)) + for i, p := range pvs { + pvList[i] = p + } + err := lvm.Vgreduce(name, pvList...) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### vgremove + * + * Deletes LVM volume group. + * + * **Accepts**: + * - *Name* (`string`): The volume group name. + */ + case "vgremove": + name := args[0].(string) + err := lvm.Vgremove(name) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### lvcreate + * + * Create LVM logical volume. + * + * **Accepts**: + * - *Name* (`string`): Logical volume name. + * - *VG* (`string`): Volume group name. + * - *Type* (`string`): Logical volume type. See lvcreate(8) for available types. If unsure, use `linear`. + * - *Size* (`float` or `string`): Logical volume size in MiB or a string containing a relative size (e.g. "100%FREE"). + */ + case "lvcreate": + name := args[0].(string) + vg := args[1].(string) + lvType := args[2].(string) + vgSize := args[3] + err := lvm.Lvcreate(name, vg, lvm.LVType(lvType), vgSize) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### lvrename + * + * Renames an LVM logical volume. + * + * **Accepts**: + * - *OldName* (`string`): The LV's current name. + * - *NewName* (`string`): The LV's new name. + * - *VG* (`string`): Volume group the LV belongs to. + */ + case "lvrename": + oldName := args[0].(string) + newName := args[1].(string) + vg := args[2].(string) + _, err := lvm.Lvrename(oldName, newName, vg) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### lvremove + * + * Deletes LVM logical volume. + * + * **Accepts**: + * - *Name* (`string`): The logical volume name. + */ + case "lvremove": + name := args[0].(string) + err := lvm.Lvremove(name) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### make-thin-pool + * + * Creates a new LVM thin pool from two LVs: one for metadata and another one for the data itself. + * + * **Accepts**: + * - *ThinDataLV* (`string`): The LV for storing data (in format `vg_name/lv_name`). + * - *ThinMetaLV* (`string`): The LV for storing pool metadata (in format `vg_name/lv_name`). + */ + case "make-thin-pool": + thinDataLV := args[0].(string) + thinMetaLV := args[1].(string) + err := lvm.MakeThinPool(thinMetaLV, thinDataLV) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### lvcreate-thin + * + * Same as `lvcreate`, but creates a thin LV instead. + * + * **Accepts**: + * - *Name* (`string`): Thin logical volume name. + * - *VG* (`string`): Volume group name. + * - *Size* (`float`): Volume group size in MiB. + * - *Thinpool* (`string`): Name of the thin pool to create the LV from. + */ + case "lvcreate-thin": + name := args[0].(string) + vg := args[1].(string) + vgSize := args[2].(float64) + thinPool := args[3].(string) + err := lvm.LvThinCreate(name, vg, thinPool, vgSize) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + /* !! ### lvm-format + * + * Same as `format`, but formats an LVM logical volume. + * + * **Accepts**: + * - *Name* (`string`): Thin logical volume name (in format `vg_name/lv_name`). + * - *FsType* (`string`): The filesystem for the partition. Can be either `btrfs`, `ext[2,3,4]`, `linux-swap`, `ntfs`\*, `reiserfs`\*, `udf`\*, or `xfs`\*. + * - *Label* (optional `string`): An optional filesystem label. If not given, no label will be set. + */ + case "lvm-format": + name := args[0].(string) + filesystem := args[1].(string) + lv, err := lvm.FindLv(name) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + dummyPart := Partition{ + Path: "/dev/" + lv.VgName + "/" + lv.Name, + Filesystem: PartitionFs(filesystem), + } + err = MakeFs(&dummyPart) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } + if len(args) == 3 { + label := args[2].(string) + err := dummyPart.SetLabel(label) + if err != nil { + return fmt.Errorf("failed to execute operation %s: %s", operation, err) + } } /* !! --- */ default: - return fmt.Errorf("Unrecognized operation %s", operation) + return fmt.Errorf("unrecognized operation %s", operation) } return nil @@ -481,7 +715,7 @@ func runPostInstallOperation(chroot bool, operation string, args []interface{}) case "efi": grubTarget = EFI default: - return fmt.Errorf("Failed to execute operation: %s: Unrecognized firmware type: '%s')", operation, target) + return fmt.Errorf("failed to execute operation: %s: Unrecognized firmware type: '%s')", operation, target) } err := RunGrubInstall(targetRoot, bootDirectory, installDevice, grubTarget, efiDevice) if err != nil { @@ -551,7 +785,7 @@ func runPostInstallOperation(chroot bool, operation string, args []interface{}) return err } default: - return fmt.Errorf("Unrecognized operation %s", operation) + return fmt.Errorf("unrecognized operation %s", operation) } return nil @@ -572,9 +806,6 @@ func (recipe *Recipe) SetupMountpoints() error { diskCache := map[string]*Disk{} rootAMounted := false - diskExpr := regexp.MustCompile("^/dev/[a-zA-Z]+([0-9]+[a-z][0-9]+)?") - partExpr := regexp.MustCompile("[0-9]+$") - /* We need to mount the partitions in order to prevent one mountpoint * from overriding another. * For example, if we mount /boot first in /mnt/a/boot and then mount / in @@ -596,33 +827,49 @@ func (recipe *Recipe) SetupMountpoints() error { mount_depth += 1 } + lvmExpr := regexp.MustCompile(`^/dev/(?P[\w-]+)/(?P[\w-]+)$`) + diskExpr := regexp.MustCompile("^/dev/[a-zA-Z]+([0-9]+[a-z][0-9]+)?") + partExpr := regexp.MustCompile("[0-9]+$") + for _, mnt := range ordered_mountpoints { - diskName := diskExpr.FindString(mnt.Partition) - part := partExpr.FindString(mnt.Partition) + baseRoot := RootA + if mnt.Target == "/" && rootAMounted { + baseRoot = RootB + } else if mnt.Target == "/" && !rootAMounted { + rootAMounted = true + } - disk, ok := diskCache[diskName] - if !ok { - diskPtr, err := LocateDisk(diskName) + // LVM partition + if lvmExpr.MatchString(mnt.Partition) { + lvmPartition := Partition{ + Number: -1, + Path: mnt.Partition, + } + err := lvmPartition.Mount(baseRoot + mnt.Target) if err != nil { return err } - diskCache[diskName] = diskPtr - disk = diskCache[diskName] + continue } - partInt, err := strconv.Atoi(part) + // Regular partition + diskName := diskExpr.FindString(mnt.Partition) + part, err := strconv.Atoi(partExpr.FindString(mnt.Partition)) if err != nil { return err } - baseRoot := RootA - if mnt.Target == "/" && rootAMounted { - baseRoot = RootB - } else if mnt.Target == "/" && !rootAMounted { - rootAMounted = true + disk, ok := diskCache[diskName] + if !ok { + diskPtr, err := LocateDisk(diskName) + if err != nil { + return err + } + diskCache[diskName] = diskPtr + disk = diskCache[diskName] } - err = disk.Partitions[partInt-1].Mount(baseRoot + mnt.Target) + err = disk.Partitions[part-1].Mount(baseRoot + mnt.Target) if err != nil { return err } @@ -731,50 +978,50 @@ func (recipe *Recipe) Install() error { return err } default: - return fmt.Errorf("Unsupported installation method '%s'", recipe.Installation.Method) + return fmt.Errorf("unsupported installation method '%s'", recipe.Installation.Method) } // Setup crypttab (if needed) crypttabEntries, err := recipe.setupCrypttabEntries() if err != nil { - return fmt.Errorf("Failed to generate crypttab entries: %s", err) + return fmt.Errorf("failed to generate crypttab entries: %s", err) } if len(crypttabEntries) > 0 { err = GenCrypttab(RootA, crypttabEntries) if err != nil { - return fmt.Errorf("Failed to generate crypttab: %s", err) + return fmt.Errorf("failed to generate crypttab: %s", err) } } // Setup fstab fstabEntries, err := recipe.setupFstabEntries() if err != nil { - return fmt.Errorf("Failed to generate fstab entries: %s", err) + return fmt.Errorf("failed to generate fstab entries: %s", err) } err = GenFstab(RootA, fstabEntries) if err != nil { - return fmt.Errorf("Failed to generate fstab: %s", err) + return fmt.Errorf("failed to generate fstab: %s", err) } // Initramfs pre-scripts for _, preCmd := range recipe.Installation.InitramfsPre { err := RunInChroot(RootA, preCmd) if err != nil { - return fmt.Errorf("Initramfs pre-script '%s' failed: %s", preCmd, err) + return fmt.Errorf("initramfs pre-script '%s' failed: %s", preCmd, err) } } // Update Initramfs err = UpdateInitramfs(RootA) if err != nil { - return fmt.Errorf("Failed to update initramfs: %s", err) + return fmt.Errorf("failed to update initramfs: %s", err) } // Initramfs post-scripts for _, postCmd := range recipe.Installation.InitramfsPost { err := RunInChroot(RootA, postCmd) if err != nil { - return fmt.Errorf("Initramfs post-script '%s' failed: %s", postCmd, err) + return fmt.Errorf("initramfs post-script '%s' failed: %s", postCmd, err) } } diff --git a/debian/control b/debian/control index 2b5aed36..b9503b66 100644 --- a/debian/control +++ b/debian/control @@ -7,6 +7,7 @@ Build-Depends: debhelper (>= 9), libbtrfs-dev, libdevmapper-dev, libgpgme-dev, + lvm2, dh-golang, golang-go, gcc, diff --git a/go.sum b/go.sum index 007b0a9d..23e0bb70 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,25 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.10.0-rc.7 h1:HBytQPxcv8Oy4244zbQbe6hnOnx544eL5QPUqhJldz8= github.com/Microsoft/hcsshim v0.10.0-rc.7/go.mod h1:ILuwjA+kNW+MrN/w5un7n3mTqkwsFu4Bp05/okFUZlE= +github.com/Microsoft/hcsshim v0.10.0 h1:PbvoxdUGgXxyirmN5Oncp3POLkxEG5LbWCEBfWmHTGA= +github.com/Microsoft/hcsshim v0.10.0/go.mod h1:3j1trOamcUdi86J5Tr5+1BpqMjSv/QeRWkX2whBF6dY= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= @@ -39,30 +49,49 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/container-orchestrated-devices/container-device-interface v0.5.4 h1:PqQGqJqQttMP5oJ/qNGEg8JttlHqGY3xDbbcKb5T9E8= github.com/container-orchestrated-devices/container-device-interface v0.5.4/go.mod h1:DjE95rfPiiSmG7uVXtg0z6MnPm/Lx4wxKCIts0ZE0vg= +github.com/container-orchestrated-devices/container-device-interface v0.6.0 h1:aWwcz/Ep0Fd7ZuBjQGjU/jdPloM7ydhMW13h85jZNvk= +github.com/container-orchestrated-devices/container-device-interface v0.6.0/go.mod h1:OQlgtJtDrOxSQ1BWODC8OZK1tzi9W69wek+Jy17ndzo= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= +github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0= +github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.7.0 h1:G/ZQr3gMZs6ZT0qPUZ15znx5QSdQdASW11nXTLTM2Pg= github.com/containerd/containerd v1.7.0/go.mod h1:QfR7Efgb/6X2BDpTPJRvPTYDE9rsF0FsXX9J8sIs/sc= +github.com/containerd/containerd v1.7.5 h1:i9T9XpAWMe11BHMN7pu1BZqOGjXaKTPyz2v+KYOZgkY= +github.com/containerd/containerd v1.7.5/go.mod h1:ieJNCSzASw2shSGYLHx8NAE7WsZ/gEigo5fQ78W5Zvw= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ= github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= github.com/containernetworking/plugins v1.2.0 h1:SWgg3dQG1yzUo4d9iD8cwSVh1VqI+bP7mkPDoSfP9VU= github.com/containernetworking/plugins v1.2.0/go.mod h1:/VjX4uHecW5vVimFa1wkG4s+r/s9qIfPdqlLF4TW8c4= +github.com/containernetworking/plugins v1.3.0 h1:QVNXMT6XloyMUoO2wUOqWTC1hWFV62Q6mVDp5H1HnjM= +github.com/containernetworking/plugins v1.3.0/go.mod h1:Pc2wcedTQQCVuROOOaLBPPxrEXqqXBFt3cZ+/yVg6l0= github.com/containers/buildah v1.30.0 h1:mdp2COGKFFEZNEGP8VZ5ITuUFVNPFoH+iK2sSesNfTA= github.com/containers/buildah v1.30.0/go.mod h1:lyMLZIevpAa6zSzjRl7z4lFJMCMQLFjfo56YIefaB/U= +github.com/containers/buildah v1.31.3 h1:M+lvvaAKPTEx+WvlTOl6E6L/RDXGrsjSLfb1Ph162eo= +github.com/containers/buildah v1.31.3/go.mod h1:GZ7ZmrwOkA92q8w1SduCSVmXJkGfOQwPdllx4nV15x8= github.com/containers/common v0.52.0 h1:S5GApgpNEGBuPhDHTFgMc55y5gsuxHcQeElvUpO5kp4= github.com/containers/common v0.52.0/go.mod h1:dNJJVNBu1wJtAH+vFIMXV+fQHBdEVNmNP3ImjbKper4= +github.com/containers/common v0.55.4 h1:7IxB/G5qtDU+rp1YiVWkDpd+ZC4ZlCQ7k2jZJYkB/R8= +github.com/containers/common v0.55.4/go.mod h1:5mVCpfMBWyO+zaD7Fw+DBHFa42YFKROwle1qpEKcX3U= github.com/containers/image/v5 v5.25.0 h1:TJ0unmalbU+scd0i3Txap2wjGsAnv06MSCwgn6bsizk= github.com/containers/image/v5 v5.25.0/go.mod h1:EKvys0WVlRFkDw26R8y52TuhV9Tfn0yq2luLX6W52Ls= +github.com/containers/image/v5 v5.27.0 h1:4jKVWAa4YurTWUyAWMoC71zJkSylBR7pWd0jqGkukYc= +github.com/containers/image/v5 v5.27.0/go.mod h1:IwlOGzTkGnmfirXxt0hZeJlzv1zVukE03WZQ203Z9GA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.1.7 h1:thhNr4fu2ltyGz8aMx8u48Ae0Pnbip3ePP9/mzkZ/3U= github.com/containers/ocicrypt v1.1.7/go.mod h1:7CAhjcj2H8AYp5YvEie7oVSK2AhBY8NscCYRawuDNtw= +github.com/containers/ocicrypt v1.1.8 h1:saSBF0/8DyPUjzcxMVzL2OBUWCkvRvqIm75pu0ADSZk= +github.com/containers/ocicrypt v1.1.8/go.mod h1:jM362hyBtbwLMWzXQZTlkjKGAQf/BN/LFMtH0FIRt34= github.com/containers/storage v1.46.1 h1:GcAe8J0Y6T2CF70fXPojUpnme6zXamuzGCrNujVtIGE= github.com/containers/storage v1.46.1/go.mod h1:81vNDX4h+nXJ2o0D6Yqy6JGXDYJGVpHZpz0nr09iJuQ= +github.com/containers/storage v1.49.0 h1:7Vqj8OKlwlcWZ4U61+eS2bNwyIG/qXQo/UZVW5kXn74= +github.com/containers/storage v1.49.0/go.mod h1:fCvGMWQ0BOvlReQf9DqRAcl73ofTfRXE8l6ifnI4a3g= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -70,6 +99,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7 h1:vU+EP9ZuFUCYE0NYLwTSob+3LNEJATzNfP/DC7SWGWI= github.com/cyberphone/json-canonicalization v0.0.0-20220623050100-57a0ce2678a7/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= +github.com/cyberphone/json-canonicalization v0.0.0-20230710064741-aa7fe85c7dbd h1:0av0vtcjA8Hqv5gyWj79CLCFVwOOyBNWPjrfUWceMNg= +github.com/cyberphone/json-canonicalization v0.0.0-20230710064741-aa7fe85c7dbd/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -81,8 +112,12 @@ github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m3 github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v23.0.3+incompatible h1:9GhVsShNWz1hO//9BNg/dpMnZW25KydO4wtVxWAIbho= github.com/docker/docker v23.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= +github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= +github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8= +github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 h1:IPrmumsT9t5BS7XcPhgsCTlkWbYg80SEXUzDpReaU6Y= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11/go.mod h1:a6bNUGTbQBsY6VRHTr4h/rkOXjl244DyRD0tx3fgq4Q= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -102,6 +137,10 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsouza/go-dockerclient v1.9.7 h1:FlIrT71E62zwKgRvCvWGdxRD+a/pIy+miY/n3MXgfuw= github.com/fsouza/go-dockerclient v1.9.7/go.mod h1:vx9C32kE2D15yDSOMCDaAEIARZpDQDFBHeqL3MgQy/U= +github.com/fsouza/go-dockerclient v1.9.8 h1:UdfyV4/w8VthS2VS0muJqUSPL/e6XSj49jqPnbuUOWA= +github.com/fsouza/go-dockerclient v1.9.8/go.mod h1:74lNReDQxrOaogajs51IvZgkDME4qe9yPJAUEUTJtHw= +github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= +github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= @@ -111,12 +150,19 @@ github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpX github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= +github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M= +github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= +github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= @@ -136,6 +182,8 @@ github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/ github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -202,6 +250,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-containerregistry v0.14.0 h1:z58vMqHxuwvAsVwvKEkmVBz2TlgBgH5k6koEXBtlYkw= github.com/google/go-containerregistry v0.14.0/go.mod h1:aiJ2fp/SXvkWgmYHioXnbMdlgB8eXiiYOY55gfN91Wk= +github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ= +github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= github.com/google/go-intervals v0.0.2 h1:FGrVEiUnTRKR8yE04qzXYaJMtnIYqobR5QbblK3ixcM= github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCjbbr4TQlcT6Y= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -212,6 +262,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -225,12 +277,17 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= +github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548 h1:dYTbLf4m0a5u0KLmPfB6mgxbcV7588bOCx79hxa5Sr4= +github.com/jmhodges/clock v1.2.0 h1:eq4kys+NI0PLngzaHEe7AmPT90XMGIEySD1JfV1PDIs= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -243,8 +300,12 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/pgzip v1.2.6-0.20220930104621-17e8dac29df8 h1:BcxbplxjtczA1a6d3wYoa7a0WL3rq9DKBMGHeKyjEF0= github.com/klauspost/pgzip v1.2.6-0.20220930104621-17e8dac29df8/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= +github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -256,6 +317,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/letsencrypt/boulder v0.0.0-20230213213521-fdfea0d469b6 h1:unJdfS94Y3k85TKy+mvKzjW5R9rIC+Lv4KGbE7uNu0I= github.com/letsencrypt/boulder v0.0.0-20230213213521-fdfea0d469b6/go.mod h1:PUgW5vI9ANEaV6qv9a6EKu8gAySgwf0xrzG9xIB/CK0= +github.com/letsencrypt/boulder v0.0.0-20230901174017-fa028b4394c5 h1:mr0whDphVg0YFTCHZnUDK5qHkGAQvPwV2UlAky/TIOY= +github.com/letsencrypt/boulder v0.0.0-20230901174017-fa028b4394c5/go.mod h1:vQ6/VAT97qxojPu1StGn+R0FtW/ZTOKVkLvdnURRDV8= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -267,6 +330,8 @@ github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsI github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -274,12 +339,16 @@ github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs/v3 v3.0.0 h1:J5QK618xRcXnQYZ2GE5FdmpS1ufIrWue+lR/mpe6/14= github.com/mistifyio/go-zfs/v3 v3.0.0/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k= +github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU= +github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= @@ -287,6 +356,8 @@ github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5 github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/term v0.0.0-20221120202655-abb19827d345 h1:J9c53/kxIH+2nTKBEfZYFMlhghtHpIHSXpm5VRGHSnU= github.com/moby/term v0.0.0-20221120202655-abb19827d345/go.mod h1:15ce4BGCFxt7I5NQKT+HV0yEDxmf6fSysfEDiVo3zFM= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -317,11 +388,17 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= +github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/runc v1.1.9 h1:XR0VIHTGce5eWPkaPesqTBrhW2yAcaraWfsEalNwQLM= +github.com/opencontainers/runc v1.1.9/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0-rc.1 h1:wHa9jroFfKGQqFHj0I1fMRKLl0pfj+ynAqBxo3v6u9w= github.com/opencontainers/runtime-spec v1.1.0-rc.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= +github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-tools v0.9.1-0.20230317050512-e931285f4b69 h1:NL4xDvl68WWqQ+8WPMM3l5PsZTxaT7Z4K3VSKDRuAGs= github.com/opencontainers/runtime-tools v0.9.1-0.20230317050512-e931285f4b69/go.mod h1:bNpfuSHA3DZRtD0TPWO8LzgtLpFPTVA/3jDkzD/OPyk= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= @@ -329,6 +406,8 @@ github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaL github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/openshift/imagebuilder v1.2.4-0.20230309135844-a3c3f8358ca3 h1:JMtosRja+FqjYFtYk439be/g0DeysMu25sI5PISmVEY= github.com/openshift/imagebuilder v1.2.4-0.20230309135844-a3c3f8358ca3/go.mod h1:k1mq/1hUuymyinjudQds8a9YcR+JGib6/9JQWvr5ql8= +github.com/openshift/imagebuilder v1.2.5 h1:dby0N3FTouXSBgWNf+gfTkj36fAb8g4iL/SRw1eNAoo= +github.com/openshift/imagebuilder v1.2.5/go.mod h1:bF4w79W8nM+jH1QkAiHSUVaqHkMBJGijafZxCJEHH5o= github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f h1:/UDgs8FGMqwnHagNDPGOlts35QkhAZ8by3DR7nMih7M= github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= @@ -341,10 +420,13 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/proglottis/gpgme v0.1.3 h1:Crxx0oz4LKB3QXc5Ea0J19K/3ICfy3ftr5exgUK1AU0= github.com/proglottis/gpgme v0.1.3/go.mod h1:fPbW/EZ0LvwQtH8Hy7eixhp1eF3G39dtx7GUN+0Gmy0= github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -362,10 +444,16 @@ github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sigstore/fulcio v1.2.0 h1:I4H764cDbryKXkPtasUvo8bcix/7xLvkxWYWNp+JtWI= github.com/sigstore/fulcio v1.2.0/go.mod h1:FS7qpBvOEqs0uEh1+hJxzxtJistWN29ybLtAzFNUi0c= +github.com/sigstore/fulcio v1.4.0 h1:05+k8BFvwTQzfCkVxESWzCN4b70KIRliGYz0Upmdrs8= +github.com/sigstore/fulcio v1.4.0/go.mod h1:wcjlktbhoy6+ZTxO3yXpvqUxsLV+JEH4FF3a5Jz4VPI= github.com/sigstore/rekor v1.2.0 h1:ahlnoEY3zo8Vc+eZLPobamw6YfBTAbI0lthzUQd6qe4= github.com/sigstore/rekor v1.2.0/go.mod h1:zcFO54qIg2G1/i0sE/nvmELUOng/n0MPjTszRYByVPo= +github.com/sigstore/rekor v1.3.0 h1:meiQhvzb7B4CwmRgGAHnsExoyf2fiGnXUNgm7rOHPIg= +github.com/sigstore/rekor v1.3.0/go.mod h1:aZH9c2g4nZS/+IfVm6WWhwRIY7In5TdUX7jfG4moI+E= github.com/sigstore/sigstore v1.6.4 h1:jH4AzR7qlEH/EWzm+opSpxCfuUcjHL+LJPuQE7h40WE= github.com/sigstore/sigstore v1.6.4/go.mod h1:pjR64lBxnjoSrAr+Ydye/FV73IfrgtoYlAI11a8xMfA= +github.com/sigstore/sigstore v1.7.3 h1:HVVTfrMezJeLyl2xhJ8edzkrEGBa4KxjQZB4FlQ4JLU= +github.com/sigstore/sigstore v1.7.3/go.mod h1:cl0c7Dtg3MM3c13L8pqqrfrmBa0eM3POcdtBepjylmw= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -373,6 +461,8 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= @@ -381,6 +471,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 h1:lIOOHPEbXzO3vnmx2gok1Tfs31Q8GQqKLc8vVqyQq/I= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= +github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw= +github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -396,12 +488,16 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/sylabs/sif/v2 v2.11.1 h1:d09yPukVa8b74wuy+QTA4Is3w8MH0UjO/xlWQUuFzpY= github.com/sylabs/sif/v2 v2.11.1/go.mod h1:i4GcKLOaT4ertznbsuf11d/G9zLEfUZa7YhrFc5L6YQ= +github.com/sylabs/sif/v2 v2.13.0 h1:dK/PQ/ohLAA4hptbjNuU0qoqkJ9Kl07hiSHArMNSKsQ= +github.com/sylabs/sif/v2 v2.13.0/go.mod h1:qEFrmE29XNbW2uyBagTsw9dgM82MwsckNYUFPweF2ek= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= github.com/theupdateframework/go-tuf v0.5.2 h1:habfDzTmpbzBLIFGWa2ZpVhYvFBoK0C1onC3a4zuPRA= github.com/theupdateframework/go-tuf v0.5.2/go.mod h1:SyMV5kg5n4uEclsyxXJZI2UxPFJNDc4Y+r7wv+MlvTA= +github.com/theupdateframework/go-tuf v0.6.1 h1:6J89fGjQf7s0mLmTG7p7pO/MbKOg+bIXhaLyQdmbKuE= +github.com/theupdateframework/go-tuf v0.6.1/go.mod h1:LAFusuQsFNBnEyYoTuA5zZrF7iaQ4TEgBXm8lb6Vj18= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= @@ -412,10 +508,16 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/vanilla-os/prometheus v0.1.5 h1:cAv0XaFtE9dZYxYpluc/wcq9Wkg2FytwMzh67F8dV+s= github.com/vanilla-os/prometheus v0.1.5/go.mod h1:ChWuR5stilaf0KkHa+aNIj4ZtnfLJO1UOBtb4FiputY= +github.com/vanilla-os/prometheus v0.1.6 h1:FU+Ts+Hxwz6C0uflD05s836CxKytclTD56ZHzgxpp70= +github.com/vanilla-os/prometheus v0.1.6/go.mod h1:A65eiUB5ZJa1PLJeEW7gLuNJKKXJBFIvXnSEa5rbMQE= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= +github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= +github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= github.com/vbauerster/mpb/v8 v8.3.0 h1:xw2eMJ6v5NP8Rd7yOVzU6OqnRPrS1yWAoLTrWe7W4Nc= github.com/vbauerster/mpb/v8 v8.3.0/go.mod h1:bngtYUAu25QGxcYYglsF6oyoHlC9Yhh582xF9LjfmL4= +github.com/vbauerster/mpb/v8 v8.6.1 h1:XbBpIbJxJOO9yMcKPpI4oEFPW6tLAptefNQJNcGWri8= +github.com/vbauerster/mpb/v8 v8.6.1/go.mod h1:S0tuIjikxlLxCeNijNhwAuD/BB3UE/d2nygG8SOldk0= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs= github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= @@ -423,19 +525,24 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= +github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= @@ -443,6 +550,8 @@ go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4x go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE= +go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdHZTy8mBTIPo7We18TuO/bak= go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= @@ -451,23 +560,32 @@ go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -484,8 +602,11 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -495,8 +616,11 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -532,20 +656,30 @@ golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -560,8 +694,11 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= +golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -573,6 +710,10 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -580,6 +721,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -594,11 +737,14 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-jose/go-jose.v2 v2.6.1 h1:qEzJlIDmG9q5VO0M/o8tGS65QMHMS1w01TQJB1VPJ4U= diff --git a/utils/create_test_env.sh b/utils/create_test_env.sh new file mode 100755 index 00000000..86f4261f --- /dev/null +++ b/utils/create_test_env.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +set -e + +distrobox-create -r -I -Y -ap "golang libbtrfs-dev libdevmapper-dev libgpgme-dev build-essential pkg-config lvm2 parted udev" -i ghcr.io/vanilla-os/vso:main albius_test \ No newline at end of file