Skip to content

Commit

Permalink
Fix getting lvm recovery (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
Itxaka authored Jun 23, 2023
1 parent f051fab commit 9dd1dbd
Show file tree
Hide file tree
Showing 14 changed files with 312 additions and 621 deletions.
2 changes: 1 addition & 1 deletion Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,4 @@ webui-tests:
COPY . src/
WORKDIR src/
RUN .github/cypress_tests.sh
SAVE ARTIFACT /src/internal/webui/public/cypress/videos videos
SAVE ARTIFACT /src/internal/webui/public/cypress/videos videos
26 changes: 26 additions & 0 deletions go.sum

Large diffs are not rendered by default.

75 changes: 0 additions & 75 deletions pkg/action/action_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ limitations under the License.
package action_test

import (
"fmt"
"testing"

"github.com/kairos-io/kairos/v2/pkg/constants"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
Expand All @@ -28,76 +26,3 @@ func TestActionSuite(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Actions test suite")
}

func lsblkMockOutput() []byte {
return []byte(fmt.Sprintf(
`{
"blockdevices": [
{
"name": "mmcblk0",
"pkname": null,
"path": "/dev/mmcblk0",
"fstype": null,
"mountpoint": null,
"size": 64088965120,
"ro": false,
"label": null
},{
"name": "mmcblk0p1",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p1",
"fstype": "vfat",
"mountpoint": null,
"size": 100663296,
"ro": false,
"label": "COS_GRUB"
},{
"name": "mmcblk0p2",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p2",
"fstype": "ext4",
"mountpoint": "%s",
"size": 6501171200,
"ro": false,
"label": "COS_STATE"
},{
"name": "mmcblk0p3",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p3",
"fstype": "LVM2_member",
"mountpoint": null,
"size": 4471128064,
"ro": false,
"label": null
},{
"name": "mmcblk0p4",
"pkname": "mmcblk0",
"path": "/dev/mmcblk0p4",
"fstype": "ext4",
"mountpoint": "/usr/local",
"size": 67108864,
"ro": false,
"label": "COS_PERSISTENT"
},{
"name": "KairosVG-oem",
"pkname": "mmcblk0p3",
"path": "/dev/mapper/KairosVG-oem",
"fstype": "ext4",
"mountpoint": "/oem",
"size": 67108864,
"ro": false,
"label": "COS_OEM"
},{
"name": "KairosVG-recovery",
"pkname": "mmcblk0p3",
"path": "/dev/mapper/KairosVG-recovery",
"fstype": "ext4",
"mountpoint": null,
"mountpoint": "%s",
"size": 4399824896,
"ro": false,
"label": "COS_RECOVERY"
}
]
}`, constants.RunningStateDir, constants.LiveDir))
}
53 changes: 45 additions & 8 deletions pkg/action/reset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"path/filepath"
"regexp"

"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kairos/v2/pkg/action"
"github.com/kairos-io/kairos/v2/pkg/constants"
conf "github.com/kairos-io/kairos/v2/pkg/elementalConfig"
Expand All @@ -46,6 +47,7 @@ var _ = Describe("Reset action tests", func() {
var cloudInit *v1mock.FakeCloudInitRunner
var cleanup func()
var memLog *bytes.Buffer
var ghwTest v1mock.GhwMock
var extractor *v1mock.FakeImageExtractor

BeforeEach(func() {
Expand All @@ -58,7 +60,7 @@ var _ = Describe("Reset action tests", func() {
extractor = v1mock.NewFakeImageExtractor(logger)
var err error
fs, cleanup, err = vfst.NewTestFS(map[string]interface{}{})
Expect(err).ToNot(HaveOccurred())
Expect(err).Should(BeNil())

cloudInit = &v1mock.FakeCloudInitRunner{}
config = conf.NewRunConfig(
Expand All @@ -80,15 +82,50 @@ var _ = Describe("Reset action tests", func() {
var reset *action.ResetAction
var cmdFail, bootedFrom string
var err error

BeforeEach(func() {

Expect(err).ShouldNot(HaveOccurred())
cmdFail = ""
recoveryImg := filepath.Join(constants.RunningStateDir, "cOS", constants.RecoveryImgFile)
err = utils.MkdirAll(fs, filepath.Dir(recoveryImg), constants.DirPerm)
Expect(err).To(BeNil())
_, err = fs.Create(recoveryImg)
Expect(err).To(BeNil())

mainDisk := block.Disk{
Name: "device",
Partitions: []*block.Partition{
{
Name: "device1",
FilesystemLabel: "COS_GRUB",
Type: "ext4",
},
{
Name: "device2",
FilesystemLabel: "COS_STATE",
Type: "ext4",
},
{
Name: "device3",
FilesystemLabel: "COS_PERSISTENT",
Type: "ext4",
},
{
Name: "device4",
FilesystemLabel: "COS_OEM",
Type: "ext4",
},
{
Name: "device5",
FilesystemLabel: "COS_RECOVERY",
Type: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()

fs.Create(constants.EfiDevice)
bootedFrom = constants.SystemLabel
runner.SideEffect = func(cmd string, args ...string) ([]byte, error) {
Expand All @@ -98,13 +135,9 @@ var _ = Describe("Reset action tests", func() {
switch cmd {
case "cat":
return []byte(bootedFrom), nil
case "lsblk":
if args[0] == "--list" {
return lsblkMockOutput(), nil
}
default:
return []byte{}, nil
}

return []byte{}, nil
}

spec, err = conf.NewResetSpec(config.Config)
Expand All @@ -129,6 +162,10 @@ var _ = Describe("Reset action tests", func() {
reset = action.NewResetAction(config, spec)
})

AfterEach(func() {
ghwTest.Clean()
})

It("Successfully resets on non-squashfs recovery", func() {
config.Reboot = true
Expect(reset.Run()).To(BeNil())
Expand Down
86 changes: 60 additions & 26 deletions pkg/action/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"path/filepath"

"github.com/jaypipes/ghw/pkg/block"
"github.com/kairos-io/kairos/v2/pkg/action"
"github.com/kairos-io/kairos/v2/pkg/constants"
conf "github.com/kairos-io/kairos/v2/pkg/elementalConfig"
Expand All @@ -45,6 +46,7 @@ var _ = Describe("Runtime Actions", func() {
var cloudInit *v1mock.FakeCloudInitRunner
var cleanup func()
var memLog *bytes.Buffer
var ghwTest v1mock.GhwMock
var extractor *v1mock.FakeImageExtractor

BeforeEach(func() {
Expand Down Expand Up @@ -82,43 +84,62 @@ var _ = Describe("Runtime Actions", func() {
var spec *v1.UpgradeSpec
var upgrade *action.UpgradeAction
var memLog *bytes.Buffer
var activeImg, passiveImg, recoveryImgSquash, recoveryImg string
activeImg := fmt.Sprintf("%s/cOS/%s", constants.RunningStateDir, constants.ActiveImgFile)
passiveImg := fmt.Sprintf("%s/cOS/%s", constants.RunningStateDir, constants.PassiveImgFile)
recoveryImgSquash := fmt.Sprintf("%s/cOS/%s", constants.LiveDir, constants.RecoverySquashFile)
recoveryImg := fmt.Sprintf("%s/cOS/%s", constants.LiveDir, constants.RecoveryImgFile)

BeforeEach(func() {
activeImg = fmt.Sprintf("%s/cOS/%s", constants.RunningStateDir, constants.ActiveImgFile)
passiveImg = fmt.Sprintf("%s/cOS/%s", constants.RunningStateDir, constants.PassiveImgFile)
recoveryImgSquash = fmt.Sprintf("%s/cOS/%s", constants.LiveDir, constants.RecoverySquashFile)
recoveryImg = fmt.Sprintf("%s/cOS/%s", constants.LiveDir, constants.RecoveryImgFile)

memLog = &bytes.Buffer{}
logger = v1.NewBufferLogger(memLog)
extractor = v1mock.NewFakeImageExtractor(logger)
config.Logger = logger
config.ImageExtractor = extractor
logger.SetLevel(logrus.DebugLevel)

runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "cat" && args[0] == "/proc/cmdline" {
return []byte(constants.RecoveryLabel), nil
}
if command == "mv" && args[0] == "-f" && args[1] == spec.Recovery.File && args[2] == recoveryImg {
// fake "move"
f, _ := fs.ReadFile(spec.Recovery.File)
_ = fs.WriteFile(recoveryImg, f, constants.FilePerm)
_ = fs.RemoveAll(spec.Recovery.File)
}

if command == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
return []byte{}, nil
}

// Create paths used by tests
utils.MkdirAll(fs, fmt.Sprintf("%s/cOS", constants.RunningStateDir), constants.DirPerm)
utils.MkdirAll(fs, fmt.Sprintf("%s/cOS", constants.LiveDir), constants.DirPerm)
})

mainDisk := block.Disk{
Name: "device",
Partitions: []*block.Partition{
{
Name: "device1",
FilesystemLabel: "COS_GRUB",
Type: "ext4",
},
{
Name: "device2",
FilesystemLabel: "COS_STATE",
Type: "ext4",
MountPoint: constants.RunningStateDir,
},
{
Name: "loop0",
FilesystemLabel: "COS_ACTIVE",
Type: "ext4",
},
{
Name: "device5",
FilesystemLabel: "COS_RECOVERY",
Type: "ext4",
MountPoint: constants.LiveDir,
},
{
Name: "device6",
FilesystemLabel: "COS_OEM",
Type: "ext4",
},
},
}
ghwTest = v1mock.GhwMock{}
ghwTest.AddDisk(mainDisk)
ghwTest.CreateDevices()
})
AfterEach(func() {
ghwTest.Clean()
})
Describe(fmt.Sprintf("Booting from %s", constants.ActiveLabel), Label("active_label"), func() {
var err error
BeforeEach(func() {
Expand Down Expand Up @@ -486,6 +507,7 @@ var _ = Describe("Runtime Actions", func() {
// Transition squash should not exist
info, err = fs.Stat(spec.Recovery.File)
Expect(err).To(HaveOccurred())

})
})
Describe("Not using squashfs", Label("non-squashfs"), func() {
Expand All @@ -495,16 +517,28 @@ var _ = Describe("Runtime Actions", func() {
err = fs.WriteFile(recoveryImg, []byte("recovery"), constants.FilePerm)
Expect(err).ShouldNot(HaveOccurred())

config.Runner = runner

spec, err = conf.NewUpgradeSpec(config.Config)
Expect(err).ShouldNot(HaveOccurred())

spec.Active.Size = 10
spec.Passive.Size = 10
spec.Recovery.Size = 10

spec.RecoveryUpgrade = true

runner.SideEffect = func(command string, args ...string) ([]byte, error) {
if command == "cat" && args[0] == "/proc/cmdline" {
return []byte(constants.RecoveryLabel), nil
}
if command == "mv" && args[0] == "-f" && args[1] == spec.Recovery.File && args[2] == recoveryImg {
// fake "move"
f, _ := fs.ReadFile(spec.Recovery.File)
_ = fs.WriteFile(recoveryImg, f, constants.FilePerm)
_ = fs.RemoveAll(spec.Recovery.File)
}
return []byte{}, nil
}
config.Runner = runner
_ = fs.WriteFile(recoveryImg, []byte("recovery"), constants.FilePerm)
// Mount recovery partition as it is expected to be mounted when booting from recovery
mounter.Mount("device5", constants.LiveDir, "auto", []string{"ro"})
Expand Down
31 changes: 1 addition & 30 deletions pkg/cloudinit/cloudinit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,6 @@ stages:
runner = v1mock.NewFakeRunner()

runner.SideEffect = func(cmd string, args ...string) ([]byte, error) {
if cmd == "lsblk" && args[0] == "--list" {
return lsblkMockOutput(), nil
}
if cmd == cmdFail {
return []byte{}, errors.New("command error")
}
Expand Down Expand Up @@ -253,8 +250,7 @@ stages:
`, device)), constants.FilePerm)
Expect(err).To(BeNil())
cloudRunner := NewYipCloudInitRunner(logger, runner, afs)
res := cloudRunner.Run("test", "/some/yip")
Expect(res).NotTo(BeNil())
Expect(cloudRunner.Run("test", "/some/yip")).NotTo(BeNil())
})
It("Fails to find device by path", func() {
err := afs.WriteFile("/some/yip/layout.yaml", []byte(`
Expand Down Expand Up @@ -284,28 +280,3 @@ stages:
})
})
})

func lsblkMockOutput() []byte {
return []byte(`{ "blockdevices":
[
{
"name": "device",
"pkname": "",
"path": "/dev/device",
"fstype": "",
"mountpoint": "",
"size": 0,
"ro": false,
"label": ""
},{
"name": "device1",
"pkname": "device",
"path": "/dev/device1",
"fstype": "ext4",
"mountpoint": "/mnt/fake1",
"size": 0,
"ro": false,
"label": "DEV_LABEL"
}
]}`)
}
2 changes: 1 addition & 1 deletion pkg/cloudinit/layout_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func layoutPlugin(l logger.Interface, s schema.Stage, fs vfs.FS, console plugins
}

if !dev.Exists() {
l.Errorf("Exiting, disk not found: %s", s.Layout.Device.Path)
l.Errorf("Exiting, disk not found:\n %s", s.Layout.Device.Path)
return errors.New("Target disk not found")
}

Expand Down
Loading

0 comments on commit 9dd1dbd

Please sign in to comment.