From 51b95b7e94c88669befc0842fb192e0bfdbfe97c Mon Sep 17 00:00:00 2001 From: Martijn Date: Tue, 10 Nov 2026 16:59:59 +0100 Subject: [PATCH 1/2] chore: add martijnhoekstra to contributors Signed-off-by: Martijn --- .github/contributors.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/contributors.yaml b/.github/contributors.yaml index ee3ba7e4a..8031d24c9 100644 --- a/.github/contributors.yaml +++ b/.github/contributors.yaml @@ -161,3 +161,6 @@ users: Inuth0603: name: Divyam Agarwal email: iitdivyamagarwal@gmail.com + martijnhoekstra: + name: Martijn + email: martijnhoekstra@gmail.com From 854ab3b87d203aca0c7e613f71ba2039fa562680 Mon Sep 17 00:00:00 2001 From: Martijn Date: Sun, 8 Nov 2026 20:17:49 +0100 Subject: [PATCH 2/2] fix(hermit): pass the gateway as part of ip= Hermit reads the address and the gateway from one boot argument, ip=/:. It does not parse a separate gateway=, so the guest got no default route and could only answer clients on its own subnet. Fixes: #1197 Signed-off-by: Martijn --- pkg/unikontainers/unikernels/hermit_rs.go | 10 ++- .../unikernels/hermit_rs_test.go | 87 +++++++++++++++++++ 2 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 pkg/unikontainers/unikernels/hermit_rs_test.go diff --git a/pkg/unikontainers/unikernels/hermit_rs.go b/pkg/unikontainers/unikernels/hermit_rs.go index 3a587f640..0cfeac8d2 100644 --- a/pkg/unikontainers/unikernels/hermit_rs.go +++ b/pkg/unikontainers/unikernels/hermit_rs.go @@ -39,11 +39,13 @@ type HermitNet struct { func (h *Hermit) CommandString() (string, error) { var args []string + // Hermit takes the gateway as part of ip=/:. if h.Net.Address != "" { - args = append(args, fmt.Sprintf("ip=%s/%d", h.Net.Address, h.Net.Mask)) - } - if h.Net.Gateway != "" { - args = append(args, fmt.Sprintf("gateway=%s", h.Net.Gateway)) + ip := fmt.Sprintf("%s/%d", h.Net.Address, h.Net.Mask) + if h.Net.Gateway != "" { + ip += ":" + h.Net.Gateway + } + args = append(args, "ip="+ip) } // Add separator ONLY if we have net args AND a command diff --git a/pkg/unikontainers/unikernels/hermit_rs_test.go b/pkg/unikontainers/unikernels/hermit_rs_test.go new file mode 100644 index 000000000..5f1e0798e --- /dev/null +++ b/pkg/unikontainers/unikernels/hermit_rs_test.go @@ -0,0 +1,87 @@ +// 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 ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestHermitCommandString(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + hermit *Hermit + expected string + }{ + { + name: "no network configured", + hermit: &Hermit{}, + expected: "", + }, + { + name: "address and gateway", + hermit: &Hermit{ + Net: HermitNet{ + Address: "10.0.0.2", + Mask: 24, + Gateway: "10.0.0.1", + }, + }, + expected: "ip=10.0.0.2/24:10.0.0.1", + }, + { + name: "address without gateway", + hermit: &Hermit{ + Net: HermitNet{ + Address: "10.0.0.2", + Mask: 24, + }, + }, + expected: "ip=10.0.0.2/24", + }, + { + name: "network and application arguments", + hermit: &Hermit{ + Command: "/app --port 8080", + Net: HermitNet{ + Address: "10.0.0.2", + Mask: 24, + Gateway: "10.0.0.1", + }, + }, + expected: "ip=10.0.0.2/24:10.0.0.1 -- /app --port 8080", + }, + { + name: "application arguments without network", + hermit: &Hermit{ + Command: "/app --port 8080", + }, + expected: "/app --port 8080", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + result, err := tc.hermit.CommandString() + require.NoError(t, err) + assert.Equal(t, tc.expected, result) + }) + } +}