Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ supported VM/Sandbox monitors and unikernels:
| Mewz | QEMU | x86 | In-memory |
| Linux | QEMU, Firecracker | x86 | Initrd, Block/Devmapper, 9pfs, Virtiofs |
| Hermit | QEMU | x86 | Initrd |

| IncludeOS | QEMU solo5-hvt solo5-svt | x86 aarch64 | Block/Devmapper |
We plan to add support for more unikernel frameworks and other platforms too.
Feel free to [contact](#Contact) us for a specific unikernel framework or similar
technologies that you would like to see in `urunc`.
Expand Down
2 changes: 2 additions & 0 deletions docs/Sample-images.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ We plan to create and maintain multi-platform images soon, as well as enrich thi
- harbor.nbfc.io/nubificus/urunc/busybox-qemu-linux-raw:latest
- harbor.nbfc.io/nubificus/urunc/busybox-firecracker-linux-raw:latest
- harbor.nbfc.io/nubificus/urunc/hello-world-qemu-hermit-initrd:latest
- harbor.nbfc.io/nubificus/urunc/hello-qemu-includeos:latest
- harbor.nbfc.io/nubificus/urunc/hello-hvt-includeos:latest
1 change: 1 addition & 0 deletions docs/hypervisor-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Supported unikernel frameworks with `urunc`:
- [Mewz](../unikernel-support#mewz)
- [Linux](../unikernel-support#linux)
- [Hermit](../unikernel-support#hermit)
- [includeOS](../unikernel-support#IncludeOS)

An example unikernel:

Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Sandbox monitors, along with the unikernels that can run on top of them.
| [Mewz](./unikernel-support#mewz)| [Qemu](./hypervisor-support#qemu) | x86 | In-memory |
| [Linux](./unikernel-support#linux)| [Qemu](./hypervisor-support#qemu), [Firecracker](./hypervisor-support#aws-firecracker) | x86, aarch64 | Initrd, Block/Devmapper, 9pfs, Virtiofs |
| [Hermit](./unikernel-support#hermit)| [Qemu](./hypervisor-support#qemu) | x86 | Initrd |

| [IncludeOS](./unikernel-support#includeos)| [Qemu](./hypervisor-support#qemu), [Solo5-hvt](./hypervisor-support#solo5-hvt), [Solo5-spt](./hypervisor-support#solo5-spt) | x86, aarch64 | Block/Devmapper |
<!-- ## urunc and the CNCF -->

## Community and Meetings
Expand Down
19 changes: 19 additions & 0 deletions docs/unikernel-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,26 @@ An example of running a Hermit unikernel with `urunc`:
```bash
sudo nerdctl run --rm -ti --runtime io.containerd.urunc.v2 harbor.nbfc.io/nubificus/urunc/hello-world-qemu-hermit-initrd:latest
```
### IncludeOS

[IncludeOS](https://github.com/includeos/IncludeOS) is a unikernel written in C++ designed for building web and cloud applications. IncludeOS can execute on top of [Solo5](https://github.com/Solo5/solo5) and [Qemu](https://www.qemu.org/), making it compatible with urunc through both these hypervisors.

#### IncludeOS and `urunc`

For IncludeOS with `urunc`, network and block storage access is supported through the respective monitor interfaces:

- **Solo5 (hvt/spt)**: IncludeOS accesses network via Solo5's tap interface and block storage through Solo5's block device interface
- **Qemu**: IncludeOS accesses network via virtio-net and block storage via virtio-blk

An example of IncludeOS on top of [Qemu](https://www.qemu.org/) with `urunc`:

```bash
sudo nerdctl run --rm -ti --runtime io.containerd.urunc.v2 <your-includeos-qemu-image>
```
An example of IncludeOS on top of Solo5-hvt with urunc:
```bash
sudo nerdctl run --rm -ti --runtime io.containerd.urunc.v2 <your-includeos-hvt-image>
```
## Future unikernels and frameworks:

In the near future, we plan to add support for the following frameworks:
Expand Down
127 changes: 127 additions & 0 deletions pkg/unikontainers/unikernels/includeos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// 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 unikernels

import (
"fmt"
"strings"

"github.com/urunc-dev/urunc/pkg/unikontainers/types"
)

const IncludeosUnikernel string = "includeos"

type IncludeOS struct {
Command string
Monitor string
Net IncludeOSNet
Block []IncludeOSBlock
}

type IncludeOSNet struct {
Address string
Gateway string
Mask string
}

type IncludeOSBlock struct {
ID string
HostPath string
}

func (i *IncludeOS) CommandString() (string, error) {
return fmt.Sprintf("%s %s %s %s", i.Net.Address,
i.Net.Gateway,
i.Net.Mask,
i.Command), nil
}

func (i *IncludeOS) SupportsBlock() bool {
return true
}

func (i *IncludeOS) SupportsFS(_ string) bool {
return false
}

func (i *IncludeOS) MonitorNetCli(ifName string, mac string) string {
switch i.Monitor {
case "hvt", "spt":
netOption := "--net:service=" + ifName
netOption += " --net-mac:service=" + mac
return netOption
case "qemu":
return ""
default:
return ""
}
}

func (i *IncludeOS) MonitorBlockCli() []types.MonitorBlockArgs {
if len(i.Block) == 0 {
return nil
}
switch i.Monitor {
case "hvt", "spt":
return []types.MonitorBlockArgs{
{
ID: "rootfs",
Path: i.Block[0].HostPath,
},
}
case "qemu":
// For QEMU, return block device configuration
return []types.MonitorBlockArgs{
{
ID: "rootfs",
Path: i.Block[0].HostPath,
},
}
default:
return nil
}
}

func (i *IncludeOS) MonitorCli() types.MonitorCliArgs {
return types.MonitorCliArgs{}
}

func (i *IncludeOS) Init(data types.UnikernelParams) error {
// if Mask is empty, there is no network support
if data.Net.Mask != "" {
i.Net.Address = data.Net.IP
i.Net.Gateway = data.Net.Gateway
i.Net.Mask = data.Net.Mask
}

i.Block = make([]IncludeOSBlock, 0, len(data.Block))
for _, blk := range data.Block {
newBlk := IncludeOSBlock{
ID: blk.ID,
HostPath: blk.Source,
}
i.Block = append(i.Block, newBlk)
}

i.Command = strings.Join(data.CmdLine, " ")
i.Monitor = data.Monitor

return nil
}

func newIncludeos() *IncludeOS {
includeosStruct := new(IncludeOS)
return includeosStruct
}
3 changes: 3 additions & 0 deletions pkg/unikontainers/unikernels/unikernel.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ func New(unikernelType string) (types.Unikernel, error) {
case HermitUnikernel:
unikernel := newHermit()
return unikernel, nil
case IncludeosUnikernel:
unikernel := newIncludeos()
return unikernel, nil
default:
return nil, ErrNotSupportedUnikernel
}
Expand Down
50 changes: 50 additions & 0 deletions tests/e2e/test_cases.go
Original file line number Diff line number Diff line change
Expand Up @@ -1208,5 +1208,55 @@ func dockerTestCases() []containerTestArgs {
Skippable: false,
TestFunc: namespaceTest,
},
{
Image: "harbor.nbfc.io/nubificus/urunc/hello-qemu-includeos:latest",
Name: "Qemu-includeos-hello-world",
Devmapper: false,
Seccomp: true,
UID: 0,
GID: 0,
Groups: []int64{},
Memory: "",
Cli: "",
Volumes: []containerVolume{},
StaticNet: false,
SideContainers: []string{},
Skippable: true,
ExpectOut: "Hello, world!",
TestFunc: matchTest,
},
{
Image: "harbor.nbfc.io/nubificus/urunc/http-server-qemu-includeos:latest",
Name: "Qemu-includeos-http-server",
Devmapper: false,
Seccomp: true,
UID: 0,
GID: 0,
Groups: []int64{},
Memory: "",
Cli: "",
Volumes: []containerVolume{},
StaticNet: false,
SideContainers: []string{},
Skippable: false,
TestFunc: pingTest,
},
{
Image: "harbor.nbfc.io/nubificus/urunc/hello-hvt-includeos:latest",
Name: "Hvt-includeos-hello-world",
Devmapper: false,
Seccomp: true,
UID: 0,
GID: 0,
Groups: []int64{},
Memory: "",
Cli: "",
Volumes: []containerVolume{},
StaticNet: false,
SideContainers: []string{},
Skippable: true,
ExpectOut: "Hello, world!",
TestFunc: matchTest,
},
}
}