Move to use our ghw clone (#535)

This commit is contained in:
Itxaka 2024-09-17 15:27:31 +02:00 committed by GitHub
parent d407679677
commit 3e99d75331
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 409 additions and 778 deletions

12
go.mod
View File

@ -10,9 +10,9 @@ require (
github.com/erikgeiser/promptkit v0.9.0
github.com/google/go-containerregistry v0.20.2
github.com/hashicorp/go-multierror v1.1.1
github.com/jaypipes/ghw v0.13.0
github.com/jaypipes/ghw v0.13.0 // indirect
github.com/joho/godotenv v1.5.1
github.com/kairos-io/kairos-sdk v0.4.4
github.com/kairos-io/kairos-sdk v0.4.5
github.com/kairos-io/kcrypt v0.12.2
github.com/labstack/echo/v4 v4.12.0
github.com/mitchellh/mapstructure v1.5.0
@ -39,6 +39,8 @@ require (
require (
github.com/distribution/reference v0.6.0
github.com/gofrs/uuid v4.4.0+incompatible
github.com/google/go-github/v63 v63.0.0
github.com/twpayne/go-vfs/v4 v4.3.0
github.com/google/go-github/v65 v65.0.0
github.com/twpayne/go-vfs/v5 v5.0.4
)
@ -68,7 +70,7 @@ require (
github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
github.com/containerd/console v1.0.4-0.20230706203907-8f6c4e4faef5 // indirect
github.com/containerd/containerd v1.7.21 // indirect
github.com/containerd/containerd v1.7.22 // indirect
github.com/containerd/continuity v0.4.2 // indirect
github.com/containerd/errdefs v0.1.0 // indirect
github.com/containerd/log v0.1.0 // indirect
@ -82,7 +84,7 @@ require (
github.com/djherbis/times v1.6.0 // indirect
github.com/docker/cli v27.1.1+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v27.2.0+incompatible // indirect
github.com/docker/docker v27.2.1+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
@ -214,7 +216,7 @@ require (
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/image v0.18.0 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/term v0.24.0 // indirect
golang.org/x/text v0.18.0 // indirect

22
go.sum
View File

@ -92,8 +92,8 @@ github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHq
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/console v1.0.4-0.20230706203907-8f6c4e4faef5 h1:Ig+OPkE3XQrrl+SKsOqAjlkrBN/zrr+Qpw7rCuDjRCE=
github.com/containerd/console v1.0.4-0.20230706203907-8f6c4e4faef5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/containerd/containerd v1.7.21 h1:USGXRK1eOC/SX0L195YgxTHb0a00anxajOzgfN0qrCA=
github.com/containerd/containerd v1.7.21/go.mod h1:e3Jz1rYRUZ2Lt51YrH9Rz0zPyJBOlSvB3ghr2jbVD8g=
github.com/containerd/containerd v1.7.22 h1:nZuNnNRA6T6jB975rx2RRNqqH2k6ELYKDZfqTHqwyy0=
github.com/containerd/containerd v1.7.22/go.mod h1:e3Jz1rYRUZ2Lt51YrH9Rz0zPyJBOlSvB3ghr2jbVD8g=
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
@ -131,8 +131,8 @@ github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2
github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4=
github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI=
github.com/docker/docker v27.2.1+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/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
@ -230,6 +230,7 @@ github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l
github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8=
github.com/google/go-github/v63 v63.0.0 h1:13xwK/wk9alSokujB9lJkuzdmQuVn2QCPeck76wR3nE=
github.com/google/go-github/v63 v63.0.0/go.mod h1:IqbcrgUmIcEaioWrGYei/09o+ge5vhffGOcxrO0AfmA=
github.com/google/go-github/v65 v65.0.0/go.mod h1:DvrqWo5hvsdhJvHd4WyVF9ttANN3BniqjP8uTFMNb60=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA=
@ -278,6 +279,12 @@ github.com/jzelinskie/whirlpool v0.0.0-20201016144138-0675e54bb004 h1:G+9t9cEtnC
github.com/jzelinskie/whirlpool v0.0.0-20201016144138-0675e54bb004/go.mod h1:KmHnJWQrgEvbuy0vcvj00gtMqbvNn1L+3YUZLK/B92c=
github.com/kairos-io/kairos-sdk v0.4.3 h1:gIC/PsWjv9/Z+6RIHRG9IS5MB9gACw1ZjPAi7VydSSo=
github.com/kairos-io/kairos-sdk v0.4.3/go.mod h1:bxUPzirl8vNtqB48FJ2835QKio3d3PrHbkAejkibV8I=
github.com/kairos-io/kairos-sdk v0.4.4-0.20240912144533-f312c84d81be h1:cY33zv58Ejwn6u0nBp0ALJYNKlLPD534HHO6SQ6lksk=
github.com/kairos-io/kairos-sdk v0.4.4-0.20240912144533-f312c84d81be/go.mod h1:fPLrvHAStnKR1wGGyNj61prnYsC9QNQCNxnKe/49H54=
github.com/kairos-io/kairos-sdk v0.4.4 h1:FolUGqpdTnYYdLwFEOND97QEp2H/htVjW7pHUOmtxNI=
github.com/kairos-io/kairos-sdk v0.4.4/go.mod h1:OIJYihhuiUOeBXHYj9V3R381SAgc/EaKrFepcBxGroM=
github.com/kairos-io/kairos-sdk v0.4.5 h1:ja3GBPODLPx4X/9dEALncpDIHvFH8TdEBMda0H6O49o=
github.com/kairos-io/kairos-sdk v0.4.5/go.mod h1:OIJYihhuiUOeBXHYj9V3R381SAgc/EaKrFepcBxGroM=
github.com/kairos-io/kcrypt v0.12.2 h1:+lr8FGS0AW6D5dWSmaR3+AobL1TBTnOFgCSYctKY+5I=
github.com/kairos-io/kcrypt v0.12.2/go.mod h1:7SPiHzNMYl4MlxeB30s1YlHDYByTusu7u1mU5Nvicm0=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
@ -529,6 +536,7 @@ github.com/tredoe/osutil v1.5.0 h1:UGVxbbHRoZi8xXVmbNZ2vgG6XoJ15ndE4LniiQ3rJKg=
github.com/tredoe/osutil v1.5.0/go.mod h1:TEzphzUUunysbdDRfdOgqkg10POQbnfIPV50ynqOfIg=
github.com/twpayne/go-vfs/v4 v4.3.0 h1:rTqFzzOQ/6ESKTSiwVubHlCBedJDOhQyVSnw8rQNZhU=
github.com/twpayne/go-vfs/v4 v4.3.0/go.mod h1:tq2UVhnUepesc0lSnPJH/jQ8HruGhzwZe2r5kDFpEIw=
github.com/twpayne/go-vfs/v5 v5.0.4/go.mod h1:zTPFJUbgsEMFNSWnWQlLq9wh4AN83edZzx3VXbxrS1w=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
@ -616,8 +624,8 @@ 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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
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=
@ -791,6 +799,8 @@ howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/mount-utils v0.31.0 h1:o+a+n6gyZ7MGc6bIERU3LeFTHbLDBiVReaDpWlJotUE=
k8s.io/mount-utils v0.31.0/go.mod h1:HV/VYBUGqYUj4vt82YltzpWvgv8FPg0G9ItyInT3NPU=
k8s.io/mount-utils v0.31.1 h1:f8UrH9kRynljmdNGM6BaCvFUON5ZPKDgE+ltmYqI4wA=
k8s.io/mount-utils v0.31.1/go.mod h1:HV/VYBUGqYUj4vt82YltzpWvgv8FPg0G9ItyInT3NPU=
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=

View File

@ -2,7 +2,11 @@ package hook_test
import (
"bytes"
"github.com/jaypipes/ghw/pkg/block"
ghwMock "github.com/kairos-io/kairos-sdk/ghw/mocks"
"os"
"path/filepath"
"testing"
_ "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks"
hook "github.com/kairos-io/kairos-agent/v2/internal/agent/hooks"
"github.com/kairos-io/kairos-agent/v2/pkg/config"
@ -11,13 +15,11 @@ import (
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
"github.com/kairos-io/kairos-sdk/collector"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/twpayne/go-vfs/v4"
"github.com/twpayne/go-vfs/v4/vfst"
"os"
"path/filepath"
"testing"
)
func TestConfig(t *testing.T) {
@ -37,7 +39,7 @@ var _ = Describe("Hooks", func() {
var cleanup func()
var memLog *bytes.Buffer
var extractor *v1mock.FakeImageExtractor
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
var err error
Context("SysExtPostInstall", func() {
@ -79,22 +81,23 @@ var _ = Describe("Hooks", func() {
)
cfg.Config = collector.Config{}
mainDisk := block.Disk{
mainDisk := sdkTypes.Disk{
Name: "device",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: "COS_GRUB",
Type: "ext4",
FS: "ext4",
MountPoint: "/efi",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
})
AfterEach(func() {
ghwTest.Clean()
cleanup()
})
It("should copy all files with .sysext.raw extension", func() {

View File

@ -16,7 +16,7 @@ type SysExtPostInstall struct{}
func (b SysExtPostInstall) Run(c config.Config, _ v1.Spec) error {
c.Logger.Logger.Debug().Msg("Running SysExtPostInstall hook")
// mount efi partition
efiPart, err := partitions.GetEfiPartition()
efiPart, err := partitions.GetEfiPartition(&c.Logger)
if err != nil {
c.Logger.Errorf("failed to get EFI partition: %s", err)
if c.FailOnBundleErrors {

View File

@ -2,13 +2,13 @@ package agent
import (
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
ghwMock "github.com/kairos-io/kairos-sdk/ghw/mocks"
"github.com/kairos-io/kairos-sdk/types"
"os"
"path/filepath"
"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
"github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
"github.com/twpayne/go-vfs/v4/vfst"
@ -63,7 +63,7 @@ var _ = Describe("RunInstall", func() {
var err error
var fs v1.FS
var cleanup func()
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
var cmdline func() ([]byte, error)
BeforeEach(func() {
@ -125,47 +125,47 @@ var _ = Describe("RunInstall", func() {
},
}
mainDisk := block.Disk{
mainDisk := types.Disk{
Name: "device",
Partitions: []*block.Partition{
Partitions: []*types.Partition{
{
Name: "device1",
FilesystemLabel: "COS_GRUB",
Type: "ext4",
FS: "ext4",
},
{
Name: "device2",
FilesystemLabel: "COS_STATE",
Type: "ext4",
FS: "ext4",
},
{
Name: "device3",
FilesystemLabel: "COS_PERSISTENT",
Type: "ext4",
FS: "ext4",
},
{
Name: "device4",
FilesystemLabel: "COS_ACTIVE",
Type: "ext4",
FS: "ext4",
},
{
Name: "device5",
FilesystemLabel: "COS_PASSIVE",
Type: "ext4",
FS: "ext4",
},
{
Name: "device5",
FilesystemLabel: "COS_RECOVERY",
Type: "ext4",
FS: "ext4",
},
{
Name: "device6",
FilesystemLabel: "COS_OEM",
Type: "ext4",
FS: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
})

View File

@ -12,10 +12,10 @@ import (
"github.com/kairos-io/kairos-agent/v2/pkg/config"
events "github.com/kairos-io/kairos-sdk/bus"
"github.com/kairos-io/kairos-sdk/collector"
"github.com/kairos-io/kairos-sdk/ghw"
"github.com/kairos-io/kairos-sdk/unstructured"
"github.com/erikgeiser/promptkit/textinput"
"github.com/jaypipes/ghw"
"github.com/kairos-io/kairos-sdk/utils"
"github.com/mudler/go-pluggable"
"github.com/mudler/yip/pkg/schema"
@ -129,9 +129,7 @@ func InteractiveInstall(debug, spawnShell bool, sourceImgURL string) error {
maxSize := float64(0)
preferedDevice := "/dev/sda"
block, err := ghw.Block()
if err == nil {
for _, disk := range block.Disks {
for _, disk := range ghw.GetDisks(ghw.NewPaths(""), nil) {
// skip useless devices (/dev/ram, /dev/loop, /dev/sr, /dev/zram)
if strings.HasPrefix(disk.Name, "loop") || strings.HasPrefix(disk.Name, "ram") || strings.HasPrefix(disk.Name, "sr") || strings.HasPrefix(disk.Name, "zram") {
continue
@ -141,8 +139,7 @@ func InteractiveInstall(debug, spawnShell bool, sourceImgURL string) error {
maxSize = size
preferedDevice = "/dev/" + disk.Name
}
disks = append(disks, fmt.Sprintf("/dev/%s: %s (%.2f GiB) ", disk.Name, disk.Model, float64(disk.SizeBytes)/float64(GiB)))
}
disks = append(disks, fmt.Sprintf("/dev/%s: (%.2f GiB) ", disk.Name, float64(disk.SizeBytes)/float64(GiB)))
}
pterm.Info.Println("Available Disks:")

View File

@ -2,6 +2,7 @@ package action
import (
"fmt"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"os"
"path/filepath"
"reflect"
@ -15,7 +16,6 @@ import (
"github.com/erikgeiser/promptkit/confirmation"
"github.com/erikgeiser/promptkit/selection"
"github.com/kairos-io/kairos-agent/v2/pkg/config"
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
"github.com/kairos-io/kairos-agent/v2/pkg/utils/partitions"
@ -75,7 +75,7 @@ func selectBootEntrySystemd(cfg *config.Config, entry string) error {
cfg.Logger.Infof("Setting default boot entry to %s", entry)
// Get EFI partition
efiPartition, err := partitions.GetEfiPartition()
efiPartition, err := partitions.GetEfiPartition(&cfg.Logger)
if err != nil {
return err
}
@ -270,7 +270,7 @@ func listBootEntriesSystemd(cfg *config.Config) error {
cleanup := utils.NewCleanStack()
defer func() { err = cleanup.Cleanup(err) }()
// Get EFI partition
efiPartition, err := partitions.GetEfiPartition()
efiPartition, err := partitions.GetEfiPartition(&cfg.Logger)
if err != nil {
return err
}
@ -319,7 +319,7 @@ func listBootEntriesSystemd(cfg *config.Config) error {
}
// ListSystemdEntries reads the systemd-boot entries and returns a list of entries found
func listSystemdEntries(cfg *config.Config, efiPartition *v1.Partition) ([]string, error) {
func listSystemdEntries(cfg *config.Config, efiPartition *sdkTypes.Partition) ([]string, error) {
var entries []string
err := fsutils.WalkDirFs(cfg.Fs, filepath.Join(efiPartition.MountPoint, "loader/entries/"), func(path string, info os.DirEntry, err error) error {
if err != nil {

View File

@ -5,13 +5,12 @@ import (
"os"
"syscall"
"github.com/jaypipes/ghw/pkg/block"
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
"github.com/kairos-io/kairos-sdk/collector"
ghwMock "github.com/kairos-io/kairos-sdk/ghw/mocks"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@ -31,7 +30,7 @@ var _ = Describe("Bootentries tests", Label("bootentry"), func() {
var cleanup func()
var memLog *bytes.Buffer
var extractor *v1mock.FakeImageExtractor
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
BeforeEach(func() {
runner = v1mock.NewFakeRunner()
@ -72,23 +71,24 @@ var _ = Describe("Bootentries tests", Label("bootentry"), func() {
)
config.Config = collector.Config{}
mainDisk := block.Disk{
mainDisk := sdkTypes.Disk{
Name: "device",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: "COS_GRUB",
Type: "ext4",
FS: "ext4",
MountPoint: "/efi",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
})
AfterEach(func() {
ghwTest.Clean()
cleanup()
})
Context("Under Uki", func() {
@ -117,7 +117,7 @@ var _ = Describe("Bootentries tests", Label("bootentry"), func() {
err = fs.WriteFile("/efi/loader/entries/statereset.conf", []byte("title kairos state reset (auto)\nefi /EFI/kairos/statereset.efi\n"), os.ModePerm)
Expect(err).ToNot(HaveOccurred())
entries, err := listSystemdEntries(config, &v1.Partition{MountPoint: "/efi"})
entries, err := listSystemdEntries(config, &sdkTypes.Partition{MountPoint: "/efi"})
Expect(err).ToNot(HaveOccurred())
Expect(entries).To(HaveLen(4))
Expect(entries).To(ContainElement("cos"))
@ -127,10 +127,9 @@ var _ = Describe("Bootentries tests", Label("bootentry"), func() {
})
It("list empty boot entries if there is none", func() {
entries, err := listSystemdEntries(config, &v1.Partition{MountPoint: "/efi"})
entries, err := listSystemdEntries(config, &sdkTypes.Partition{MountPoint: "/efi"})
Expect(err).ToNot(HaveOccurred())
Expect(entries).To(HaveLen(0))
})
})
Context("SelectBootEntry", func() {

View File

@ -20,21 +20,22 @@ import (
"bytes"
"fmt"
"github.com/diskfs/go-diskfs"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"os"
"path/filepath"
"regexp"
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
"github.com/kairos-io/kairos-sdk/collector"
"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kairos-agent/v2/pkg/action"
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
"github.com/kairos-io/kairos-sdk/collector"
ghwMock "github.com/kairos-io/kairos-sdk/ghw/mocks"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/twpayne/go-vfs/v4"
@ -52,7 +53,7 @@ var _ = Describe("Install action tests", func() {
var cloudInit *v1mock.FakeCloudInitRunner
var cleanup func()
var memLog *bytes.Buffer
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
var extractor *v1mock.FakeImageExtractor
BeforeEach(func() {
@ -148,47 +149,47 @@ var _ = Describe("Install action tests", func() {
_, err = fs.Create(grubCfg)
Expect(err).To(BeNil())
mainDisk := block.Disk{
mainDisk := sdkTypes.Disk{
Name: "device",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: "COS_GRUB",
Type: "ext4",
FS: "ext4",
},
{
Name: "device2",
FilesystemLabel: "COS_STATE",
Type: "ext4",
FS: "ext4",
},
{
Name: "device3",
FilesystemLabel: "COS_PERSISTENT",
Type: "ext4",
FS: "ext4",
},
{
Name: "device4",
FilesystemLabel: "COS_ACTIVE",
Type: "ext4",
FS: "ext4",
},
{
Name: "device5",
FilesystemLabel: "COS_PASSIVE",
Type: "ext4",
FS: "ext4",
},
{
Name: "device5",
FilesystemLabel: "COS_RECOVERY",
Type: "ext4",
FS: "ext4",
},
{
Name: "device6",
FilesystemLabel: "COS_OEM",
Type: "ext4",
FS: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()

View File

@ -20,18 +20,19 @@ import (
"bytes"
"errors"
"fmt"
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"path/filepath"
"regexp"
"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kairos-agent/v2/pkg/action"
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
"github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
ghwMock "github.com/kairos-io/kairos-sdk/ghw/mocks"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/twpayne/go-vfs/v4"
@ -49,7 +50,7 @@ var _ = Describe("Reset action tests", func() {
var cloudInit *v1mock.FakeCloudInitRunner
var cleanup func()
var memLog *bytes.Buffer
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
var extractor *v1mock.FakeImageExtractor
BeforeEach(func() {
@ -97,37 +98,37 @@ var _ = Describe("Reset action tests", func() {
_, err = fs.Create(recoveryImg)
Expect(err).To(BeNil())
mainDisk := block.Disk{
mainDisk := sdkTypes.Disk{
Name: "device",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: "COS_GRUB",
Type: "ext4",
FS: "ext4",
},
{
Name: "device2",
FilesystemLabel: "COS_STATE",
Type: "ext4",
FS: "ext4",
},
{
Name: "device3",
FilesystemLabel: "COS_PERSISTENT",
Type: "ext4",
FS: "ext4",
},
{
Name: "device4",
FilesystemLabel: "COS_OEM",
Type: "ext4",
FS: "ext4",
},
{
Name: "device5",
FilesystemLabel: "COS_RECOVERY",
Type: "ext4",
FS: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()

View File

@ -24,18 +24,17 @@ import (
"path/filepath"
"strings"
"github.com/kairos-io/kairos-sdk/collector"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"github.com/kairos-io/kairos-agent/v2/internal/agent"
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kairos-agent/v2/pkg/action"
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
"github.com/kairos-io/kairos-sdk/collector"
ghwMock "github.com/kairos-io/kairos-sdk/ghw/mocks"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/twpayne/go-vfs/v4"
@ -53,7 +52,7 @@ var _ = Describe("Upgrade Actions test", func() {
var cloudInit *v1mock.FakeCloudInitRunner
var cleanup func()
var memLog *bytes.Buffer
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
var extractor *v1mock.FakeImageExtractor
var dummySourceFile string
var dummySourceSizeMb int64
@ -115,39 +114,39 @@ var _ = Describe("Upgrade Actions test", func() {
fsutils.MkdirAll(fs, fmt.Sprintf("%s/cOS", constants.RunningStateDir), constants.DirPerm)
fsutils.MkdirAll(fs, fmt.Sprintf("%s/cOS", constants.LiveDir), constants.DirPerm)
mainDisk := block.Disk{
mainDisk := sdkTypes.Disk{
Name: "device",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: "COS_GRUB",
Type: "ext4",
FS: "ext4",
},
{
Name: "device2",
FilesystemLabel: "COS_STATE",
Type: "ext4",
FS: "ext4",
MountPoint: constants.RunningStateDir,
},
{
Name: "loop0",
FilesystemLabel: "COS_ACTIVE",
Type: "ext4",
FS: "ext4",
},
{
Name: "device5",
FilesystemLabel: "COS_RECOVERY",
Type: "ext4",
FS: "ext4",
MountPoint: constants.LiveDir,
},
{
Name: "device6",
FilesystemLabel: "COS_OEM",
Type: "ext4",
FS: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
})

View File

@ -20,22 +20,21 @@ import (
"bytes"
"errors"
"fmt"
"github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"io/ioutil"
"log"
"os"
"github.com/jaypipes/ghw/pkg/block"
. "github.com/kairos-io/kairos-agent/v2/pkg/cloudinit"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
"github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
"github.com/twpayne/go-vfs/v4/vfst"
ghwMock "github.com/kairos-io/kairos-sdk/ghw/mocks"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/twpayne/go-vfs/v4/vfst"
)
// Parted print sample output
@ -159,8 +158,8 @@ stages:
pLabel: partLabel
`, device)), constants.FilePerm)
Expect(err).To(BeNil())
ghwTest := v1mock.GhwMock{}
disk := block.Disk{Name: "device", Partitions: []*block.Partition{
ghwTest := ghwMock.GhwMock{}
disk := sdkTypes.Disk{Name: "device", Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: "DEV_LABEL",
@ -187,11 +186,11 @@ stages:
size: 0
`, device)), constants.FilePerm)
Expect(err).To(BeNil())
ghwTest := v1mock.GhwMock{}
disk := block.Disk{Name: "device", Partitions: []*block.Partition{
ghwTest := ghwMock.GhwMock{}
disk := sdkTypes.Disk{Name: "device", Partitions: []*sdkTypes.Partition{
{
Name: fmt.Sprintf("device%d", partNum),
Type: "ext4",
FS: "ext4",
},
}}
ghwTest.AddDisk(disk)

View File

@ -52,7 +52,7 @@ type Install struct {
Recovery v1.Image `yaml:"recovery-system,omitempty" mapstructure:"recovery-system"`
Passive v1.Image `yaml:"passive,omitempty" mapstructure:"recovery-system"`
GrubDefEntry string `yaml:"grub-entry-name,omitempty" mapstructure:"grub-entry-name"`
ExtraPartitions v1.PartitionList `yaml:"extra-partitions,omitempty" mapstructure:"extra-partitions"`
ExtraPartitions sdkTypes.PartitionList `yaml:"extra-partitions,omitempty" mapstructure:"extra-partitions"`
ExtraDirsRootfs []string `yaml:"extra-dirs-rootfs,omitempty" mapstructure:"extra-dirs-rootfs"`
Force bool `yaml:"force,omitempty" mapstructure:"force"`
}

View File

@ -17,6 +17,7 @@ package config_test
import (
"fmt"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"path/filepath"
"reflect"
"strings"
@ -151,7 +152,7 @@ var _ = Describe("Schema", func() {
Size: 10000,
},
Partitions: v1.ElementalPartitions{
OEM: &v1.Partition{
OEM: &sdkTypes.Partition{
Size: 5120,
FS: "ext4",
},

View File

@ -24,20 +24,19 @@ import (
"reflect"
"strings"
"github.com/kairos-io/kairos-sdk/collector"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"github.com/google/go-containerregistry/pkg/crane"
"github.com/jaypipes/ghw"
"golang.org/x/sys/unix"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
"github.com/kairos-io/kairos-agent/v2/pkg/utils/partitions"
"github.com/kairos-io/kairos-sdk/collector"
"github.com/kairos-io/kairos-sdk/ghw"
"github.com/kairos-io/kairos-sdk/types"
"github.com/google/go-containerregistry/pkg/crane"
"github.com/mitchellh/mapstructure"
"github.com/sanity-io/litter"
"github.com/spf13/viper"
"golang.org/x/sys/unix"
)
const (
@ -143,7 +142,7 @@ func NewInstallSpec(cfg *Config) (*v1.InstallSpec, error) {
return spec, nil
}
func NewInstallElementalPartitions(log sdkTypes.KairosLogger, spec *v1.InstallSpec) v1.ElementalPartitions {
func NewInstallElementalPartitions(log types.KairosLogger, spec *v1.InstallSpec) v1.ElementalPartitions {
pt := v1.ElementalPartitions{}
var oemSize uint
if spec.Partitions.OEM != nil && spec.Partitions.OEM.Size != 0 {
@ -151,7 +150,7 @@ func NewInstallElementalPartitions(log sdkTypes.KairosLogger, spec *v1.InstallSp
} else {
oemSize = constants.OEMSize
}
pt.OEM = &v1.Partition{
pt.OEM = &types.Partition{
FilesystemLabel: constants.OEMLabel,
Size: oemSize,
Name: constants.OEMPartName,
@ -176,7 +175,7 @@ func NewInstallElementalPartitions(log sdkTypes.KairosLogger, spec *v1.InstallSp
}
}
log.Infof("Setting recovery partition size to %dMb", recoverySize)
pt.Recovery = &v1.Partition{
pt.Recovery = &types.Partition{
FilesystemLabel: constants.RecoveryLabel,
Size: recoverySize,
Name: constants.RecoveryPartName,
@ -202,7 +201,7 @@ func NewInstallElementalPartitions(log sdkTypes.KairosLogger, spec *v1.InstallSp
}
}
log.Infof("Setting state partition size to %dMb", stateSize)
pt.State = &v1.Partition{
pt.State = &types.Partition{
FilesystemLabel: constants.StateLabel,
Size: stateSize,
Name: constants.StatePartName,
@ -216,7 +215,7 @@ func NewInstallElementalPartitions(log sdkTypes.KairosLogger, spec *v1.InstallSp
} else {
persistentSize = spec.Partitions.Persistent.Size
}
pt.Persistent = &v1.Partition{
pt.Persistent = &types.Partition{
FilesystemLabel: constants.PersistentLabel,
Size: persistentSize,
Name: constants.PersistentPartName,
@ -238,7 +237,7 @@ func NewUpgradeSpec(cfg *Config) (*v1.UpgradeSpec, error) {
cfg.Logger.Warnf("failed reading installation state: %s", err.Error())
}
parts, err := partitions.GetAllPartitions()
parts, err := partitions.GetAllPartitions(&cfg.Logger)
if err != nil {
return nil, fmt.Errorf("could not read host partitions")
}
@ -401,7 +400,7 @@ func NewResetSpec(cfg *Config) (*v1.ResetSpec, error) {
cfg.Logger.Warnf("failed reading installation state: %s", err.Error())
}
parts, err := partitions.GetAllPartitions()
parts, err := partitions.GetAllPartitions(&cfg.Logger)
if err != nil {
return nil, fmt.Errorf("could not read host partitions")
}
@ -554,7 +553,7 @@ func NewUkiResetSpec(cfg *Config) (spec *v1.ResetUkiSpec, err error) {
spec.Partitions.OEM = partitions.GetPartitionViaDM(cfg.Fs, constants.OEMLabel)
// Get EFI partition
parts, err := partitions.GetAllPartitions()
parts, err := partitions.GetAllPartitions(&cfg.Logger)
if err != nil {
return spec, fmt.Errorf("could not read host partitions")
}
@ -630,7 +629,7 @@ func NewUkiInstallSpec(cfg *Config) (*v1.InstallUkiSpec, error) {
}
// Calculate the partitions afterwards so they use the image sizes for the final partition sizes
spec.Partitions.EFI = &v1.Partition{
spec.Partitions.EFI = &types.Partition{
FilesystemLabel: constants.EfiLabel,
Size: constants.ImgSize * 5, // 15Gb for the EFI partition as default
Name: constants.EfiPartName,
@ -638,7 +637,7 @@ func NewUkiInstallSpec(cfg *Config) (*v1.InstallUkiSpec, error) {
MountPoint: constants.EfiDir,
Flags: []string{"esp"},
}
spec.Partitions.OEM = &v1.Partition{
spec.Partitions.OEM = &types.Partition{
FilesystemLabel: constants.OEMLabel,
Size: constants.OEMSize,
Name: constants.OEMPartName,
@ -646,7 +645,7 @@ func NewUkiInstallSpec(cfg *Config) (*v1.InstallUkiSpec, error) {
MountPoint: constants.OEMDir,
Flags: []string{},
}
spec.Partitions.Persistent = &v1.Partition{
spec.Partitions.Persistent = &types.Partition{
FilesystemLabel: constants.PersistentLabel,
Size: constants.PersistentSize,
Name: constants.PersistentPartName,
@ -718,16 +717,11 @@ func NewUkiUpgradeSpec(cfg *Config) (*v1.UpgradeUkiSpec, error) {
}
// Get EFI partition
parts, err := partitions.GetAllPartitions()
spec.EfiPartition, err = partitions.GetEfiPartition(&cfg.Logger)
if err != nil {
return spec, fmt.Errorf("could not read host partitions")
}
for _, p := range parts {
if p.FilesystemLabel == constants.EfiLabel {
spec.EfiPartition = p
break
}
}
// Get free size of partition
var stat unix.Statfs_t
_ = unix.Statfs(spec.EfiPartition.MountPoint, &stat)
@ -954,7 +948,7 @@ func BootedFrom(runner v1.Runner, label string) bool {
}
// HasSquashedRecovery returns true if a squashed recovery image is found in the system
func hasSquashedRecovery(config *Config, recovery *v1.Partition) (squashed bool, err error) {
func hasSquashedRecovery(config *Config, recovery *types.Partition) (squashed bool, err error) {
mountPoint := recovery.MountPoint
if mnt, _ := isMounted(config, recovery); !mnt {
tmpMountDir, err := fsutils.TempDir(config.Fs, "", "elemental")
@ -979,7 +973,7 @@ func hasSquashedRecovery(config *Config, recovery *v1.Partition) (squashed bool,
return fsutils.Exists(config.Fs, filepath.Join(mountPoint, "cOS", constants.RecoverySquashFile))
}
func isMounted(config *Config, part *v1.Partition) (bool, error) {
func isMounted(config *Config, part *types.Partition) (bool, error) {
if part == nil {
return false, fmt.Errorf("nil partition")
}
@ -1022,29 +1016,21 @@ func detectLargestDevice() string {
preferedDevice := "/dev/sda"
maxSize := float64(0)
block, err := ghw.Block()
if err == nil {
for _, disk := range block.Disks {
for _, disk := range ghw.GetDisks(ghw.NewPaths(""), nil) {
size := float64(disk.SizeBytes) / float64(GiB)
if size > maxSize {
maxSize = size
preferedDevice = "/dev/" + disk.Name
}
}
}
return preferedDevice
}
// DetectPreConfiguredDevice returns a disk that has partitions labeled with
// Kairos labels. It can be used to detect a pre-configured device.
func DetectPreConfiguredDevice(logger sdkTypes.KairosLogger) (string, error) {
block, err := ghw.Block()
if err != nil {
logger.Errorf("failed getting block devices: %s", err.Error())
return "", err
}
for _, disk := range block.Disks {
func DetectPreConfiguredDevice(logger types.KairosLogger) (string, error) {
for _, disk := range ghw.GetDisks(ghw.NewPaths(""), &logger) {
for _, p := range disk.Partitions {
if p.FilesystemLabel == "COS_STATE" {
return filepath.Join("/", "dev", disk.Name), nil

View File

@ -18,23 +18,21 @@ package config_test
import (
"bytes"
"fmt"
"os"
"path/filepath"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"github.com/rs/zerolog"
"github.com/jaypipes/ghw/pkg/block"
config "github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
"github.com/kairos-io/kairos-sdk/collector"
ghwMock "github.com/kairos-io/kairos-sdk/ghw/mocks"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/sanity-io/litter"
"github.com/rs/zerolog"
"github.com/twpayne/go-vfs/v4/vfst"
"k8s.io/mount-utils"
)
@ -73,7 +71,6 @@ var _ = Describe("Types", Label("types", "config"), func() {
c.Install = &config.Install{}
c.Bundles = config.Bundles{}
c.Config = collector.Config{}
fmt.Println(litter.Sdump(c))
})
AfterEach(func() {
cleanup()
@ -207,7 +204,6 @@ var _ = Describe("Types", Label("types", "config"), func() {
spec, err := config.NewInstallSpec(c)
Expect(err).ToNot(HaveOccurred())
Expect(spec.Firmware).To(Equal(v1.BIOS))
fmt.Println(litter.Sdump(spec))
Expect(spec.Active.Source.IsEmpty()).To(BeFalse())
Expect(spec.Recovery.Source.Value()).To(Equal(spec.Active.File))
Expect(spec.PartTable).To(Equal(v1.GPT))
@ -217,7 +213,6 @@ var _ = Describe("Types", Label("types", "config"), func() {
spec, err := config.NewInstallSpec(c)
Expect(err).ToNot(HaveOccurred())
Expect(spec.Firmware).To(Equal(v1.BIOS))
fmt.Println(litter.Sdump(spec))
Expect(spec.Active.Source.IsEmpty()).To(BeTrue())
Expect(spec.Recovery.Source.Value()).To(Equal(spec.Active.File))
Expect(spec.PartTable).To(Equal(v1.GPT))
@ -226,39 +221,39 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
Describe("ResetSpec", Label("reset"), func() {
Describe("Successful executions", func() {
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
BeforeEach(func() {
mainDisk := block.Disk{
mainDisk := sdkTypes.Disk{
Name: "device",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: constants.EfiLabel,
Type: "vfat",
FS: "vfat",
},
{
Name: "device2",
FilesystemLabel: constants.OEMLabel,
Type: "ext4",
FS: "ext4",
},
{
Name: "device3",
FilesystemLabel: constants.RecoveryLabel,
Type: "ext4",
FS: "ext4",
},
{
Name: "device4",
FilesystemLabel: constants.StateLabel,
Type: "ext4",
FS: "ext4",
},
{
Name: "device5",
FilesystemLabel: constants.PersistentLabel,
Type: "ext4",
FS: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
@ -312,7 +307,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
Describe("Failures", func() {
var bootedFrom string
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
BeforeEach(func() {
bootedFrom = ""
runner.SideEffect = func(cmd string, args ...string) ([]byte, error) {
@ -325,17 +320,17 @@ var _ = Describe("Types", Label("types", "config"), func() {
}
// Set an empty disk for tests, otherwise reads the hosts hardware
mainDisk := block.Disk{
mainDisk := sdkTypes.Disk{
Name: "device",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "device4",
FilesystemLabel: constants.StateLabel,
Type: "ext4",
FS: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
})
@ -354,11 +349,11 @@ var _ = Describe("Types", Label("types", "config"), func() {
Expect(err.Error()).To(ContainSubstring("recovery partition not found"))
})
It("fails to set defaults if no state partition detected", func() {
mainDisk := block.Disk{
mainDisk := sdkTypes.Disk{
Name: "device",
Partitions: []*block.Partition{},
Partitions: []*sdkTypes.Partition{},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
defer ghwTest.Clean()
@ -384,40 +379,40 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
Describe("UpgradeSpec", Label("upgrade"), func() {
Describe("Successful executions", func() {
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
BeforeEach(func() {
mainDisk := block.Disk{
mainDisk := sdkTypes.Disk{
Name: "device",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: constants.EfiLabel,
Type: "vfat",
FS: "vfat",
},
{
Name: "device2",
FilesystemLabel: constants.OEMLabel,
Type: "ext4",
FS: "ext4",
},
{
Name: "device3",
FilesystemLabel: constants.RecoveryLabel,
Type: "ext4",
FS: "ext4",
MountPoint: constants.LiveDir,
},
{
Name: "device4",
FilesystemLabel: constants.StateLabel,
Type: "ext4",
FS: "ext4",
},
{
Name: "device5",
FilesystemLabel: constants.PersistentLabel,
Type: "ext4",
FS: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
})
@ -454,7 +449,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
Describe("Config from cloudconfig", Label("cloud-config"), func() {
var bootedFrom string
var dir string
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
BeforeEach(func() {
bootedFrom = ""
@ -494,37 +489,37 @@ cloud-init-paths:
err = os.WriteFile(filepath.Join(dir, "cc.yaml"), ccdata, os.ModePerm)
Expect(err).ToNot(HaveOccurred())
mainDisk := block.Disk{
mainDisk := sdkTypes.Disk{
Name: "device",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: constants.EfiLabel,
Type: "vfat",
FS: "vfat",
},
{
Name: "device2",
FilesystemLabel: constants.OEMLabel,
Type: "ext4",
FS: "ext4",
},
{
Name: "device3",
FilesystemLabel: constants.RecoveryLabel,
Type: "ext4",
FS: "ext4",
},
{
Name: "device4",
FilesystemLabel: constants.StateLabel,
Type: "ext4",
FS: "ext4",
},
{
Name: "device5",
FilesystemLabel: constants.PersistentLabel,
Type: "ext4",
FS: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
@ -683,7 +678,6 @@ var _ = Describe("GetSourceSize", Label("GetSourceSize"), func() {
})
AfterEach(func() {
fmt.Println(memLog.String())
defer os.RemoveAll(tempDir)
})

View File

@ -19,6 +19,7 @@ package elemental
import (
"errors"
"fmt"
"github.com/kairos-io/kairos-sdk/types"
"os"
"path/filepath"
"syscall"
@ -46,7 +47,7 @@ func NewElemental(config *agentConfig.Config) *Elemental {
}
// FormatPartition will format an already existing partition
func (e *Elemental) FormatPartition(part *v1.Partition, opts ...string) error {
func (e *Elemental) FormatPartition(part *types.Partition, opts ...string) error {
e.config.Logger.Infof("Formatting '%s' partition", part.FilesystemLabel)
return partitioner.FormatDevice(e.config.Runner, part.Path, part.FS, part.FilesystemLabel, opts...)
}
@ -125,7 +126,7 @@ func (e *Elemental) PartitionAndFormatDevice(i v1.SharedInstallSpec) error {
// MountPartitions mounts configured partitions. Partitions with an unset mountpoint are not mounted.
// Note umounts must be handled by caller logic.
func (e Elemental) MountPartitions(parts v1.PartitionList) error {
func (e Elemental) MountPartitions(parts types.PartitionList) error {
e.config.Logger.Infof("Mounting disk partitions")
var err error
@ -143,7 +144,7 @@ func (e Elemental) MountPartitions(parts v1.PartitionList) error {
}
// UnmountPartitions unmounts configured partitiosn. Partitions with an unset mountpoint are not unmounted.
func (e Elemental) UnmountPartitions(parts v1.PartitionList) error {
func (e Elemental) UnmountPartitions(parts types.PartitionList) error {
e.config.Logger.Infof("Unmounting disk partitions")
var err error
errMsg := ""
@ -166,7 +167,7 @@ func (e Elemental) UnmountPartitions(parts v1.PartitionList) error {
}
// MountRWPartition mounts, or remounts if needed, a partition with RW permissions
func (e Elemental) MountRWPartition(part *v1.Partition) (umount func() error, err error) {
func (e Elemental) MountRWPartition(part *types.Partition) (umount func() error, err error) {
if mnt, _ := utils.IsMounted(e.config, part); mnt {
err = e.MountPartition(part, "remount", "rw")
if err != nil {
@ -186,7 +187,7 @@ func (e Elemental) MountRWPartition(part *v1.Partition) (umount func() error, er
}
// MountPartition mounts a partition with the given mount options
func (e Elemental) MountPartition(part *v1.Partition, opts ...string) error {
func (e Elemental) MountPartition(part *types.Partition, opts ...string) error {
e.config.Logger.Debugf("Mounting partition %s", part.FilesystemLabel)
err := fsutils.MkdirAll(e.config.Fs, part.MountPoint, cnst.DirPerm)
if err != nil {
@ -194,7 +195,7 @@ func (e Elemental) MountPartition(part *v1.Partition, opts ...string) error {
}
if part.Path == "" {
// Lets error out only after 10 attempts to find the device
device, err := utils.GetDeviceByLabel(e.config.Runner, part.FilesystemLabel, 10)
device, err := utils.GetDeviceByLabel(e.config, part.FilesystemLabel, 10)
if err != nil {
e.config.Logger.Errorf("Could not find a device with label %s", part.FilesystemLabel)
return err
@ -210,7 +211,7 @@ func (e Elemental) MountPartition(part *v1.Partition, opts ...string) error {
}
// UnmountPartition unmounts the given partition or does nothing if not mounted
func (e Elemental) UnmountPartition(part *v1.Partition) error {
func (e Elemental) UnmountPartition(part *types.Partition) error {
if mnt, _ := utils.IsMounted(e.config, part); !mnt {
e.config.Logger.Debugf("Not unmounting partition, %s doesn't look like mountpoint", part.MountPoint)
return nil
@ -453,7 +454,7 @@ func (e *Elemental) CheckActiveDeployment(labels []string) bool {
e.config.Logger.Infof("Checking for active deployment")
for _, label := range labels {
found, _ := utils.GetDeviceByLabel(e.config.Runner, label, 1)
found, _ := utils.GetDeviceByLabel(e.config, label, 1)
if found != "" {
e.config.Logger.Debug("there is already an active deployment in the system")
return true

View File

@ -20,12 +20,6 @@ import (
"bytes"
"errors"
"fmt"
"github.com/diskfs/go-diskfs"
"github.com/diskfs/go-diskfs/partition/gpt"
"github.com/gofrs/uuid"
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"github.com/sanity-io/litter"
"golang.org/x/sys/unix"
"os"
"path/filepath"
@ -35,18 +29,22 @@ import (
"testing"
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
"github.com/jaypipes/ghw/pkg/block"
cnst "github.com/kairos-io/kairos-agent/v2/pkg/constants"
"github.com/kairos-io/kairos-agent/v2/pkg/elemental"
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
ghwMock "github.com/kairos-io/kairos-sdk/ghw/mocks"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"github.com/diskfs/go-diskfs"
"github.com/diskfs/go-diskfs/partition/gpt"
"github.com/gofrs/uuid"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/sanity-io/litter"
"github.com/twpayne/go-vfs/v4/vfst"
"k8s.io/mount-utils"
)
func TestElementalSuite(t *testing.T) {
@ -343,7 +341,7 @@ var _ = Describe("Elemental", Label("elemental"), func() {
Describe("FormatPartition", Label("FormatPartition", "partition", "format"), func() {
It("Reformats an already existing partition", func() {
el := elemental.NewElemental(config)
part := &v1.Partition{
part := &sdkTypes.Partition{
Path: "/dev/device1",
FS: "ext4",
FilesystemLabel: "MY_LABEL",
@ -611,8 +609,8 @@ var _ = Describe("Elemental", Label("elemental"), func() {
})
Describe("CheckActiveDeployment", Label("check"), func() {
It("deployment found", func() {
ghwTest := v1mock.GhwMock{}
disk := block.Disk{Name: "device", Partitions: []*block.Partition{
ghwTest := ghwMock.GhwMock{}
disk := sdkTypes.Disk{Name: "device", Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: cnst.ActiveLabel,
@ -620,7 +618,7 @@ var _ = Describe("Elemental", Label("elemental"), func() {
}}
ghwTest.AddDisk(disk)
ghwTest.CreateDevices()
defer ghwTest.Clean()
runner.ReturnValue = []byte(
fmt.Sprintf(
`{"blockdevices": [{"label": "%s", "type": "loop", "path": "/some/device"}]}`,
@ -629,6 +627,8 @@ var _ = Describe("Elemental", Label("elemental"), func() {
)
e := elemental.NewElemental(config)
Expect(e.CheckActiveDeployment([]string{cnst.ActiveLabel, cnst.PassiveLabel})).To(BeTrue())
ghwTest.Clean()
})
It("Should not error out", func() {
@ -922,14 +922,3 @@ var _ = Describe("Elemental", Label("elemental"), func() {
})
})
})
// PathInMountPoints will check if the given path is in the mountPoints list
func pathInMountPoints(mounter mount.Interface, path string) bool {
mountPoints, _ := mounter.List()
for _, m := range mountPoints {
if path == m.Path {
return true
}
}
return false
}

View File

@ -18,7 +18,7 @@ type Disk struct {
logger sdkTypes.KairosLogger
}
func (d *Disk) NewPartitionTable(partType string, parts v1.PartitionList) error {
func (d *Disk) NewPartitionTable(partType string, parts sdkTypes.PartitionList) error {
d.logger.Infof("Creating partition table for partition type %s", partType)
var table partition.Table
switch partType {
@ -43,7 +43,7 @@ func getSectorEndFromSize(start, size uint64) uint64 {
return (size / uint64(diskfs.SectorSize512)) + start - 1
}
func kairosPartsToDiskfsGPTParts(parts v1.PartitionList, diskSize int64) []*gpt.Partition {
func kairosPartsToDiskfsGPTParts(parts sdkTypes.PartitionList, diskSize int64) []*gpt.Partition {
var partitions []*gpt.Partition
for index, part := range parts {
var start uint64

View File

@ -21,8 +21,9 @@ import (
"path/filepath"
"sort"
"github.com/jaypipes/ghw"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
"github.com/kairos-io/kairos-sdk/ghw"
"github.com/kairos-io/kairos-sdk/types"
"gopkg.in/yaml.v3"
)
@ -47,7 +48,7 @@ type SharedInstallSpec interface {
GetPartTable() string
GetTarget() string
GetPartitions() ElementalPartitions
GetExtraPartitions() PartitionList
GetExtraPartitions() types.PartitionList
}
// InstallSpec struct represents all the installation action details
@ -56,7 +57,7 @@ type InstallSpec struct {
Firmware string `yaml:"firmware,omitempty" mapstructure:"firmware"`
PartTable string `yaml:"part-table,omitempty" mapstructure:"part-table"`
Partitions ElementalPartitions `yaml:"partitions,omitempty" mapstructure:"partitions"`
ExtraPartitions PartitionList `yaml:"extra-partitions,omitempty" mapstructure:"extra-partitions"`
ExtraPartitions types.PartitionList `yaml:"extra-partitions,omitempty" mapstructure:"extra-partitions"`
NoFormat bool `yaml:"no-format,omitempty" mapstructure:"no-format"`
Force bool `yaml:"force,omitempty" mapstructure:"force"`
CloudInit []string `yaml:"cloud-init,omitempty" mapstructure:"cloud-init"`
@ -76,9 +77,8 @@ type InstallSpec struct {
// if unsolvable inconsistencies are found
func (i *InstallSpec) Sanitize() error {
// Check if the target device has mounted partitions
block, err := ghw.Block()
if err == nil {
for _, disk := range block.Disks {
for _, disk := range ghw.GetDisks(ghw.NewPaths(""), nil) {
if fmt.Sprintf("/dev/%s", disk.Name) == i.Target {
for _, p := range disk.Partitions {
if p.MountPoint != "" {
@ -88,7 +88,7 @@ func (i *InstallSpec) Sanitize() error {
}
}
}
if i.Active.Source.IsEmpty() && i.Iso == "" {
return fmt.Errorf("undefined system source to install")
}
@ -134,7 +134,7 @@ func (i *InstallSpec) ShouldShutdown() bool { return i.PowerOff }
func (i *InstallSpec) GetTarget() string { return i.Target }
func (i *InstallSpec) GetPartTable() string { return i.PartTable }
func (i *InstallSpec) GetPartitions() ElementalPartitions { return i.Partitions }
func (i *InstallSpec) GetExtraPartitions() PartitionList { return i.ExtraPartitions }
func (i *InstallSpec) GetExtraPartitions() types.PartitionList { return i.ExtraPartitions }
// ResetSpec struct represents all the reset action details
type ResetSpec struct {
@ -220,63 +220,19 @@ func (r *EmptySpec) Sanitize() error {
func (r *EmptySpec) ShouldReboot() bool { return false }
func (r *EmptySpec) ShouldShutdown() bool { return false }
// Partition struct represents a partition with its commonly configurable values, size in MiB
type Partition struct {
Name string `yaml:"-"`
FilesystemLabel string `yaml:"label,omitempty" mapstructure:"label"`
Size uint `yaml:"size,omitempty" mapstructure:"size"`
FS string `yaml:"fs,omitempty" mapstrcuture:"fs"`
Flags []string `yaml:"flags,omitempty" mapstrcuture:"flags"`
MountPoint string `yaml:"-"`
Path string `yaml:"-"`
Disk string `yaml:"-"`
}
type PartitionList []*Partition
// GetByName gets a partitions by its name from the PartitionList
func (pl PartitionList) GetByName(name string) *Partition {
var part *Partition
for _, p := range pl {
if p.Name == name {
part = p
if part.MountPoint != "" {
return part
}
}
}
return part
}
// GetByLabel gets a partition by its label from the PartitionList
func (pl PartitionList) GetByLabel(label string) *Partition {
var part *Partition
for _, p := range pl {
if p.FilesystemLabel == label {
part = p
if part.MountPoint != "" {
return part
}
}
}
return part
}
type ElementalPartitions struct {
BIOS *Partition `yaml:"-"`
EFI *Partition `yaml:"-"`
OEM *Partition `yaml:"oem,omitempty" mapstructure:"oem"`
Recovery *Partition `yaml:"recovery,omitempty" mapstructure:"recovery"`
State *Partition `yaml:"state,omitempty" mapstructure:"state"`
Persistent *Partition `yaml:"persistent,omitempty" mapstructure:"persistent"`
BIOS *types.Partition `yaml:"-"`
EFI *types.Partition `yaml:"-"`
OEM *types.Partition `yaml:"oem,omitempty" mapstructure:"oem"`
Recovery *types.Partition `yaml:"recovery,omitempty" mapstructure:"recovery"`
State *types.Partition `yaml:"state,omitempty" mapstructure:"state"`
Persistent *types.Partition `yaml:"persistent,omitempty" mapstructure:"persistent"`
}
// SetFirmwarePartitions sets firmware partitions for a given firmware and partition table type
func (ep *ElementalPartitions) SetFirmwarePartitions(firmware string, partTable string) error {
if firmware == EFI && partTable == GPT {
ep.EFI = &Partition{
ep.EFI = &types.Partition{
FilesystemLabel: constants.EfiLabel,
Size: constants.EfiSize,
Name: constants.EfiPartName,
@ -286,7 +242,7 @@ func (ep *ElementalPartitions) SetFirmwarePartitions(firmware string, partTable
}
ep.BIOS = nil
} else if firmware == BIOS && partTable == GPT {
ep.BIOS = &Partition{
ep.BIOS = &types.Partition{
FilesystemLabel: constants.EfiLabel,
Size: constants.BiosSize,
Name: constants.BiosPartName,
@ -322,40 +278,41 @@ func (ep *ElementalPartitions) SetDefaultLabels() {
// partitions list. First tries to match partitions by partition label, if not,
// it tries to match partitions by default filesystem label
// TODO find a way to map custom labels when partition labels are not available
func NewElementalPartitionsFromList(pl PartitionList) ElementalPartitions {
func NewElementalPartitionsFromList(pl types.PartitionList) ElementalPartitions {
ep := ElementalPartitions{}
ep.BIOS = pl.GetByName(constants.BiosPartName)
ep.EFI = pl.GetByName(constants.EfiPartName)
if ep.EFI == nil {
ep.EFI = pl.GetByLabel(constants.EfiLabel)
}
ep.OEM = pl.GetByName(constants.OEMPartName)
if ep.OEM == nil {
ep.OEM = pl.GetByLabel(constants.OEMLabel)
}
ep.Recovery = pl.GetByName(constants.RecoveryPartName)
if ep.Recovery == nil {
ep.Recovery = pl.GetByLabel(constants.RecoveryLabel)
}
ep.State = pl.GetByName(constants.StatePartName)
if ep.State == nil {
ep.State = pl.GetByLabel(constants.StateLabel)
}
ep.Persistent = pl.GetByName(constants.PersistentPartName)
if ep.Persistent == nil {
ep.Persistent = pl.GetByLabel(constants.PersistentLabel)
}
ep.BIOS = GetPartitionByNameOrLabel(constants.BiosPartName, "", pl)
ep.EFI = GetPartitionByNameOrLabel(constants.EfiPartName, constants.EfiLabel, pl)
ep.OEM = GetPartitionByNameOrLabel(constants.OEMPartName, constants.OEMLabel, pl)
ep.Recovery = GetPartitionByNameOrLabel(constants.RecoveryPartName, constants.RecoveryLabel, pl)
ep.State = GetPartitionByNameOrLabel(constants.StatePartName, constants.StateLabel, pl)
ep.Persistent = GetPartitionByNameOrLabel(constants.PersistentPartName, constants.PersistentLabel, pl)
return ep
}
// GetPartitionByNameOrLabel will get a types.Partition from a types.PartitionList by name or label
func GetPartitionByNameOrLabel(name string, label string, partitionList types.PartitionList) *types.Partition {
var part *types.Partition
for _, p := range partitionList {
if p.Name == name || p.FilesystemLabel == label {
part = p
if part.MountPoint != "" {
return part
}
break
}
}
return part
}
// PartitionsByInstallOrder sorts partitions according to the default layout
// nil partitions are ignored
// partition with 0 size is set last
func (ep ElementalPartitions) PartitionsByInstallOrder(extraPartitions PartitionList, excludes ...*Partition) PartitionList {
partitions := PartitionList{}
var lastPartition *Partition
func (ep ElementalPartitions) PartitionsByInstallOrder(extraPartitions types.PartitionList, excludes ...*types.Partition) types.PartitionList {
partitions := types.PartitionList{}
var lastPartition *types.Partition
inExcludes := func(part *Partition, list ...*Partition) bool {
inExcludes := func(part *types.Partition, list ...*types.Partition) bool {
for _, p := range list {
if part == p {
return true
@ -412,12 +369,12 @@ func (ep ElementalPartitions) PartitionsByInstallOrder(extraPartitions Partition
// PartitionsByMountPoint sorts partitions according to its mountpoint, ignores nil
// partitions or partitions with an empty mountpoint
func (ep ElementalPartitions) PartitionsByMountPoint(descending bool, excludes ...*Partition) PartitionList {
mountPointKeys := map[string]*Partition{}
func (ep ElementalPartitions) PartitionsByMountPoint(descending bool, excludes ...*types.Partition) types.PartitionList {
mountPointKeys := map[string]*types.Partition{}
mountPoints := []string{}
partitions := PartitionList{}
partitions := types.PartitionList{}
for _, p := range ep.PartitionsByInstallOrder([]*Partition{}, excludes...) {
for _, p := range ep.PartitionsByInstallOrder([]*types.Partition{}, excludes...) {
if p.MountPoint != "" {
mountPointKeys[p.MountPoint] = p
mountPoints = append(mountPoints, p.MountPoint)
@ -513,7 +470,7 @@ type InstallUkiSpec struct {
Reboot bool `yaml:"reboot,omitempty" mapstructure:"reboot"`
PowerOff bool `yaml:"poweroff,omitempty" mapstructure:"poweroff"`
Partitions ElementalPartitions `yaml:"partitions,omitempty" mapstructure:"partitions"`
ExtraPartitions PartitionList `yaml:"extra-partitions,omitempty" mapstructure:"extra-partitions"`
ExtraPartitions types.PartitionList `yaml:"extra-partitions,omitempty" mapstructure:"extra-partitions"`
NoFormat bool `yaml:"no-format,omitempty" mapstructure:"no-format"`
CloudInit []string `yaml:"cloud-init,omitempty" mapstructure:"cloud-init"`
SkipEntries []string `yaml:"skip-entries,omitempty" mapstructure:"skip-entries"`
@ -529,14 +486,14 @@ func (i *InstallUkiSpec) ShouldShutdown() bool { return i.PowerOff
func (i *InstallUkiSpec) GetTarget() string { return i.Target }
func (i *InstallUkiSpec) GetPartTable() string { return "gpt" }
func (i *InstallUkiSpec) GetPartitions() ElementalPartitions { return i.Partitions }
func (i *InstallUkiSpec) GetExtraPartitions() PartitionList { return i.ExtraPartitions }
func (i *InstallUkiSpec) GetExtraPartitions() types.PartitionList { return i.ExtraPartitions }
type UpgradeUkiSpec struct {
Entry string `yaml:"entry,omitempty" mapstructure:"entry"`
Active Image `yaml:"system,omitempty" mapstructure:"system"`
Reboot bool `yaml:"reboot,omitempty" mapstructure:"reboot"`
PowerOff bool `yaml:"poweroff,omitempty" mapstructure:"poweroff"`
EfiPartition *Partition `yaml:"efi-partition,omitempty" mapstructure:"efi-partition"`
EfiPartition *types.Partition `yaml:"efi-partition,omitempty" mapstructure:"efi-partition"`
}
func (i *UpgradeUkiSpec) RecoveryUpgrade() bool {

View File

@ -17,6 +17,7 @@ limitations under the License.
package v1_test
import (
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"path/filepath"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
@ -27,12 +28,12 @@ import (
var _ = Describe("Types", Label("types", "config"), func() {
Describe("ElementalPartitions", func() {
var p v1.PartitionList
var p sdkTypes.PartitionList
var ep v1.ElementalPartitions
BeforeEach(func() {
ep = v1.ElementalPartitions{}
p = v1.PartitionList{
&v1.Partition{
p = sdkTypes.PartitionList{
&sdkTypes.Partition{
FilesystemLabel: "COS_OEM",
Size: 0,
Name: "oem",
@ -42,7 +43,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
Path: "",
Disk: "",
},
&v1.Partition{
&sdkTypes.Partition{
FilesystemLabel: "COS_CUSTOM",
Size: 0,
Name: "persistent",
@ -52,7 +53,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
Path: "",
Disk: "",
},
&v1.Partition{
&sdkTypes.Partition{
FilesystemLabel: "SOMETHING",
Size: 0,
Name: "somethingelse",
@ -77,7 +78,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
Expect(ep.EFI == nil && ep.BIOS != nil).To(BeTrue())
})
It("sets firmware partitions on msdos", func() {
ep.State = &v1.Partition{}
ep.State = &sdkTypes.Partition{}
Expect(ep.EFI == nil && ep.BIOS == nil).To(BeTrue())
err := ep.SetFirmwarePartitions(v1.BIOS, v1.MSDOS)
Expect(err).ShouldNot(HaveOccurred())
@ -101,15 +102,15 @@ var _ = Describe("Types", Label("types", "config"), func() {
Describe("returns a partition list by install order", func() {
It("with no extra parts", func() {
ep := v1.NewElementalPartitionsFromList(p)
lst := ep.PartitionsByInstallOrder([]*v1.Partition{})
lst := ep.PartitionsByInstallOrder([]*sdkTypes.Partition{})
Expect(len(lst)).To(Equal(2))
Expect(lst[0].Name == "oem").To(BeTrue())
Expect(lst[1].Name == "persistent").To(BeTrue())
})
It("with extra parts with size > 0", func() {
ep := v1.NewElementalPartitionsFromList(p)
var extraParts []*v1.Partition
extraParts = append(extraParts, &v1.Partition{Name: "extra", Size: 5})
var extraParts []*sdkTypes.Partition
extraParts = append(extraParts, &sdkTypes.Partition{Name: "extra", Size: 5})
lst := ep.PartitionsByInstallOrder(extraParts)
Expect(len(lst)).To(Equal(3))
@ -119,8 +120,8 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
It("with extra part with size == 0 and persistent.Size == 0", func() {
ep := v1.NewElementalPartitionsFromList(p)
var extraParts []*v1.Partition
extraParts = append(extraParts, &v1.Partition{Name: "extra", Size: 0})
var extraParts []*sdkTypes.Partition
extraParts = append(extraParts, &sdkTypes.Partition{Name: "extra", Size: 0})
lst := ep.PartitionsByInstallOrder(extraParts)
// Should ignore the wrong partition had have the persistent over it
Expect(len(lst)).To(Equal(2))
@ -130,8 +131,8 @@ var _ = Describe("Types", Label("types", "config"), func() {
It("with extra part with size == 0 and persistent.Size > 0", func() {
ep := v1.NewElementalPartitionsFromList(p)
ep.Persistent.Size = 10
var extraParts []*v1.Partition
extraParts = append(extraParts, &v1.Partition{Name: "extra", FilesystemLabel: "LABEL", Size: 0})
var extraParts []*sdkTypes.Partition
extraParts = append(extraParts, &sdkTypes.Partition{Name: "extra", FilesystemLabel: "LABEL", Size: 0})
lst := ep.PartitionsByInstallOrder(extraParts)
// Will have our size == 0 partition the latest
Expect(len(lst)).To(Equal(3))
@ -142,9 +143,9 @@ var _ = Describe("Types", Label("types", "config"), func() {
It("with several extra parts with size == 0 and persistent.Size > 0", func() {
ep := v1.NewElementalPartitionsFromList(p)
ep.Persistent.Size = 10
var extraParts []*v1.Partition
extraParts = append(extraParts, &v1.Partition{Name: "extra1", Size: 0})
extraParts = append(extraParts, &v1.Partition{Name: "extra2", Size: 0})
var extraParts []*sdkTypes.Partition
extraParts = append(extraParts, &sdkTypes.Partition{Name: "extra1", Size: 0})
extraParts = append(extraParts, &sdkTypes.Partition{Name: "extra2", Size: 0})
lst := ep.PartitionsByInstallOrder(extraParts)
// Should ignore the wrong partition had have the first partition with size 0 added last
Expect(len(lst)).To(Equal(3))
@ -170,10 +171,10 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
})
Describe("PartitionList", func() {
var p v1.PartitionList
var p sdkTypes.PartitionList
BeforeEach(func() {
p = v1.PartitionList{
&v1.Partition{
p = sdkTypes.PartitionList{
&sdkTypes.Partition{
FilesystemLabel: "ONE",
Size: 0,
Name: "one",
@ -183,7 +184,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
Path: "",
Disk: "",
},
&v1.Partition{
&sdkTypes.Partition{
FilesystemLabel: "TWO",
Size: 0,
Name: "two",
@ -196,7 +197,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
}
})
It("returns partitions by name", func() {
Expect(p.GetByName("two")).To(Equal(&v1.Partition{
Expect(v1.GetPartitionByNameOrLabel("two", "", p)).To(Equal(&sdkTypes.Partition{
FilesystemLabel: "TWO",
Size: 0,
Name: "two",
@ -208,10 +209,10 @@ var _ = Describe("Types", Label("types", "config"), func() {
}))
})
It("returns nil if partiton name not found", func() {
Expect(p.GetByName("nonexistent")).To(BeNil())
Expect(v1.GetPartitionByNameOrLabel("dsd", "nonexistent", p)).To(BeNil())
})
It("returns partitions by filesystem label", func() {
Expect(p.GetByLabel("TWO")).To(Equal(&v1.Partition{
Expect(v1.GetPartitionByNameOrLabel("", "TWO", p)).To(Equal(&sdkTypes.Partition{
FilesystemLabel: "TWO",
Size: 0,
Name: "two",
@ -223,7 +224,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
}))
})
It("returns nil if filesystem label not found", func() {
Expect(p.GetByName("nonexistent")).To(BeNil())
Expect(v1.GetPartitionByNameOrLabel("sd", "nonexistent", p)).To(BeNil())
})
})
Describe("Specs", func() {
@ -241,11 +242,11 @@ var _ = Describe("Types", Label("types", "config"), func() {
Source: v1.NewEmptySrc(),
},
Partitions: v1.ElementalPartitions{
OEM: &v1.Partition{},
Recovery: &v1.Partition{},
Persistent: &v1.Partition{},
OEM: &sdkTypes.Partition{},
Recovery: &sdkTypes.Partition{},
Persistent: &sdkTypes.Partition{},
},
ExtraPartitions: v1.PartitionList{},
ExtraPartitions: sdkTypes.PartitionList{},
}
})
It("fails with empty source", func() {
@ -261,7 +262,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
It("passes if state and source are ready", func() {
spec.Active.Source = v1.NewFileSrc("/tmp")
spec.Partitions.State = &v1.Partition{
spec.Partitions.State = &sdkTypes.Partition{
MountPoint: "/tmp",
}
err := spec.Sanitize()
@ -269,7 +270,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
It("fills the spec with defaults (BIOS)", func() {
spec.Active.Source = v1.NewFileSrc("/tmp")
spec.Partitions.State = &v1.Partition{
spec.Partitions.State = &sdkTypes.Partition{
MountPoint: "/tmp",
}
spec.Firmware = constants.BiosPartName
@ -292,7 +293,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
It("fills the spec with defaults (EFI)", func() {
spec.Active.Source = v1.NewFileSrc("/tmp")
spec.Partitions.State = &v1.Partition{
spec.Partitions.State = &sdkTypes.Partition{
MountPoint: "/tmp",
}
spec.Firmware = constants.EfiPartName
@ -319,16 +320,16 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
It("Cannot add extra partitions with 0 size + persistent with 0 size", func() {
spec.Active.Source = v1.NewFileSrc("/tmp")
spec.Partitions.State = &v1.Partition{
spec.Partitions.State = &sdkTypes.Partition{
MountPoint: "/tmp",
}
spec.Partitions.Persistent = &v1.Partition{
spec.Partitions.Persistent = &sdkTypes.Partition{
Size: 0,
}
spec.Firmware = constants.BiosPartName
spec.PartTable = constants.GPT
spec.ExtraPartitions = v1.PartitionList{
&v1.Partition{
spec.ExtraPartitions = sdkTypes.PartitionList{
&sdkTypes.Partition{
Size: 0,
},
}
@ -338,19 +339,19 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
It("Cannot add more than 1 extra partition with 0 size", func() {
spec.Active.Source = v1.NewFileSrc("/tmp")
spec.Partitions.State = &v1.Partition{
spec.Partitions.State = &sdkTypes.Partition{
MountPoint: "/tmp",
}
spec.Partitions.Persistent = &v1.Partition{
spec.Partitions.Persistent = &sdkTypes.Partition{
Size: 100,
}
spec.Firmware = constants.BiosPartName
spec.PartTable = constants.GPT
spec.ExtraPartitions = v1.PartitionList{
&v1.Partition{
spec.ExtraPartitions = sdkTypes.PartitionList{
&sdkTypes.Partition{
Size: 0,
},
&v1.Partition{
&sdkTypes.Partition{
Size: 0,
},
}
@ -360,16 +361,16 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
It("Can add 1 extra partition with 0 size", func() {
spec.Active.Source = v1.NewFileSrc("/tmp")
spec.Partitions.State = &v1.Partition{
spec.Partitions.State = &sdkTypes.Partition{
MountPoint: "/tmp",
}
spec.Partitions.Persistent = &v1.Partition{
spec.Partitions.Persistent = &sdkTypes.Partition{
Size: 100,
}
spec.Firmware = constants.BiosPartName
spec.PartTable = constants.GPT
spec.ExtraPartitions = v1.PartitionList{
&v1.Partition{
spec.ExtraPartitions = sdkTypes.PartitionList{
&sdkTypes.Partition{
Size: 0,
},
}
@ -399,12 +400,12 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
It("passes if state and source are ready", func() {
spec.Active.Source = v1.NewFileSrc("/tmp")
spec.Partitions.State = &v1.Partition{
spec.Partitions.State = &sdkTypes.Partition{
MountPoint: "/tmp",
}
spec.Partitions.OEM = &v1.Partition{}
spec.Partitions.Recovery = &v1.Partition{}
spec.Partitions.Persistent = &v1.Partition{}
spec.Partitions.OEM = &sdkTypes.Partition{}
spec.Partitions.Recovery = &sdkTypes.Partition{}
spec.Partitions.Persistent = &sdkTypes.Partition{}
err := spec.Sanitize()
Expect(err).ToNot(HaveOccurred())
})
@ -436,7 +437,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
It("passes if state and source are ready", func() {
spec.Active.Source = v1.NewFileSrc("/tmp")
spec.Partitions.State = &v1.Partition{
spec.Partitions.State = &sdkTypes.Partition{
MountPoint: "/tmp",
}
err := spec.Sanitize()
@ -460,7 +461,7 @@ var _ = Describe("Types", Label("types", "config"), func() {
})
It("passes if state and source are ready", func() {
spec.Recovery.Source = v1.NewFileSrc("/tmp")
spec.Partitions.Recovery = &v1.Partition{
spec.Partitions.Recovery = &sdkTypes.Partition{
MountPoint: "/tmp",
}
err := spec.Sanitize()

View File

@ -35,6 +35,7 @@ import (
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"github.com/kairos-io/kairos-sdk/state"
"github.com/kairos-io/kairos-sdk/types"
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
@ -55,31 +56,21 @@ func CommandExists(command string) bool {
// GetDeviceByLabel will try to return the device that matches the given label.
// attempts value sets the number of attempts to find the device, it
// waits a second between attempts.
func GetDeviceByLabel(runner v1.Runner, label string, attempts int) (string, error) {
part, err := GetFullDeviceByLabel(runner, label, attempts)
func GetDeviceByLabel(config *agentConfig.Config, label string, attempts int) (string, error) {
for tries := 0; tries < attempts; tries++ {
_, _ = config.Runner.Run("udevadm", "trigger")
_, _ = config.Runner.Run("udevadm", "settle")
parts, err := partitions.GetAllPartitions(&config.Logger)
if err != nil {
return "", err
}
return part.Path, nil
}
// GetFullDeviceByLabel works like GetDeviceByLabel, but it will try to get as much info as possible from the existing
// partition and return a v1.Partition object
func GetFullDeviceByLabel(runner v1.Runner, label string, attempts int) (*v1.Partition, error) {
for tries := 0; tries < attempts; tries++ {
_, _ = runner.Run("udevadm", "trigger")
_, _ = runner.Run("udevadm", "settle")
parts, err := partitions.GetAllPartitions()
if err != nil {
return nil, err
}
part := parts.GetByLabel(label)
part := v1.GetPartitionByNameOrLabel("", label, parts)
if part != nil {
return part, nil
return part.Path, nil
}
time.Sleep(1 * time.Second)
}
return nil, errors.New("no device found")
return "", errors.New("no device found")
}
// CopyFile Copies source file to target file using Fs interface. If target
@ -310,7 +301,7 @@ func LoadEnvFile(fs v1.FS, file string) (map[string]string, error) {
return envMap, err
}
func IsMounted(config *agentConfig.Config, part *v1.Partition) (bool, error) {
func IsMounted(config *agentConfig.Config, part *types.Partition) (bool, error) {
if part == nil {
return false, fmt.Errorf("nil partition")
}
@ -343,7 +334,7 @@ func GetTempDir(config *agentConfig.Config, suffix string) string {
config.Logger.Debugf("Got tmpdir from TMPDIR var: %s", dir)
return filepath.Join(dir, elementalTmpDir)
}
parts, err := partitions.GetAllPartitions()
parts, err := partitions.GetAllPartitions(&config.Logger)
if err != nil {
config.Logger.Debug("Could not get partitions, defaulting to /tmp")
return filepath.Join("/", "tmp", elementalTmpDir)

View File

@ -25,40 +25,20 @@ import (
"strconv"
"strings"
"github.com/jaypipes/ghw"
"github.com/jaypipes/ghw/pkg/block"
"github.com/jaypipes/ghw/pkg/context"
"github.com/jaypipes/ghw/pkg/linuxpath"
ghwUtil "github.com/jaypipes/ghw/pkg/util"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
"github.com/kairos-io/kairos-sdk/ghw"
"github.com/kairos-io/kairos-sdk/types"
log "github.com/sirupsen/logrus"
)
// ghwPartitionToInternalPartition transforms a block.Partition from ghw lib to our v1.Partition type
func ghwPartitionToInternalPartition(partition *block.Partition) *v1.Partition {
return &v1.Partition{
FilesystemLabel: partition.FilesystemLabel,
Size: uint(partition.SizeBytes / (1024 * 1024)), // Converts B to MB
Name: partition.Name,
FS: partition.Type,
Flags: nil,
MountPoint: partition.MountPoint,
Path: filepath.Join("/dev", partition.Name),
Disk: filepath.Join("/dev", partition.Disk.Name),
}
}
// GetAllPartitions returns all partitions in the system for all disks
func GetAllPartitions() (v1.PartitionList, error) {
var parts []*v1.Partition
blockDevices, err := block.New(ghw.WithDisableTools(), ghw.WithDisableWarnings())
if err != nil {
return nil, err
}
for _, d := range blockDevices.Disks {
func GetAllPartitions(logger *types.KairosLogger) (types.PartitionList, error) {
var parts []*types.Partition
for _, d := range ghw.GetDisks(ghw.NewPaths(""), logger) {
for _, part := range d.Partitions {
parts = append(parts, ghwPartitionToInternalPartition(part))
parts = append(parts, part)
}
}
return parts, nil
@ -117,39 +97,15 @@ func parseMountEntry(line string) (string, string) {
return fields[0], mp
}
// GetPartitionFS gets the FS of a partition given
func GetPartitionFS(partition string) (string, error) {
// We want to have the device always prefixed with a /dev
if !strings.HasPrefix(partition, "/dev") {
partition = filepath.Join("/dev", partition)
}
blockDevices, err := block.New(ghw.WithDisableTools(), ghw.WithDisableWarnings())
if err != nil {
return "", err
}
for _, disk := range blockDevices.Disks {
for _, part := range disk.Partitions {
if filepath.Join("/dev", part.Name) == partition {
if part.Type == ghwUtil.UNKNOWN {
return "", fmt.Errorf("could not find filesystem for partition %s", partition)
}
return part.Type, nil
}
}
}
return "", fmt.Errorf("could not find filesystem for partition %s", partition)
}
// GetPartitionViaDM tries to get the partition via devicemapper for reset
// We only need to get all this info due to the fS that we need to use to format the partition
// Otherwise we could just format with the label ¯\_(ツ)_/¯
// TODO: store info about persistent and oem in the state.yaml so we can directly load it
func GetPartitionViaDM(fs v1.FS, label string) *v1.Partition {
var part *v1.Partition
func GetPartitionViaDM(fs v1.FS, label string) *types.Partition {
var part *types.Partition
rootPath, _ := fs.RawPath("/")
ctx := context.New(ghw.WithDisableTools(), ghw.WithDisableWarnings(), ghw.WithChroot(rootPath))
lp := linuxpath.New(ctx)
lp := ghw.NewPaths(rootPath)
devices, _ := fs.ReadDir(lp.SysBlock)
for _, dev := range devices {
if !strings.HasPrefix(dev.Name(), "dm-") {
@ -178,7 +134,7 @@ func GetPartitionViaDM(fs v1.FS, label string) *v1.Partition {
partitionFS := udevInfo["ID_FS_TYPE"]
partitionName := udevInfo["DM_LV_NAME"]
part = &v1.Partition{
part = &types.Partition{
Name: partitionName,
FilesystemLabel: label,
FS: partitionFS,
@ -268,18 +224,17 @@ func GetPartitionViaDM(fs v1.FS, label string) *v1.Partition {
}
// GetEfiPartition returns the EFI partition by looking for the partition with the label "COS_GRUB"
func GetEfiPartition() (*v1.Partition, error) {
var efiPartition *v1.Partition
parts, err := GetAllPartitions()
if err != nil {
return efiPartition, fmt.Errorf("could not read host partitions")
}
for _, p := range parts {
if p.FilesystemLabel == constants.EfiLabel {
efiPartition = p
func GetEfiPartition(logger *types.KairosLogger) (*types.Partition, error) {
var efiPartition *types.Partition
for _, d := range ghw.GetDisks(ghw.NewPaths(""), logger) {
for _, part := range d.Partitions {
if part.FilesystemLabel == constants.EfiLabel {
efiPartition = part
break
}
}
}
if efiPartition == nil {
return efiPartition, fmt.Errorf("could not find EFI partition")
}

View File

@ -20,22 +20,22 @@ import (
"bytes"
"errors"
"fmt"
"github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
"github.com/kairos-io/kairos-agent/v2/pkg/utils/partitions"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
"io/fs"
"os"
"path/filepath"
"strings"
"time"
"github.com/jaypipes/ghw/pkg/block"
agentConfig "github.com/kairos-io/kairos-agent/v2/pkg/config"
"github.com/kairos-io/kairos-agent/v2/pkg/constants"
v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1"
"github.com/kairos-io/kairos-agent/v2/pkg/utils"
"github.com/kairos-io/kairos-agent/v2/pkg/utils/fs"
"github.com/kairos-io/kairos-agent/v2/pkg/utils/partitions"
v1mock "github.com/kairos-io/kairos-agent/v2/tests/mocks"
ghwMock "github.com/kairos-io/kairos-sdk/ghw/mocks"
sdkTypes "github.com/kairos-io/kairos-sdk/types"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/twpayne/go-vfs/v4"
@ -189,8 +189,8 @@ var _ = Describe("Utils", Label("utils"), func() {
}
})
It("returns found device", func() {
ghwTest := v1mock.GhwMock{}
disk := block.Disk{Name: "device", Partitions: []*block.Partition{
ghwTest := ghwMock.GhwMock{}
disk := sdkTypes.Disk{Name: "device", Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: "FAKE",
@ -199,24 +199,24 @@ var _ = Describe("Utils", Label("utils"), func() {
ghwTest.AddDisk(disk)
ghwTest.CreateDevices()
defer ghwTest.Clean()
out, err := utils.GetDeviceByLabel(runner, "FAKE", 1)
out, err := utils.GetDeviceByLabel(config, "FAKE", 1)
Expect(err).To(BeNil())
Expect(out).To(Equal("/dev/device1"))
Expect(runner.CmdsMatch(cmds)).To(BeNil())
})
It("fails if no device is found in two attempts", func() {
_, err := utils.GetDeviceByLabel(runner, "FAKE", 2)
_, err := utils.GetDeviceByLabel(config, "FAKE", 2)
Expect(err).NotTo(BeNil())
Expect(runner.CmdsMatch(append(cmds, cmds...))).To(BeNil())
})
})
Describe("GetAllPartitions", Label("lsblk", "partitions"), func() {
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
BeforeEach(func() {
ghwTest = v1mock.GhwMock{}
disk1 := block.Disk{
ghwTest = ghwMock.GhwMock{}
disk1 := sdkTypes.Disk{
Name: "sda",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "sda1Test",
},
@ -225,9 +225,9 @@ var _ = Describe("Utils", Label("utils"), func() {
},
},
}
disk2 := block.Disk{
disk2 := sdkTypes.Disk{
Name: "sdb",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "sdb1Test",
},
@ -241,7 +241,7 @@ var _ = Describe("Utils", Label("utils"), func() {
ghwTest.Clean()
})
It("returns all found partitions", func() {
parts, err := partitions.GetAllPartitions()
parts, err := partitions.GetAllPartitions(&logger)
Expect(err).To(BeNil())
var partNames []string
for _, p := range parts {
@ -252,40 +252,6 @@ var _ = Describe("Utils", Label("utils"), func() {
Expect(partNames).To(ContainElement("sdb1Test"))
})
})
Describe("GetPartitionFS", Label("lsblk", "partitions"), func() {
var ghwTest v1mock.GhwMock
BeforeEach(func() {
ghwTest = v1mock.GhwMock{}
disk := block.Disk{Name: "device", Partitions: []*block.Partition{
{
Name: "device1",
Type: "xfs",
},
{
Name: "device2",
},
}}
ghwTest.AddDisk(disk)
ghwTest.CreateDevices()
})
AfterEach(func() {
ghwTest.Clean()
})
It("returns found device with plain partition device", func() {
pFS, err := partitions.GetPartitionFS("device1")
Expect(err).To(BeNil())
Expect(pFS).To(Equal("xfs"))
})
It("returns found device with full partition device", func() {
pFS, err := partitions.GetPartitionFS("/dev/device1")
Expect(err).To(BeNil())
Expect(pFS).To(Equal("xfs"))
})
It("fails if no partition is found", func() {
_, err := partitions.GetPartitionFS("device2")
Expect(err).NotTo(BeNil())
})
})
Describe("CosignVerify", Label("cosign"), func() {
It("runs a keyless verification", func() {
_, err := utils.CosignVerify(fs, runner, "some/image:latest", "")
@ -320,57 +286,6 @@ var _ = Describe("Utils", Label("utils"), func() {
Expect(duration.Seconds() >= 3).To(BeTrue())
})
})
Describe("GetFullDeviceByLabel", Label("lsblk", "partitions"), func() {
var cmds [][]string
BeforeEach(func() {
cmds = [][]string{
{"udevadm", "trigger"},
{"udevadm", "settle"},
}
})
It("returns found v1.Partition", func() {
var flags []string
ghwTest := v1mock.GhwMock{}
disk := block.Disk{Name: "device", Partitions: []*block.Partition{
{
Name: "device1",
FilesystemLabel: "FAKE",
Type: "fakefs",
MountPoint: "/mnt/fake",
SizeBytes: 0,
},
}}
ghwTest.AddDisk(disk)
ghwTest.CreateDevices()
defer ghwTest.Clean()
out, err := utils.GetFullDeviceByLabel(runner, "FAKE", 1)
Expect(err).To(BeNil())
Expect(out.FilesystemLabel).To(Equal("FAKE"))
Expect(out.Size).To(Equal(uint(0)))
Expect(out.FS).To(Equal("fakefs"))
Expect(out.MountPoint).To(Equal("/mnt/fake"))
Expect(out.Flags).To(Equal(flags))
Expect(runner.CmdsMatch(cmds)).To(BeNil())
})
It("fails to run lsblk", func() {
runner.ReturnError = errors.New("failed running lsblk")
_, err := utils.GetFullDeviceByLabel(runner, "FAKE", 1)
Expect(err).To(HaveOccurred())
Expect(runner.CmdsMatch(cmds)).To(BeNil())
})
It("fails to parse json output", func() {
runner.ReturnValue = []byte(`{"invalidobject": []}`)
_, err := utils.GetFullDeviceByLabel(runner, "FAKE", 1)
Expect(err).To(HaveOccurred())
Expect(runner.CmdsMatch(cmds)).To(BeNil())
})
It("fails if no device is found in two attempts", func() {
runner.ReturnValue = []byte(`{"blockdevices":[{"label":"something","type": "part"}]}`)
_, err := utils.GetFullDeviceByLabel(runner, "FAKE", 2)
Expect(err).To(HaveOccurred())
Expect(runner.CmdsMatch(append(cmds, cmds...))).To(BeNil())
})
})
Describe("CopyFile", Label("CopyFile"), func() {
It("Copies source file to target file", func() {
err := fsutils.MkdirAll(fs, "/some", constants.DirPerm)
@ -967,7 +882,7 @@ var _ = Describe("Utils", Label("utils"), func() {
})
Describe("IsMounted", Label("ismounted"), func() {
It("checks a mounted partition", func() {
part := &v1.Partition{
part := &sdkTypes.Partition{
MountPoint: "/some/mountpoint",
}
err := mounter.Mount("/some/device", "/some/mountpoint", "auto", []string{})
@ -977,7 +892,7 @@ var _ = Describe("Utils", Label("utils"), func() {
Expect(mnt).To(BeTrue())
})
It("checks a not mounted partition", func() {
part := &v1.Partition{
part := &sdkTypes.Partition{
MountPoint: "/some/mountpoint",
}
mnt, err := utils.IsMounted(config, part)
@ -985,7 +900,7 @@ var _ = Describe("Utils", Label("utils"), func() {
Expect(mnt).To(BeFalse())
})
It("checks a partition without mountpoint", func() {
part := &v1.Partition{}
part := &sdkTypes.Partition{}
mnt, err := utils.IsMounted(config, part)
Expect(err).ShouldNot(HaveOccurred())
Expect(mnt).To(BeFalse())
@ -1071,33 +986,36 @@ var _ = Describe("Utils", Label("utils"), func() {
})
})
Describe("GetEfiPartition", func() {
var ghwTest v1mock.GhwMock
var ghwTest ghwMock.GhwMock
BeforeEach(func() {
mainDisk := block.Disk{
mainDisk := sdkTypes.Disk{
Name: "device",
Partitions: []*block.Partition{
Partitions: []*sdkTypes.Partition{
{
Name: "device1",
FilesystemLabel: "COS_GRUB",
Type: "ext4",
FS: "ext4",
MountPoint: "/efi",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest = ghwMock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
})
AfterEach(func() {
ghwTest.Clean()
})
It("returns the efi partition", func() {
efi, err := partitions.GetEfiPartition()
efi, err := partitions.GetEfiPartition(&logger)
Expect(err).ToNot(HaveOccurred())
Expect(efi.FilesystemLabel).To(Equal("COS_GRUB"))
Expect(efi.Name).To(Equal("device1")) // Just to make sure its our mocked system
})
It("fails to find the efi partition", func() {
ghwTest.Clean() // Remove the disk
efi, err := partitions.GetEfiPartition()
efi, err := partitions.GetEfiPartition(&logger)
Expect(err).To(HaveOccurred())
Expect(efi).To(BeNil())
})

View File

@ -1,173 +0,0 @@
/*
Copyright © 2022 SUSE LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mocks
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/jaypipes/ghw/pkg/block"
"github.com/jaypipes/ghw/pkg/context"
"github.com/jaypipes/ghw/pkg/linuxpath"
)
// GhwMock is used to construct a fake disk to present to ghw when scanning block devices
// The way this works is ghw will use the existing files in the system to determine the different disks, partitions and
// mountpoints. It uses /sys/block, /proc/self/mounts and /run/udev/data to gather everything
// It also has an entrypoint to overwrite the root dir from which the paths are constructed so that allows us to override
// it easily and make it read from a different location.
// This mock is used to construct a fake FS with all its needed files on a different chroot and just add a Disk with its
// partitions and let the struct do its thing creating files and mountpoints and such
// You can even just pass no disks to simulate a system in which there is no disk/no cos partitions
type GhwMock struct {
chroot string
paths *linuxpath.Paths
disks []block.Disk
mounts []string
}
// AddDisk adds a disk to GhwMock
func (g *GhwMock) AddDisk(disk block.Disk) {
g.disks = append(g.disks, disk)
}
// AddPartitionToDisk will add a partition to the given disk and call Clean+CreateDevices, so we recreate all files
// It makes no effort checking if the disk exists
func (g *GhwMock) AddPartitionToDisk(diskName string, partition *block.Partition) {
for _, disk := range g.disks {
if disk.Name == diskName {
disk.Partitions = append(disk.Partitions, partition)
g.Clean()
g.CreateDevices()
}
}
}
// CreateDevices will create a new context and paths for ghw using the Chroot value as base, then set the env var GHW_ROOT so the
// ghw library picks that up and then iterate over the disks and partitions and create the necessary files
func (g *GhwMock) CreateDevices() {
d, _ := os.MkdirTemp("", "ghwmock")
g.chroot = d
ctx := context.New()
ctx.Chroot = d
g.paths = linuxpath.New(ctx)
_ = os.Setenv("GHW_CHROOT", g.chroot)
// Create the /sys/block dir
_ = os.MkdirAll(g.paths.SysBlock, 0755)
// Create the /run/udev/data dir
_ = os.MkdirAll(g.paths.RunUdevData, 0755)
// Create only the /proc/self dir, we add the mounts file afterwards
procDir, _ := filepath.Split(g.paths.ProcMounts)
_ = os.MkdirAll(procDir, 0755)
for indexDisk, disk := range g.disks {
// For each dir we create the /sys/block/DISK_NAME
diskPath := filepath.Join(g.paths.SysBlock, disk.Name)
_ = os.Mkdir(diskPath, 0755)
for indexPart, partition := range disk.Partitions {
// For each partition we create the /sys/block/DISK_NAME/PARTITION_NAME
_ = os.Mkdir(filepath.Join(diskPath, partition.Name), 0755)
// Create the /sys/block/DISK_NAME/PARTITION_NAME/dev file which contains the major:minor of the partition
_ = os.WriteFile(filepath.Join(diskPath, partition.Name, "dev"), []byte(fmt.Sprintf("%d:6%d\n", indexDisk, indexPart)), 0644)
// Create the /run/udev/data/bMAJOR:MINOR file with the data inside to mimic the udev database
data := []string{fmt.Sprintf("E:ID_FS_LABEL=%s\n", partition.FilesystemLabel)}
if partition.Type != "" {
data = append(data, fmt.Sprintf("E:ID_FS_TYPE=%s\n", partition.Type))
}
_ = os.WriteFile(filepath.Join(g.paths.RunUdevData, fmt.Sprintf("b%d:6%d", indexDisk, indexPart)), []byte(strings.Join(data, "")), 0644)
// If we got a mountpoint, add it to our fake /proc/self/mounts
if partition.MountPoint != "" {
// Check if the partition has a fs, otherwise default to ext4
if partition.Type == "" {
partition.Type = "ext4"
}
// Prepare the g.mounts with all the mount lines
g.mounts = append(
g.mounts,
fmt.Sprintf("%s %s %s ro,relatime 0 0\n", filepath.Join("/dev", partition.Name), partition.MountPoint, partition.Type))
}
}
}
// Finally, write all the mounts
_ = os.WriteFile(g.paths.ProcMounts, []byte(strings.Join(g.mounts, "")), 0644)
}
// RemoveDisk will remove the files for a disk. It makes no effort to check if the disk exists or not
func (g *GhwMock) RemoveDisk(disk string) {
// This could be simpler I think, just removing the /sys/block/DEVICE should make ghw not find anything and not search
// for partitions, but just in case do it properly
var newMounts []string
diskPath := filepath.Join(g.paths.SysBlock, disk)
_ = os.RemoveAll(diskPath)
// Try to find any mounts that match the disk given and remove them from the mounts
for _, mount := range g.mounts {
fields := strings.Fields(mount)
// If first field does not contain the /dev/DEVICE, add it to the newmounts
if !strings.Contains(fields[0], filepath.Join("/dev", disk)) {
newMounts = append(newMounts, mount)
}
}
g.mounts = newMounts
// Write the mounts again
_ = os.WriteFile(g.paths.ProcMounts, []byte(strings.Join(g.mounts, "")), 0644)
}
// RemovePartitionFromDisk will remove the files for a partition
// It makes no effort checking if the disk/partition/files exist
func (g *GhwMock) RemovePartitionFromDisk(diskName string, partitionName string) {
var newMounts []string
diskPath := filepath.Join(g.paths.SysBlock, diskName)
// Read the dev major:minor
devName, _ := os.ReadFile(filepath.Join(diskPath, partitionName, "dev"))
// Remove the MAJOR:MINOR file from the udev database
_ = os.RemoveAll(filepath.Join(g.paths.RunUdevData, fmt.Sprintf("b%s", devName)))
// Remove the /sys/block/DISK/PARTITION dir
_ = os.RemoveAll(filepath.Join(diskPath, partitionName))
// Try to find any mounts that match the partition given and remove them from the mounts
for _, mount := range g.mounts {
fields := strings.Fields(mount)
// If first field does not contain the /dev/PARTITION, add it to the newmounts
if !strings.Contains(fields[0], filepath.Join("/dev", partitionName)) {
newMounts = append(newMounts, mount)
}
}
g.mounts = newMounts
// Write the mounts again
_ = os.WriteFile(g.paths.ProcMounts, []byte(strings.Join(g.mounts, "")), 0644)
// Remove it from the partitions list
for index, disk := range g.disks {
if disk.Name == diskName {
var newPartitions []*block.Partition
for _, partition := range disk.Partitions {
if partition.Name != partitionName {
newPartitions = append(newPartitions, partition)
}
}
g.disks[index].Partitions = newPartitions
}
}
}
// Clean will remove the chroot dir and unset the env var
func (g *GhwMock) Clean() {
_ = os.Unsetenv("GHW_CHROOT")
_ = os.RemoveAll(g.chroot)
}