github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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  // addPackagePreferencesCmds is a helper function which returns the bootcmds
    37  // which set the given PackagePreferences.
    38  func addPackagePreferencesCmds(cfg CloudConfig, prefs []packaging.PackagePreferences) []string {
    39  	cmds := []string{}
    40  	for _, pref := range prefs {
    41  		prefFile, _ := cfg.getPackagingConfigurer().RenderPreferences(pref)
    42  		data := []byte(prefFile)
    43  		cmds = append(cmds, addFileCmds(pref.Path, data, 0644, false)...)
    44  	}
    45  
    46  	return cmds
    47  }
    48  
    49  // addFile is a helper function returns all the required shell commands to write
    50  // a file (be it text or binary) with regards to the given parameters
    51  // NOTE: if the file already exists, it will be overwritten.
    52  func addFileCmds(filename string, data []byte, mode uint, binary bool) []string {
    53  	// Note: recent versions of cloud-init have the "write_files"
    54  	// module, which can write arbitrary files. We currently support
    55  	// 12.04 LTS, which uses an older version of cloud-init without
    56  	// this module.
    57  	// TODO (aznashwan): eagerly await 2017 and to do the right thing here
    58  	p := utils.ShQuote(filename)
    59  
    60  	cmds := []string{fmt.Sprintf("install -D -m %o /dev/null %s", mode, p)}
    61  	// Don't use the shell's echo builtin here; the interpretation
    62  	// of escape sequences differs between shells, namely bash and
    63  	// dash. Instead, we use printf (or we could use /bin/echo).
    64  	if binary {
    65  		encoded := base64.StdEncoding.EncodeToString(data)
    66  		cmds = append(cmds, fmt.Sprintf(`printf %%s %s | base64 -d > %s`, encoded, p))
    67  	} else {
    68  		cmds = append(cmds, fmt.Sprintf(`printf '%%s\n' %s > %s`, utils.ShQuote(string(data)), p))
    69  	}
    70  
    71  	return cmds
    72  }
    73  
    74  // removeStringFromSlice is a helper function which removes a given string from
    75  // the given slice, if it exists it returns the slice, be it modified or unmodified
    76  func removeStringFromSlice(slice []string, val string) []string {
    77  	for i, str := range slice {
    78  		if str == val {
    79  			slice = append(slice[:i], slice[i+1:]...)
    80  		}
    81  	}
    82  
    83  	return slice
    84  }