From 428bedd1c09669904ec58c9f7199d3d25d8a505e Mon Sep 17 00:00:00 2001 From: Kimmo Lehto Date: Mon, 23 Aug 2021 14:16:28 +0300 Subject: [PATCH] More flexible sudo/doas/elevated access usage (#192) * More flexible sudo/doas/elevated access usage * Sprintf does not understand exec.Sudo * Everything was broken * Rig was totally broken * exec.Sudo is not a string * Bring in rig from a branch for debug info * Hmm? * Dont know how to properly point to a branch * Wait for k0s stop * More logging * Phase ordering seems to have some problems * Rig 0.4.4 final --- cmd/apply.go | 4 ++-- config/cluster/host.go | 39 ++++++++++++++++++++++++++++------- config/cluster/k0s.go | 4 ++-- configurer/linux.go | 13 ++++++------ configurer/linux/alpine.go | 7 ++----- configurer/linux/slackware.go | 12 ++++++++++- go.mod | 13 ++++++++++-- go.sum | 39 +++++++++++++++++++++++++---------- phase/backup.go | 4 ++-- phase/configure_k0s.go | 5 +++-- phase/download_k0s.go | 3 ++- phase/gather_k0s_facts.go | 5 +++-- phase/reset.go | 3 ++- phase/restore.go | 5 +++-- phase/upgrade_controllers.go | 3 +++ phase/upgrade_workers.go | 3 +++ phase/upload_binaries.go | 3 ++- phase/uploadfiles.go | 5 +++-- 18 files changed, 121 insertions(+), 49 deletions(-) diff --git a/cmd/apply.go b/cmd/apply.go index 04ad0ea9..adc4b553 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -69,12 +69,12 @@ var applyCommand = &cli.Command{ &phase.PrepareHosts{}, &phase.GatherFacts{}, &phase.DownloadBinaries{}, - &phase.UploadBinaries{}, - &phase.DownloadK0s{}, &phase.UploadFiles{}, &phase.ValidateHosts{}, &phase.GatherK0sFacts{}, &phase.ValidateFacts{SkipDowngradeCheck: ctx.Bool("disable-downgrade-check")}, + &phase.UploadBinaries{}, + &phase.DownloadK0s{}, &phase.RunHooks{Stage: "before", Action: "apply"}, &phase.ConfigureK0s{}, &phase.Restore{ diff --git a/config/cluster/host.go b/config/cluster/host.go index 9e7ce8fe..ea8ba62e 100644 --- a/config/cluster/host.go +++ b/config/cluster/host.go @@ -204,7 +204,13 @@ func (h *Host) K0sInstallCommand() string { flags.AddOrReplace(fmt.Sprintf("--kubelet-extra-args=%s", strconv.Quote(extra.Join()))) } - return h.Configurer.K0sCmdf("install %s %s", role, flags.Join()) + cmd := h.Configurer.K0sCmdf("install %s %s", role, flags.Join()) + sudocmd, err := h.Sudo(cmd) + if err != nil { + log.Warnf("%s: %s", h, err.Error()) + return cmd + } + return sudocmd } // K0sBackupCommand returns a full command to be used as run k0s backup @@ -233,7 +239,7 @@ func (h *Host) K0sServiceName() string { // UpdateK0sBinary updates the binary on the host either by downloading or uploading, based on the config func (h *Host) UpdateK0sBinary(version string) error { if h.K0sBinaryPath != "" { - if err := h.Upload(h.K0sBinaryPath, h.Configurer.K0sBinaryPath()); err != nil { + if err := h.Upload(h.K0sBinaryPath, h.Configurer.K0sBinaryPath(), exec.Sudo(h)); err != nil { return err } if err := h.Configurer.Chmod(h, h.Configurer.K0sBinaryPath(), "0700"); err != nil { @@ -244,7 +250,7 @@ func (h *Host) UpdateK0sBinary(version string) error { return err } - output, err := h.ExecOutput(h.Configurer.K0sCmdf("version")) + output, err := h.ExecOutput(h.Configurer.K0sCmdf("version"), exec.Sudo(h)) if err != nil { return fmt.Errorf("downloaded k0s binary is invalid: %s", err.Error()) } @@ -270,7 +276,7 @@ type kubeNodeStatus struct { // KubeNodeReady runs kubectl on the host and returns true if the given node is marked as ready func (h *Host) KubeNodeReady(node *Host) (bool, error) { - output, err := h.ExecOutput(h.Configurer.KubectlCmdf("get node -l kubernetes.io/hostname=%s -o json", node.Metadata.Hostname), exec.HideOutput()) + output, err := h.ExecOutput(h.Configurer.KubectlCmdf("get node -l kubernetes.io/hostname=%s -o json", node.Metadata.Hostname), exec.HideOutput(), exec.Sudo(h)) if err != nil { return false, err } @@ -314,12 +320,12 @@ func (h *Host) WaitKubeNodeReady(node *Host) error { // DrainNode drains the given node func (h *Host) DrainNode(node *Host) error { - return h.Exec(h.Configurer.KubectlCmdf("drain --grace-period=120 --force --timeout=5m --ignore-daemonsets --delete-local-data %s", node.Metadata.Hostname)) + return h.Exec(h.Configurer.KubectlCmdf("drain --grace-period=120 --force --timeout=5m --ignore-daemonsets --delete-local-data %s", node.Metadata.Hostname), exec.Sudo(h)) } // UncordonNode marks the node schedulable again func (h *Host) UncordonNode(node *Host) error { - return h.Exec(h.Configurer.KubectlCmdf("uncordon %s", node.Metadata.Hostname)) + return h.Exec(h.Configurer.KubectlCmdf("uncordon %s", node.Metadata.Hostname), exec.Sudo(h)) } // CheckHTTPStatus will perform a web request to the url and return an error if the http status is not the expected @@ -359,7 +365,26 @@ func (h *Host) WaitK0sServiceRunning() error { if !h.Configurer.ServiceIsRunning(h, h.K0sServiceName()) { return fmt.Errorf("not running") } - return h.Exec(h.Configurer.K0sCmdf("status")) + return h.Exec(h.Configurer.K0sCmdf("status"), exec.Sudo(h)) + }, + retry.DelayType(retry.CombineDelay(retry.FixedDelay, retry.RandomDelay)), + retry.MaxJitter(time.Second*2), + retry.Delay(time.Second*3), + retry.Attempts(60), + ) +} + +// WaitK0sServiceStopped blocks until the k0s service is no longer running on the host +func (h *Host) WaitK0sServiceStopped() error { + return retry.Do( + func() error { + if h.Configurer.ServiceIsRunning(h, h.K0sServiceName()) { + return fmt.Errorf("k0s still running") + } + if h.Exec(h.Configurer.K0sCmdf("status"), exec.Sudo(h)) == nil { + return fmt.Errorf("k0s still running") + } + return nil }, retry.DelayType(retry.CombineDelay(retry.FixedDelay, retry.RandomDelay)), retry.MaxJitter(time.Second*2), diff --git a/config/cluster/k0s.go b/config/cluster/k0s.go index 8d92e89f..2fd43b56 100644 --- a/config/cluster/k0s.go +++ b/config/cluster/k0s.go @@ -57,7 +57,7 @@ func (k *K0s) SetDefaults() { func (k K0s) GenerateToken(h *Host, role string, expiry time.Duration) (token string, err error) { err = retry.Do( func() error { - output, err := h.ExecOutput(h.Configurer.K0sCmdf("token create --config %s --role %s --expiry %s", h.K0sConfigPath(), role, expiry.String()), exec.HideOutput()) + output, err := h.ExecOutput(h.Configurer.K0sCmdf("token create --config %s --role %s --expiry %s", h.K0sConfigPath(), role, expiry.String()), exec.HideOutput(), exec.Sudo(h)) if err != nil { return err } @@ -74,5 +74,5 @@ func (k K0s) GenerateToken(h *Host, role string, expiry time.Duration) (token st // GetClusterID uses kubectl to fetch the kube-system namespace uid func (k K0s) GetClusterID(h *Host) (string, error) { - return h.ExecOutput(h.Configurer.KubectlCmdf("get -n kube-system namespace kube-system -o template={{.metadata.uid}}")) + return h.ExecOutput(h.Configurer.KubectlCmdf("get -n kube-system namespace kube-system -o template={{.metadata.uid}}"), exec.Sudo(h)) } diff --git a/configurer/linux.go b/configurer/linux.go index 6d832891..7dcb1f03 100644 --- a/configurer/linux.go +++ b/configurer/linux.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" + "github.com/k0sproject/rig/exec" "github.com/k0sproject/rig/os" ) @@ -40,12 +41,12 @@ func (l Linux) Arch(h os.Host) (string, error) { // Chmod changes file permissions func (l Linux) Chmod(h os.Host, path, chmod string) error { - return h.Execf("sudo chmod %s %s", chmod, path) + return h.Execf("chmod %s %s", chmod, path, exec.Sudo(h)) } // K0sCmdf can be used to construct k0s commands in sprintf style. func (l Linux) K0sCmdf(template string, args ...interface{}) string { - return fmt.Sprintf("sudo %s %s", l.K0sBinaryPath(), fmt.Sprintf(template, args...)) + return fmt.Sprintf("%s %s", l.K0sBinaryPath(), fmt.Sprintf(template, args...)) } // K0sBinaryPath returns the location of k0s binary @@ -86,7 +87,7 @@ func (l Linux) DownloadK0s(h os.Host, version, arch string) error { return err } - return h.Execf(`sudo install -m 0750 -o root -g adm "%s" "%s"`, tmp, l.K0sBinaryPath()) + return h.Execf(`install -m 0750 -o root -g adm "%s" "%s"`, tmp, l.K0sBinaryPath(), exec.Sudo(h)) } // ReplaceK0sTokenPath replaces the config path in the service stub @@ -96,17 +97,17 @@ func (l Linux) ReplaceK0sTokenPath(h os.Host, spath string) error { // FileContains returns true if a file contains the substring func (l Linux) FileContains(h os.Host, path, s string) bool { - return h.Execf(`sudo grep -q "%s" "%s"`, s, path) == nil + return h.Execf(`grep -q "%s" "%s"`, s, path, exec.Sudo(h)) == nil } // MoveFile moves a file on the host func (l Linux) MoveFile(h os.Host, src, dst string) error { - return h.Execf(`sudo mv "%s" "%s"`, src, dst) + return h.Execf(`mv "%s" "%s"`, src, dst, exec.Sudo(h)) } // DeleteFile deletes a file on the host func (l Linux) DeleteFile(h os.Host, path string) error { - return h.Execf(`sudo rm -f "%s"`, path) + return h.Execf(`rm -f "%s"`, path, exec.Sudo(h)) } // KubeconfigPath returns the path to a kubeconfig on the host diff --git a/configurer/linux/alpine.go b/configurer/linux/alpine.go index 4e866d92..1f625878 100644 --- a/configurer/linux/alpine.go +++ b/configurer/linux/alpine.go @@ -5,6 +5,7 @@ import ( "github.com/k0sproject/k0sctl/configurer" "github.com/k0sproject/rig" + "github.com/k0sproject/rig/exec" "github.com/k0sproject/rig/os" "github.com/k0sproject/rig/os/registry" ) @@ -33,13 +34,9 @@ func init() { // InstallPackage installs packages via slackpkg func (l Alpine) InstallPackage(h os.Host, pkg ...string) error { - return h.Execf("sudo apk add --update %s", strings.Join(pkg, " ")) + return h.Execf("apk add --update %s", strings.Join(pkg, " "), exec.Sudo(h)) } func (l Alpine) Prepare(h os.Host) error { - if !l.CommandExist(h, "sudo") { - return h.Exec("apk add --update sudo") - } - return l.InstallPackage(h, "findutils", "coreutils") } diff --git a/configurer/linux/slackware.go b/configurer/linux/slackware.go index e45fe68e..24118d6c 100644 --- a/configurer/linux/slackware.go +++ b/configurer/linux/slackware.go @@ -1,6 +1,7 @@ package linux import ( + "fmt" "strings" "github.com/k0sproject/rig" @@ -27,5 +28,14 @@ func init() { // InstallPackage installs packages via slackpkg func (l Slackware) InstallPackage(h os.Host, pkg ...string) error { - return h.Execf("sudo slackpkg update && sudo slackpkg install --priority ADD %s", strings.Join(pkg, " ")) + updatecmd, err := h.Sudo("slackpkg update") + if err != nil { + return err + } + installcmd, err := h.Sudo(fmt.Sprintf("slackpkg install --priority ADD %s", strings.Join(pkg, " "))) + if err != nil { + return err + } + + return h.Execf("%s && %s", updatecmd, installcmd) } diff --git a/go.mod b/go.mod index e5c85dec..0f1a621c 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.16 require ( github.com/AlecAivazis/survey/v2 v2.2.8 + github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect + github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 // indirect github.com/Masterminds/semver v1.5.0 github.com/avast/retry-go v3.0.0+incompatible github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect @@ -11,10 +13,13 @@ require ( github.com/denisbrodbeck/machineid v1.0.1 github.com/gammazero/workerpool v1.1.1 github.com/go-playground/validator/v10 v10.4.1 + github.com/gofrs/uuid v4.0.0+incompatible // indirect github.com/hashicorp/go-version v1.2.1 github.com/k0sproject/dig v0.2.0 - github.com/k0sproject/rig v0.3.23 + github.com/k0sproject/rig v0.4.4 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-20210623064412-3b76017826b0 // indirect github.com/mattn/go-isatty v0.0.12 github.com/segmentio/analytics-go v3.1.0+incompatible github.com/segmentio/backo-go v0.0.0-20200129164019-23eae7c10bd3 // indirect @@ -23,7 +28,11 @@ require ( github.com/stretchr/testify v1.7.0 github.com/urfave/cli/v2 v2.3.0 github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect - golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect + golang.org/x/sys v0.0.0-20210819072135-bce67f096156 + golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect + golang.org/x/text v0.3.7 // indirect gopkg.in/yaml.v2 v2.4.0 k8s.io/client-go v0.19.3 ) diff --git a/go.sum b/go.sum index 7b7c5943..78b972f8 100644 --- a/go.sum +++ b/go.sum @@ -24,12 +24,14 @@ github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxB github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4 h1:pSm8mp0T2OH2CPmPDPtwHPr3VAQaOwVF/JbllOPP4xA= github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28= +github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChrisTrenkamp/goxpath v0.0.0-20170922090931-c385f95c6022 h1:y8Gs8CzNfDF5AZvjr+5UyGQvQEBL7pwo+v+wX6q9JI8= github.com/ChrisTrenkamp/goxpath v0.0.0-20170922090931-c385f95c6022/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4= +github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 h1:w0E0fgc1YafGEh5cROhlROMWXiNoZqApk2PDN0M1+Ns= +github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -90,8 +92,9 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -149,8 +152,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 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.3.23 h1:jmGxX8nuT0GNrjmjCCQIASaSPg5g26gYJjdPMo6Mu2Y= -github.com/k0sproject/rig v0.3.23/go.mod h1:6BgqiLQMw5SCMrysZ42ORzyXd3NOyr9KDEa2UGYphdY= +github.com/k0sproject/rig v0.4.4 h1:Wj7+BIKVhzhRau6Ht66zJXebBxnQc/7K8if2oeAF5K8= +github.com/k0sproject/rig v0.4.4/go.mod h1:4FKfoqz5HOE8v8pJ0K8BCvWw3ypB2vJINkAY4P+yTpo= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -168,10 +171,12 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9 h1:SmVbOZFWAlyQshuMfOkiAx1f5oUTsOGG5IXplAEYeeM= github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc= -github.com/masterzen/winrm v0.0.0-20201030141608-56ca5c5f2380 h1:uKhPH5dYpx3Z8ZAnaTGfGZUiHOWa5p5mdG8wZlh+tLo= +github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 h1:2ZKn+w/BJeL43sCxI2jhPLRv73oVVOjEKZjKkflyqxg= +github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc= github.com/masterzen/winrm v0.0.0-20201030141608-56ca5c5f2380/go.mod h1:a2HXwefeat3evJHxFXSayvRHpYEPJYtErl4uIzfaUqY= +github.com/masterzen/winrm v0.0.0-20210623064412-3b76017826b0 h1:KqYuDbSr8I2X8H65InN8SafDEa0UaLRy6WEmxDqd0F0= +github.com/masterzen/winrm v0.0.0-20210623064412-3b76017826b0/go.mod h1:l31LCh9VvG43RJ83A5JLkFPjuz48cZAxBSLQLaIn1p8= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -237,8 +242,9 @@ golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -271,8 +277,10 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -301,13 +309,22 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819072135-bce67f096156 h1:f7XLk/QXGE6IM4HjJ4ttFFlPSwJ65A1apfDd+mmViR0= +golang.org/x/sys v0.0.0-20210819072135-bce67f096156/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= diff --git a/phase/backup.go b/phase/backup.go index 4da79386..ddda5494 100644 --- a/phase/backup.go +++ b/phase/backup.go @@ -34,7 +34,7 @@ func (p *Backup) Prepare(config *config.Cluster) error { return fmt.Errorf("failed to find a running controller") } - if leader.Exec(leader.Configurer.K0sCmdf("backup --help")) != nil { + if leader.Exec(leader.Configurer.K0sCmdf("backup --help"), exec.Sudo(leader)) != nil { return fmt.Errorf("the version of k0s on the host does not support taking backups") } @@ -58,7 +58,7 @@ func (p *Backup) Run() error { return err } - if err := h.Exec(h.K0sBackupCommand(backupDir)); err != nil { + if err := h.Exec(h.K0sBackupCommand(backupDir), exec.Sudo(h)); err != nil { return err } diff --git a/phase/configure_k0s.go b/phase/configure_k0s.go index fa4d5a26..08a8f81a 100644 --- a/phase/configure_k0s.go +++ b/phase/configure_k0s.go @@ -8,6 +8,7 @@ import ( "time" "github.com/k0sproject/k0sctl/config/cluster" + "github.com/k0sproject/rig/exec" log "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" ) @@ -28,7 +29,7 @@ func (p *ConfigureK0s) Run() error { p.SetProp("default-config", true) leader := p.Config.Spec.K0sLeader() log.Warnf("%s: generating default configuration", leader) - cfg, err := leader.ExecOutput(leader.Configurer.K0sCmdf("default-config")) + cfg, err := leader.ExecOutput(leader.Configurer.K0sCmdf("default-config"), exec.Sudo(leader)) if err != nil { return err } @@ -46,7 +47,7 @@ func (p *ConfigureK0s) Run() error { func (p *ConfigureK0s) validateConfig(h *cluster.Host) error { log.Infof("%s: validating configuration", h) - output, err := h.ExecOutput(h.Configurer.K0sCmdf(`validate config --config "%s"`, h.K0sConfigPath())) + output, err := h.ExecOutput(h.Configurer.K0sCmdf(`validate config --config "%s"`, h.K0sConfigPath()), exec.Sudo(h)) if err != nil { return fmt.Errorf("spec.k0s.config fails validation:\n%s", output) } diff --git a/phase/download_k0s.go b/phase/download_k0s.go index b736b6b5..16c9739d 100644 --- a/phase/download_k0s.go +++ b/phase/download_k0s.go @@ -6,6 +6,7 @@ import ( "github.com/k0sproject/k0sctl/config" "github.com/k0sproject/k0sctl/config/cluster" + "github.com/k0sproject/rig/exec" log "github.com/sirupsen/logrus" ) @@ -46,7 +47,7 @@ func (p *DownloadK0s) downloadK0s(h *cluster.Host) error { return err } - output, err := h.ExecOutput(h.Configurer.K0sCmdf("version")) + output, err := h.ExecOutput(h.Configurer.K0sCmdf("version"), exec.Sudo(h)) if err != nil { if err := h.Configurer.DeleteFile(h, h.Configurer.K0sBinaryPath()); err != nil { log.Warnf("%s: failed to remove %s: %s", h, h.Configurer.K0sBinaryPath(), err.Error()) diff --git a/phase/gather_k0s_facts.go b/phase/gather_k0s_facts.go index bb3ec9d0..31929ab5 100644 --- a/phase/gather_k0s_facts.go +++ b/phase/gather_k0s_facts.go @@ -7,6 +7,7 @@ import ( "github.com/Masterminds/semver" "github.com/k0sproject/k0sctl/config/cluster" + "github.com/k0sproject/rig/exec" log "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" ) @@ -53,7 +54,7 @@ func (p *GatherK0sFacts) Run() error { } func (p *GatherK0sFacts) investigateK0s(h *cluster.Host) error { - output, err := h.ExecOutput(h.Configurer.K0sCmdf("version")) + output, err := h.ExecOutput(h.Configurer.K0sCmdf("version"), exec.Sudo(h)) if err != nil { return nil } @@ -71,7 +72,7 @@ func (p *GatherK0sFacts) investigateK0s(h *cluster.Host) error { } } - output, err = h.ExecOutput(h.Configurer.K0sCmdf("status -o json")) + output, err = h.ExecOutput(h.Configurer.K0sCmdf("status -o json"), exec.Sudo(h)) if err != nil { return nil } diff --git a/phase/reset.go b/phase/reset.go index bf786b1d..94c6c0f1 100644 --- a/phase/reset.go +++ b/phase/reset.go @@ -6,6 +6,7 @@ import ( "github.com/Masterminds/semver" "github.com/k0sproject/k0sctl/config" "github.com/k0sproject/k0sctl/config/cluster" + "github.com/k0sproject/rig/exec" log "github.com/sirupsen/logrus" ) @@ -55,6 +56,6 @@ func (p *Reset) Run() error { } log.Infof("%s: running k0s reset", h) - return h.Exec(h.Configurer.K0sCmdf("reset")) + return h.Exec(h.Configurer.K0sCmdf("reset"), exec.Sudo(h)) }) } diff --git a/phase/restore.go b/phase/restore.go index cb6ef220..4c09eccb 100644 --- a/phase/restore.go +++ b/phase/restore.go @@ -5,6 +5,7 @@ import ( "github.com/k0sproject/k0sctl/config" "github.com/k0sproject/k0sctl/config/cluster" + "github.com/k0sproject/rig/exec" log "github.com/sirupsen/logrus" ) @@ -31,7 +32,7 @@ func (p *Restore) Prepare(config *config.Cluster) error { p.Config = config p.leader = p.Config.Spec.K0sLeader() - if p.RestoreFrom != "" && p.leader.Exec(p.leader.Configurer.K0sCmdf("restore --help")) != nil { + if p.RestoreFrom != "" && p.leader.Exec(p.leader.Configurer.K0sCmdf("restore --help"), exec.Sudo(p.leader)) != nil { return fmt.Errorf("the version of k0s on the host does not support restoring backups") } @@ -55,7 +56,7 @@ func (p *Restore) Run() error { // Run restore log.Infof("%s: restoring cluster state", h) - if err := h.Exec(h.K0sRestoreCommand(dstFile)); err != nil { + if err := h.Exec(h.K0sRestoreCommand(dstFile), exec.Sudo(h)); err != nil { return err } diff --git a/phase/upgrade_controllers.go b/phase/upgrade_controllers.go index fd86b6fa..ecdad6bc 100644 --- a/phase/upgrade_controllers.go +++ b/phase/upgrade_controllers.go @@ -53,6 +53,9 @@ func (p *UpgradeControllers) Run() error { return err } } + if err := h.WaitK0sServiceStopped(); err != nil { + return err + } if err := h.UpdateK0sBinary(p.Config.Spec.K0s.Version); err != nil { return err } diff --git a/phase/upgrade_workers.go b/phase/upgrade_workers.go index b6ea6d5d..75894680 100644 --- a/phase/upgrade_workers.go +++ b/phase/upgrade_workers.go @@ -87,6 +87,9 @@ func (p *UpgradeWorkers) upgradeWorker(h *cluster.Host) error { if err := h.Configurer.StopService(h, h.K0sServiceName()); err != nil { return err } + if err := h.WaitK0sServiceStopped(); err != nil { + return err + } if err := h.UpdateK0sBinary(p.Config.Spec.K0s.Version); err != nil { return err } diff --git a/phase/upload_binaries.go b/phase/upload_binaries.go index 1a58bd6d..c8c0cef0 100644 --- a/phase/upload_binaries.go +++ b/phase/upload_binaries.go @@ -3,6 +3,7 @@ package phase import ( "github.com/k0sproject/k0sctl/config" "github.com/k0sproject/k0sctl/config/cluster" + "github.com/k0sproject/rig/exec" log "github.com/sirupsen/logrus" ) @@ -38,7 +39,7 @@ func (p *UploadBinaries) Run() error { func (p *UploadBinaries) uploadBinary(h *cluster.Host) error { log.Infof("%s: uploading k0s binary from %s", h, h.K0sBinaryPath) - if err := h.Upload(h.K0sBinaryPath, h.Configurer.K0sBinaryPath()); err != nil { + if err := h.Upload(h.K0sBinaryPath, h.Configurer.K0sBinaryPath(), exec.Sudo(h)); err != nil { return err } diff --git a/phase/uploadfiles.go b/phase/uploadfiles.go index 1f9fe0dd..cb5c9239 100644 --- a/phase/uploadfiles.go +++ b/phase/uploadfiles.go @@ -5,6 +5,7 @@ import ( "github.com/k0sproject/k0sctl/config" "github.com/k0sproject/k0sctl/config/cluster" + "github.com/k0sproject/rig/exec" log "github.com/sirupsen/logrus" ) @@ -49,7 +50,7 @@ func (p *UploadFiles) uploadFiles(h *cluster.Host) error { return err } - if err := h.Execf("sudo install -d %s -m %s", f.DestinationDir, f.PermMode); err != nil { + if err := h.Execf("install -d %s -m %s", f.DestinationDir, f.PermMode, exec.Sudo(h)); err != nil { return err } @@ -57,7 +58,7 @@ func (p *UploadFiles) uploadFiles(h *cluster.Host) error { log.Debugf("%s: uploading %s to %s", h, file, f.DestinationDir) destination := filepath.Join(f.DestinationDir, filepath.Base(file)) - if err := h.Upload(file, destination); err != nil { + if err := h.Upload(file, destination, exec.Sudo(h)); err != nil { return err }