1
16
17 package upgrade
18
19 import (
20 "os"
21 "path/filepath"
22 "regexp"
23 "strings"
24 "testing"
25
26 "github.com/pkg/errors"
27
28 errorsutil "k8s.io/apimachinery/pkg/util/errors"
29 kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
30 "k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
31 "k8s.io/kubernetes/cmd/kubeadm/app/constants"
32 "k8s.io/kubernetes/cmd/kubeadm/app/preflight"
33 testutil "k8s.io/kubernetes/cmd/kubeadm/test"
34 )
35
36 func TestMoveFiles(t *testing.T) {
37 tmpdir := testutil.SetupTempDir(t)
38 defer os.RemoveAll(tmpdir)
39 os.Chmod(tmpdir, 0766)
40
41 certPath := filepath.Join(tmpdir, constants.APIServerCertName)
42 certFile, err := os.OpenFile(certPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
43 if err != nil {
44 t.Fatalf("Failed to create cert file %s: %v", certPath, err)
45 }
46 certFile.Close()
47
48 keyPath := filepath.Join(tmpdir, constants.APIServerKeyName)
49 keyFile, err := os.OpenFile(keyPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
50 if err != nil {
51 t.Fatalf("Failed to create key file %s: %v", keyPath, err)
52 }
53 keyFile.Close()
54
55 subDir := filepath.Join(tmpdir, "expired")
56 if err := os.Mkdir(subDir, 0766); err != nil {
57 t.Fatalf("Failed to create backup directory %s: %v", subDir, err)
58 }
59
60 filesToMove := map[string]string{
61 filepath.Join(tmpdir, constants.APIServerCertName): filepath.Join(subDir, constants.APIServerCertName),
62 filepath.Join(tmpdir, constants.APIServerKeyName): filepath.Join(subDir, constants.APIServerKeyName),
63 }
64
65 if err := moveFiles(filesToMove); err != nil {
66 t.Fatalf("Failed to move files %v: %v", filesToMove, err)
67 }
68 }
69
70 func TestRollbackFiles(t *testing.T) {
71 tmpdir := testutil.SetupTempDir(t)
72 defer os.RemoveAll(tmpdir)
73 os.Chmod(tmpdir, 0766)
74
75 subDir := filepath.Join(tmpdir, "expired")
76 if err := os.Mkdir(subDir, 0766); err != nil {
77 t.Fatalf("Failed to create backup directory %s: %v", subDir, err)
78 }
79
80 certPath := filepath.Join(subDir, constants.APIServerCertName)
81 certFile, err := os.OpenFile(certPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
82 if err != nil {
83 t.Fatalf("Failed to create cert file %s: %v", certPath, err)
84 }
85 defer certFile.Close()
86
87 keyPath := filepath.Join(subDir, constants.APIServerKeyName)
88 keyFile, err := os.OpenFile(keyPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
89 if err != nil {
90 t.Fatalf("Failed to create key file %s: %v", keyPath, err)
91 }
92 defer keyFile.Close()
93
94 filesToRollBack := map[string]string{
95 filepath.Join(subDir, constants.APIServerCertName): filepath.Join(tmpdir, constants.APIServerCertName),
96 filepath.Join(subDir, constants.APIServerKeyName): filepath.Join(tmpdir, constants.APIServerKeyName),
97 }
98
99 errString := "there are files need roll back"
100 originalErr := errors.New(errString)
101 err = rollbackFiles(filesToRollBack, originalErr)
102 if err == nil {
103 t.Fatalf("Expected error contains %q, got nil", errString)
104 }
105 if !strings.Contains(err.Error(), errString) {
106 t.Fatalf("Expected error contains %q, got %v", errString, err)
107 }
108 }
109
110 func TestWriteKubeletConfigFiles(t *testing.T) {
111
112
113 isPrivileged := preflight.IsPrivilegedUserCheck{}
114 if _, err := isPrivileged.Check(); err != nil {
115 return
116 }
117 testCases := []struct {
118 name string
119 dryrun bool
120 patchesDir string
121 errPattern string
122 cfg *kubeadmapi.InitConfiguration
123 }{
124
125
126
127
128 {
129 name: "write kubelet config file successfully",
130 dryrun: true,
131 cfg: &kubeadmapi.InitConfiguration{
132 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
133 ComponentConfigs: kubeadmapi.ComponentConfigMap{
134 componentconfigs.KubeletGroup: &componentConfig{},
135 },
136 },
137 },
138 },
139 {
140 name: "aggregate errs: no kubelet config file and cannot read config file",
141 dryrun: true,
142 errPattern: missingKubeletConfig,
143 cfg: &kubeadmapi.InitConfiguration{},
144 },
145 {
146 name: "only one err: patch dir does not exist",
147 dryrun: true,
148 patchesDir: "Bogus",
149 errPattern: "could not list patch files for path \"Bogus\"",
150 cfg: &kubeadmapi.InitConfiguration{
151 ClusterConfiguration: kubeadmapi.ClusterConfiguration{
152 ComponentConfigs: kubeadmapi.ComponentConfigMap{
153 componentconfigs.KubeletGroup: &componentConfig{},
154 },
155 },
156 },
157 },
158 }
159 for _, tc := range testCases {
160 err := WriteKubeletConfigFiles(tc.cfg, tc.patchesDir, tc.dryrun, os.Stdout)
161 if err != nil && tc.errPattern != "" {
162 if match, _ := regexp.MatchString(tc.errPattern, err.Error()); !match {
163 t.Fatalf("Expected error contains %q, got %v", tc.errPattern, err.Error())
164 }
165 }
166 if err == nil && len(tc.errPattern) != 0 {
167 t.Fatalf("WriteKubeletConfigFiles didn't return error expected %s", tc.errPattern)
168 }
169 }
170 }
171
172
173 type componentConfig struct {
174 userSupplied bool
175 }
176
177 func (cc *componentConfig) DeepCopy() kubeadmapi.ComponentConfig {
178 result := &componentConfig{}
179 return result
180 }
181
182 func (cc *componentConfig) Marshal() ([]byte, error) {
183 return nil, nil
184 }
185
186 func (cc *componentConfig) Unmarshal(docmap kubeadmapi.DocumentMap) error {
187 return nil
188 }
189
190 func (cc *componentConfig) Get() interface{} {
191 return &cc
192 }
193
194 func (cc *componentConfig) Set(cfg interface{}) {
195 }
196
197 func (cc *componentConfig) Default(_ *kubeadmapi.ClusterConfiguration, _ *kubeadmapi.APIEndpoint, _ *kubeadmapi.NodeRegistrationOptions) {
198 }
199
200 func (cc *componentConfig) Mutate() error {
201 return nil
202 }
203
204 func (cc *componentConfig) IsUserSupplied() bool {
205 return false
206 }
207 func (cc *componentConfig) SetUserSupplied(userSupplied bool) {
208 cc.userSupplied = userSupplied
209 }
210
211
212 func moveFiles(files map[string]string) error {
213 filesToRecover := make(map[string]string, len(files))
214 for from, to := range files {
215 if err := os.Rename(from, to); err != nil {
216 return rollbackFiles(filesToRecover, err)
217 }
218 filesToRecover[to] = from
219 }
220 return nil
221 }
222
223
224 func rollbackFiles(files map[string]string, originalErr error) error {
225 errs := []error{originalErr}
226 for from, to := range files {
227 if err := os.Rename(from, to); err != nil {
228 errs = append(errs, err)
229 }
230 }
231 return errors.Errorf("couldn't move these files: %v. Got errors: %v", files, errorsutil.NewAggregate(errs))
232 }
233
View as plain text