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  }