Skip to content

Commit e1c86fa

Browse files
authored
Merge pull request #21642 from medyagh/invoke_kubeadm
Refactor Invoking Kubeadm command to prepare for debian 12
2 parents 8e14ec5 + 5910c46 commit e1c86fa

File tree

9 files changed

+139
-102
lines changed

9 files changed

+139
-102
lines changed

pkg/minikube/bootstrapper/bsutil/binaries.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ import (
2828
"golang.org/x/sync/errgroup"
2929

3030
"k8s.io/klog/v2"
31+
"k8s.io/minikube/pkg/minikube/assets"
3132
"k8s.io/minikube/pkg/minikube/command"
3233
"k8s.io/minikube/pkg/minikube/config"
3334
"k8s.io/minikube/pkg/minikube/constants"
3435
"k8s.io/minikube/pkg/minikube/download"
35-
"k8s.io/minikube/pkg/minikube/machine"
3636
"k8s.io/minikube/pkg/minikube/sysinit"
3737
"k8s.io/minikube/pkg/minikube/vmpath"
3838
)
@@ -68,7 +68,7 @@ func TransferBinaries(cfg config.KubernetesConfig, c command.Runner, sm sysinit.
6868
}
6969

7070
dst := path.Join(dir, name)
71-
if err := machine.CopyBinary(c, src, dst); err != nil {
71+
if err := copyBinary(c, src, dst); err != nil {
7272
return errors.Wrapf(err, "copybinary %s -> %s", src, dst)
7373
}
7474
return nil
@@ -101,3 +101,21 @@ func binariesExist(cfg config.KubernetesConfig, c command.Runner) (bool, error)
101101
func binRoot(version string) string {
102102
return path.Join(vmpath.GuestPersistentDir, "binaries", version)
103103
}
104+
105+
// copyBinary copies a locally cached binary to the guest VM
106+
func copyBinary(cr command.Runner, src, dest string) error {
107+
f, err := assets.NewFileAsset(src, path.Dir(dest), path.Base(dest), "0755")
108+
if err != nil {
109+
return errors.Wrap(err, "new file asset")
110+
}
111+
defer func() {
112+
if err := f.Close(); err != nil {
113+
klog.Warningf("error closing the file %s: %v", f.GetSourcePath(), err)
114+
}
115+
}()
116+
117+
if err := cr.Copy(f); err != nil {
118+
return errors.Wrapf(err, "copy")
119+
}
120+
return nil
121+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
Copyright 2016 The Kubernetes Authors All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package bsutil
18+
19+
import (
20+
"fmt"
21+
"os"
22+
"path/filepath"
23+
"testing"
24+
25+
"k8s.io/minikube/pkg/minikube/assets"
26+
"k8s.io/minikube/pkg/minikube/command"
27+
)
28+
29+
type copyFailRunner struct {
30+
command.Runner
31+
}
32+
33+
func (copyFailRunner) Copy(_ assets.CopyableFile) error {
34+
return fmt.Errorf("test error during copy file")
35+
}
36+
37+
func newFakeCommandRunnerCopyFail() command.Runner {
38+
return copyFailRunner{command.NewFakeCommandRunner()}
39+
}
40+
41+
func TestCopyBinary(t *testing.T) {
42+
tmpDir := t.TempDir()
43+
srcFile := filepath.Join(tmpDir, "source")
44+
if err := os.WriteFile(srcFile, []byte("data"), 0o644); err != nil {
45+
t.Fatalf("failed to create source file: %v", err)
46+
}
47+
48+
tests := []struct {
49+
name string
50+
runner command.Runner
51+
src string
52+
dst string
53+
wantErr bool
54+
}{
55+
{
56+
name: "missing source",
57+
runner: command.NewFakeCommandRunner(),
58+
src: filepath.Join(tmpDir, "missing"),
59+
dst: filepath.Join(tmpDir, "dest"),
60+
wantErr: true,
61+
},
62+
{
63+
name: "success",
64+
runner: command.NewFakeCommandRunner(),
65+
src: srcFile,
66+
dst: filepath.Join(tmpDir, "dest"),
67+
wantErr: false,
68+
},
69+
{
70+
name: "copy failure",
71+
runner: newFakeCommandRunnerCopyFail(),
72+
src: srcFile,
73+
dst: filepath.Join(tmpDir, "dest"),
74+
wantErr: true,
75+
},
76+
}
77+
78+
for _, tc := range tests {
79+
tc := tc
80+
t.Run(tc.name, func(t *testing.T) {
81+
err := copyBinary(tc.runner, tc.src, tc.dst)
82+
if (err != nil) != tc.wantErr {
83+
t.Fatalf("copyBinary() error = %v, wantErr %v", err, tc.wantErr)
84+
}
85+
})
86+
}
87+
}

pkg/minikube/bootstrapper/bsutil/kubeadm.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,12 @@ var KubeadmExtraConfigOpts = []string{
220220
Kubeproxy,
221221
}
222222

223-
// InvokeKubeadm returns the invocation command for Kubeadm
224-
func InvokeKubeadm(version string) string {
225-
return fmt.Sprintf("sudo env PATH=\"%s:$PATH\" kubeadm", binRoot(version))
223+
// KubeadmCmdWithPath returns the invocation command for Kubeadm
224+
// NOTE: The command must run with the a root shell to expand PATH to the
225+
// root PATH. On Debian 12 user PATH does not contain /usr/sbin which breaks
226+
// kubeadm since https://github.com/kubernetes/kubernetes/pull/129450.
227+
func KubeadmCmdWithPath(version string) string {
228+
return fmt.Sprintf("env PATH=\"%s:$PATH\" kubeadm", binRoot(version))
226229
}
227230

228231
// EtcdDataDir is where etcd data is stored.

pkg/minikube/bootstrapper/certs.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import (
4343

4444
"k8s.io/minikube/pkg/drivers/kic/oci"
4545
"k8s.io/minikube/pkg/minikube/assets"
46+
"k8s.io/minikube/pkg/minikube/bootstrapper/bsutil"
4647
"k8s.io/minikube/pkg/minikube/command"
4748
"k8s.io/minikube/pkg/minikube/config"
4849
"k8s.io/minikube/pkg/minikube/constants"
@@ -418,9 +419,8 @@ func renewExpiredKubeadmCerts(cmd command.Runner, cc config.ClusterConfig) error
418419
return nil
419420
}
420421
out.WarningT("kubeadm certificates have expired. Generating new ones...")
421-
kubeadmPath := path.Join(vmpath.GuestPersistentDir, "binaries", cc.KubernetesConfig.KubernetesVersion)
422-
bashCmd := fmt.Sprintf("sudo env PATH=\"%s:$PATH\" kubeadm certs renew all --config %s", kubeadmPath, constants.KubeadmYamlPath)
423-
if _, err := cmd.RunCmd(exec.Command("/bin/bash", "-c", bashCmd)); err != nil {
422+
bashCmd := fmt.Sprintf("%s certs renew all --config %s", bsutil.KubeadmCmdWithPath(cc.KubernetesConfig.KubernetesVersion), constants.KubeadmYamlPath)
423+
if _, err := cmd.RunCmd(exec.Command("sudo", "/bin/bash", "-c", bashCmd)); err != nil {
424424
return errors.Wrap(err, "kubeadm certs renew")
425425
}
426426
return nil

pkg/minikube/bootstrapper/kubeadm/kubeadm.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,16 @@ func (k *Bootstrapper) init(cfg config.ClusterConfig) error {
228228
ctx, cancel := context.WithTimeout(context.Background(), initTimeoutMinutes*time.Minute)
229229
defer cancel()
230230
kr, kw := io.Pipe()
231-
c := exec.CommandContext(ctx, "/bin/bash", "-c", fmt.Sprintf("%s init --config %s %s --ignore-preflight-errors=%s",
232-
bsutil.InvokeKubeadm(cfg.KubernetesConfig.KubernetesVersion), conf, extraFlags, strings.Join(ignore, ",")))
231+
232+
cmd := fmt.Sprintf(
233+
"%s init --config %s %s --ignore-preflight-errors=%s",
234+
bsutil.KubeadmCmdWithPath(cfg.KubernetesConfig.KubernetesVersion),
235+
conf,
236+
extraFlags,
237+
strings.Join(ignore, ","),
238+
)
239+
c := exec.CommandContext(ctx, "sudo", "/bin/bash", "-c", cmd)
240+
233241
c.Stdout = kw
234242
c.Stderr = kw
235243
var wg sync.WaitGroup
@@ -650,7 +658,7 @@ func (k *Bootstrapper) restartPrimaryControlPlane(cfg config.ClusterConfig) erro
650658
return errors.Wrap(err, "cp")
651659
}
652660

653-
baseCmd := fmt.Sprintf("%s init", bsutil.InvokeKubeadm(cfg.KubernetesConfig.KubernetesVersion))
661+
baseCmd := fmt.Sprintf("%s init", bsutil.KubeadmCmdWithPath(cfg.KubernetesConfig.KubernetesVersion))
654662
cmds := []string{
655663
fmt.Sprintf("%s phase certs all --config %s", baseCmd, conf),
656664
fmt.Sprintf("%s phase kubeconfig all --config %s", baseCmd, conf),
@@ -661,10 +669,10 @@ func (k *Bootstrapper) restartPrimaryControlPlane(cfg config.ClusterConfig) erro
661669

662670
// Run commands one at a time so that it is easier to root cause failures.
663671
for _, c := range cmds {
664-
if _, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", c)); err != nil {
672+
if _, err := k.c.RunCmd(exec.Command("sudo", "/bin/bash", "-c", c)); err != nil {
665673
klog.Errorf("%s failed - will try once more: %v", c, err)
666674

667-
if _, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", c)); err != nil {
675+
if _, err := k.c.RunCmd(exec.Command("sudo", "/bin/bash", "-c", c)); err != nil {
668676
return errors.Wrap(err, "run")
669677
}
670678
}
@@ -703,7 +711,7 @@ func (k *Bootstrapper) restartPrimaryControlPlane(cfg config.ClusterConfig) erro
703711
if cfg.KubernetesConfig.ExtraOptions.Exists("kubeadm.skip-phases=addon/kube-proxy") {
704712
addons = "coredns"
705713
}
706-
_, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("%s phase addon %s --config %s", baseCmd, addons, conf)))
714+
_, err := k.c.RunCmd(exec.Command("sudo", "/bin/bash", "-c", fmt.Sprintf("%s phase addon %s --config %s", baseCmd, addons, conf)))
707715
return err
708716
}
709717
if err = retry.Expo(addonPhase, 100*time.Microsecond, 30*time.Second); err != nil {
@@ -759,11 +767,11 @@ func (k *Bootstrapper) JoinCluster(cc config.ClusterConfig, n config.Node, joinC
759767
" --apiserver-bind-port=" + strconv.Itoa(n.Port)
760768
}
761769

762-
if _, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", joinCmd)); err != nil {
770+
if _, err := k.c.RunCmd(exec.Command("sudo", "/bin/bash", "-c", joinCmd)); err != nil {
763771
return errors.Wrapf(err, "kubeadm join")
764772
}
765773

766-
if _, err := k.c.RunCmd(exec.Command("/bin/bash", "-c", "sudo systemctl daemon-reload && sudo systemctl enable kubelet && sudo systemctl start kubelet")); err != nil {
774+
if _, err := k.c.RunCmd(exec.Command("sudo", "/bin/bash", "-c", "systemctl daemon-reload && systemctl enable kubelet && systemctl start kubelet")); err != nil {
767775
return errors.Wrap(err, "starting kubelet")
768776
}
769777

@@ -773,14 +781,14 @@ func (k *Bootstrapper) JoinCluster(cc config.ClusterConfig, n config.Node, joinC
773781
// GenerateToken creates a token and returns the appropriate kubeadm join command to run, or the already existing token
774782
func (k *Bootstrapper) GenerateToken(cc config.ClusterConfig) (string, error) {
775783
// Take that generated token and use it to get a kubeadm join command
776-
tokenCmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("%s token create --print-join-command --ttl=0", bsutil.InvokeKubeadm(cc.KubernetesConfig.KubernetesVersion)))
784+
tokenCmd := exec.Command("sudo", "/bin/bash", "-c", fmt.Sprintf("%s token create --print-join-command --ttl=0", bsutil.KubeadmCmdWithPath(cc.KubernetesConfig.KubernetesVersion)))
777785
r, err := k.c.RunCmd(tokenCmd)
778786
if err != nil {
779787
return "", errors.Wrap(err, "generating join command")
780788
}
781789

782790
joinCmd := r.Stdout.String()
783-
joinCmd = strings.Replace(joinCmd, "kubeadm", bsutil.InvokeKubeadm(cc.KubernetesConfig.KubernetesVersion), 1)
791+
joinCmd = strings.Replace(joinCmd, "kubeadm", bsutil.KubeadmCmdWithPath(cc.KubernetesConfig.KubernetesVersion), 1)
784792
joinCmd = fmt.Sprintf("%s --ignore-preflight-errors=all", strings.TrimSpace(joinCmd))
785793

786794
// avoid "Found multiple CRI endpoints on the host. Please define which one do you wish to use by setting the 'criSocket' field in the kubeadm configuration file: unix:///var/run/containerd/containerd.sock, unix:///var/run/cri-dockerd.sock" error
@@ -849,14 +857,14 @@ func (k *Bootstrapper) DeleteCluster(k8s config.KubernetesConfig) error {
849857
return errors.Wrap(err, "runtime")
850858
}
851859

852-
ka := bsutil.InvokeKubeadm(k8s.KubernetesVersion)
860+
ka := bsutil.KubeadmCmdWithPath(k8s.KubernetesVersion)
853861
sp := cr.SocketPath()
854862
cmd := fmt.Sprintf("%s reset --cri-socket %s --force", ka, sp)
855863
if ver.LT(semver.MustParse("1.11.0")) {
856864
cmd = fmt.Sprintf("%s reset --cri-socket %s", ka, sp)
857865
}
858866

859-
rr, derr := k.c.RunCmd(exec.Command("/bin/bash", "-c", cmd))
867+
rr, derr := k.c.RunCmd(exec.Command("sudo", "/bin/bash", "-c", cmd))
860868
if derr != nil {
861869
klog.Warningf("%s: %v", rr.Command(), err)
862870
}

pkg/minikube/machine/cache_binaries.go

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,11 @@ limitations under the License.
1717
package machine
1818

1919
import (
20-
"path"
2120
"runtime"
2221

2322
"github.com/pkg/errors"
2423
"golang.org/x/sync/errgroup"
25-
"k8s.io/klog/v2"
26-
"k8s.io/minikube/pkg/minikube/assets"
2724
"k8s.io/minikube/pkg/minikube/bootstrapper"
28-
"k8s.io/minikube/pkg/minikube/command"
2925
"k8s.io/minikube/pkg/minikube/download"
3026
)
3127

@@ -61,21 +57,3 @@ func CacheBinariesForBootstrapper(version string, excludeBinaries []string, bina
6157
}
6258
return g.Wait()
6359
}
64-
65-
// CopyBinary copies a locally cached binary to the guest VM
66-
func CopyBinary(cr command.Runner, src string, dest string) error {
67-
f, err := assets.NewFileAsset(src, path.Dir(dest), path.Base(dest), "0755")
68-
if err != nil {
69-
return errors.Wrap(err, "new file asset")
70-
}
71-
defer func() {
72-
if err := f.Close(); err != nil {
73-
klog.Warningf("error closing the file %s: %v", f.GetSourcePath(), err)
74-
}
75-
}()
76-
77-
if err := cr.Copy(f); err != nil {
78-
return errors.Wrapf(err, "copy")
79-
}
80-
return nil
81-
}

pkg/minikube/machine/cache_binaries_test.go

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -17,70 +17,13 @@ limitations under the License.
1717
package machine
1818

1919
import (
20-
"fmt"
2120
"strings"
2221
"testing"
2322

24-
"k8s.io/minikube/pkg/minikube/assets"
2523
"k8s.io/minikube/pkg/minikube/bootstrapper"
26-
"k8s.io/minikube/pkg/minikube/command"
2724
"k8s.io/minikube/pkg/minikube/download"
2825
)
2926

30-
type copyFailRunner struct {
31-
command.Runner
32-
}
33-
34-
func (copyFailRunner) Copy(_ assets.CopyableFile) error {
35-
return fmt.Errorf("test error during copy file")
36-
}
37-
38-
func newFakeCommandRunnerCopyFail() command.Runner {
39-
return copyFailRunner{command.NewFakeCommandRunner()}
40-
}
41-
42-
func TestCopyBinary(t *testing.T) {
43-
var tc = []struct {
44-
lastUpdateCheckFilePath string
45-
src, dst, desc string
46-
err bool
47-
runner command.Runner
48-
}{
49-
{
50-
desc: "not existing src",
51-
dst: "/tmp/testCopyBinary1",
52-
src: "/tmp/testCopyBinary2",
53-
err: true,
54-
runner: command.NewFakeCommandRunner(),
55-
},
56-
{
57-
desc: "src /etc/hosts",
58-
dst: "/tmp/testCopyBinary1",
59-
src: "/etc/hosts",
60-
err: false,
61-
runner: command.NewFakeCommandRunner(),
62-
},
63-
{
64-
desc: "existing src, copy fail",
65-
dst: "/etc/passwd",
66-
src: "/etc/hosts",
67-
err: true,
68-
runner: newFakeCommandRunnerCopyFail(),
69-
},
70-
}
71-
for _, test := range tc {
72-
t.Run(test.desc, func(t *testing.T) {
73-
err := CopyBinary(test.runner, test.src, test.dst)
74-
if err != nil && !test.err {
75-
t.Fatalf("Got unexpected error %v", err)
76-
}
77-
if err == nil && test.err {
78-
t.Fatal("Expected error but got nil")
79-
}
80-
})
81-
}
82-
}
83-
8427
func TestCacheBinariesForBootstrapper(t *testing.T) {
8528
download.DownloadMock = download.CreateDstDownloadMock
8629

pkg/minikube/node/node.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ func teardown(cc config.ClusterConfig, name string) (*config.Node, error) {
149149
sp = "unix://" + sp
150150
}
151151

152-
cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("KUBECONFIG=/var/lib/minikube/kubeconfig %s reset --force --ignore-preflight-errors=all --cri-socket=%s",
153-
bsutil.InvokeKubeadm(cc.KubernetesConfig.KubernetesVersion), sp))
152+
cmd := exec.Command("sudo", "/bin/bash", "-c", fmt.Sprintf("KUBECONFIG=/var/lib/minikube/kubeconfig %s reset --force --ignore-preflight-errors=all --cri-socket=%s",
153+
bsutil.KubeadmCmdWithPath(cc.KubernetesConfig.KubernetesVersion), sp))
154154
if _, kerr = r.RunCmd(cmd); kerr == nil {
155155
klog.Infof("successfully reset node %q", m)
156156
}

pkg/minikube/node/start.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ func joinCluster(starter Starter, cpBs bootstrapper.Bootstrapper, bs bootstrappe
346346

347347
// reset node to revert any changes made by previous kubeadm init/join
348348
klog.Infof("resetting %s node %q before attempting to rejoin cluster...", role, starter.Node.Name)
349-
if _, err := starter.Runner.RunCmd(exec.Command("/bin/bash", "-c", fmt.Sprintf("%s reset --force", bsutil.InvokeKubeadm(starter.Cfg.KubernetesConfig.KubernetesVersion)))); err != nil {
349+
if _, err := starter.Runner.RunCmd(exec.Command("sudo", "/bin/bash", "-c", fmt.Sprintf("%s reset --force", bsutil.KubeadmCmdWithPath(starter.Cfg.KubernetesConfig.KubernetesVersion)))); err != nil {
350350
klog.Infof("kubeadm reset failed, continuing anyway: %v", err)
351351
} else {
352352
klog.Infof("successfully reset %s node %q", role, starter.Node.Name)

0 commit comments

Comments
 (0)