Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package k0sctl for openSUSE:Factory checked 
in at 2024-10-27 11:25:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/k0sctl (Old)
 and      /work/SRC/openSUSE:Factory/.k0sctl.new.2020 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "k0sctl"

Sun Oct 27 11:25:22 2024 rev:7 rq:1218409 version:0.19.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/k0sctl/k0sctl.changes    2024-09-16 
17:42:31.923708417 +0200
+++ /work/SRC/openSUSE:Factory/.k0sctl.new.2020/k0sctl.changes  2024-10-27 
11:25:47.287680621 +0100
@@ -1,0 +2,25 @@
+Fri Oct 25 12:22:54 UTC 2024 - opensuse_buildserv...@ojkastl.de
+
+- Update to version 0.19.2:
+  * Fix k0s CPLB config parsing interface conversion panic (#776)
+
+-------------------------------------------------------------------
+Wed Oct 23 08:40:19 UTC 2024 - opensuse_buildserv...@ojkastl.de
+
+- Update to version 0.19.1:
+  * Use go1.23.2, update dependencies (#774)
+  * Extract etcd membership check into a separate phase (#770)
+  * Remove all SANs manipulation as k0s does it on its own
+  * Validate worker connectivity to cluster-internal addresses
+  * Consider k0s onlyBindToAddress option when building API URLs
+  * Fall back to CPLB virtual address in external API URL
+  * Make Apply action phase list modifiable before Run()
+  * Shortcut to get an UnlockPhase for a LockPhase
+  * Add phase manager SetPhases to allow overriding the whole list
+  * Convenience Phases type for []phase.Phase
+  * Expose phase.Phase
+  * Bump k8s.io/client-go from 0.31.0 to 0.31.1 (#765)
+  * Bump github.com/go-playground/validator/v10 from 10.22.0 to
+    10.22.1 (#762)
+
+-------------------------------------------------------------------

Old:
----
  k0sctl-0.19.0.obscpio

New:
----
  k0sctl-0.19.2.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ k0sctl.spec ++++++
--- /var/tmp/diff_new_pack.MJwoD9/_old  2024-10-27 11:25:48.227719587 +0100
+++ /var/tmp/diff_new_pack.MJwoD9/_new  2024-10-27 11:25:48.231719753 +0100
@@ -17,10 +17,8 @@
 #
 
 
-%define __arch_install_post export NO_BRP_STRIP_DEBUG=true
-
 Name:           k0sctl
-Version:        0.19.0
+Version:        0.19.2
 Release:        0
 Summary:        A bootstrapping and management tool for k0s clusters
 License:        Apache-2.0
@@ -28,7 +26,10 @@
 URL:            https://github.com/k0sproject/k0sctl
 Source0:        %{name}-%{version}.tar.gz
 Source1:        vendor.tar.gz
-BuildRequires:  go >= 1.22
+BuildRequires:  bash-completion
+BuildRequires:  fish
+BuildRequires:  go >= 1.23.2
+BuildRequires:  zsh
 
 %description
 k0sctl is a bootstrapping and management tool for k0s clusters.
@@ -95,9 +96,9 @@
 sed -i '1d' %{buildroot}%{_datarootdir}/fish/vendor_completions.d/%{name}.fish
 
 # create the zsh completion file
-mkdir -p %{buildroot}%{_datarootdir}/zsh_completion.d/
-%{buildroot}/%{_bindir}/%{name} completion zsh > 
%{buildroot}%{_datarootdir}/zsh_completion.d/_%{name}
-sed -i '1d' %{buildroot}%{_datarootdir}/zsh_completion.d/_%{name}
+mkdir -p %{buildroot}%{_datarootdir}/zsh/site-functions/
+%{buildroot}/%{_bindir}/%{name} completion zsh > 
%{buildroot}%{_datarootdir}/zsh/site-functions/_%{name}
+sed -i '1d' %{buildroot}%{_datarootdir}/zsh/site-functions/_%{name}
 
 %check
 
@@ -107,16 +108,11 @@
 %{_bindir}/%{name}
 
 %files -n %{name}-bash-completion
-%dir %{_datarootdir}/bash-completion/completions/
 %{_datarootdir}/bash-completion/completions/%{name}
 
 %files -n %{name}-fish-completion
-%dir %{_datarootdir}/fish
-%dir %{_datarootdir}/fish/vendor_completions.d
 %{_datarootdir}/fish/vendor_completions.d/%{name}.fish
 
 %files -n %{name}-zsh-completion
-%defattr(-,root,root)
-%dir %{_datarootdir}/zsh_completion.d/
-%{_datarootdir}/zsh_completion.d/_%{name}
+%{_datarootdir}/zsh/site-functions/_%{name}
 

++++++ _service ++++++
--- /var/tmp/diff_new_pack.MJwoD9/_old  2024-10-27 11:25:48.259720914 +0100
+++ /var/tmp/diff_new_pack.MJwoD9/_new  2024-10-27 11:25:48.263721080 +0100
@@ -2,7 +2,7 @@
   <service name="obs_scm" mode="manual">
     <param name="url">https://github.com/k0sproject/k0sctl.git</param>
     <param name="scm">git</param>
-    <param name="revision">v0.19.0</param>
+    <param name="revision">v0.19.2</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.MJwoD9/_old  2024-10-27 11:25:48.279721743 +0100
+++ /var/tmp/diff_new_pack.MJwoD9/_new  2024-10-27 11:25:48.283721909 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/k0sproject/k0sctl.git</param>
-              <param 
name="changesrevision">9246ddc823198b572b51fb19bdf5effee4721a9d</param></service></servicedata>
+              <param 
name="changesrevision">081dfeb085418df4824e00778b092e77f84715ad</param></service></servicedata>
 (No newline at EOF)
 

++++++ k0sctl-0.19.0.obscpio -> k0sctl-0.19.2.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/action/apply.go 
new/k0sctl-0.19.2/action/apply.go
--- old/k0sctl-0.19.0/action/apply.go   2024-09-11 08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/action/apply.go   2024-10-25 12:43:06.000000000 +0200
@@ -15,7 +15,7 @@
        log "github.com/sirupsen/logrus"
 )
 
-type Apply struct {
+type ApplyOptions struct {
        // Manager is the phase manager
        Manager *phase.Manager
        // DisableDowngradeCheck skips the downgrade check
@@ -36,59 +36,81 @@
        ConfigPath string
 }
 
-func (a Apply) Run() error {
-       start := time.Now()
-
-       phase.NoWait = a.NoWait
-       phase.Force = a.Force
+type Apply struct {
+       ApplyOptions
+       Phases phase.Phases
+}
 
+// NewApply creates a new Apply action. The list of phases can be modified via 
the Phases field, for example:
+//
+//     apply := NewApply(opts)
+//     gatherK0sFacts := &phase.GatherK0sFacts{} // advisable to get the title 
from the phase itself instead of hardcoding the title.
+//     apply.Phases.InsertBefore(gatherK0sFacts.Title(), &myCustomPhase{}) // 
insert a custom phase before the GatherK0sFacts phase
+func NewApply(opts ApplyOptions) *Apply {
        lockPhase := &phase.Lock{}
-
-       a.Manager.AddPhase(
-               &phase.DefaultK0sVersion{},
-               &phase.Connect{},
-               &phase.DetectOS{},
-               lockPhase,
-               &phase.PrepareHosts{},
-               &phase.GatherFacts{},
-               &phase.ValidateHosts{},
-               &phase.GatherK0sFacts{},
-               &phase.ValidateFacts{SkipDowngradeCheck: 
a.DisableDowngradeCheck},
-
-               // if UploadBinaries: true
-               &phase.DownloadBinaries{}, // downloads k0s binaries to local 
cache
-               &phase.UploadK0s{},        // uploads k0s binaries to hosts 
from cache
-
-               // if UploadBinaries: false
-               &phase.DownloadK0s{}, // downloads k0s binaries directly from 
hosts
-
-               &phase.UploadFiles{},
-               &phase.InstallBinaries{},
-               &phase.PrepareArm{},
-               &phase.ConfigureK0s{},
-               &phase.Restore{
-                       RestoreFrom: a.RestoreFrom,
+       unlockPhase := lockPhase.UnlockPhase()
+       apply := &Apply{
+               ApplyOptions: opts,
+               Phases: phase.Phases{
+                       &phase.DefaultK0sVersion{},
+                       &phase.Connect{},
+                       &phase.DetectOS{},
+                       lockPhase,
+                       &phase.PrepareHosts{},
+                       &phase.GatherFacts{},
+                       &phase.ValidateHosts{},
+                       &phase.GatherK0sFacts{},
+                       &phase.ValidateFacts{SkipDowngradeCheck: 
opts.DisableDowngradeCheck},
+                       &phase.ValidateEtcdMembers{},
+
+                       // if UploadBinaries: true
+                       &phase.DownloadBinaries{}, // downloads k0s binaries to 
local cache
+                       &phase.UploadK0s{},        // uploads k0s binaries to 
hosts from cache
+
+                       // if UploadBinaries: false
+                       &phase.DownloadK0s{}, // downloads k0s binaries 
directly from hosts
+
+                       &phase.UploadFiles{},
+                       &phase.InstallBinaries{},
+                       &phase.PrepareArm{},
+                       &phase.ConfigureK0s{},
+                       &phase.Restore{
+                               RestoreFrom: opts.RestoreFrom,
+                       },
+                       &phase.RunHooks{Stage: "before", Action: "apply"},
+                       &phase.InitializeK0s{},
+                       &phase.InstallControllers{},
+                       &phase.InstallWorkers{},
+                       &phase.UpgradeControllers{},
+                       &phase.UpgradeWorkers{NoDrain: opts.NoDrain},
+                       &phase.Reinstall{},
+                       &phase.ResetWorkers{NoDrain: opts.NoDrain},
+                       &phase.ResetControllers{NoDrain: opts.NoDrain},
+                       &phase.RunHooks{Stage: "after", Action: "apply"},
+                       unlockPhase,
+                       &phase.Disconnect{},
                },
-               &phase.RunHooks{Stage: "before", Action: "apply"},
-               &phase.InitializeK0s{},
-               &phase.InstallControllers{},
-               &phase.InstallWorkers{},
-               &phase.UpgradeControllers{},
-               &phase.UpgradeWorkers{NoDrain: a.NoDrain},
-               &phase.Reinstall{},
-               &phase.ResetWorkers{NoDrain: a.NoDrain},
-               &phase.ResetControllers{NoDrain: a.NoDrain},
-               &phase.RunHooks{Stage: "after", Action: "apply"},
-       )
+       }
+       if opts.KubeconfigOut != nil {
+               apply.Phases.InsertBefore(unlockPhase.Title(), 
&phase.GetKubeconfig{APIAddress: opts.KubeconfigAPIAddress})
+       }
 
-       if a.KubeconfigOut != nil {
-               a.Manager.AddPhase(&phase.GetKubeconfig{APIAddress: 
a.KubeconfigAPIAddress})
+       return apply
+}
+
+// Run the Apply action
+func (a Apply) Run() error {
+       if len(a.Phases) == 0 {
+               // for backwards compatibility with the old Apply struct 
without NewApply(..)
+               tmpApply := NewApply(a.ApplyOptions)
+               a.Phases = tmpApply.Phases
        }
+       start := time.Now()
+
+       phase.NoWait = a.NoWait
+       phase.Force = a.Force
 
-       a.Manager.AddPhase(
-               &phase.Unlock{Cancel: lockPhase.Cancel},
-               &phase.Disconnect{},
-       )
+       a.Manager.SetPhases(a.Phases)
 
        analytics.Client.Publish("apply-start", map[string]interface{}{})
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/cmd/apply.go 
new/k0sctl-0.19.2/cmd/apply.go
--- old/k0sctl-0.19.0/cmd/apply.go      2024-09-11 08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/cmd/apply.go      2024-10-25 12:43:06.000000000 +0200
@@ -72,7 +72,7 @@
                        kubeconfigOut = out
                }
 
-               applyAction := action.Apply{
+               applyOpts := action.ApplyOptions{
                        Force:                 ctx.Bool("force"),
                        Manager:               
ctx.Context.Value(ctxManagerKey{}).(*phase.Manager),
                        KubeconfigOut:         kubeconfigOut,
@@ -84,6 +84,8 @@
                        ConfigPath:            ctx.String("config"),
                }
 
+               applyAction := action.NewApply(applyOpts)
+
                if err := applyAction.Run(); err != nil {
                        return fmt.Errorf("apply failed - log file saved to %s: 
%w", ctx.Context.Value(ctxLogFileKey{}).(string), err)
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/go.mod new/k0sctl-0.19.2/go.mod
--- old/k0sctl-0.19.0/go.mod    2024-09-11 08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/go.mod    2024-10-25 12:43:06.000000000 +0200
@@ -1,22 +1,20 @@
 module github.com/k0sproject/k0sctl
 
-go 1.22.0
-
-toolchain go1.22.4
+go 1.23.2
 
 require (
        github.com/AlecAivazis/survey/v2 v2.3.7
        github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // 
indirect
        github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 // 
indirect
        github.com/a8m/envsubst v1.4.2
-       github.com/adrg/xdg v0.5.0
-       github.com/bmatcuk/doublestar/v4 v4.6.1
+       github.com/adrg/xdg v0.5.1
+       github.com/bmatcuk/doublestar/v4 v4.7.1
        github.com/creasty/defaults v1.8.0
        github.com/denisbrodbeck/machineid v1.0.1
        github.com/gofrs/uuid v4.4.0+incompatible // indirect
        github.com/hashicorp/go-version v1.7.0 // indirect
        github.com/k0sproject/dig v0.2.0
-       github.com/k0sproject/rig v0.18.7
+       github.com/k0sproject/rig v0.18.8
        github.com/logrusorgru/aurora v2.0.3+incompatible
        github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 // 
indirect
        github.com/masterzen/winrm v0.0.0-20240702205601-3fad6e106085 // 
indirect
@@ -26,24 +24,24 @@
        github.com/shiena/ansicolor v0.0.0-20230509054315-a9deabde6e02
        github.com/sirupsen/logrus v1.9.3
        github.com/stretchr/testify v1.9.0
-       github.com/urfave/cli/v2 v2.27.4
+       github.com/urfave/cli/v2 v2.27.5
        github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
-       golang.org/x/crypto v0.26.0 // indirect
-       golang.org/x/net v0.28.0 // indirect
-       golang.org/x/sys v0.23.0 // indirect
-       golang.org/x/term v0.23.0 // indirect
-       golang.org/x/text v0.18.0
+       golang.org/x/crypto v0.28.0 // indirect
+       golang.org/x/net v0.30.0 // indirect
+       golang.org/x/sys v0.26.0 // indirect
+       golang.org/x/term v0.25.0 // indirect
+       golang.org/x/text v0.19.0
        gopkg.in/yaml.v2 v2.4.0
 )
 
 require (
        github.com/alessio/shellescape v1.4.2
        github.com/carlmjohnson/versioninfo v0.22.5
-       github.com/go-playground/validator/v10 v10.22.0
+       github.com/go-playground/validator/v10 v10.22.1
        github.com/jellydator/validation v1.1.0
        github.com/k0sproject/version v0.6.0
        github.com/sergi/go-diff v1.3.1
-       k8s.io/client-go v0.31.0
+       k8s.io/client-go v0.31.1
 )
 
 require (
@@ -52,11 +50,11 @@
        github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // 
indirect
        github.com/bodgit/ntlmssp v0.0.0-20240506230425-31973bb52d9b // indirect
        github.com/bodgit/windows v1.0.1 // indirect
-       github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
+       github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
        github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // 
indirect
        github.com/davidmz/go-pageant v1.0.2 // indirect
        github.com/fxamacker/cbor/v2 v2.7.0 // indirect
-       github.com/gabriel-vasile/mimetype v1.4.4 // indirect
+       github.com/gabriel-vasile/mimetype v1.4.6 // indirect
        github.com/go-logr/logr v1.4.2 // indirect
        github.com/go-playground/locales v0.14.1 // indirect
        github.com/go-playground/universal-translator v0.18.1 // indirect
@@ -88,14 +86,14 @@
        github.com/tidwall/transform v0.0.0-20201103190739-32f242e2dbde // 
indirect
        github.com/x448/float16 v0.8.4 // indirect
        github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
-       golang.org/x/oauth2 v0.21.0 // indirect
-       golang.org/x/time v0.5.0 // indirect
+       golang.org/x/oauth2 v0.23.0 // indirect
+       golang.org/x/time v0.7.0 // indirect
        gopkg.in/inf.v0 v0.9.1 // indirect
        gopkg.in/yaml.v3 v3.0.1 // indirect
-       k8s.io/apimachinery v0.31.0 // indirect
+       k8s.io/apimachinery v0.31.1 // indirect
        k8s.io/klog/v2 v2.130.1 // indirect
-       k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
-       sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
+       k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 // indirect
+       sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
        sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
        sigs.k8s.io/yaml v1.4.0 // indirect
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/go.sum new/k0sctl-0.19.2/go.sum
--- old/k0sctl-0.19.0/go.sum    2024-09-11 08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/go.sum    2024-10-25 12:43:06.000000000 +0200
@@ -12,23 +12,23 @@
 github.com/a8m/envsubst v1.4.2/go.mod 
h1:MVUTQNGQ3tsjOOtKCNd+fl8RzhsXcDvvAEzkhGtlsbY=
 github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d 
h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
 github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod 
h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
-github.com/adrg/xdg v0.5.0 h1:dDaZvhMXatArP1NPHhnfaQUqWBLBsmx1h1HXQdMoFCY=
-github.com/adrg/xdg v0.5.0/go.mod 
h1:dDdY4M4DF9Rjy4kHPeNL+ilVF+p2lK8IdM9/rTSGcI4=
+github.com/adrg/xdg v0.5.1 h1:Im8iDbEFARltY09yOJlSGu4Asjk2vF85+3Dyru8uJ0U=
+github.com/adrg/xdg v0.5.1/go.mod 
h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
 github.com/alessio/shellescape v1.4.2 
h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4uEoM0=
 github.com/alessio/shellescape v1.4.2/go.mod 
h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
 github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod 
h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 
h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod 
h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
-github.com/bmatcuk/doublestar/v4 v4.6.1 
h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
-github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod 
h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
+github.com/bmatcuk/doublestar/v4 v4.7.1 
h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
+github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod 
h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
 github.com/bodgit/ntlmssp v0.0.0-20240506230425-31973bb52d9b 
h1:baFN6AnR0SeC194X2D292IUZcHDs4JjStpqtE70fjXE=
 github.com/bodgit/ntlmssp v0.0.0-20240506230425-31973bb52d9b/go.mod 
h1:Ram6ngyPDmP+0t6+4T2rymv0w0BS9N8Ch5vvUJccw5o=
 github.com/bodgit/windows v1.0.1 
h1:tF7K6KOluPYygXa3Z2594zxlkbKPAOvqr97etrGNIz4=
 github.com/bodgit/windows v1.0.1/go.mod 
h1:a6JLwrB4KrTR5hBpp8FI9/9W9jJfeQ2h4XDXU74ZCdM=
 github.com/carlmjohnson/versioninfo v0.22.5 
h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc=
 github.com/carlmjohnson/versioninfo v0.22.5/go.mod 
h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8=
-github.com/cpuguy83/go-md2man/v2 v2.0.4 
h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod 
h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.5 
h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
+github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod 
h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 github.com/creack/pty v1.1.9/go.mod 
h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
 github.com/creack/pty v1.1.17/go.mod 
h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
@@ -46,8 +46,8 @@
 github.com/emicklei/go-restful/v3 v3.11.0/go.mod 
h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
 github.com/fxamacker/cbor/v2 v2.7.0 
h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
 github.com/fxamacker/cbor/v2 v2.7.0/go.mod 
h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
-github.com/gabriel-vasile/mimetype v1.4.4 
h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
-github.com/gabriel-vasile/mimetype v1.4.4/go.mod 
h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
+github.com/gabriel-vasile/mimetype v1.4.6 
h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc=
+github.com/gabriel-vasile/mimetype v1.4.6/go.mod 
h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc=
 github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
 github.com/go-logr/logr v1.4.2/go.mod 
h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-openapi/jsonpointer v0.19.6 
h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
@@ -62,8 +62,8 @@
 github.com/go-playground/locales v0.14.1/go.mod 
h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
 github.com/go-playground/universal-translator v0.18.1 
h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
 github.com/go-playground/universal-translator v0.18.1/go.mod 
h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
-github.com/go-playground/validator/v10 v10.22.0 
h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
-github.com/go-playground/validator/v10 v10.22.0/go.mod 
h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
+github.com/go-playground/validator/v10 v10.22.1 
h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
+github.com/go-playground/validator/v10 v10.22.1/go.mod 
h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
 github.com/gofrs/uuid v4.4.0+incompatible 
h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
 github.com/gofrs/uuid v4.4.0+incompatible/go.mod 
h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@@ -115,8 +115,8 @@
 github.com/json-iterator/go v1.1.12/go.mod 
h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/k0sproject/dig v0.2.0 
h1:cNxEIl96g9kqSMfPSZLhpnZ0P8bWXKv08nxvsMHop5w=
 github.com/k0sproject/dig v0.2.0/go.mod 
h1:rBcqaQlJpcKdt2x/OE/lPvhGU50u/e95CSm5g/r4s78=
-github.com/k0sproject/rig v0.18.7 
h1:MFLTVmhj+lGcCHbemwoWorlCD26CwzxhKckec+lGgdc=
-github.com/k0sproject/rig v0.18.7/go.mod 
h1:FS9xKO2a4hco2XthIcXnYBozKSLr/V3tlP+fWi7OVyE=
+github.com/k0sproject/rig v0.18.8 
h1:Dudzljvztdk5f5DGV8f07eRZBIXRTxpIslEMhRthLNA=
+github.com/k0sproject/rig v0.18.8/go.mod 
h1:rV9v56TQ6e62jgpAO1kEuoMMczwNH/I1MIxiV8gsvmg=
 github.com/k0sproject/version v0.6.0 
h1:Wi8wu9j+H36+okIQA47o/YHbzNpKeIYj8IjGdJOdqsI=
 github.com/k0sproject/version v0.6.0/go.mod 
h1:5/7Js62gDCLBP6mEs0mUcYEEkYneM5qXDKN/hyFlQTM=
 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 
h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
@@ -196,8 +196,8 @@
 github.com/stretchr/testify v1.9.0/go.mod 
h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/tidwall/transform v0.0.0-20201103190739-32f242e2dbde 
h1:AMNpJRc7P+GTwVbl8DkK2I9I8BBUzNiHuH/tlxrpan0=
 github.com/tidwall/transform v0.0.0-20201103190739-32f242e2dbde/go.mod 
h1:MvrEmduDUz4ST5pGZ7CABCnOU5f3ZiOAZzT6b1A6nX8=
-github.com/urfave/cli/v2 v2.27.4 
h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8=
-github.com/urfave/cli/v2 v2.27.4/go.mod 
h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
+github.com/urfave/cli/v2 v2.27.5 
h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
+github.com/urfave/cli/v2 v2.27.5/go.mod 
h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
 github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
 github.com/x448/float16 v0.8.4/go.mod 
h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
 github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 
h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
@@ -213,8 +213,8 @@
 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod 
h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod 
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.6.0/go.mod 
h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
-golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
-golang.org/x/crypto v0.26.0/go.mod 
h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
+golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
+golang.org/x/crypto v0.28.0/go.mod 
h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod 
h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -227,10 +227,10 @@
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod 
h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
-golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
-golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
-golang.org/x/oauth2 v0.21.0/go.mod 
h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
+golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
+golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
+golang.org/x/oauth2 v0.23.0/go.mod 
h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -247,22 +247,22 @@
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
-golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
+golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod 
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod 
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
-golang.org/x/term v0.23.0/go.mod 
h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
+golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
+golang.org/x/term v0.25.0/go.mod 
h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
-golang.org/x/text v0.18.0/go.mod 
h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
-golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
-golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
+golang.org/x/text v0.19.0/go.mod 
h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
+golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod 
h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod 
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod 
h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -286,20 +286,20 @@
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod 
h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo=
-k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE=
-k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc=
-k8s.io/apimachinery v0.31.0/go.mod 
h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
-k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8=
-k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU=
+k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU=
+k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI=
+k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U=
+k8s.io/apimachinery v0.31.1/go.mod 
h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
+k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0=
+k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
 k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
 k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 
h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
 k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod 
h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
-k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 
h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
-k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod 
h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd 
h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
-sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod 
h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
+k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 
h1:MDF6h2H/h4tbzmtIKTuctcwZmY0tY9mD9fNT47QO6HI=
+k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod 
h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 
h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
+sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod 
h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
 sigs.k8s.io/structured-merge-diff/v4 v4.4.1 
h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
 sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod 
h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
 sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/backup.go 
new/k0sctl-0.19.2/phase/backup.go
--- old/k0sctl-0.19.0/phase/backup.go   2024-09-11 08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/phase/backup.go   2024-10-25 12:43:06.000000000 +0200
@@ -14,7 +14,7 @@
        log "github.com/sirupsen/logrus"
 )
 
-var _ phase = &Backup{}
+var _ Phase = &Backup{}
 
 var backupSinceVersion = version.MustConstraint(">= v1.21.0-rc.1+k0s.0")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/configure_k0s.go 
new/k0sctl-0.19.2/phase/configure_k0s.go
--- old/k0sctl-0.19.0/phase/configure_k0s.go    2024-09-11 08:57:50.000000000 
+0200
+++ new/k0sctl-0.19.2/phase/configure_k0s.go    2024-10-25 12:43:06.000000000 
+0200
@@ -183,7 +183,7 @@
 func (p *ConfigureK0s) Run() error {
        controllers := p.Config.Spec.Hosts.Controllers().Filter(func(h 
*cluster.Host) bool {
                return !h.Reset && len(h.Metadata.K0sNewConfig) > 0
-       })      
+       })
        return p.parallelDo(controllers, p.configureK0s)
 }
 
@@ -270,19 +270,6 @@
        return nil
 }
 
-func addUnlessExist(slice *[]string, s string) {
-       var found bool
-       for _, v := range *slice {
-               if v == s {
-                       found = true
-                       break
-               }
-       }
-       if !found {
-               *slice = append(*slice, s)
-       }
-}
-
 func (p *ConfigureK0s) configFor(h *cluster.Host) (string, error) {
        var cfg dig.Mapping
 
@@ -298,40 +285,12 @@
                cfg = p.newBaseConfig.Dup()
        }
 
-       var sans []string
-
        var addr string
        if h.PrivateAddress != "" {
                addr = h.PrivateAddress
        } else {
                addr = h.Address()
        }
-       cfg.DigMapping("spec", "api")["address"] = addr
-       addUnlessExist(&sans, addr)
-
-       oldsans := cfg.Dig("spec", "api", "sans")
-       switch oldsans := oldsans.(type) {
-       case []interface{}:
-               for _, v := range oldsans {
-                       if s, ok := v.(string); ok {
-                               addUnlessExist(&sans, s)
-                       }
-               }
-       case []string:
-               for _, v := range oldsans {
-                       addUnlessExist(&sans, v)
-               }
-       }
-
-       var controllers cluster.Hosts = p.Config.Spec.Hosts.Controllers()
-       for _, c := range controllers {
-               addUnlessExist(&sans, c.Address())
-               if c.PrivateAddress != "" {
-                       addUnlessExist(&sans, c.PrivateAddress)
-               }
-       }
-       addUnlessExist(&sans, "127.0.0.1")
-       cfg.DigMapping("spec", "api")["sans"] = sans
 
        if cfg.Dig("spec", "storage", "etcd", "peerAddress") != nil || 
h.PrivateAddress != "" {
                cfg.DigMapping("spec", "storage", "etcd")["peerAddress"] = addr
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/get_kubeconfig.go 
new/k0sctl-0.19.2/phase/get_kubeconfig.go
--- old/k0sctl-0.19.0/phase/get_kubeconfig.go   2024-09-11 08:57:50.000000000 
+0200
+++ new/k0sctl-0.19.2/phase/get_kubeconfig.go   2024-10-25 12:43:06.000000000 
+0200
@@ -2,13 +2,10 @@
 
 import (
        "fmt"
-       "strings"
 
        "github.com/alessio/shellescape"
-       "github.com/k0sproject/dig"
        
"github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster"
        "github.com/k0sproject/rig/exec"
-       "gopkg.in/yaml.v2"
        "k8s.io/client-go/tools/clientcmd"
 )
 
@@ -31,24 +28,6 @@
        return output, nil
 }
 
-var k0sConfig = func(h *cluster.Host) (dig.Mapping, error) {
-       cfgContent, err := h.Configurer.ReadFile(h, 
h.Configurer.K0sConfigPath())
-       if err != nil {
-               return nil, fmt.Errorf("read k0s config from host: %w", err)
-       }
-
-       var cfg dig.Mapping
-       if err := yaml.Unmarshal([]byte(cfgContent), &cfg); err != nil {
-               return nil, fmt.Errorf("unmarshal k0s config: %w", err)
-       }
-
-       if err != nil {
-               return nil, fmt.Errorf("parse k0s config: %w", err)
-       }
-
-       return cfg, nil
-}
-
 func (p *GetKubeconfig) DryRun() error {
        p.DryMsg(p.Config.Spec.Hosts.Controllers()[0], "get admin kubeconfig")
        return nil
@@ -58,34 +37,13 @@
 func (p *GetKubeconfig) Run() error {
        h := p.Config.Spec.Hosts.Controllers()[0]
 
-       cfg, err := k0sConfig(h)
-       if err != nil {
-               return err
-       }
-
        output, err := readKubeconfig(h)
        if err != nil {
                return fmt.Errorf("read kubeconfig from host: %w", err)
        }
 
        if p.APIAddress == "" {
-               // the controller admin.conf is aways pointing to localhost, 
thus we need to change the address
-               // something usable from outside
-               address := h.Address()
-               if a, ok := cfg.Dig("spec", "api", "externalAddress").(string); 
ok && a != "" {
-                       address = a
-               }
-
-               port := 6443
-               if p, ok := cfg.Dig("spec", "api", "port").(int); ok && p != 0 {
-                       port = p
-               }
-
-               if strings.Contains(address, ":") {
-                       p.APIAddress = fmt.Sprintf("https://[%s]:%d";, address, 
port)
-               } else {
-                       p.APIAddress = fmt.Sprintf("https://%s:%d";, address, 
port)
-               }
+               p.APIAddress = p.Config.Spec.KubeAPIURL()
        }
 
        cfgString, err := kubeConfig(output, p.Config.Metadata.Name, 
p.APIAddress)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/get_kubeconfig_test.go 
new/k0sctl-0.19.2/phase/get_kubeconfig_test.go
--- old/k0sctl-0.19.0/phase/get_kubeconfig_test.go      2024-09-11 
08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/phase/get_kubeconfig_test.go      2024-10-25 
12:43:06.000000000 +0200
@@ -49,12 +49,6 @@
        defer func() { readKubeconfig = origReadKubeconfig }()
        readKubeconfig = fakeReader
 
-       origK0sConfig := k0sConfig
-       defer func() { k0sConfig = origK0sConfig }()
-       k0sConfig = func(h *cluster.Host) (dig.Mapping, error) {
-               return cfg.Spec.K0s.Config, nil
-       }
-
        p := GetKubeconfig{GenericPhase: GenericPhase{Config: cfg}}
        require.NoError(t, p.Run())
        conf, err := clientcmd.Load([]byte(cfg.Metadata.Kubeconfig))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/initialize_k0s.go 
new/k0sctl-0.19.2/phase/initialize_k0s.go
--- old/k0sctl-0.19.0/phase/initialize_k0s.go   2024-09-11 08:57:50.000000000 
+0200
+++ new/k0sctl-0.19.2/phase/initialize_k0s.go   2024-10-25 12:43:06.000000000 
+0200
@@ -100,7 +100,6 @@
                        }
                        return nil
                })
-
                if err != nil {
                        return err
                }
@@ -116,18 +115,13 @@
                        return err
                }
 
-               port := 6443
-               if p, ok := p.Config.Spec.K0s.Config.Dig("spec", "api", 
"port").(int); ok {
-                       port = p
-               }
                log.Infof("%s: waiting for kubernetes api to respond", h)
-               if err := retry.Timeout(context.TODO(), retry.DefaultTimeout, 
node.KubeAPIReadyFunc(h, port)); err != nil {
+               if err := retry.Timeout(context.TODO(), retry.DefaultTimeout, 
node.KubeAPIReadyFunc(h, p.Config)); err != nil {
                        return err
                }
 
                return nil
        })
-
        if err != nil {
                return err
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/install_controllers.go 
new/k0sctl-0.19.2/phase/install_controllers.go
--- old/k0sctl-0.19.0/phase/install_controllers.go      2024-09-11 
08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/phase/install_controllers.go      2024-10-25 
12:43:06.000000000 +0200
@@ -88,7 +88,7 @@
 
 // Run the phase
 func (p *InstallControllers) Run() error {
-       url := p.Config.Spec.KubeAPIURL()
+       url := p.Config.Spec.InternalKubeAPIURL()
        healthz := fmt.Sprintf("%s/healthz", url)
 
        err := p.parallelDo(p.hosts, func(h *cluster.Host) error {
@@ -191,11 +191,6 @@
 }
 
 func (p *InstallControllers) waitJoined(h *cluster.Host) error {
-       port := 6443
-       if p, ok := p.Config.Spec.K0s.Config.Dig("spec", "api", "port").(int); 
ok {
-               port = p
-       }
-
        log.Infof("%s: waiting for kubernetes api to respond", h)
-       return retry.Timeout(context.TODO(), retry.DefaultTimeout, 
node.KubeAPIReadyFunc(h, port))
+       return retry.Timeout(context.TODO(), retry.DefaultTimeout, 
node.KubeAPIReadyFunc(h, p.Config))
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/install_workers.go 
new/k0sctl-0.19.2/phase/install_workers.go
--- old/k0sctl-0.19.0/phase/install_workers.go  2024-09-11 08:57:50.000000000 
+0200
+++ new/k0sctl-0.19.2/phase/install_workers.go  2024-10-25 12:43:06.000000000 
+0200
@@ -98,7 +98,7 @@
 
 // Run the phase
 func (p *InstallWorkers) Run() error {
-       url := p.Config.Spec.KubeAPIURL()
+       url := p.Config.Spec.InternalKubeAPIURL()
        healthz := fmt.Sprintf("%s/healthz", url)
 
        err := p.parallelDo(p.hosts, func(h *cluster.Host) error {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/lock.go 
new/k0sctl-0.19.2/phase/lock.go
--- old/k0sctl-0.19.0/phase/lock.go     2024-09-11 08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/phase/lock.go     2024-10-25 12:43:06.000000000 +0200
@@ -52,6 +52,11 @@
        p.Cancel()
 }
 
+// UnlockPhase returns an unlock phase for this lock phase
+func (p *Lock) UnlockPhase() Phase {
+       return &Unlock{Cancel: p.Cancel}
+}
+
 // Run the phase
 func (p *Lock) Run() error {
        if err := p.parallelDo(p.Config.Spec.Hosts, p.startLock); err != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/manager.go 
new/k0sctl-0.19.2/phase/manager.go
--- old/k0sctl-0.19.0/phase/manager.go  2024-09-11 08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/phase/manager.go  2024-10-25 12:43:06.000000000 +0200
@@ -19,11 +19,61 @@
 // Colorize is an instance of "aurora", used to colorize the output
 var Colorize = aurora.NewAurora(false)
 
-type phase interface {
+// Phase represents a runnable phase which can be added to Manager.
+type Phase interface {
        Run() error
        Title() string
 }
 
+// Phases is a slice of Phases
+type Phases []Phase
+
+// Index returns the index of the first occurrence matching the given phase 
title or -1 if not found
+func (p Phases) Index(title string) int {
+       for i, phase := range p {
+               if phase.Title() == title {
+                       return i
+               }
+       }
+       return -1
+}
+
+// Remove removes the first occurrence of a phase with the given title
+func (p *Phases) Remove(title string) {
+       i := p.Index(title)
+       if i == -1 {
+               return
+       }
+       *p = append((*p)[:i], (*p)[i+1:]...)
+}
+
+// InsertAfter inserts a phase after the first occurrence of a phase with the 
given title
+func (p *Phases) InsertAfter(title string, phase Phase) {
+       i := p.Index(title)
+       if i == -1 {
+               return
+       }
+       *p = append((*p)[:i+1], append(Phases{phase}, (*p)[i+1:]...)...)
+}
+
+// InsertBefore inserts a phase before the first occurrence of a phase with 
the given title
+func (p *Phases) InsertBefore(title string, phase Phase) {
+       i := p.Index(title)
+       if i == -1 {
+               return
+       }
+       *p = append((*p)[:i], append(Phases{phase}, (*p)[i:]...)...)
+}
+
+// Replace replaces the first occurrence of a phase with the given title
+func (p *Phases) Replace(title string, phase Phase) {
+       i := p.Index(title)
+       if i == -1 {
+               return
+       }
+       (*p)[i] = phase
+}
+
 type withconfig interface {
        Title() string
        Prepare(*v1beta1.Cluster) error
@@ -60,7 +110,7 @@
 
 // Manager executes phases to construct the cluster
 type Manager struct {
-       phases            []phase
+       phases            Phases
        Config            *v1beta1.Cluster
        Concurrency       int
        ConcurrentUploads int
@@ -80,10 +130,15 @@
 }
 
 // AddPhase adds a Phase to Manager
-func (m *Manager) AddPhase(p ...phase) {
+func (m *Manager) AddPhase(p ...Phase) {
        m.phases = append(m.phases, p...)
 }
 
+// SetPhases sets the list of phases
+func (m *Manager) SetPhases(p Phases) {
+       m.phases = p
+}
+
 type errorfunc func() error
 
 // DryMsg prints a message in dry-run mode
@@ -124,7 +179,7 @@
 
 // Run executes all the added Phases in order
 func (m *Manager) Run() error {
-       var ran []phase
+       var ran []Phase
        var result error
 
        defer func() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/runhooks.go 
new/k0sctl-0.19.2/phase/runhooks.go
--- old/k0sctl-0.19.0/phase/runhooks.go 2024-09-11 08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/phase/runhooks.go 2024-10-25 12:43:06.000000000 +0200
@@ -10,7 +10,7 @@
        
"github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster"
 )
 
-var _ phase = &RunHooks{}
+var _ Phase = &RunHooks{}
 
 // RunHooks phase runs a set of hooks configured for the host
 type RunHooks struct {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/upgrade_controllers.go 
new/k0sctl-0.19.2/phase/upgrade_controllers.go
--- old/k0sctl-0.19.0/phase/upgrade_controllers.go      2024-09-11 
08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/phase/upgrade_controllers.go      2024-10-25 
12:43:06.000000000 +0200
@@ -131,13 +131,9 @@
                if err != nil {
                        return err
                }
-               port := 6443
-               if p, ok := p.Config.Spec.K0s.Config.Dig("spec", "api", 
"port").(int); ok {
-                       port = p
-               }
 
                if p.IsWet() {
-                       if err := retry.Timeout(context.TODO(), 
retry.DefaultTimeout, node.KubeAPIReadyFunc(h, port)); err != nil {
+                       if err := retry.Timeout(context.TODO(), 
retry.DefaultTimeout, node.KubeAPIReadyFunc(h, p.Config)); err != nil {
                                return fmt.Errorf("kube api did not become 
ready: %w", err)
                        }
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/validate_etcd_members.go 
new/k0sctl-0.19.2/phase/validate_etcd_members.go
--- old/k0sctl-0.19.0/phase/validate_etcd_members.go    1970-01-01 
01:00:00.000000000 +0100
+++ new/k0sctl-0.19.2/phase/validate_etcd_members.go    2024-10-25 
12:43:06.000000000 +0200
@@ -0,0 +1,90 @@
+package phase
+
+import (
+       "fmt"
+       "slices"
+
+       "github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1"
+       
"github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster"
+       log "github.com/sirupsen/logrus"
+)
+
+// ValidateEtcdMembers checks for existing etcd members with the same IP as a 
new controller
+type ValidateEtcdMembers struct {
+       GenericPhase
+       hosts cluster.Hosts
+}
+
+// Title for the phase
+func (p *ValidateEtcdMembers) Title() string {
+       return "Validate etcd members"
+}
+
+// Prepare the phase
+func (p *ValidateEtcdMembers) Prepare(config *v1beta1.Cluster) error {
+       p.Config = config
+       p.hosts = p.Config.Spec.Hosts.Controllers().Filter(func(h 
*cluster.Host) bool {
+               return h.Metadata.K0sRunningVersion == nil // only check new 
controllers
+       })
+
+       return nil
+}
+
+// ShouldRun is true when there are new controllers and etcd
+func (p *ValidateEtcdMembers) ShouldRun() bool {
+       if p.Config.Spec.K0sLeader().Metadata.K0sRunningVersion == nil {
+               log.Debugf("%s: leader has no k0s running, assuming a fresh 
cluster", p.Config.Spec.K0sLeader())
+               return false
+       }
+
+       if p.Config.Spec.K0sLeader().Role == "single" {
+               log.Debugf("%s: leader is a single node, assuming no etcd", 
p.Config.Spec.K0sLeader())
+               return false
+       }
+
+       if len(p.Config.Spec.K0s.Config) > 0 {
+               storageType := p.Config.Spec.K0s.Config.DigString("spec", 
"storage", "type")
+               if storageType != "" && storageType != "etcd" {
+                       log.Debugf("%s: storage type is %q, not k0s managed 
etcd", p.Config.Spec.K0sLeader(), storageType)
+                       return false
+               }
+       }
+       return len(p.hosts) > 0
+}
+
+// Run the phase
+func (p *ValidateEtcdMembers) Run() error {
+       if err := p.validateControllerSwap(); err != nil {
+               return err
+       }
+
+       return nil
+}
+
+func (p *ValidateEtcdMembers) validateControllerSwap() error {
+       if len(p.Config.Metadata.EtcdMembers) > 
len(p.Config.Spec.Hosts.Controllers()) {
+               log.Warnf("there are more etcd members in the cluster than 
controllers listed in the configuration")
+       }
+
+       for _, h := range p.hosts {
+               log.Debugf("%s: host is new, checking if etcd members list 
already contains %s", h, h.PrivateAddress)
+               if slices.Contains(p.Config.Metadata.EtcdMembers, 
h.PrivateAddress) {
+                       if Force {
+                               log.Infof("%s: force used, running 'k0s etcd 
leave' for the host", h)
+                               leader := p.Config.Spec.K0sLeader()
+                               leaveCommand := leader.Configurer.K0sCmdf("etcd 
leave --peer-address %s", h.PrivateAddress)
+                               err := p.Wet(h, fmt.Sprintf("remove host from 
etcd using %v", leaveCommand), func() error {
+                                       return leader.Exec(leaveCommand)
+                               })
+                               if err != nil {
+                                       return fmt.Errorf("controller %s is 
listed as an existing etcd member but k0s is not found installed on it, the 
host may have been replaced. attempted etcd leave for the address %s but it 
failed: %w", h, h.PrivateAddress, err)
+                               }
+                               continue
+                       }
+                       return fmt.Errorf("controller %s is listed as an 
existing etcd member but k0s is not found installed on it, the host may have 
been replaced. check the host and use `k0s etcd leave --peer-address %s on a 
controller or re-run apply with --force", h, h.PrivateAddress)
+               }
+               log.Debugf("%s: no match, assuming its safe to install", h)
+       }
+
+       return nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/phase/validate_facts.go 
new/k0sctl-0.19.2/phase/validate_facts.go
--- old/k0sctl-0.19.0/phase/validate_facts.go   2024-09-11 08:57:50.000000000 
+0200
+++ new/k0sctl-0.19.2/phase/validate_facts.go   2024-10-25 12:43:06.000000000 
+0200
@@ -2,7 +2,6 @@
 
 import (
        "fmt"
-       "slices"
 
        log "github.com/sirupsen/logrus"
 )
@@ -28,10 +27,6 @@
                return err
        }
 
-       if err := p.validateControllerSwap(); err != nil {
-               return err
-       }
-
        return nil
 }
 
@@ -73,48 +68,4 @@
        }
 
        return nil
-}
-
-func (p *ValidateFacts) validateControllerSwap() error {
-       log.Debugf("validating controller list vs etcd member list")
-       if p.Config.Spec.K0sLeader().Metadata.K0sRunningVersion == nil {
-               log.Debugf("%s: leader has no k0s running, assuming a fresh 
cluster", p.Config.Spec.K0sLeader())
-               return nil
-       }
-
-       if p.Config.Spec.K0sLeader().Role == "single" {
-               log.Debugf("%s: leader is a single node, assuming no etcd", 
p.Config.Spec.K0sLeader())
-               return nil
-       }
-
-       if len(p.Config.Metadata.EtcdMembers) > 
len(p.Config.Spec.Hosts.Controllers()) {
-               log.Warnf("there are more etcd members in the cluster than 
controllers listed in the k0sctl configuration")
-       }
-
-       for _, h := range p.Config.Spec.Hosts.Controllers() {
-               if h.Metadata.K0sRunningVersion != nil {
-                       log.Debugf("%s: host has k0s running, no need to check 
if it was replaced", h)
-                       continue
-               }
-
-               log.Debugf("%s: host is new, checking if etcd members list 
already contains %s", h, h.PrivateAddress)
-               if slices.Contains(p.Config.Metadata.EtcdMembers, 
h.PrivateAddress) {
-                       if Force {
-                               log.Infof("%s: force used, running 'k0s etcd 
leave' for the host", h)
-                               leader := p.Config.Spec.K0sLeader()
-                               leaveCommand := leader.Configurer.K0sCmdf("etcd 
leave --peer-address %s", h.PrivateAddress)
-                               err := p.Wet(h, fmt.Sprintf("remove host from 
etcd using %v", leaveCommand), func() error {
-                                       return leader.Exec(leaveCommand)
-                               })
-                               if err != nil {
-                                       return fmt.Errorf("controller %s is 
listed as an existing etcd member but k0s is not found installed on it, the 
host may have been replaced. attempted etcd leave for the address %s but it 
failed: %w", h, h.PrivateAddress, err)
-                               }
-                               continue
-                       }
-                       return fmt.Errorf("controller %s is listed as an 
existing etcd member but k0s is not found installed on it, the host may have 
been replaced. check the host and use `k0s etcd leave --peer-address %s on a 
controller or re-run apply with --force", h, h.PrivateAddress)
-               }
-               log.Debugf("%s: no match, assuming its safe to install", h)
-       }
-
-       return nil
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/k0sctl-0.19.0/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/spec.go 
new/k0sctl-0.19.2/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/spec.go
--- old/k0sctl-0.19.0/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/spec.go     
2024-09-11 08:57:50.000000000 +0200
+++ new/k0sctl-0.19.2/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/spec.go     
2024-10-25 12:43:06.000000000 +0200
@@ -2,9 +2,11 @@
 
 import (
        "fmt"
+       "strings"
 
        "github.com/creasty/defaults"
        "github.com/jellydator/validation"
+       "github.com/k0sproject/dig"
 )
 
 // Spec defines cluster config spec section
@@ -80,24 +82,72 @@
        )
 }
 
-// KubeAPIURL returns an url to the cluster's kube api
-func (s *Spec) KubeAPIURL() string {
-       var caddr string
+func (s *Spec) clusterExternalAddress() string {
        if a := s.K0s.Config.DigString("spec", "api", "externalAddress"); a != 
"" {
-               caddr = a
-       } else {
-               leader := s.K0sLeader()
-               if leader.PrivateAddress != "" {
-                       caddr = leader.PrivateAddress
-               } else {
-                       caddr = leader.Address()
+               return a
+       }
+
+       if cplb, ok := s.K0s.Config.Dig("spec", "network", 
"controlPlaneLoadBalancing").(dig.Mapping); ok {
+               if enabled, ok := cplb.Dig("enabled").(bool); ok && enabled && 
cplb.DigString("type") == "Keepalived" {
+                       if vrrpAddresses, ok := cplb.Dig("keepalived", 
"virtualServers").([]dig.Mapping); ok && len(vrrpAddresses) > 0 {
+                               if addr, ok := 
vrrpAddresses[0]["ipAddress"].(string); ok && addr != "" {
+                                       return addr
+                               }
+                       }
                }
        }
 
-       cport := 6443
+       return s.K0sLeader().Address()
+}
+
+func (s *Spec) clusterInternalAddress() string {
+       leader := s.K0sLeader()
+       if leader.PrivateAddress != "" {
+               return leader.PrivateAddress
+       } else {
+               return leader.Address()
+       }
+}
+
+const defaultAPIPort = 6443
+
+func (s *Spec) APIPort() int {
        if p, ok := s.K0s.Config.Dig("spec", "api", "port").(int); ok {
-               cport = p
+               return p
        }
+       return defaultAPIPort
+}
 
-       return fmt.Sprintf("https://%s:%d";, caddr, cport)
+// KubeAPIURL returns an external url to the cluster's kube API
+func (s *Spec) KubeAPIURL() string {
+       return fmt.Sprintf("https://%s:%d";, 
formatIPV6(s.clusterExternalAddress()), s.APIPort())
+}
+
+// InternalKubeAPIURL returns a cluster internal url to the cluster's kube API
+func (s *Spec) InternalKubeAPIURL() string {
+       return fmt.Sprintf("https://%s:%d";, 
formatIPV6(s.clusterInternalAddress()), s.APIPort())
+}
+
+// NodeInternalKubeAPIURL returns a cluster internal url to the node's kube API
+func (s *Spec) NodeInternalKubeAPIURL(h *Host) string {
+       addr := "127.0.0.1"
+
+       // spec.api.onlyBindToAddress was introduced in k0s 1.30. Setting it to 
true will make the API server only
+       // listen on the IP address configured by the `address` option.
+       if onlyBindAddr, ok := s.K0s.Config.Dig("spec", "api", 
"onlyBindToAddress").(bool); ok && onlyBindAddr {
+               if h.PrivateAddress != "" {
+                       addr = h.PrivateAddress
+               } else {
+                       addr = h.Address()
+               }
+       }
+
+       return fmt.Sprintf("https://%s:%d";, formatIPV6(addr), s.APIPort())
+}
+
+func formatIPV6(address string) string {
+       if strings.Contains(address, ":") {
+               return fmt.Sprintf("[%s]", address)
+       }
+       return address
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/k0sctl-0.19.0/pkg/node/statusfunc.go 
new/k0sctl-0.19.2/pkg/node/statusfunc.go
--- old/k0sctl-0.19.0/pkg/node/statusfunc.go    2024-09-11 08:57:50.000000000 
+0200
+++ new/k0sctl-0.19.2/pkg/node/statusfunc.go    2024-10-25 12:43:06.000000000 
+0200
@@ -7,6 +7,7 @@
        "strings"
        "time"
 
+       "github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1"
        
"github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster"
        "github.com/k0sproject/rig/exec"
 
@@ -195,8 +196,8 @@
 }
 
 // KubeAPIReadyFunc returns a function that returns an error unless the host's 
local kube api responds to /version
-func KubeAPIReadyFunc(h *cluster.Host, port int) retryFunc {
+func KubeAPIReadyFunc(h *cluster.Host, config *v1beta1.Cluster) retryFunc {
        // If the anon-auth is disabled on kube api the version endpoint will 
give 401
        // thus we need to accept both 200 and 401 as valid statuses when 
checking kube api
-       return HTTPStatusFunc(h, fmt.Sprintf("https://localhost:%d/version";, 
port), 200, 401)
+       return HTTPStatusFunc(h, fmt.Sprintf("%s/version", 
config.Spec.NodeInternalKubeAPIURL(h)), 200, 401)
 }

++++++ k0sctl.obsinfo ++++++
--- /var/tmp/diff_new_pack.MJwoD9/_old  2024-10-27 11:25:48.443728541 +0100
+++ /var/tmp/diff_new_pack.MJwoD9/_new  2024-10-27 11:25:48.447728707 +0100
@@ -1,5 +1,5 @@
 name: k0sctl
-version: 0.19.0
-mtime: 1726037870
-commit: 9246ddc823198b572b51fb19bdf5effee4721a9d
+version: 0.19.2
+mtime: 1729852986
+commit: 081dfeb085418df4824e00778b092e77f84715ad
 

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/k0sctl/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.k0sctl.new.2020/vendor.tar.gz differ: char 5, line 1

Reply via email to