github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/cloudconfig/userdatacfg_win.go (about) 1 // Copyright 2012, 2013, 2014, 2015 Canonical Ltd. 2 // Copyright 2014, 2015 Cloudbase Solutions SRL 3 // Licensed under the AGPLv3, see LICENCE file for details. 4 5 package cloudconfig 6 7 import ( 8 "encoding/json" 9 "fmt" 10 "path/filepath" 11 12 "github.com/juju/errors" 13 "github.com/juju/names" 14 "github.com/juju/utils/featureflag" 15 16 "github.com/juju/juju/juju/osenv" 17 "github.com/juju/juju/juju/paths" 18 ) 19 20 type windowsConfigure struct { 21 baseConfigure 22 } 23 24 // Configure updates the provided cloudinit.Config with 25 // configuration to initialize a Juju machine agent. 26 func (w *windowsConfigure) Configure() error { 27 if err := w.ConfigureBasic(); err != nil { 28 return err 29 } 30 return w.ConfigureJuju() 31 } 32 33 func (w *windowsConfigure) ConfigureBasic() error { 34 35 series := w.icfg.Series 36 tmpDir, err := paths.TempDir(series) 37 if err != nil { 38 return err 39 } 40 renderer := w.conf.ShellRenderer() 41 dataDir := renderer.FromSlash(w.icfg.DataDir) 42 baseDir := renderer.FromSlash(filepath.Dir(tmpDir)) 43 binDir := renderer.Join(baseDir, "bin") 44 45 w.conf.AddScripts( 46 fmt.Sprintf(`%s`, winPowershellHelperFunctions), 47 fmt.Sprintf(`icacls "%s" /grant "jujud:(OI)(CI)(F)" /T`, renderer.FromSlash(baseDir)), 48 fmt.Sprintf(`mkdir %s`, renderer.FromSlash(tmpDir)), 49 fmt.Sprintf(`mkdir "%s"`, binDir), 50 fmt.Sprintf(`mkdir "%s\locks"`, renderer.FromSlash(dataDir)), 51 fmt.Sprintf(`Start-ProcessAsUser -Command $cmdExe -Arguments '/C setx PATH "%%PATH%%;C:\Juju\bin"' -Credential $jujuCreds`), 52 ) 53 noncefile := renderer.Join(dataDir, NonceFile) 54 w.conf.AddScripts( 55 fmt.Sprintf(`Set-Content "%s" "%s"`, noncefile, shquote(w.icfg.MachineNonce)), 56 ) 57 return nil 58 } 59 60 func (w *windowsConfigure) ConfigureJuju() error { 61 if err := w.icfg.VerifyConfig(); err != nil { 62 return errors.Trace(err) 63 } 64 if w.icfg.Bootstrap == true { 65 // Bootstrap machine not supported on windows 66 return errors.Errorf("bootstrapping is not supported on windows") 67 } 68 69 toolsJson, err := json.Marshal(w.icfg.Tools) 70 if err != nil { 71 return errors.Annotate(err, "while serializing the tools") 72 } 73 const python = `${env:ProgramFiles(x86)}\Cloudbase Solutions\Cloudbase-Init\Python27\python.exe` 74 renderer := w.conf.ShellRenderer() 75 w.conf.AddScripts( 76 fmt.Sprintf(`$binDir="%s"`, renderer.FromSlash(w.icfg.JujuTools())), 77 `$tmpBinDir=$binDir.Replace('\', '\\')`, 78 fmt.Sprintf(`mkdir '%s'`, renderer.FromSlash(w.icfg.LogDir)), 79 `mkdir $binDir`, 80 `$WebClient = New-Object System.Net.WebClient`, 81 `[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}`, 82 fmt.Sprintf(`ExecRetry { $WebClient.DownloadFile('%s', "$binDir\tools.tar.gz") }`, w.icfg.Tools.URL), 83 `$dToolsHash = (Get-FileHash -Algorithm SHA256 "$binDir\tools.tar.gz").hash`, 84 fmt.Sprintf(`$dToolsHash > "$binDir\juju%s.sha256"`, 85 w.icfg.Tools.Version), 86 fmt.Sprintf(`if ($dToolsHash.ToLower() -ne "%s"){ Throw "Tools checksum mismatch"}`, 87 w.icfg.Tools.SHA256), 88 fmt.Sprintf(`& "%s" -c "import tarfile;archive = tarfile.open('$tmpBinDir\\tools.tar.gz');archive.extractall(path='$tmpBinDir')"`, python), 89 `rm "$binDir\tools.tar*"`, 90 fmt.Sprintf(`Set-Content $binDir\downloaded-tools.txt '%s'`, string(toolsJson)), 91 ) 92 93 for _, cmd := range CreateJujuRegistryKeyCmds() { 94 w.conf.AddRunCmd(cmd) 95 } 96 97 machineTag := names.NewMachineTag(w.icfg.MachineId) 98 _, err = w.addAgentInfo(machineTag) 99 if err != nil { 100 return errors.Trace(err) 101 } 102 return w.addMachineAgentToBoot() 103 } 104 105 // CreateJujuRegistryKey is going to create a juju registry key and set 106 // permissions on it such that it's only accessible to administrators 107 // It is exported because it is used in an upgrade step 108 func CreateJujuRegistryKeyCmds() []string { 109 return []string{ 110 // Create a registry key for storing juju related information 111 fmt.Sprintf(`New-Item -Path '%s'`, osenv.JujuRegistryKey), 112 fmt.Sprintf(`$acl = Get-Acl -Path '%s'`, osenv.JujuRegistryKey), 113 114 // Reset the ACL's on it and add administrator access only. 115 `$acl.SetAccessRuleProtection($true, $false)`, 116 `$perm = "BUILTIN\Administrators", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"`, 117 `$rule = New-Object System.Security.AccessControl.RegistryAccessRule $perm`, 118 `$acl.SetAccessRule($rule)`, 119 fmt.Sprintf(`Set-Acl -Path '%s' -AclObject $acl`, osenv.JujuRegistryKey), 120 // Create a JUJU_DEV_FEATURE_FLAGS entry which may or may not be empty. 121 fmt.Sprintf(`New-ItemProperty -Path '%s' -Name '%s'`, 122 osenv.JujuRegistryKey, 123 osenv.JujuFeatureFlagEnvKey), 124 fmt.Sprintf(`Set-ItemProperty -Path '%s' -Name '%s' -Value '%s'`, 125 osenv.JujuRegistryKey, 126 osenv.JujuFeatureFlagEnvKey, 127 featureflag.AsEnvironmentValue()), 128 } 129 }