chef-boneyard / chef-provisioning

A library for creating machines and infrastructures idempotently in Chef.
Apache License 2.0
524 stars 164 forks source link

set_attributes and get_attributes override for WindowsMachine #285

Open joelwilson opened 9 years ago

joelwilson commented 9 years ago

Using the machine_file resource to upload a file to a windows machine results in an error:

set_attributes not overridden on Chef::Provisioning::Machine::WindowsMachine

The cause is pretty obvious; the set_attributes and get_attributes in WindowsMachine.rb are not implemented in the windows machine provider.

Reproduce:

machine_file 'C:/chef/trusted_certs/chefserv01_companyname_com.crt' do
  local_path "#{Chef::Config[:trusted_certs_dir]}/chefserv01_companyname_com.crt"
  machine HOSTNAME
end

Full error message

- upload file U:/.chef/trusted_certs/chefserv01_companyname_com.crt to C:/chef/trusted_certs/chefserv01_castingn
etworks_com.crt on wintest01
================================================================================
Error executing action `upload` on resource 
'machine_file[C:/chef/trusted_certs/chefserv01_companyname_com.crt]'

================================================================================

RuntimeError
------------
set_attributes not overridden on Chef::Provisioning::Machine::WindowsMachine

Resource Declaration:
---------------------
# In C:/Users/auser/Code/chef/provision-windows-test/recipes/win-test.rb

  7: machine_file 'C:/chef/trusted_certs/chefserv01_companyname_com.crt' do
  8:   local_path "#{Chef::Config[:trusted_certs_dir]}/chefserv01_companyname_com.crt"
  9:   machine HOSTNAME
 10: end
 11:

Compiled Resource:
------------------
# Declared in C:/Users/auser/Code/chef/provision-windows-test/recipes/win-test.rb:7:in `from_file'

machine_file("C:/chef/trusted_certs/chefserv01_companyname_com.crt") do
  action :upload
  retries 0
  retry_delay 2
  guard_interpreter :default
  chef_server {:chef_server_url=>"https://chefserv01.companyname.com/organizations/xxxxxx", 
:options=>{:client_name=>"auser", :signing_key_filename=>"U:\\.chef/client.pem"}}
  cookbook_name "@recipe_files"
  recipe_name "C:/Users/auser/Code/chef/provision-windows-test/recipes/win-test.rb"
  local_path "U:/.chef/trusted_certs/chefserv01_companyname_com.crt"
  machine "wintest01"
  path "C:/chef/trusted_certs/chefserv01_companyname_com.crt"
end

I know very little Ruby and nothing about writing custom Chef code, but I'd be willing to give it a try if somebody can point me in the right direction (Ex. code to port this functionality from).

joelwilson commented 9 years ago

I looked through the code and now think that these methods maybe don't need to be implemented. Would it make sense to just not set file attributes for Windows nodes? They will get their attributes inherited anyway.

# In chef/provider/machine_file.rb
action :upload do
  if new_resource.content
    machine.write_file(action_handler, new_resource.path, new_resource.content)
  else
    machine.upload_file(action_handler, new_resource.local_path, new_resource.path)
  end

  ### Wrap with this statement?
  unless machine.kind_of?(Chef::Provisioning::Machine::WindowsMachine)
    attributes = {}
    attributes[:group] = new_resource.group if new_resource.group
    attributes[:owner] = new_resource.owner if new_resource.owner
    attributes[:mode] = new_resource.mode if new_resource.mode
  end

  machine.set_attributes(action_handler, new_resource.path, attributes)
end

Monkey-patching on my machine seems to work. In any case, this could be a workaround until attribute support for Windows is added, no?

jkeiser commented 9 years ago

Yeah. We can do one or the other, but one or the other we must do. Adding to the 1.0 ready queue :)

paustin01 commented 8 years ago

+1 on fixing this!

paustin01 commented 7 years ago

Still running into this one a year+ later. Seems like @joelwilson 's solution is an easy fix. Can we, can we?

One correction however. The machine.set_attributes line needs to be inside the block. A la...

  ### Wrap with this statement?
  unless machine.kind_of?(Chef::Provisioning::Machine::WindowsMachine)
    attributes = {}
    attributes[:group] = new_resource.group if new_resource.group
    attributes[:owner] = new_resource.owner if new_resource.owner
    attributes[:mode] = new_resource.mode if new_resource.mode

    machine.set_attributes(action_handler, new_resource.path, attributes)
  end