provisoiners/chef: windows command builder
This commit is contained in:
parent
7022b1c29d
commit
2929f7a853
|
@ -0,0 +1,83 @@
|
||||||
|
require "tempfile"
|
||||||
|
|
||||||
|
require "vagrant/util/template_renderer"
|
||||||
|
|
||||||
|
module VagrantPlugins
|
||||||
|
module Chef
|
||||||
|
class CommandBuilderWindows < CommandBuilder
|
||||||
|
def build_command
|
||||||
|
binary_path = "chef-#{@client_type}"
|
||||||
|
if @config.binary_path
|
||||||
|
binary_path = File.join(@config.binary_path, binary_path)
|
||||||
|
binary_path.gsub!("/", "\\")
|
||||||
|
binary_path = "c:#{binary_path}" if binary_path.start_with?("\\")
|
||||||
|
end
|
||||||
|
|
||||||
|
chef_arguments = "-c #{provisioning_path("#{@client_type}.rb")}"
|
||||||
|
chef_arguments << " -j #{provisioning_path("dna.json")}"
|
||||||
|
chef_arguments << " #{@config.arguments}" if @config.arguments
|
||||||
|
|
||||||
|
command_env = ""
|
||||||
|
command_env = "#{@config.binary_env} " if @config.binary_env
|
||||||
|
|
||||||
|
task_ps1_path = provisioning_path("cheftask.ps1")
|
||||||
|
|
||||||
|
opts = {
|
||||||
|
user: @machine.config.winrm.username,
|
||||||
|
pass: @machine.config.winrm.password,
|
||||||
|
chef_arguments: chef_arguments,
|
||||||
|
chef_binary_path: "#{command_env}#{binary_path}",
|
||||||
|
chef_stdout_log: provisioning_path("chef-#{@client_type}.log"),
|
||||||
|
chef_stderr_log: provisioning_path("chef-#{@client_type}.err.log"),
|
||||||
|
chef_task_exitcode: provisioning_path('cheftask.exitcode'),
|
||||||
|
chef_task_running: provisioning_path('cheftask.running'),
|
||||||
|
chef_task_ps1: task_ps1_path,
|
||||||
|
chef_task_run_ps1: provisioning_path('cheftaskrun.ps1'),
|
||||||
|
chef_task_xml: provisioning_path('cheftask.xml'),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Upload the files we'll need
|
||||||
|
render_and_upload(
|
||||||
|
"cheftaskrun.ps1", opts[:chef_task_run_ps1], opts)
|
||||||
|
render_and_upload(
|
||||||
|
"cheftask.xml", opts[:chef_task_xml], opts)
|
||||||
|
render_and_upload(
|
||||||
|
"cheftask.ps1", opts[:chef_task_ps1], opts)
|
||||||
|
|
||||||
|
return <<-EOH
|
||||||
|
$old = Get-ExecutionPolicy;
|
||||||
|
Set-ExecutionPolicy Unrestricted -force;
|
||||||
|
#{task_ps1_path};
|
||||||
|
Set-ExecutionPolicy $old -force
|
||||||
|
EOH
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def provisioning_path(file)
|
||||||
|
path = "#{@config.provisioning_path}/#{file}"
|
||||||
|
path.gsub!("/", "\\")
|
||||||
|
path = "c:#{path}" if path.start_with?("\\")
|
||||||
|
path
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_and_upload(template, dest, opts)
|
||||||
|
path = File.expand_path("../scripts/#{template}", __FILE__)
|
||||||
|
data = Vagrant::Util::TemplateRenderer.render(path, options)
|
||||||
|
|
||||||
|
file = Tempfile.new("vagrant-chef")
|
||||||
|
file.binmode
|
||||||
|
file.write(data)
|
||||||
|
file.fsync
|
||||||
|
file.close
|
||||||
|
|
||||||
|
@machine.communicate.upload(file.path, dest)
|
||||||
|
ensure
|
||||||
|
if file
|
||||||
|
file.close
|
||||||
|
file.unlink
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,48 @@
|
||||||
|
# kill the task so we can recreate it
|
||||||
|
schtasks /delete /tn "chef-solo" /f 2>&1 | out-null
|
||||||
|
|
||||||
|
# Ensure the chef task running file doesn't exist from a previous failure
|
||||||
|
if (Test-Path "<%= options[:chef_task_running] %>") {
|
||||||
|
del "<%= options[:chef_task_running] %>"
|
||||||
|
}
|
||||||
|
|
||||||
|
# schedule the task to run once in the far distant future
|
||||||
|
schtasks /create /tn 'chef-solo' /xml '<%= options[:chef_task_xml] %>' /ru '<%= options[:user] %>' /rp '<%= options[:pass] %>' | Out-Null
|
||||||
|
|
||||||
|
# start the scheduled task right now
|
||||||
|
schtasks /run /tn "chef-solo" | Out-Null
|
||||||
|
|
||||||
|
# wait for run_chef.ps1 to start or timeout after 1 minute
|
||||||
|
$timeoutSeconds = 60
|
||||||
|
$elapsedSeconds = 0
|
||||||
|
while ( (!(Test-Path "<%= options[:chef_task_running] %>")) -and ($elapsedSeconds -lt $timeoutSeconds) ) {
|
||||||
|
Start-Sleep -s 1
|
||||||
|
$elapsedSeconds++
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($elapsedSeconds -ge $timeoutSeconds) {
|
||||||
|
Write-Error "Timed out waiting for chef scheduled task to start"
|
||||||
|
exit -2
|
||||||
|
}
|
||||||
|
|
||||||
|
# read the entire file, but only write out new lines we haven't seen before
|
||||||
|
$numLinesRead = 0
|
||||||
|
$success = $TRUE
|
||||||
|
while (Test-Path "<%= options[:chef_task_running] %>") {
|
||||||
|
Start-Sleep -m 100
|
||||||
|
|
||||||
|
if (Test-Path "<%= options[:chef_stdout_log] %>") {
|
||||||
|
$text = (get-content "<%= options[:chef_stdout_log] %>")
|
||||||
|
$numLines = ($text | Measure-Object -line).lines
|
||||||
|
$numLinesToRead = $numLines - $numLinesRead
|
||||||
|
|
||||||
|
if ($numLinesToRead -gt 0) {
|
||||||
|
$text | select -first $numLinesToRead -skip $numLinesRead | ForEach {
|
||||||
|
Write-Host "$_"
|
||||||
|
}
|
||||||
|
$numLinesRead += $numLinesToRead
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit Get-Content "<%= options[:chef_task_exitcode] %>"
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-16"?>
|
||||||
|
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
||||||
|
<RegistrationInfo>
|
||||||
|
<Date>2013-06-21T22:41:43</Date>
|
||||||
|
<Author>Administrator</Author>
|
||||||
|
</RegistrationInfo>
|
||||||
|
<Triggers>
|
||||||
|
<TimeTrigger>
|
||||||
|
<StartBoundary>2045-01-01T12:00:00</StartBoundary>
|
||||||
|
<Enabled>true</Enabled>
|
||||||
|
</TimeTrigger>
|
||||||
|
</Triggers>
|
||||||
|
<Principals>
|
||||||
|
<Principal id="Author">
|
||||||
|
<UserId>vagrant</UserId>
|
||||||
|
<LogonType>Password</LogonType>
|
||||||
|
<RunLevel>HighestAvailable</RunLevel>
|
||||||
|
</Principal>
|
||||||
|
</Principals>
|
||||||
|
<Settings>
|
||||||
|
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
|
||||||
|
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
|
||||||
|
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
|
||||||
|
<AllowHardTerminate>true</AllowHardTerminate>
|
||||||
|
<StartWhenAvailable>false</StartWhenAvailable>
|
||||||
|
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
|
||||||
|
<IdleSettings>
|
||||||
|
<StopOnIdleEnd>true</StopOnIdleEnd>
|
||||||
|
<RestartOnIdle>false</RestartOnIdle>
|
||||||
|
</IdleSettings>
|
||||||
|
<AllowStartOnDemand>true</AllowStartOnDemand>
|
||||||
|
<Enabled>true</Enabled>
|
||||||
|
<Hidden>false</Hidden>
|
||||||
|
<RunOnlyIfIdle>false</RunOnlyIfIdle>
|
||||||
|
<WakeToRun>false</WakeToRun>
|
||||||
|
<ExecutionTimeLimit>PT2H</ExecutionTimeLimit>
|
||||||
|
<Priority>4</Priority>
|
||||||
|
</Settings>
|
||||||
|
<Actions Context="Author">
|
||||||
|
<Exec>
|
||||||
|
<Command>powershell</Command>
|
||||||
|
<Arguments>-file <%= options[:chef_task_run_ps1] %></Arguments>
|
||||||
|
</Exec>
|
||||||
|
</Actions>
|
||||||
|
</Task>
|
|
@ -0,0 +1,18 @@
|
||||||
|
$exitCode = -1
|
||||||
|
Set-ExecutionPolicy Unrestricted -force;
|
||||||
|
|
||||||
|
Try
|
||||||
|
{
|
||||||
|
"running" | Out-File "<%= options[:chef_task_running] %>"
|
||||||
|
$process = (Start-Process "<%= options[:chef_binary_path] %>" -ArgumentList "<%= options[:chef_arguments] %>" -NoNewWindow -PassThru -Wait -RedirectStandardOutput "<%= options[:chef_stdout_log] %>" -RedirectStandardError "<%= options[:chef_stderr_log] %>")
|
||||||
|
$exitCode = $process.ExitCode
|
||||||
|
}
|
||||||
|
Finally
|
||||||
|
{
|
||||||
|
$exitCode | Out-File "<%= options[:chef_task_exitcode] %>"
|
||||||
|
if (Test-Path "<%= options[:chef_task_running] %>") {
|
||||||
|
del "<%= options[:chef_task_running] %>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit $exitCode
|
Loading…
Reference in New Issue