diff --git a/pkg/unikontainers/hypervisors/hyperlight.go b/pkg/unikontainers/hypervisors/hyperlight.go new file mode 100644 index 000000000..e303ee83c --- /dev/null +++ b/pkg/unikontainers/hypervisors/hyperlight.go @@ -0,0 +1,71 @@ +// Copyright (c) 2023-2026, Nubificus LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hypervisors + +import ( + "strings" + + "github.com/urunc-dev/urunc/pkg/unikontainers/types" +) + +const ( + HyperlightVmm VmmType = "hyperlight" + HyperlightBinary string = "" +) + +type Hyperlight struct { + binaryPath string + binary string +} + +// Stop kills the hyperlight process +func (h *Hyperlight) Stop(pid int) error { + return killProcess(pid) +} + +// UsesKVM returns a bool value depending on if the monitor uses KVM +func (h *Hyperlight) UsesKVM() bool { + return true +} + +// SupportsSharedfs returns a bool value depending on the monitor support for shared-fs +func (h *Hyperlight) SupportsSharedfs(_ string) bool { + return false +} + +// Path returns the path to the hyperlight binary. +func (h *Hyperlight) Path() string { + return h.binaryPath +} + +// Ok checks if the hyperlight binary is available. +// Since hyperlight is embedded, we just return nil. +func (h *Hyperlight) Ok() error { + return nil +} + +func (h *Hyperlight) BuildExecCmd(args types.ExecArgs, _ types.Unikernel) ([]string, error) { + // Hyperlight is an embedded VMM, so we just run the unikernel directly. + cmdArgs := []string{args.UnikernelPath} + if args.Command != "" { + cmdArgs = append(cmdArgs, strings.Split(args.Command, " ")...) + } + return cmdArgs, nil +} + +// PreExec performs pre-execution setup. Hyperlight has no special pre-exec requirements. +func (h *Hyperlight) PreExec(_ types.ExecArgs) error { + return nil +} diff --git a/pkg/unikontainers/hypervisors/hyperlight_test.go b/pkg/unikontainers/hypervisors/hyperlight_test.go new file mode 100644 index 000000000..a99ff1f83 --- /dev/null +++ b/pkg/unikontainers/hypervisors/hyperlight_test.go @@ -0,0 +1,46 @@ +// Copyright (c) 2023-2026, Nubificus LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hypervisors + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/urunc-dev/urunc/pkg/unikontainers/types" +) + +func TestHyperlightBuildExecCmd(t *testing.T) { + h := &Hyperlight{} + args := types.ExecArgs{ + UnikernelPath: "/path/to/unikernel", + Command: "arg1 arg2", + } + + cmd, err := h.BuildExecCmd(args, nil) + assert.NoError(t, err) + assert.Equal(t, []string{"/path/to/unikernel", "arg1", "arg2"}, cmd) +} + +func TestHyperlightBuildExecCmdNoArgs(t *testing.T) { + h := &Hyperlight{} + args := types.ExecArgs{ + UnikernelPath: "/path/to/unikernel", + Command: "", + } + + cmd, err := h.BuildExecCmd(args, nil) + assert.NoError(t, err) + assert.Equal(t, []string{"/path/to/unikernel"}, cmd) +} diff --git a/pkg/unikontainers/hypervisors/vmm.go b/pkg/unikontainers/hypervisors/vmm.go index c8600957b..a4ea1d139 100644 --- a/pkg/unikontainers/hypervisors/vmm.go +++ b/pkg/unikontainers/hypervisors/vmm.go @@ -66,6 +66,12 @@ var vmmFactories = map[VmmType]VMMFactory{ return &CloudHypervisor{binary: binary, binaryPath: binaryPath} }, }, + HyperlightVmm: { + binary: HyperlightBinary, + createFunc: func(binary, binaryPath string, _ bool) types.VMM { + return &Hyperlight{binary: binary, binaryPath: binaryPath} + }, + }, } func NewVMM(vmmType VmmType, monitors map[string]types.MonitorConfig) (vmm types.VMM, err error) { @@ -98,6 +104,9 @@ func NewVMM(vmmType VmmType, monitors map[string]types.MonitorConfig) (vmm types } func getVMMPath(vmmType VmmType, binary string, monitors map[string]types.MonitorConfig) (string, error) { + if vmmType == HyperlightVmm { + return "", nil + } if vmmPath := monitors[string(vmmType)].BinaryPath; vmmPath != "" { return vmmPath, nil }