Open hh opened 9 years ago
Related if we want a pure SchTask based install and run:
schtask support for installing chef-client on windows : chef/mixlib-install#9
Background, where we got the powershell script working:
Upload the installation script and run it from the host. : chef/chef-provisioning#409 Upload the PS1 script and run directly : chef/chef-provisioning#410
We need updates applied, and they can only be applied successfully via schtask criteo-cookbooks/wsus-client#16. This is a spike that works, but I'd definitely feeling the pain of our lack of schtask provisioning to do this properly. (It sorta works, I get a 401 authentication fails after the wsus-updates apply, but that a different issue) @adamedx @tyler-ball @mwrock ?
require 'chef/provisioning/aws_driver'
require 'pry-byebug'
current_dir = File.dirname(__FILE__) # to get relative files... encrypted databag
with_chef_server "https://api.chef.io/organizations/#{ENV['CHEF_ORG']}",
:client_name => Chef::Config[:node_name],
:signing_key_filename => Chef::Config[:client_key]
with_machine_options bootstrap_options: {
instance_type: 'c3.2xlarge',
subnet_id: 'subnet-6021b417',
security_group_ids: [
'sg-689c5a0c',
'sg-6f9c5a0b',
'sg-0a9a5c6e'
]
},
aws_tags: {
:created_by => 'chris',
:please_destroy => 'true'
},
transport_address_location: :private_ip,
image_id: 'ami-7bc3e04b' # aws-marketplace/CIS Microsoft Windows Server 2012 R2 Benchmark v1.1.0-26bb465c-ce26-4da9-afb8-040b2f8c9a7f-ami-7a88f312.2
machine_name = 'base-2012-hardened-xv'
m = machine "#{machine_name}" do
action :allocate
end
# converge a machine with chef-client::task
machine "#{machine_name}" do
#action :nothing
action :converge
attribute %w{ client_client task frequency}, 'once'
recipe 'chef-client::task'
# these attributes will be use in the wsus convergence via schtask
attribute %w{ wsus_client no_reboot_with_logged_users }, false
attribute %w{ wsus_client automatic_update_behavior }, :install
attribute %w{ wsus_client reboot_warning }, 1
attribute %w{ wsus_client reboot_prompt_timeout }, 1
end
ruby_block "Run wsus-update via schtask on #{machine_name}" do
#action :nothing
block do
mr=resources(machine: machine_name).provider_for_action(:ready)
mr.load_current_resource
machine=mr.action_ready
driver = node.run_state[:chef_provisioning].drivers.values.first
i=driver.ec2.instances[machine.machine_spec.reference['instance_id']]
#not sure how to add recipes in a ruby_block...
# it also seems that any machine 'thismachine' { recipe 'foo' }
# resources that come later in __FILE__ update the run_list before
# they execute, probably something to do with execution contexts
ah = Chef::Provisioning::ChefProviderActionHandler.new(mr)
if machine.execute_always(
"knife node show #{machine_name} -a run_list -c c:\\chef\\client.rb"
).stdout.lines.grep(/wsus-client/).empty?
machine.execute(ah,
"knife node run_list add #{machine_name} wsus-client -c c:\\chef\\client.rb"
)
end
machine.execute(ah, 'schtasks /run /tn chef-client')
finished_running = false
timer = 0
until finished_running
task_query = machine.execute_always('schtasks /query /tn chef-client').stdout.lines.grep(/chef-client/)
finished_running = task_query.grep(/Running/).empty?
Chef::Log.warn "chef-client wsus-client schtask running for #{timer} seconds"
sleep 10
timer += 10
end
end
end
@hh rather than loading the machine from the resource_collection, I think you could just do m = machine "#{machine_name}" do
so that m
would be in scope during the ruby_block.
The bottom of your example (where the scheduled task is ran then queried) LGTM for getting into the convergence strategy. But I would hope this is ultimately something handled by Mixlib::Install. In that case I could see us still having to query the node to see when the scheduled task is finished (unless Mixlib::Install would do this for us).
A couple thoughts here.
#create the batch file from a template which does the stuff you want done in the task
batch_path = "#{node['platform_octopus']['home_path']}/octopus.bat"
template batch_path do
source 'octopus.bat.erb'
action :create
end
#create the task. Note this will create and run the task immediately and delete itself when done
windows_task 'octopus' do
user 'administrator'
password provisioner_bootstrap_password
cwd 'C:\\Program Files\\Octopus Deploy\\Tentacle'
command batch_path
frequency :monthly
frequency_modifier 12
run_level :highest
action [:create, :run]
notifies :delete, 'windows_task[octopus]', :delayed
guard_interpreter :powershell_script
not_if "(Get-Service | ? {$_.name -Contains 'OctopusDeploy Tentacle'}).count -gt 0"
end
ruby_block "Discover Octopus Machine (#{node['platform_octopus']['server_uri']})" do # ignore ~FC014
block do
# your code that checks if the task has finished
end
end
I find this to be alot cleaner and can separate the wsus stuff from the provisioning script. This does not address possible issues with timeouts or reboots but like your code above, it will run the updates driven by a winrm based run.
Not sure if this helps at all in your scenario. Windows updates are a major pain (I say as I test a packer template against windows 7 with about 250 updates).
We should create a new convergence strategy called install_msi_schedule.rb
and either set that as the default or let users specify that they want to use that. We should also add a toggle for whether to run system updates since those can take forevvvvvvver. This will also probably depend on https://github.com/chef/chef-provisioning/issues/362
Looks like we should be using https://github.com/WinRb/winrm-elevated
@tyler-ball @sneal is https://github.com/WinRb/winrm-elevated/ working well enough for me to try to create a stake in the ground for this?
@hh I haven't tested it
Looks like the dependency may have been moved from winrm-elevated into WinRb/winrm-fs#22 supplanting test-kitchen/winrm-transport#16 and directly using winrm-elevated. @mwrock is this correct?
I'm guessing I should wait for WinRb/winrm-fs#22 to support schtask before tackling this. Willing to help on that, but didn't want to overlap.
winrm-elevated would be the gem to leverage for elevated winrm commands that use a scheduled task under the hood. I know @sneal extracted that out of the current vagrant code. If that is what vagrant master is using, then I'd say it is pretty solid.
It's a dependency for getting machine_image supported for run_lists that include wsus updates and other tasks required to be run on \LocalMachine.
chef/mixlib-install#9 should get us to a point where MixLib install support SchTask by creating a install_command but I think we'll need make changes to ConvergenceStrategy::InstallMsi.converge to support creation / usage of a chef-client-schtask