github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/pkg/env/env.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 env 16 17 import ( 18 "encoding/base64" 19 "fmt" 20 "os" 21 "path/filepath" 22 "sort" 23 "strings" 24 "text/template" 25 ) 26 27 const templateSuffix = ".tmpl" 28 29 func base64encode(v string) string { 30 return base64.StdEncoding.EncodeToString([]byte(v)) 31 } 32 33 func base64decode(v string) string { 34 data, err := base64.StdEncoding.DecodeString(v) 35 if err != nil { 36 return err.Error() 37 } 38 return string(data) 39 } 40 41 // RenderTemplate :using renderData got from clusterfile to render all the files in dir with ".tmpl" as suffix. 42 // The scope of renderData comes from cluster.spec.env 43 func RenderTemplate(dir string, renderData map[string]string) error { 44 return filepath.Walk(dir, func(path string, info os.FileInfo, errIn error) error { 45 if errIn != nil { 46 return errIn 47 } 48 if info.IsDir() || !strings.HasSuffix(info.Name(), templateSuffix) { 49 return nil 50 } 51 writer, err := os.Create(strings.TrimSuffix(path, templateSuffix)) 52 if err != nil { 53 return fmt.Errorf("failed to open file [%s] when render env: %v", path, err) 54 } 55 defer func() { 56 _ = writer.Close() 57 }() 58 t, err := template.New(info.Name()).Funcs(template.FuncMap{ 59 "b64enc": base64encode, 60 "b64dec": base64decode, 61 }).ParseFiles(path) 62 if err != nil { 63 return fmt.Errorf("failed to create template(%s): %v", path, err) 64 } 65 if err := t.Execute(writer, renderData); err != nil { 66 return fmt.Errorf("failed to render env template(%s): %v", path, err) 67 } 68 return nil 69 }) 70 } 71 72 // WrapperShell :If target host already set env like DATADISK=/data in the clusterfile, 73 // This function will WrapperShell cmd like: 74 // Input shell: cat /etc/hosts 75 // Output shell: DATADISK=/data cat /etc/hosts 76 // it is convenient for user to get env in scripts 77 // The scope of env comes from cluster.spec.env and host.env 78 func WrapperShell(shell string, wrapperData map[string]string) string { 79 env := getEnvFromData(wrapperData) 80 81 if len(env) == 0 { 82 return shell 83 } 84 return fmt.Sprintf("%s %s", strings.Join(env, " "), shell) 85 } 86 87 func getEnvFromData(wrapperData map[string]string) []string { 88 var env []string 89 for k, v := range wrapperData { 90 env = append(env, fmt.Sprintf("export %s=\"%s\";", k, v)) 91 } 92 sort.Strings(env) 93 return env 94 }