My Profile Photo

Spencer Owen

The art of progress is to preserve order amid change and preserve change amid order - Alfred North Whitehead

CHEF copy from network path

I discovered a bug in the CHEF mount resource which has been reported here:

Until that bug is fixed, mount can wreak havoc on your VM. Use this code instead:

  batch "download_someAwesomePackage" do
    code <<-EOH
    SET username=#{node['domain']}\\#{someuser}
    SET password=#{somepassword}
    net use "\\\\msi" %password% /user:%username%
    copy "\\\\msi\\someAwesomePackage.msi" "c:\\someAwesomePackage.msi
    IF ERRORLEVEL 0 goto disconnect
    goto end
    net use "\\\\msi" /delete
    goto end
    action :run
    not_if do File.exists?("c:\\someAwesomePackage.msi") end

  windows_package 'someAwesomePackage' do
    source 'c:\\someAwesomePackage.msi'

One of the beauties of chef is the ease of deploying software from a package or git repo.

If you are in a windows world, or have a samba network share that requires authentication, you might notice something weird.

Given the following example:

remote_file "c:\\someAwesomePackage.msi" do
  source "\\\\\\someAwesomePackage.msi"

If you run this from the command line, it work work as expected.

However if you run chef from a scheduled task, you will get errors.

[2015-09-09T14:36:31-04:00] FATAL: Errno::EACCES: remote_file[c:\someAwesomePackage.msi] (foo::bar line 1) had an
 error: Errno::EACCES: Permission denied - \\\someAwesomePackage.msi

Thats because when you run chef as yourself, you will inherit your credentials. Whereas when running from a scheduled task, chef runs as SYSTEM


powershell_script "foo" do
  code <<-EOH
    whoami >> c:\\whoami.txt
  action :run

chef-apply ~\Desktop\foo.rb


Clever chefers might think of two solutions:

  • Add credentials to remote_file => Unfortunately, remote_file doesn’t have the option for credentials
  • deploy => While deploy does accept credentials, it only works with git repos, not UNC paths.

Luckliy chef has a native way to mount network shares that does accept network credentials.

mount 'T:' do
  device '\\\\'
  domain ''
  username 'foo'
  password 'correct-horse-battery-staple'
  action :mount

# Note that you need 3 slashes after 'file:'
remote_file 'C:\\someAwesomePackage.msi' do
  source 'file:///T:/someAwesomePackage.msi' #Use T:/ not T:\\
  checksum "12345" #shasum -a 256 someAwesomePackage.msi
  notifies :umount, 'mount[N:]', :delayed # Not needed but doesn't hurt

The network share will automatically disappear when the chef run ends. Additionally you don’t need to worry about the mapped network drive being available to other users, nor be visible in ‘My Computer’

Additional Information: mount

Thanks to stevenmurawski in the IRC channel for the suggestion


3 core principles in automating:

  • repeatability
  • portability
  • predictability

If you pulling files from network shares, then your code likely isn’t very portable. Also network shares are hard to make idempotent since they are statefull. Its better to put your files in an s3 compatible object store, and use REST to fetch files in a stateless fashion. A great way to quickly get an object store up and running is with an artifact repository

On premise artifact repositories

Aws & Azure also have their own s3 object stores



 remote_file[c:\someAwesomePackage.msi] action create[2015-09-10T13:47:46-04:00] WARN: file:///T:\someAwesomePackage.msi was an invalid URI. Trying to escape invalid characters


Make sure you use file:///T:/foo and not file:///T:\\foo


Network Share won’t unmount and powershell gives error “Attempting to perform the InitializeDefaultDrives operation on the ‘FileSystem’ provider failed.”


You had a typo in your mount point. You need to edit the registry to unmount