github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/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(`%s`, winSetPasswdScript),
    51  		fmt.Sprintf(`Start-ProcessAsUser -Command $powershell -Arguments "-File C:\juju\bin\save_pass.ps1 $juju_passwd" -Credential $jujuCreds`),
    52  		fmt.Sprintf(`mkdir "%s\locks"`, renderer.FromSlash(dataDir)),
    53  		fmt.Sprintf(`Start-ProcessAsUser -Command $cmdExe -Arguments '/C setx PATH "%%PATH%%;C:\Juju\bin"' -Credential $jujuCreds`),
    54  	)
    55  	noncefile := renderer.Join(dataDir, NonceFile)
    56  	w.conf.AddScripts(
    57  		fmt.Sprintf(`Set-Content "%s" "%s"`, noncefile, shquote(w.icfg.MachineNonce)),
    58  	)
    59  	return nil
    60  }
    61  
    62  func (w *windowsConfigure) ConfigureJuju() error {
    63  	if err := w.icfg.VerifyConfig(); err != nil {
    64  		return errors.Trace(err)
    65  	}
    66  	toolsJson, err := json.Marshal(w.icfg.Tools)
    67  	if err != nil {
    68  		return errors.Annotate(err, "while serializing the tools")
    69  	}
    70  	const python = `${env:ProgramFiles(x86)}\Cloudbase Solutions\Cloudbase-Init\Python27\python.exe`
    71  	renderer := w.conf.ShellRenderer()
    72  	w.conf.AddScripts(
    73  		fmt.Sprintf(`$binDir="%s"`, renderer.FromSlash(w.icfg.JujuTools())),
    74  		`$tmpBinDir=$binDir.Replace('\', '\\')`,
    75  		fmt.Sprintf(`mkdir '%s'`, renderer.FromSlash(w.icfg.LogDir)),
    76  		`mkdir $binDir`,
    77  		`$WebClient = New-Object System.Net.WebClient`,
    78  		`[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}`,
    79  		fmt.Sprintf(`ExecRetry { $WebClient.DownloadFile('%s', "$binDir\tools.tar.gz") }`, w.icfg.Tools.URL),
    80  		`$dToolsHash = (Get-FileHash -Algorithm SHA256 "$binDir\tools.tar.gz").hash`,
    81  		fmt.Sprintf(`$dToolsHash > "$binDir\juju%s.sha256"`,
    82  			w.icfg.Tools.Version),
    83  		fmt.Sprintf(`if ($dToolsHash.ToLower() -ne "%s"){ Throw "Tools checksum mismatch"}`,
    84  			w.icfg.Tools.SHA256),
    85  		fmt.Sprintf(`& "%s" -c "import tarfile;archive = tarfile.open('$tmpBinDir\\tools.tar.gz');archive.extractall(path='$tmpBinDir')"`, python),
    86  		`rm "$binDir\tools.tar*"`,
    87  		fmt.Sprintf(`Set-Content $binDir\downloaded-tools.txt '%s'`, string(toolsJson)),
    88  
    89  		// Create a registry key for storing juju related information
    90  		fmt.Sprintf(`New-Item -Path '%s'`, osenv.JujuRegistryKey),
    91  		fmt.Sprintf(`$acl = Get-Acl -Path '%s'`, osenv.JujuRegistryKey),
    92  
    93  		// Reset the ACL's on it and add administrator access only.
    94  		`$acl.SetAccessRuleProtection($true, $false)`,
    95  		`$perm = "BUILTIN\Administrators", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"`,
    96  		`$rule = New-Object System.Security.AccessControl.RegistryAccessRule $perm`,
    97  		`$acl.SetAccessRule($rule)`,
    98  		fmt.Sprintf(`Set-Acl -Path '%s' -AclObject $acl`, osenv.JujuRegistryKey),
    99  
   100  		// Create a JUJU_DEV_FEATURE_FLAGS entry which may or may not be empty.
   101  		fmt.Sprintf(`New-ItemProperty -Path '%s' -Name '%s'`,
   102  			osenv.JujuRegistryKey,
   103  			osenv.JujuFeatureFlagEnvKey),
   104  		fmt.Sprintf(`Set-ItemProperty -Path '%s' -Name '%s' -Value '%s'`,
   105  			osenv.JujuRegistryKey,
   106  			osenv.JujuFeatureFlagEnvKey,
   107  			featureflag.AsEnvironmentValue()),
   108  	)
   109  
   110  	if w.icfg.Bootstrap == true {
   111  		// Bootstrap machine not supported on windows
   112  		return errors.Errorf("bootstrapping is not supported on windows")
   113  	}
   114  
   115  	machineTag := names.NewMachineTag(w.icfg.MachineId)
   116  	_, err = w.addAgentInfo(machineTag)
   117  	if err != nil {
   118  		return errors.Trace(err)
   119  	}
   120  	return w.addMachineAgentToBoot()
   121  }