github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cloudconfig/cloudinit/utils.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Copyright 2015 Cloudbase Solutions SRL 3 // Licensed under the AGPLv3, see LICENCE file for details. 4 5 package cloudinit 6 7 import ( 8 "encoding/base64" 9 "fmt" 10 "path/filepath" 11 12 "github.com/juju/utils" 13 "github.com/juju/utils/packaging" 14 "github.com/juju/utils/packaging/config" 15 ) 16 17 // addPackageSourceCmds is a helper function that returns the corresponding 18 // runcmds to apply the package source settings on a CentOS machine. 19 func addPackageSourceCmds(cfg CloudConfig, src packaging.PackageSource) []string { 20 cmds := []string{} 21 22 // if keyfile is required, add it first 23 if src.Key != "" { 24 keyFilePath := config.YumKeyfileDir + src.KeyFileName() 25 cmds = append(cmds, addFileCmds(keyFilePath, []byte(src.Key), 0644, false)...) 26 } 27 28 repoPath := filepath.Join(config.YumSourcesDir, src.Name+".repo") 29 sourceFile, _ := cfg.getPackagingConfigurer().RenderSource(src) 30 data := []byte(sourceFile) 31 cmds = append(cmds, addFileCmds(repoPath, data, 0644, false)...) 32 33 return cmds 34 } 35 36 // addFile is a helper function returns all the required shell commands to write 37 // a file (be it text or binary) with regards to the given parameters 38 // NOTE: if the file already exists, it will be overwritten. 39 func addFileCmds(filename string, data []byte, mode uint, binary bool) []string { 40 // Note: recent versions of cloud-init have the "write_files" 41 // module, which can write arbitrary files. We currently support 42 // 12.04 LTS, which uses an older version of cloud-init without 43 // this module. 44 // TODO (aznashwan): eagerly await 2017 and to do the right thing here 45 p := utils.ShQuote(filename) 46 47 cmds := []string{fmt.Sprintf("install -D -m %o /dev/null %s", mode, p)} 48 // Don't use the shell's echo builtin here; the interpretation 49 // of escape sequences differs between shells, namely bash and 50 // dash. Instead, we use printf (or we could use /bin/echo). 51 if binary { 52 encoded := base64.StdEncoding.EncodeToString(data) 53 cmds = append(cmds, fmt.Sprintf(`printf %%s %s | base64 -d > %s`, encoded, p)) 54 } else { 55 cmds = append(cmds, fmt.Sprintf(`printf '%%s\n' %s > %s`, utils.ShQuote(string(data)), p)) 56 } 57 58 return cmds 59 } 60 61 // removeStringFromSlice is a helper function which removes a given string from 62 // the given slice, if it exists it returns the slice, be it modified or unmodified 63 func removeStringFromSlice(slice []string, val string) []string { 64 for i, str := range slice { 65 if str == val { 66 slice = append(slice[:i], slice[i+1:]...) 67 } 68 } 69 70 return slice 71 }