Old flow on every 'banger vm run' that hit the seeded path: CopyFilePreferClone the seed file (FICLONE attempt + io.Copy + fsync fallback), then e2fsck -fp + resize2fs to grow the FS to the spec size. On filesystems without reflink support that meant pushing 512+ MiB through the kernel followed by a full filesystem check and resize, even though the seed only carries a few KB of dotfiles — minWorkSeedBytes is 512 MiB but the actual payload is tiny. That is the minute-long stall on the 'cloning work seed' stage users see today. Replace the copy with a sized fresh ext4: truncate to WorkDiskSizeBytes, mkfs.ext4 -F -E root_owner=0:0, debugfs rdump to extract the seed's contents, then ingest each file via the sudoless ext4 toolkit (MkdirExt4 / WriteExt4FileOwned, root:root, mode preserved). Sub-second regardless of seed size or requested work-disk size; no fsck or resize needed because the FS is created at its final size from the start. Also drop the now-implementation-pinned TestEnsureWorkDiskClonesSeedImageAndResizes — its premise (a scripted e2fsck/resize2fs sequence) no longer reflects the code, and smoke covers the new flow end to end. Stage label changed from 'cloning work seed' to 'applying work seed' to match what actually happens. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
97 lines
2.8 KiB
Go
97 lines
2.8 KiB
Go
package daemon
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"banger/internal/guest"
|
|
"banger/internal/model"
|
|
)
|
|
|
|
func TestTapPoolWarmsAndReusesIdleTap(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
runner := &scriptedRunner{
|
|
t: t,
|
|
steps: []runnerStep{
|
|
{call: runnerCall{name: "ip", args: []string{"link", "show", "tap-pool-0"}}, err: errors.New("exit status 1")},
|
|
sudoStep("", nil, "ip", "tuntap", "add", "dev", "tap-pool-0", "mode", "tap", "user", strconv.Itoa(os.Getuid()), "group", strconv.Itoa(os.Getgid())),
|
|
sudoStep("", nil, "ip", "link", "set", "tap-pool-0", "master", model.DefaultBridgeName),
|
|
sudoStep("", nil, "ip", "link", "set", "tap-pool-0", "up"),
|
|
sudoStep("", nil, "ip", "link", "set", model.DefaultBridgeName, "up"),
|
|
},
|
|
}
|
|
d := &Daemon{
|
|
runner: runner,
|
|
config: model.DaemonConfig{
|
|
BridgeName: model.DefaultBridgeName,
|
|
TapPoolSize: 1,
|
|
},
|
|
closing: make(chan struct{}),
|
|
}
|
|
wireServices(d)
|
|
|
|
d.net.ensureTapPool(context.Background())
|
|
tapName, err := d.net.acquireTap(context.Background(), "tap-fallback")
|
|
if err != nil {
|
|
t.Fatalf("acquireTap: %v", err)
|
|
}
|
|
if tapName != "tap-pool-0" {
|
|
t.Fatalf("tapName = %q, want tap-pool-0", tapName)
|
|
}
|
|
if err := d.net.releaseTap(context.Background(), tapName); err != nil {
|
|
t.Fatalf("releaseTap: %v", err)
|
|
}
|
|
tapName, err = d.net.acquireTap(context.Background(), "tap-fallback")
|
|
if err != nil {
|
|
t.Fatalf("acquireTap second time: %v", err)
|
|
}
|
|
if tapName != "tap-pool-0" {
|
|
t.Fatalf("tapName second = %q, want tap-pool-0", tapName)
|
|
}
|
|
runner.assertExhausted()
|
|
}
|
|
|
|
func TestEnsureAuthorizedKeyOnWorkDiskSkipsRepairForMatchingSeededFingerprint(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
|
|
if err != nil {
|
|
t.Fatalf("GenerateKey: %v", err)
|
|
}
|
|
privateKeyPEM := pem.EncodeToMemory(&pem.Block{
|
|
Type: "RSA PRIVATE KEY",
|
|
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
|
|
})
|
|
sshKeyPath := filepath.Join(t.TempDir(), "id_rsa")
|
|
if err := os.WriteFile(sshKeyPath, privateKeyPEM, 0o600); err != nil {
|
|
t.Fatalf("WriteFile(private key): %v", err)
|
|
}
|
|
fingerprint, err := guest.AuthorizedPublicKeyFingerprint(sshKeyPath)
|
|
if err != nil {
|
|
t.Fatalf("AuthorizedPublicKeyFingerprint: %v", err)
|
|
}
|
|
|
|
runner := &scriptedRunner{t: t}
|
|
d := &Daemon{
|
|
runner: runner,
|
|
config: model.DaemonConfig{SSHKeyPath: sshKeyPath},
|
|
}
|
|
wireServices(d)
|
|
vm := testVM("seeded-fastpath", "image-seeded-fastpath", "172.16.0.62")
|
|
vm.Runtime.WorkDiskPath = filepath.Join(t.TempDir(), "root.ext4")
|
|
image := model.Image{SeededSSHPublicKeyFingerprint: fingerprint}
|
|
|
|
if err := d.ws.ensureAuthorizedKeyOnWorkDisk(context.Background(), &vm, image, workDiskPreparation{ClonedFromSeed: true}); err != nil {
|
|
t.Fatalf("ensureAuthorizedKeyOnWorkDisk: %v", err)
|
|
}
|
|
runner.assertExhausted()
|
|
}
|