mirror of
https://github.com/siderolabs/talos.git
synced 2025-12-11 12:31:44 +01:00
Re-design some methods, simplify flows and allow more simple interactions. Learn from mistakes and design better methods. Fixes #9471 Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
117 lines
2.7 KiB
Go
117 lines
2.7 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package mount_test
|
|
|
|
import (
|
|
"errors"
|
|
randv2 "math/rand/v2"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/freddierice/go-losetup/v2"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"golang.org/x/sys/unix"
|
|
|
|
"github.com/siderolabs/talos/internal/pkg/mount/v2"
|
|
"github.com/siderolabs/talos/pkg/makefs"
|
|
)
|
|
|
|
// Some tests in this package cannot be run under buildkit, as buildkit doesn't propagate partition devices
|
|
// like /dev/loopXpY into the sandbox. To run the tests on your local computer, do the following:
|
|
//
|
|
// go test -exec sudo -v --count 1 github.com/siderolabs/talos/internal/pkg/mount/v2
|
|
|
|
const diskSize = 4 * 1024 * 1024 * 1024 // 4 GiB
|
|
|
|
func losetupAttachHelper(t *testing.T, rawImage string, readonly bool) losetup.Device {
|
|
t.Helper()
|
|
|
|
for range 10 {
|
|
loDev, err := losetup.Attach(rawImage, 0, readonly)
|
|
if err != nil {
|
|
if errors.Is(err, unix.EBUSY) {
|
|
spraySleep := max(randv2.ExpFloat64(), 2.0)
|
|
|
|
t.Logf("retrying after %v seconds", spraySleep)
|
|
|
|
time.Sleep(time.Duration(spraySleep * float64(time.Second)))
|
|
|
|
continue
|
|
}
|
|
}
|
|
|
|
require.NoError(t, err)
|
|
|
|
return loDev
|
|
}
|
|
|
|
t.Fatal("failed to attach loop device") //nolint:revive
|
|
|
|
panic("unreachable")
|
|
}
|
|
|
|
func TestRepair(t *testing.T) {
|
|
if os.Getuid() != 0 {
|
|
t.Skip("can't run the test as non-root")
|
|
}
|
|
|
|
hostname, _ := os.Hostname() //nolint:errcheck
|
|
|
|
if hostname == "buildkitsandbox" {
|
|
t.Skip("test not supported under buildkit as partition devices are not propagated from /dev")
|
|
}
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
rawImage := filepath.Join(tmpDir, "image.raw")
|
|
|
|
f, err := os.Create(rawImage)
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, f.Truncate(int64(diskSize)))
|
|
require.NoError(t, f.Close())
|
|
|
|
loDev := losetupAttachHelper(t, rawImage, false)
|
|
|
|
t.Cleanup(func() {
|
|
assert.NoError(t, loDev.Detach())
|
|
})
|
|
|
|
mountDir := filepath.Join(tmpDir, "var")
|
|
|
|
require.NoError(t, os.MkdirAll(mountDir, 0o700))
|
|
require.NoError(t, makefs.XFS(loDev.Path()))
|
|
|
|
mountPoint := mount.NewPoint(loDev.Path(), mountDir, "xfs", mount.WithFlags(unix.MS_NOATIME))
|
|
|
|
unmounter1, err := mountPoint.Mount(mount.WithMountPrinter(t.Logf))
|
|
require.NoError(t, err)
|
|
|
|
t.Cleanup(func() {
|
|
require.NoError(t, unmounter1())
|
|
})
|
|
|
|
assert.NoError(t, unmounter1())
|
|
|
|
// // now corrupt the disk
|
|
cmd := exec.Command("xfs_db", []string{
|
|
"-x",
|
|
"-c blockget",
|
|
"-c blocktrash -s 512109 -n 100",
|
|
loDev.Path(),
|
|
}...)
|
|
|
|
assert.NoError(t, cmd.Run())
|
|
|
|
unmounter2, err := mountPoint.Mount(mount.WithMountPrinter(t.Logf))
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, unmounter2())
|
|
}
|