Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
b4ce05d
add watchers for system input files
nluaces Dec 2, 2025
1963564
change system controller reload to manual by default
nluaces Dec 4, 2025
039657e
fix unit test given that the default value for SYSTEM_AUTO_RELOAD is …
nluaces Dec 4, 2025
58a6230
make the reload type env variable manual by default
nluaces Jan 2, 2026
f4a552f
change log level
nluaces Jan 2, 2026
e754fd5
tear down if there is no site configured
nluaces Jan 27, 2026
dab70d7
adapt tests
nluaces Jan 27, 2026
f99f1c6
improve parameter readability
nluaces Feb 9, 2026
303188b
use appropiate logger when checking valid platforms
nluaces Feb 9, 2026
c64192f
add system reload type at the startup
nluaces Feb 9, 2026
867d6ac
modify default container function to respond properly if it is runnin…
nluaces Feb 11, 2026
a90b119
use the right container endpoint when removing a router
nluaces Feb 11, 2026
352e7ea
delete RemoveAll function as it is no longer necessary
nluaces Feb 12, 2026
6d3a0b9
system adaptor handler wip
nluaces Jan 18, 2026
71850d7
fix sslProfiles synchronisation
nluaces Jan 30, 2026
7ef8d1f
add some unit tests
nluaces Jan 31, 2026
e93419b
add extra validation to start, stop and reload system commands in cas…
nluaces Jan 31, 2026
363a1b1
only refresh the site with new resources if it is not a bundle
nluaces Jan 31, 2026
e7c1d58
add safety check when recovering skupper-local-normal listener port
nluaces Feb 10, 2026
d7bbe85
fix format
nluaces Feb 10, 2026
8941183
handle refresh error
nluaces Feb 10, 2026
d63b383
fix wrong setup of callbacks for the router state handler
nluaces Feb 10, 2026
5b88d34
handle errors better when loading a site
nluaces Feb 13, 2026
e0671e1
manage several sites scenario
nluaces Feb 15, 2026
e921cc6
allow reload command when the reloading type is set to auto
nluaces Feb 15, 2026
0e31736
add reload-type flag for system install command
nluaces Feb 23, 2026
99d9019
remove env variable check for the reload type in start/stop commands,…
nluaces Feb 27, 2026
3cd2fe1
remove bootstrapping in case loading the site from the input director…
nluaces Feb 27, 2026
0692497
check container engine env. variable if the skupper platform env vari…
nluaces Feb 27, 2026
6f2a30b
remove files in the correct path during teardown depending if it is r…
nluaces Feb 27, 2026
3b6f42a
modify how to get the configured platform
nluaces Mar 23, 2026
09c6900
add current and configured check validation
nluaces Mar 27, 2026
ed724f1
check container endpoint env variable first
nluaces Mar 27, 2026
8264e2c
add the correct value for the container endopint env variable in the …
nluaces Mar 27, 2026
879a8cd
remove unit test
nluaces Mar 27, 2026
99ce0cb
refactor: allow CONTAINER_ENDPOINT override via env variable and reor…
nluaces Apr 6, 2026
b225027
add platform mismatch validation in the system stop command instead o…
nluaces Apr 6, 2026
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
6 changes: 5 additions & 1 deletion api/types/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import (
)

const (
ENV_PLATFORM = "SKUPPER_PLATFORM"
ENV_PLATFORM = "SKUPPER_PLATFORM"
ENV_SYSTEM_AUTO_RELOAD = "SKUPPER_SYSTEM_RELOAD_TYPE"

SystemReloadTypeAuto string = "auto"
SystemReloadTypeManual string = "manual"
)

type ConnectorCreateOptions struct {
Expand Down
5 changes: 5 additions & 0 deletions cmd/system-controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (
"syscall"
"time"

"github.com/skupperproject/skupper/api/types"
"github.com/skupperproject/skupper/internal/nonkube/controller"
"github.com/skupperproject/skupper/internal/utils"
"github.com/skupperproject/skupper/internal/version"
"github.com/skupperproject/skupper/pkg/nonkube/api"
)
Expand All @@ -23,6 +25,9 @@ func main() {
if api.IsRunningInContainer() {
slog.Info("Host path info:", slog.String("path", api.GetHostNamespacesPath()))
}
systemReloadType := utils.DefaultStr(os.Getenv(types.ENV_SYSTEM_AUTO_RELOAD),
types.SystemReloadTypeManual)
slog.Info("System Reload:", slog.String("type", systemReloadType))
if err := os.MkdirAll(namespacesPath, 0755); err != nil {
slog.Error("Error creating skupper namespaces directory", slog.String("path", namespacesPath), slog.Any("error", err))
os.Exit(1)
Expand Down
1 change: 1 addition & 0 deletions internal/cmd/skupper/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var (
WorkloadTypes = []string{"deployment", "service", "daemonset", "statefulset"}
WaitStatusTypes = []string{"ready", "configured", "none"}
BundleTypes = []string{"tarball", "shell-script"}
ReloadTypes = []string{"manual", "auto"}
)

const (
Expand Down
7 changes: 7 additions & 0 deletions internal/cmd/skupper/common/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ for other Kubernetes flavors, loadbalancer is the default.`

FlagNameFileName = "filename"
FlagDescFileName = "The name of the file with custom resources"

FlagNameReloadType = "reload-type"
FlagDescReloadType = "Specify the type of reload to perform. Choices: manual, auto"
)

type CommandSiteCreateFlags struct {
Expand Down Expand Up @@ -265,3 +268,7 @@ type CommandSystemApplyFlags struct {
type CommandSystemDeleteFlags struct {
Filename string
}

type CommandSystemInstallFlags struct {
ReloadType string
}
3 changes: 3 additions & 0 deletions internal/cmd/skupper/system/kube/system_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package kube

import (
"fmt"

"github.com/skupperproject/skupper/internal/cmd/skupper/common"
skupperv2alpha1 "github.com/skupperproject/skupper/pkg/generated/client/clientset/versioned/typed/skupper/v2alpha1"
"github.com/spf13/cobra"
"k8s.io/client-go/kubernetes"
Expand All @@ -12,6 +14,7 @@ type CmdSystemInstall struct {
KubeClient kubernetes.Interface
CobraCmd *cobra.Command
Namespace string
Flags *common.CommandSystemInstallFlags
}

func NewCmdSystemInstall() *CmdSystemInstall {
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/skupper/system/nonkube/system_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ func (cmd *CmdSystemApply) Run() error {
}

if crApplied {
fmt.Println("Custom resources are applied. If a site is already running, run `skupper system reload` to make effective the changes.")
fmt.Println("Custom resources are applied.")
}

return nil
Expand Down
24 changes: 21 additions & 3 deletions internal/cmd/skupper/system/nonkube/system_install.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package nonkube
import (
"errors"
"fmt"

"github.com/skupperproject/skupper/api/types"
"github.com/skupperproject/skupper/internal/cmd/skupper/common"
"github.com/skupperproject/skupper/internal/config"
"github.com/skupperproject/skupper/internal/utils/validator"

"github.com/skupperproject/skupper/internal/nonkube/bootstrap"
"github.com/spf13/cobra"
Expand All @@ -13,7 +16,9 @@ import (
type CmdSystemInstall struct {
CobraCmd *cobra.Command
Namespace string
SystemInstall func(string) error
SystemInstall func(string, string) error
Flags *common.CommandSystemInstallFlags
reloadType string
}

func NewCmdSystemInstall() *CmdSystemInstall {
Expand All @@ -30,6 +35,7 @@ func (cmd *CmdSystemInstall) NewClient(cobraCommand *cobra.Command, args []strin
func (cmd *CmdSystemInstall) ValidateInput(args []string) error {

var validationErrors []error
reloadTypeValidator := validator.NewOptionValidator(common.ReloadTypes)

if len(args) > 0 {
validationErrors = append(validationErrors, fmt.Errorf("this command does not accept arguments"))
Expand All @@ -38,13 +44,25 @@ func (cmd *CmdSystemInstall) ValidateInput(args []string) error {
if config.GetPlatform() != types.PlatformPodman && config.GetPlatform() != types.PlatformDocker {
validationErrors = append(validationErrors, fmt.Errorf("the selected platform is not supported by this command. There is nothing to install"))
}

if cmd.Flags != nil && cmd.Flags.ReloadType != "" {
ok, err := reloadTypeValidator.Evaluate(cmd.Flags.ReloadType)
if !ok {
validationErrors = append(validationErrors, fmt.Errorf("reload type is not valid: %s", err))
}
}

return errors.Join(validationErrors...)
}

func (cmd *CmdSystemInstall) InputToOptions() {}
func (cmd *CmdSystemInstall) InputToOptions() {
if cmd.Flags != nil && cmd.Flags.ReloadType != "" {
cmd.reloadType = cmd.Flags.ReloadType
}
}

func (cmd *CmdSystemInstall) Run() error {
err := cmd.SystemInstall(string(config.GetPlatform()))
err := cmd.SystemInstall(string(config.GetPlatform()), cmd.reloadType)

if err != nil {
return fmt.Errorf("failed to configure the environment : %s", err)
Expand Down
18 changes: 14 additions & 4 deletions internal/cmd/skupper/system/nonkube/system_install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package nonkube

import (
"fmt"
"github.com/skupperproject/skupper/internal/config"
"os"
"testing"

cmd "github.com/skupperproject/skupper/internal/cmd/skupper/common"
"github.com/skupperproject/skupper/internal/config"

"github.com/skupperproject/skupper/internal/cmd/skupper/common/testutils"
"gotest.tools/v3/assert"
)
Expand All @@ -15,6 +17,7 @@ func TestCmdSystemInstall_ValidateInput(t *testing.T) {
name string
args []string
platform string
reloadType string
expectedError string
}

Expand All @@ -30,6 +33,12 @@ func TestCmdSystemInstall_ValidateInput(t *testing.T) {
platform: "linux",
expectedError: "the selected platform is not supported by this command. There is nothing to install",
},
{
name: "reload type not supported",
reloadType: "both",
platform: "podman",
expectedError: "reload type is not valid: value both not allowed. It should be one of this options: [manual auto]",
},
}

for _, test := range testTable {
Expand All @@ -39,7 +48,8 @@ func TestCmdSystemInstall_ValidateInput(t *testing.T) {
err := os.Setenv("SKUPPER_PLATFORM", test.platform)
assert.Check(t, err == nil)

command := &CmdSystemInstall{}
command := &CmdSystemInstall{Flags: &cmd.CommandSystemInstallFlags{}}
command.Flags.ReloadType = test.reloadType

testutils.CheckValidateInput(t, command, test.expectedError, test.args)
})
Expand Down Expand Up @@ -96,7 +106,7 @@ func newCmdSystemInstallWithMocks(podmanSocketEnablementFails bool) *CmdSystemIn
return cmdMock
}

func mockCmdSystemInstall(platform string) error { return nil }
func mockCmdSystemInstallSocketEnablementFails(platform string) error {
func mockCmdSystemInstall(platform string, reloadType string) error { return nil }
func mockCmdSystemInstallSocketEnablementFails(platform string, reloadType string) error {
return fmt.Errorf("systemd failed to enable podman socket")
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ func TestCmdSystemReload_ValidateInput(t *testing.T) {

for _, test := range testTable {
t.Run(test.name, func(t *testing.T) {

command := &CmdSystemReload{}
command.Namespace = test.namespace
command.CobraCmd = common.ConfigureCobraCommand(common.PlatformLinux, common.SkupperCmdDescription{}, command, nil)
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/skupper/system/nonkube/system_start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"testing"

"github.com/skupperproject/skupper/api/types"
"github.com/skupperproject/skupper/internal/cmd/skupper/common"
"github.com/skupperproject/skupper/internal/cmd/skupper/common/testutils"
"github.com/skupperproject/skupper/internal/config"
Expand Down Expand Up @@ -38,7 +39,7 @@ func TestCmdSystemSetup_ValidateInput(t *testing.T) {

for _, test := range testTable {
t.Run(test.name, func(t *testing.T) {

t.Setenv(types.ENV_SYSTEM_AUTO_RELOAD, types.SystemReloadTypeManual)
command := &CmdSystemStart{}
command.CobraCmd = common.ConfigureCobraCommand(common.PlatformLinux, common.SkupperCmdDescription{}, command, nil)
command.Namespace = test.namespace
Expand Down
16 changes: 16 additions & 0 deletions internal/cmd/skupper/system/nonkube/system_stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"errors"
"fmt"

"github.com/skupperproject/skupper/api/types"
"github.com/skupperproject/skupper/internal/config"
"github.com/skupperproject/skupper/internal/nonkube/bootstrap"
"github.com/skupperproject/skupper/internal/nonkube/common"
"github.com/skupperproject/skupper/internal/utils/validator"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -45,6 +47,20 @@ func (cmd *CmdSystemStop) ValidateInput(args []string) error {
}
}

platformLoader := &common.NamespacePlatformLoader{}
configuredPlatform, err := platformLoader.Load(cmd.Namespace)
if err != nil {
return err
}

currentPlatform := config.GetPlatform()
if currentPlatform.IsKubernetes() {
currentPlatform = types.PlatformPodman
}
if string(currentPlatform) != configuredPlatform {
validationErrors = append(validationErrors, fmt.Errorf("existing namespace uses %q platform and it cannot change to %q", configuredPlatform, string(currentPlatform)))
}

return errors.Join(validationErrors...)
}

Expand Down
65 changes: 55 additions & 10 deletions internal/cmd/skupper/system/nonkube/system_stop_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,82 @@ package nonkube

import (
"fmt"
"os"
"path"
"testing"

"github.com/skupperproject/skupper/api/types"
"github.com/skupperproject/skupper/internal/cmd/skupper/common"
"github.com/skupperproject/skupper/internal/cmd/skupper/common/testutils"
"github.com/skupperproject/skupper/internal/config"
"github.com/skupperproject/skupper/pkg/nonkube/api"
"gotest.tools/v3/assert"
)

func TestCmdSystemTearDown_ValidateInput(t *testing.T) {
type test struct {
name string
namespace string
args []string
expectedError string
name string
namespace string
args []string
envSystemReload string
expectedError string
configPlatform string // platform.yaml content
currentPlatform string // SKUPPER_PLATFORM env var value
}

testTable := []test{
{
name: "arg-not-accepted",
args: []string{"namespace"},
expectedError: "this command does not accept arguments",
name: "arg-not-accepted",
args: []string{"namespace"},
configPlatform: "podman",
currentPlatform: "podman",
expectedError: "this command does not accept arguments",
},
{
name: "invalid-namespace",
namespace: "Invalid",
configPlatform: "docker",
currentPlatform: "docker",
expectedError: "namespace is not valid: value does not match this regular expression: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
},
{
name: "invalid-namespace",
namespace: "Invalid",
expectedError: "namespace is not valid: value does not match this regular expression: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
name: "platform-mismatch-podman-vs-docker",
namespace: "test-ns",
configPlatform: "podman",
currentPlatform: "docker",
expectedError: `existing namespace uses "podman" platform and it cannot change to "docker"`,
},
}

for _, test := range testTable {
t.Run(test.name, func(t *testing.T) {

// Create a temporary directory to simulate the namespace output path
tmpDir := t.TempDir()

namespace := test.namespace
if namespace == "" {
namespace = "default"
}

internalDir := path.Join(tmpDir, "skupper", "namespaces", namespace, string(api.InternalBasePath))
err := os.MkdirAll(internalDir, 0755)
assert.NilError(t, err)

//create platform config file
platformYaml := fmt.Sprintf("platform: %s\n", test.configPlatform)
err = os.WriteFile(path.Join(internalDir, "platform.yaml"), []byte(platformYaml), 0644)
assert.NilError(t, err)

t.Setenv("XDG_DATA_HOME", tmpDir)

//set the current platform
config.ClearPlatform()
t.Setenv(types.ENV_PLATFORM, test.currentPlatform)
t.Cleanup(func() {
config.ClearPlatform()
})

command := &CmdSystemStop{}
command.Namespace = test.namespace
command.CobraCmd = common.ConfigureCobraCommand(common.PlatformLinux, common.SkupperCmdDescription{}, command, nil)
Expand Down
6 changes: 6 additions & 0 deletions internal/cmd/skupper/system/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,14 @@ func CmdSystemInstallFactory(configuredPlatform common.Platform) *cobra.Command

cmd := common.ConfigureCobraCommand(configuredPlatform, cmdSystemInstallDesc, kubeCommand, nonKubeCommand)

cmdFlags := common.CommandSystemInstallFlags{}

cmd.Flags().StringVar(&cmdFlags.ReloadType, common.FlagNameReloadType, "manual", common.FlagDescReloadType)

kubeCommand.CobraCmd = cmd
kubeCommand.Flags = &cmdFlags
nonKubeCommand.CobraCmd = cmd
nonKubeCommand.Flags = &cmdFlags

return cmd
}
Expand Down
8 changes: 5 additions & 3 deletions internal/cmd/skupper/system/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ func TestCmdSystemFactory(t *testing.T) {
command: CmdSystemGenerateBundleFactory(common.PlatformPodman),
},
{
name: "CmdSystemInstallFactory",
expectedFlagsWithDefaultValue: map[string]interface{}{},
command: CmdSystemInstallFactory(common.PlatformKubernetes),
name: "CmdSystemInstallFactory",
expectedFlagsWithDefaultValue: map[string]interface{}{
common.FlagNameReloadType: "manual",
},
command: CmdSystemInstallFactory(common.PlatformKubernetes),
},
{
name: "CmdSystemUninstallFactory",
Expand Down
2 changes: 1 addition & 1 deletion internal/kube/adaptor/config_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func syncConnectors(agent *qdr.Agent, desired *qdr.RouterConfig) error {

ignorePrefix := "auto-mesh"
if differences := qdr.ConnectorsDifference(actual, desired, &ignorePrefix); !differences.Empty() {
if err = agent.UpdateConnectorConfig(differences); err != nil {
if err = agent.UpdateConnectorConfig(differences, true); err != nil {
return fmt.Errorf("Error syncing connectors: %s", err)
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/nonkube/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func Bootstrap(config *Config) (*api.SiteState, error) {
if err != nil {
return nil, fmt.Errorf("failed to load site state: %v", err)
}
// if sources are being consume from namespace sources, they must be properly set
// if sources are being consumed from namespace sources, they must be properly set
crNamespace := siteState.GetNamespace()
targetNamespace := utils.DefaultStr(config.Namespace, "default")
if config.InputPath == sourcesPath {
Expand Down
Loading
Loading