Skip to content

Commit bedeb49

Browse files
committed
Add Linux bundle transformation and testing for VM adaptation
1 parent 74bcb8e commit bedeb49

5 files changed

Lines changed: 33 additions & 39 deletions

File tree

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//go:build linux
22

3-
// Package transform provides OCI bundle transformations for VM compatibility.
4-
package transform
3+
package bundle
54

65
import (
76
"context"
@@ -12,12 +11,10 @@ import (
1211
"github.com/containerd/log"
1312
"github.com/opencontainers/runc/libcontainer/capabilities"
1413
"github.com/opencontainers/runtime-spec/specs-go"
15-
16-
"github.com/spin-stack/spinbox/internal/shim/bundle"
1714
)
1815

1916
// TransformBindMounts converts bind mounts to extra files for the VM.
20-
func TransformBindMounts(ctx context.Context, b *bundle.Bundle) error {
17+
func TransformBindMounts(ctx context.Context, b *Bundle) error {
2118
for i, m := range b.Spec.Mounts {
2219
if m.Type == "bind" {
2320
filename := filepath.Base(m.Source)
@@ -44,7 +41,7 @@ func TransformBindMounts(ctx context.Context, b *bundle.Bundle) error {
4441
// - Remove network/cgroup namespaces (container uses VM's)
4542
// - Ensure cgroup2 mount exists
4643
// - Grant full capabilities (VM is the security boundary)
47-
func AdaptForVM(ctx context.Context, b *bundle.Bundle) error {
44+
func AdaptForVM(ctx context.Context, b *Bundle) error {
4845
// Remove network and cgroup namespaces
4946
if b.Spec.Linux != nil {
5047
var namespaces []specs.LinuxNamespace
@@ -117,8 +114,8 @@ func ensureRW(opts []string) []string {
117114
}
118115

119116
// LoadForCreate loads and transforms an OCI bundle for container creation.
120-
func LoadForCreate(ctx context.Context, bundlePath string) (*bundle.Bundle, error) {
121-
return bundle.Load(ctx, bundlePath,
117+
func LoadForCreate(ctx context.Context, bundlePath string) (*Bundle, error) {
118+
return Load(ctx, bundlePath,
122119
TransformBindMounts,
123120
AdaptForVM,
124121
)

internal/shim/transform/bundle_test.go renamed to internal/shim/bundle/transform_linux_test.go

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//go:build linux
22

3-
package transform
3+
package bundle
44

55
import (
66
"context"
@@ -12,13 +12,11 @@ import (
1212
"github.com/opencontainers/runtime-spec/specs-go"
1313
"github.com/stretchr/testify/assert"
1414
"github.com/stretchr/testify/require"
15-
16-
"github.com/spin-stack/spinbox/internal/shim/bundle"
1715
)
1816

1917
const cgroupPath = "/sys/fs/cgroup"
2018

21-
func createTestBundle(t *testing.T, bundlePath string) {
19+
func setupTransformTestBundle(t *testing.T, bundlePath string) {
2220
t.Helper()
2321
require.NoError(t, os.MkdirAll(bundlePath, 0750))
2422

@@ -48,13 +46,13 @@ func TestTransformBindMounts(t *testing.T) {
4846
t.Run("transforms bind mount from bundle path", func(t *testing.T) {
4947
tmpDir := t.TempDir()
5048
bundlePath := filepath.Join(tmpDir, "test-container")
51-
createTestBundle(t, bundlePath)
49+
setupTransformTestBundle(t, bundlePath)
5250

5351
testFile := filepath.Join(bundlePath, "config.yaml")
5452
testContent := []byte("key: value\n")
5553
require.NoError(t, os.WriteFile(testFile, testContent, 0600))
5654

57-
b, err := bundle.Load(ctx, bundlePath)
55+
b, err := Load(ctx, bundlePath)
5856
require.NoError(t, err)
5957

6058
b.Spec.Mounts = append(b.Spec.Mounts, specs.Mount{
@@ -75,14 +73,14 @@ func TestTransformBindMounts(t *testing.T) {
7573
t.Run("ignores bind mount from different path", func(t *testing.T) {
7674
tmpDir := t.TempDir()
7775
bundlePath := filepath.Join(tmpDir, "test-container")
78-
createTestBundle(t, bundlePath)
76+
setupTransformTestBundle(t, bundlePath)
7977

8078
otherDir := filepath.Join(tmpDir, "other")
8179
require.NoError(t, os.MkdirAll(otherDir, 0750))
8280
testFile := filepath.Join(otherDir, "secret.txt")
8381
require.NoError(t, os.WriteFile(testFile, []byte("secret"), 0600))
8482

85-
b, err := bundle.Load(ctx, bundlePath)
83+
b, err := Load(ctx, bundlePath)
8684
require.NoError(t, err)
8785

8886
b.Spec.Mounts = append(b.Spec.Mounts, specs.Mount{
@@ -104,9 +102,9 @@ func TestAdaptForVM(t *testing.T) {
104102
t.Run("removes network and cgroup namespaces", func(t *testing.T) {
105103
tmpDir := t.TempDir()
106104
bundlePath := filepath.Join(tmpDir, "test-container")
107-
createTestBundle(t, bundlePath)
105+
setupTransformTestBundle(t, bundlePath)
108106

109-
b, err := bundle.Load(ctx, bundlePath)
107+
b, err := Load(ctx, bundlePath)
110108
require.NoError(t, err)
111109

112110
err = AdaptForVM(ctx, b)
@@ -134,9 +132,9 @@ func TestAdaptForVM(t *testing.T) {
134132
t.Run("adds cgroup2 mount if missing", func(t *testing.T) {
135133
tmpDir := t.TempDir()
136134
bundlePath := filepath.Join(tmpDir, "test-container")
137-
createTestBundle(t, bundlePath)
135+
setupTransformTestBundle(t, bundlePath)
138136

139-
b, err := bundle.Load(ctx, bundlePath)
137+
b, err := Load(ctx, bundlePath)
140138
require.NoError(t, err)
141139

142140
err = AdaptForVM(ctx, b)
@@ -171,7 +169,7 @@ func TestAdaptForVM(t *testing.T) {
171169
require.NoError(t, os.WriteFile(filepath.Join(bundlePath, "config.json"), specBytes, 0600))
172170
require.NoError(t, os.MkdirAll(filepath.Join(bundlePath, "rootfs"), 0750))
173171

174-
b, err := bundle.Load(ctx, bundlePath)
172+
b, err := Load(ctx, bundlePath)
175173
require.NoError(t, err)
176174

177175
err = AdaptForVM(ctx, b)
@@ -185,9 +183,9 @@ func TestAdaptForVM(t *testing.T) {
185183
t.Run("grants full capabilities", func(t *testing.T) {
186184
tmpDir := t.TempDir()
187185
bundlePath := filepath.Join(tmpDir, "test-container")
188-
createTestBundle(t, bundlePath)
186+
setupTransformTestBundle(t, bundlePath)
189187

190-
b, err := bundle.Load(ctx, bundlePath)
188+
b, err := Load(ctx, bundlePath)
191189
require.NoError(t, err)
192190

193191
err = AdaptForVM(ctx, b)
@@ -212,7 +210,7 @@ func TestAdaptForVM(t *testing.T) {
212210
require.NoError(t, os.WriteFile(filepath.Join(bundlePath, "config.json"), specBytes, 0600))
213211
require.NoError(t, os.MkdirAll(filepath.Join(bundlePath, "rootfs"), 0750))
214212

215-
b, err := bundle.Load(ctx, bundlePath)
213+
b, err := Load(ctx, bundlePath)
216214
require.NoError(t, err)
217215

218216
err = AdaptForVM(ctx, b)
@@ -226,7 +224,7 @@ func TestLoadForCreate(t *testing.T) {
226224
t.Run("applies all transforms", func(t *testing.T) {
227225
tmpDir := t.TempDir()
228226
bundlePath := filepath.Join(tmpDir, "test-container")
229-
createTestBundle(t, bundlePath)
227+
setupTransformTestBundle(t, bundlePath)
230228

231229
testFile := filepath.Join(bundlePath, "app.conf")
232230
require.NoError(t, os.WriteFile(testFile, []byte("config"), 0600))

internal/shim/cpuhotplug/controller.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ type Config struct {
5151
}
5252

5353
const (
54-
defaultMonitorInterval = 5 * time.Second
55-
defaultScaleUpCooldown = 10 * time.Second
56-
defaultScaleDownCooldown = 30 * time.Second
57-
defaultScaleUpThreshold = 80.0
54+
defaultMonitorInterval = 5 * time.Second
55+
defaultScaleUpCooldown = 10 * time.Second
56+
defaultScaleDownCooldown = 30 * time.Second
57+
defaultScaleUpThreshold = 80.0
5858
defaultScaleDownThreshold = 50.0
59-
defaultThrottleLimit = 5.0
60-
defaultScaleUpStability = 2
59+
defaultThrottleLimit = 5.0
60+
defaultScaleUpStability = 2
6161
defaultScaleDownStability = 6
6262
)
6363

@@ -253,7 +253,7 @@ func (c *Controller) ScaleUp(ctx context.Context) error {
253253
}
254254

255255
// Find first available CPU ID
256-
for nextID := 0; nextID < c.maxCPUs; nextID++ {
256+
for nextID := range c.maxCPUs {
257257
if existingCPUs[nextID] {
258258
continue
259259
}

internal/shim/hotplug/monitor_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ type mockScaler struct {
2121
scaleUpErr error
2222
scaleDownErr error
2323

24-
evaluateCalls atomic.Int32
25-
scaleUpCalls atomic.Int32
24+
evaluateCalls atomic.Int32
25+
scaleUpCalls atomic.Int32
2626
scaleDownCalls atomic.Int32
2727
}
2828

@@ -50,9 +50,9 @@ func (m *mockScaler) ScaleDown(ctx context.Context) error {
5050
}
5151

5252
func TestScaleDirection(t *testing.T) {
53-
assert.Equal(t, ScaleDirection(0), ScaleNone)
54-
assert.Equal(t, ScaleDirection(1), ScaleUp)
55-
assert.Equal(t, ScaleDirection(2), ScaleDown)
53+
assert.Equal(t, ScaleNone, ScaleDirection(0))
54+
assert.Equal(t, ScaleUp, ScaleDirection(1))
55+
assert.Equal(t, ScaleDown, ScaleDirection(2))
5656
}
5757

5858
func TestNewMonitor(t *testing.T) {

internal/shim/task/create.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"github.com/spin-stack/spinbox/internal/shim/lifecycle"
2727
platformNetwork "github.com/spin-stack/spinbox/internal/shim/platform/network"
2828
"github.com/spin-stack/spinbox/internal/shim/resources"
29-
"github.com/spin-stack/spinbox/internal/shim/transform"
3029
)
3130

3231
// createCleanup tracks resources that need cleanup on failure.
@@ -121,7 +120,7 @@ func (s *service) setupVMInstance(ctx context.Context, state *createState) error
121120
}
122121

123122
// Load and transform bundle
124-
b, err := transform.LoadForCreate(ctx, r.Bundle)
123+
b, err := bundle.LoadForCreate(ctx, r.Bundle)
125124
if err != nil {
126125
return err
127126
}

0 commit comments

Comments
 (0)