~james/core

core/spindle/engines/microvm/placement_linux.go -rw-r--r-- 1.8 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 16 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//go:build linux

package microvm

import (
	"fmt"
	"os/exec"
	"runtime"

	"tangled.org/core/spindle/engines/microvm/placement"
	"tangled.org/core/spindle/models"
)

func (e *Engine) ValidateWorkflowPlacement(wf *models.Workflow) error {
	state, ok := wf.Data.(*workflowState)
	if !ok || state == nil {
		return fmt.Errorf("microVM workflow state is not initialized")
	}
	return e.validateImagePlacement(state.ImageSpec)
}

func (e *Engine) validateImagePlacement(spec ImageSpec) error {
	if err := spec.Validate(); err != nil {
		return err
	}
	if !placement.IsNativeArchitecture(spec.Arch, runtime.GOARCH) {
		return fmt.Errorf("microVM image architecture %q is not native to executor architecture %q", spec.Arch, runtime.GOARCH)
	}
	if err := spec.validateImageFiles(); err != nil {
		return err
	}
	runner, err := runnerFor(spec.RunnerType)
	if err != nil {
		return err
	}
	if err := runner.Validate(spec, e.cfg.MicroVMPipelines.EnableKVM); err != nil {
		return err
	}
	if len(spec.Volumes) > 0 {
		if _, err := exec.LookPath("mkfs.ext4"); err != nil {
			return fmt.Errorf("required host command %q not found in PATH: %w", "mkfs.ext4", err)
		}
		for _, volume := range spec.Volumes {
			if volume.ReadOnly {
				return fmt.Errorf("read-only microvm volume %q is not supported yet", volume.Image)
			}
			if volume.FSType != "ext4" {
				return fmt.Errorf("microvm volume %q uses unsupported fsType %q", volume.Image, volume.FSType)
			}
			if volume.ImageType != "" && volume.ImageType != "raw" {
				return fmt.Errorf("microvm volume %q uses unsupported imageType %q", volume.Image, volume.ImageType)
			}
		}
	}

	request := resourcesForImage(spec)
	if !request.Fits(e.budget) || !request.Fits(e.maxWorkflow) {
		return fmt.Errorf("microVM image resources exceed executor limits: request=%v budget=%v max=%v", request, e.budget, e.maxWorkflow)
	}
	return nil
}