Skip to content

Commit

Permalink
Fix dual stack installation with cloud provider (#432)
Browse files Browse the repository at this point in the history
Fixes k0sproject/k0s#2464

--node-ip is incompatible with cloud providers because:
kubernetes/kubernetes#95239

Not defining the flag --node-ip if --enable-cloud-provider is defined
fixes the issue. In the long term we need to handle the configuration
using a KubeletConfiguration file instead of flags. But for now this
fixes the issue.

Signed-off-by: Juan Luis de Sousa-Valadas Castaño <[email protected]>
  • Loading branch information
juanluisvaladas authored Dec 12, 2022
1 parent 0e8e8c5 commit 53a7d8e
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 15 deletions.
6 changes: 5 additions & 1 deletion phase/initialize_k0s.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ func (p *InitializeK0s) Run() error {
}

log.Infof("%s: installing k0s controller", h)
if err := h.Exec(h.K0sInstallCommand()); err != nil {
cmd, err := h.K0sInstallCommand()
if err != nil {
return err
}
if err = h.Exec(cmd); err != nil {
return err
}

Expand Down
6 changes: 5 additions & 1 deletion phase/install_controllers.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,11 @@ func (p *InstallControllers) Run() error {
}()

log.Infof("%s: installing k0s controller", h)
if err := h.Exec(h.K0sInstallCommand()); err != nil {
cmd, err := h.K0sInstallCommand()
if err != nil {
return err
}
if err = h.Exec(cmd); err != nil {
return err
}

Expand Down
6 changes: 5 additions & 1 deletion phase/install_workers.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,11 @@ func (p *InstallWorkers) Run() error {
}

log.Infof("%s: installing k0s worker", h)
if err := h.Exec(h.K0sInstallCommand()); err != nil {
cmd, err := h.K0sInstallCommand()
if err != nil {
return err
}
if err = h.Exec(cmd); err != nil {
return err
}

Expand Down
17 changes: 17 additions & 0 deletions pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,23 @@ func (f Flags) GetValue(s string) string {
return val
}

// GetValue returns the boolean value part of a flag such as true for a flag like "--san"
// If the flag is not defined returns false. If the flag is defined without a value, returns true
// If no value is set, returns true
func (f Flags) GetBoolean(s string) (bool, error) {
idx := f.Index(s)
if idx < 0 {
return false, nil
}

fl := f.GetValue(s)
if fl == "" {
return true, nil
}

return strconv.ParseBool(fl)
}

// Delete removes a matching flag from the list
func (f *Flags) Delete(s string) {
idx := f.Index(s)
Expand Down
53 changes: 53 additions & 0 deletions pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,56 @@ func TestString(t *testing.T) {
flags := Flags{"--help", "--setting=false"}
require.Equal(t, "--help --setting=false", flags.Join())
}

func TestGetBoolean(t *testing.T) {
t.Run("Valid flags", func(t *testing.T) {
testsValid := []struct {
flag string
expect bool
}{
{"--flag", true},
{"--flag=true", true},
{"--flag=false", false},
{"--flag=1", true},
{"--flag=TRUE", true},
}
for _, test := range testsValid {
flags := Flags{test.flag}
result, err := flags.GetBoolean(test.flag)
require.NoError(t, err)
require.Equal(t, test.expect, result)

flags = Flags{"--unrelated-flag1", "--unrelated-flag2=foo", test.flag}
result, err = flags.GetBoolean(test.flag)
require.NoError(t, err)
require.Equal(t, test.expect, result)
}
})

t.Run("Invalid flags", func(t *testing.T) {
testsInvalid := []string{
"--flag=foo",
"--flag=2",
"--flag=TrUe",
"--flag=-4",
"--flag=FalSe",
}
for _, test := range testsInvalid {
flags := Flags{test}
_, err := flags.GetBoolean(test)
require.Error(t, err)

flags = Flags{"--unrelated-flag1", "--unrelated-flag2=foo", test}
_, err = flags.GetBoolean(test)
require.Error(t, err)
}
})

t.Run("Unknown flags", func(t *testing.T) {
flags := Flags{"--flag1=1", "--flag2"}
result, err := flags.GetBoolean("--flag3")
require.NoError(t, err)
require.Equal(t, result, false)

})
}
15 changes: 10 additions & 5 deletions pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func unQE(s string) string {
}

// K0sInstallCommand returns a full command that will install k0s service with necessary flags
func (h *Host) K0sInstallCommand() string {
func (h *Host) K0sInstallCommand() (string, error) {
role := h.Role
flags := h.InstallFlags

Expand Down Expand Up @@ -268,10 +268,15 @@ func (h *Host) K0sInstallCommand() string {
if old := flags.GetValue("--kubelet-extra-args"); old != "" {
extra = Flags{unQE(old)}
}
// set worker's private address to --node-ip in --extra-kubelet-args
if h.PrivateAddress != "" {
// set worker's private address to --node-ip in --extra-kubelet-args if cloud ins't enabled
enableCloudProvider, err := h.InstallFlags.GetBoolean("--enable-cloud-provider")
if err != nil {
return "", fmt.Errorf("--enable-cloud-provider flag is set to invalid value: %s. (%v)", h.InstallFlags.GetValue("--enable-cloud-provider"), err)
}
if !enableCloudProvider && h.PrivateAddress != "" {
extra.AddUnlessExist(fmt.Sprintf("--node-ip=%s", h.PrivateAddress))
}

if h.HostnameOverride != "" {
extra.AddOrReplace(fmt.Sprintf("--hostname-override=%s", h.HostnameOverride))
}
Expand All @@ -284,9 +289,9 @@ func (h *Host) K0sInstallCommand() string {
sudocmd, err := h.Sudo(cmd)
if err != nil {
log.Warnf("%s: %s", h, err.Error())
return cmd
return cmd, nil
}
return sudocmd
return sudocmd, nil
}

// K0sBackupCommand returns a full command to be used as run k0s backup
Expand Down
35 changes: 28 additions & 7 deletions pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,44 @@ func TestK0sInstallCommand(t *testing.T) {
h := Host{Role: "worker"}
h.Configurer = &mockconfigurer{}

require.Equal(t, `k0s install worker --token-file "from-configurer"`, h.K0sInstallCommand())
cmd, err := h.K0sInstallCommand()
require.NoError(t, err)
require.Equal(t, `k0s install worker --token-file "from-configurer"`, cmd)

h.Role = "controller"
h.Metadata.IsK0sLeader = true
require.Equal(t, `k0s install controller --config "from-configurer"`, h.K0sInstallCommand())
cmd, err = h.K0sInstallCommand()
require.NoError(t, err)
require.Equal(t, `k0s install controller --config "from-configurer"`, cmd)

h.Metadata.IsK0sLeader = false
require.Equal(t, `k0s install controller --token-file "from-configurer" --config "from-configurer"`, h.K0sInstallCommand())
cmd, err = h.K0sInstallCommand()
require.NoError(t, err)
require.Equal(t, `k0s install controller --token-file "from-configurer" --config "from-configurer"`, cmd)

h.Role = "controller+worker"
h.Metadata.IsK0sLeader = true
require.Equal(t, `k0s install controller --enable-worker --config "from-configurer"`, h.K0sInstallCommand())
cmd, err = h.K0sInstallCommand()
require.NoError(t, err)
require.Equal(t, `k0s install controller --enable-worker --config "from-configurer"`, cmd)
h.Metadata.IsK0sLeader = false
require.Equal(t, `k0s install controller --enable-worker --token-file "from-configurer" --config "from-configurer"`, h.K0sInstallCommand())
cmd, err = h.K0sInstallCommand()
require.NoError(t, err)
require.Equal(t, `k0s install controller --enable-worker --token-file "from-configurer" --config "from-configurer"`, cmd)

h.Role = "worker"
h.PrivateAddress = "10.0.0.9"
require.Equal(t, `k0s install worker --token-file "from-configurer" --kubelet-extra-args="--node-ip=10.0.0.9"`, h.K0sInstallCommand())
cmd, err = h.K0sInstallCommand()
require.NoError(t, err)
require.Equal(t, `k0s install worker --token-file "from-configurer" --kubelet-extra-args="--node-ip=10.0.0.9"`, cmd)

h.InstallFlags = []string{`--kubelet-extra-args="--foo bar"`}
require.Equal(t, `k0s install worker --kubelet-extra-args="--foo bar --node-ip=10.0.0.9" --token-file "from-configurer"`, h.K0sInstallCommand())
cmd, err = h.K0sInstallCommand()
require.NoError(t, err)
require.Equal(t, `k0s install worker --kubelet-extra-args="--foo bar --node-ip=10.0.0.9" --token-file "from-configurer"`, cmd)

h.InstallFlags = []string{`--enable-cloud-provider`}
cmd, err = h.K0sInstallCommand()
require.NoError(t, err)
require.Equal(t, `k0s install worker --enable-cloud-provider --token-file "from-configurer"`, cmd)
}

0 comments on commit 53a7d8e

Please sign in to comment.