github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/test/suites/apply/apply.go (about) 1 // Copyright © 2021 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package apply 16 17 import ( 18 "bytes" 19 "fmt" 20 "path/filepath" 21 "strconv" 22 "time" 23 24 "github.com/sealerio/sealer/common" 25 "github.com/sealerio/sealer/pkg/checker" 26 k "github.com/sealerio/sealer/pkg/client/k8s" 27 "github.com/sealerio/sealer/pkg/infra" 28 "github.com/sealerio/sealer/test/testhelper" 29 "github.com/sealerio/sealer/test/testhelper/client/k8s" 30 "github.com/sealerio/sealer/test/testhelper/settings" 31 "github.com/sealerio/sealer/types/api/constants" 32 v1 "github.com/sealerio/sealer/types/api/v1" 33 "github.com/sealerio/sealer/utils" 34 "github.com/sealerio/sealer/utils/exec" 35 "github.com/sealerio/sealer/utils/os" 36 37 "github.com/onsi/gomega" 38 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 39 "sigs.k8s.io/yaml" 40 ) 41 42 func getFixtures() string { 43 pwd := settings.DefaultTestEnvDir 44 return filepath.Join(pwd, "suites", "apply", "fixtures") 45 } 46 47 func GetRawClusterFilePath() string { 48 fixtures := getFixtures() 49 return filepath.Join(fixtures, "cluster_file_for_test.yaml") 50 } 51 52 func GetRawConfigPluginFilePath() string { 53 fixtures := getFixtures() 54 return filepath.Join(fixtures, "config_plugin_for_test.yaml") 55 } 56 57 func DeleteClusterByFile(clusterFile string) { 58 testhelper.RunCmdAndCheckResult(SealerDeleteCmd(clusterFile), 0) 59 } 60 61 func WriteClusterFileToDisk(cluster *v1.Cluster, clusterFilePath string) { 62 testhelper.CheckNotNil(cluster) 63 //convert clusterfilev1 to clusterfilev2 64 clusterv2 := utils.ConvertV1ClusterToV2Cluster(cluster) 65 clusterv2.Spec.Env = []string{"env=TestEnv"} 66 err := testhelper.MarshalYamlToFile(clusterFilePath, clusterv2) 67 testhelper.CheckErr(err) 68 } 69 70 func LoadClusterFileFromDisk(clusterFilePath string) *v1.Cluster { 71 cluster, err := utils.DecodeV1ClusterFromFile(clusterFilePath) 72 testhelper.CheckErr(err) 73 testhelper.CheckNotNil(cluster) 74 return cluster 75 } 76 77 func LoadConfigFromDisk(clusterFilePath string) []v1.Config { 78 configs, err := utils.DecodeCRDFromFile(clusterFilePath, constants.ConfigKind) 79 testhelper.CheckErr(err) 80 testhelper.CheckNotNil(configs) 81 return configs.([]v1.Config) 82 } 83 84 func LoadPluginFromDisk(clusterFilePath string) []v1.Plugin { 85 plugins, err := utils.DecodeCRDFromFile(clusterFilePath, constants.PluginKind) 86 testhelper.CheckErr(err) 87 testhelper.CheckNotNil(plugins) 88 return plugins.([]v1.Plugin) 89 } 90 91 func GenerateClusterfile(clusterfile string) { 92 fp := GetRawConfigPluginFilePath() 93 cluster := LoadClusterFileFromDisk(clusterfile) 94 //convert clusterfilev1 to clusterfilev2 95 clusterv2 := utils.ConvertV1ClusterToV2Cluster(cluster) 96 clusterv2.Spec.Env = []string{"env=TestEnv"} 97 data, err := yaml.Marshal(clusterv2) 98 testhelper.CheckErr(err) 99 appendData := [][]byte{data} 100 plugins := LoadPluginFromDisk(fp) 101 configs := LoadConfigFromDisk(fp) 102 for _, plugin := range plugins { 103 if plugin.Spec.Type == common.LABEL { 104 pluginData := "\n" 105 for _, ip := range cluster.Spec.Masters.IPList { 106 pluginData += fmt.Sprintf(" %s sealer-test=true \n", ip) 107 } 108 plugin.Spec.Data = pluginData 109 } 110 if plugin.Spec.Type == common.HOSTNAME { 111 pluginData := "\n" 112 for i, ip := range cluster.Spec.Masters.IPList { 113 pluginData += fmt.Sprintf("%s master-%s\n", ip, strconv.Itoa(i)) 114 } 115 for i, ip := range cluster.Spec.Nodes.IPList { 116 pluginData += fmt.Sprintf("%s node-%s\n", ip, strconv.Itoa(i)) 117 } 118 plugin.Spec.Data = pluginData 119 } 120 if plugin.Spec.Type == common.TAINT { 121 pluginData := "\n" 122 for _, ip := range cluster.Spec.Masters.IPList { 123 pluginData += fmt.Sprintf("%s node-role.kubernetes.io/master:NoSchedule-\n", ip) 124 } 125 for _, ip := range cluster.Spec.Nodes.IPList { 126 pluginData += fmt.Sprintf("%s sealer-test=true:NoSchedule\n", ip) 127 } 128 plugin.Spec.Data = pluginData 129 } 130 data, err := yaml.Marshal(plugin) 131 testhelper.CheckErr(err) 132 appendData = append(appendData, []byte("---\n"), data) 133 } 134 for _, config := range configs { 135 data, err := yaml.Marshal(config) 136 testhelper.CheckErr(err) 137 appendData = append(appendData, []byte("---\n"), data) 138 } 139 err = os.NewCommonWriter(clusterfile).WriteFile(bytes.Join(appendData, []byte(""))) 140 testhelper.CheckErr(err) 141 } 142 143 func SealerDeleteCmd(clusterFile string) string { 144 return fmt.Sprintf("%s delete -f %s --force -d", settings.DefaultSealerBin, clusterFile) 145 } 146 147 func SealerDeleteAll() string { 148 return fmt.Sprintf("%s delete --all --force -d", settings.DefaultSealerBin) 149 } 150 151 func SealerDeleteNodeCmd(ip string) string { 152 return fmt.Sprintf("%s delete -n %s --force -d", settings.DefaultSealerBin, ip) 153 } 154 155 func SealerApplyCmd(clusterFile string) string { 156 return fmt.Sprintf("%s apply -f %s --force -d", settings.DefaultSealerBin, clusterFile) 157 } 158 159 func SealerRunCmd(masters, nodes, passwd string, provider string) string { 160 if masters != "" { 161 masters = fmt.Sprintf("-m %s", masters) 162 } 163 if nodes != "" { 164 nodes = fmt.Sprintf("-n %s", nodes) 165 } 166 if passwd != "" { 167 passwd = fmt.Sprintf("-p %s", passwd) 168 } 169 if provider != "" { 170 provider = fmt.Sprintf("--provider %s", provider) 171 } 172 return fmt.Sprintf("%s run %s %s %s %s %s -d", settings.DefaultSealerBin, settings.TestImageName, masters, nodes, passwd, provider) 173 } 174 175 func SealerRun(masters, nodes, passwd, provider string) { 176 testhelper.RunCmdAndCheckResult(SealerRunCmd(masters, nodes, passwd, provider), 0) 177 } 178 179 func SealerJoinCmd(masters, nodes string) string { 180 if masters != "" { 181 masters = fmt.Sprintf("-m %s", masters) 182 } 183 if nodes != "" { 184 nodes = fmt.Sprintf("-n %s", nodes) 185 } 186 return fmt.Sprintf("%s join %s %s -d", settings.DefaultSealerBin, masters, nodes) 187 } 188 189 func SealerJoin(masters, nodes string) { 190 testhelper.RunCmdAndCheckResult(SealerJoinCmd(masters, nodes), 0) 191 } 192 193 func CreateContainerInfraAndSave(cluster *v1.Cluster, clusterFile string) *v1.Cluster { 194 CreateContainerInfra(cluster) 195 //save used cluster file 196 cluster.Spec.Provider = settings.BAREMETAL 197 MarshalClusterToFile(clusterFile, cluster) 198 cluster.Spec.Provider = settings.CONTAINER 199 return cluster 200 } 201 202 func ChangeMasterOrderAndSave(cluster *v1.Cluster, clusterFile string) *v1.Cluster { 203 cluster.Spec.Masters.Count = strconv.Itoa(3) 204 CreateContainerInfra(cluster) 205 //change master order and save used cluster file 206 cluster.Spec.Masters.IPList[0], cluster.Spec.Masters.IPList[1] = cluster.Spec.Masters.IPList[1], cluster.Spec.Masters.IPList[0] 207 cluster.Spec.Provider = settings.BAREMETAL 208 MarshalClusterToFile(clusterFile, cluster) 209 cluster.Spec.Provider = settings.CONTAINER 210 return cluster 211 } 212 213 func CreateContainerInfra(cluster *v1.Cluster) { 214 cluster.DeletionTimestamp = nil 215 infraManager, err := infra.NewDefaultProvider(cluster) 216 testhelper.CheckErr(err) 217 err = infraManager.Apply() 218 testhelper.CheckErr(err) 219 } 220 221 func SendAndApplyCluster(sshClient *testhelper.SSHClient, clusterFile string) { 222 SendAndRemoteExecCluster(sshClient, clusterFile, SealerApplyCmd(clusterFile)) 223 } 224 225 func SendAndJoinCluster(sshClient *testhelper.SSHClient, clusterFile string, joinMasters, joinNodes string) { 226 SendAndRemoteExecCluster(sshClient, clusterFile, SealerJoinCmd(joinMasters, joinNodes)) 227 } 228 229 func SendAndRunCluster(sshClient *testhelper.SSHClient, clusterFile string, joinMasters, joinNodes, passwd string) { 230 SendAndRemoteExecCluster(sshClient, clusterFile, SealerRunCmd(joinMasters, joinNodes, passwd, "")) 231 } 232 233 func SendAndRemoteExecCluster(sshClient *testhelper.SSHClient, clusterFile string, remoteCmd string) { 234 // send tmp cluster file to remote server and run apply cmd 235 gomega.Eventually(func() bool { 236 err := sshClient.SSH.Copy(sshClient.RemoteHostIP, clusterFile, clusterFile) 237 return err == nil 238 }, settings.MaxWaiteTime).Should(gomega.BeTrue()) 239 err := sshClient.SSH.CmdAsync(sshClient.RemoteHostIP, nil, remoteCmd) 240 testhelper.CheckErr(err) 241 } 242 243 func CleanUpContainerInfra(cluster *v1.Cluster) { 244 if cluster == nil { 245 return 246 } 247 if cluster.Spec.Provider != settings.CONTAINER { 248 cluster.Spec.Provider = settings.CONTAINER 249 } 250 t := metav1.Now() 251 cluster.DeletionTimestamp = &t 252 infraManager, err := infra.NewDefaultProvider(cluster) 253 testhelper.CheckErr(err) 254 err = infraManager.Apply() 255 testhelper.CheckErr(err) 256 } 257 258 // CheckNodeNumWithSSH check node num of remote cluster 259 func CheckNodeNumWithSSH(client *k8s.Client, expectNum int) { 260 if client == nil { 261 return 262 } 263 nodes, err := client.ListNodes() 264 testhelper.CheckErr(err) 265 num := len(nodes.Items) 266 testhelper.CheckEqual(num, expectNum) 267 } 268 269 // CheckNodeNumLocally check node num of local cluster 270 func CheckNodeNumLocally(client *k.Client, expectNum int) { 271 if client == nil { 272 return 273 } 274 nodes, err := client.ListNodes() 275 testhelper.CheckErr(err) 276 num := len(nodes.Items) 277 testhelper.CheckEqual(num, expectNum) 278 } 279 280 func WaitAllNodeRunning() { 281 time.Sleep(30 * time.Second) 282 err := utils.Retry(10, 5*time.Second, func() error { 283 return checker.NewNodeChecker().Check(nil, checker.PhasePost) 284 }) 285 testhelper.CheckErr(err) 286 } 287 288 func WaitAllNodeRunningBySSH(client *k8s.Client) { 289 time.Sleep(30 * time.Second) 290 err := utils.Retry(10, 5*time.Second, func() error { 291 flag, err := client.CheckAllNodeReady() 292 if err != nil { 293 return err 294 } 295 if !flag { 296 err = client.OutputNotReadyPodInfo() 297 if err != nil { 298 return err 299 } 300 return fmt.Errorf("node not ready") 301 } 302 return nil 303 }) 304 testhelper.CheckErr(err) 305 } 306 307 func MarshalClusterToFile(ClusterFile string, cluster *v1.Cluster) { 308 err := testhelper.MarshalYamlToFile(ClusterFile, &cluster) 309 testhelper.CheckErr(err) 310 testhelper.CheckNotNil(cluster) 311 } 312 313 func CheckDockerAndSwapOff() { 314 _, err := exec.RunSimpleCmd("docker -v") 315 testhelper.CheckErr(err) 316 _, err = exec.RunSimpleCmd("swapoff -a") 317 testhelper.CheckErr(err) 318 }