computer-host/internal/firecracker/sdk.go

92 lines
2.4 KiB
Go

package firecracker
import (
"fmt"
"net"
"net/netip"
"os"
"path/filepath"
"strings"
sdk "github.com/firecracker-microvm/firecracker-go-sdk"
models "github.com/firecracker-microvm/firecracker-go-sdk/client/models"
)
const defaultNumaNode = 0
func buildSDKConfig(spec MachineSpec, paths machinePaths, network NetworkAllocation, firecrackerBinaryPath string, jailerBinaryPath string) (sdk.Config, error) {
if err := spec.Validate(); err != nil {
return sdk.Config{}, err
}
firecrackerBinaryPath = strings.TrimSpace(firecrackerBinaryPath)
if firecrackerBinaryPath == "" {
return sdk.Config{}, fmt.Errorf("firecracker binary path is required")
}
jailerBinaryPath = strings.TrimSpace(jailerBinaryPath)
if jailerBinaryPath == "" {
return sdk.Config{}, fmt.Errorf("jailer binary path is required")
}
drives := sdk.NewDrivesBuilder(spec.RootFSPath)
for _, drive := range spec.Drives {
drives = drives.AddDrive(
drive.Path,
drive.ReadOnly,
sdk.WithDriveID(strings.TrimSpace(drive.ID)),
)
}
cfg := sdk.Config{
SocketPath: paths.SocketName,
KernelImagePath: spec.KernelImagePath,
KernelArgs: strings.TrimSpace(spec.KernelArgs),
Drives: drives.Build(),
NetworkInterfaces: sdk.NetworkInterfaces{{
StaticConfiguration: &sdk.StaticNetworkConfiguration{
HostDevName: network.TapName,
MacAddress: network.GuestMAC,
IPConfiguration: &sdk.IPConfiguration{
IPAddr: toIPNet(network.GuestCIDR),
Gateway: net.ParseIP(network.GatewayIP.String()),
Nameservers: nil,
},
},
}},
MachineCfg: models.MachineConfiguration{
VcpuCount: sdk.Int64(spec.VCPUs),
MemSizeMib: sdk.Int64(spec.MemoryMiB),
Smt: sdk.Bool(false),
},
JailerCfg: &sdk.JailerConfig{
GID: sdk.Int(os.Getgid()),
UID: sdk.Int(os.Getuid()),
ID: string(spec.ID),
NumaNode: sdk.Int(defaultNumaNode),
ExecFile: firecrackerBinaryPath,
JailerBinary: jailerBinaryPath,
ChrootBaseDir: paths.JailerBaseDir,
ChrootStrategy: sdk.NewNaiveChrootStrategy(filepath.Clean(spec.KernelImagePath)),
},
VMID: string(spec.ID),
}
if spec.Vsock != nil {
cfg.VsockDevices = []sdk.VsockDevice{{
ID: spec.Vsock.ID,
Path: spec.Vsock.Path,
CID: spec.Vsock.CID,
}}
}
return cfg, nil
}
func toIPNet(prefix netip.Prefix) net.IPNet {
bits := prefix.Bits()
return net.IPNet{
IP: net.ParseIP(prefix.Addr().String()),
Mask: net.CIDRMask(bits, 32),
}
}