Use the remote_file resource to transfer a file from a remote location using file specificity. This resource is similar to the file resource.
Note
Fetching files from the files/ directory in a cookbook should be done with the cookbook_file resource.
A remote_file resource block manages files by using files that exist remotely. For example, to write the home page for an Apache website:
remote_file '/var/www/customers/public_html/index.php' do source 'http://somesite.com/index.php' owner 'web_admin' group 'web_admin' mode '0755' action :create end
where
'/var/www/customers/public_html/index.php' is path to the file to be created'http://somesite.com/index.php' specifies the location of the remote fileowner, group, and mode define the permissionsThe full syntax for all of the properties that are available to the remote_file resource is:
remote_file 'name' do atomic_update TrueClass, FalseClass backup FalseClass, Integer checksum String force_unlink TrueClass, FalseClass ftp_active_mode TrueClass, FalseClass group String, Integer headers Hash inherits TrueClass, FalseClass manage_symlink_source TrueClass, FalseClass, NilClass mode String, Integer notifies # see description owner String, Integer path String # defaults to 'name' if not specified provider Chef::Provider::File::RemoteFile rights Hash source String, Array subscribes # see description use_conditional_get TrueClass, FalseClass use_etag TrueClass, FalseClass use_last_modified TrueClass, FalseClass verify String, Block action Symbol # defaults to :create if not specified end
where
remote_file is the resourcename is the name of the resource block:action identifies the steps the chef-client will take to bring the node into the desired stateatomic_update, backup, checksum, force_unlink, ftp_active_mode, group, headers, inherits, manage_symlink_source, mode, owner, path, provider, rights, source, use_conditional_get, use_etag, use_last_modified, and verify are properties of this resource, with the Ruby type shown. See “Properties” section below for more information about all of the properties that may be used with this resource.This resource has the following actions:
:createDefault. Create a file. If a file already exists (but does not match), update that file to match.
Warning
For a machine on which SELinux is enabled, the chef-client will create files that correctly match the default policy settings only when the cookbook that defines the action also conforms to the same policy.
:create_if_missing:delete:nothing:touchThis resource has the following properties:
atomic_updateRuby Types: TrueClass, FalseClass
Perform atomic file updates on a per-resource basis. Set to true for atomic file updates. Set to false for non-atomic file updates. This setting overrides file_atomic_update, which is a global setting found in the client.rb file. Default value: true.
backupRuby Types: FalseClass, Integer
The number of backups to be kept in /var/chef/backup (for UNIX- and Linux-based platforms) or C:/chef/backup (for the Microsoft Windows platform). Set to false to prevent backups from being kept. Default value: 5.
checksumRuby Type: String
Optional, see use_conditional_get. The SHA-256 checksum of the file. Use to prevent a file from being re-downloaded. When the local file matches the checksum, the chef-client does not download it.
force_unlinkRuby Types: TrueClass, FalseClass
How the chef-client handles certain situations when the target file turns out not to be a file. For example, when a target file is actually a symlink. Set to true for the chef-client delete the non-file target and replace it with the specified file. Set to false for the chef-client to raise an error. Default value: false.
ftp_active_modeRuby Types: TrueClass, FalseClass
Whether the chef-client uses active or passive FTP. Set to true to use active FTP. Default value: false.
groupRuby Types: Integer, String
A string or ID that identifies the group owner by group name, including fully qualified group names such as domain\group or group@domain. If this value is not specified, existing groups remain unchanged and new group assignments use the default POSIX group (if available).
headers()Ruby Type: Hash
A Hash of custom headers. Default value: {}. For example:
headers({ "Cookie" => "user=grantmc; pass=p@ssw0rd!" }) or:
headers({ "Referer" => "#{header}" }) or:
headers( "Authorization"=>"Basic #{ Base64.encode64("#{username}:#{password}").gsub("\n", "") }" ) ignore_failureRuby Types: TrueClass, FalseClass
Continue running a recipe if a resource fails for any reason. Default value: false.
inheritsRuby Types: TrueClass, FalseClass
Microsoft Windows only. Whether a file inherits rights from its parent directory. Default value: true.
manage_symlink_sourceRuby Types: TrueClass, FalseClass, NilClass
Cause the chef-client to detect and manage the source file for a symlink. Possible values: nil, true, or false. When this value is set to nil, the chef-client will manage a symlink’s source file and emit a warning. When this value is set to true, the chef-client will manage a symlink’s source file and not emit a warning. Default value: nil. The default value will be changed to false in a future version.
modeRuby Types: Integer, String
A quoted 3-5 character string that defines the octal mode. For example: '755', '0755', or 00755. If mode is not specified and if the file already exists, the existing mode on the file is used. If mode is not specified, the file does not exist, and the :create action is specified, the chef-client assumes a mask value of '0777' and then applies the umask for the system on which the file is to be created to the mask value. For example, if the umask on a system is '022', the chef-client uses the default value of '0755'.
The behavior is different depending on the platform.
UNIX- and Linux-based systems: A quoted 3-5 character string that defines the octal mode that is passed to chmod. For example: '755', '0755', or 00755. If the value is specified as a quoted string, it works exactly as if the chmod command was passed. If the value is specified as an integer, prepend a zero (0) to the value to ensure that it is interpreted as an octal number. For example, to assign read, write, and execute rights for all users, use '0777' or '777'; for the same rights, plus the sticky bit, use 01777 or '1777'.
Microsoft Windows: A quoted 3-5 character string that defines the octal mode that is translated into rights for Microsoft Windows security. For example: '755', '0755', or 00755. Values up to '0777' are allowed (no sticky bits) and mean the same in Microsoft Windows as they do in UNIX, where 4 equals GENERIC_READ, 2 equals GENERIC_WRITE, and 1 equals GENERIC_EXECUTE. This property cannot be used to set :full_control. This property has no effect if not specified, but when it and rights are both specified, the effects are cumulative.
notifiesRuby Type: Symbol, ‘Chef::Resource[String]’
A resource may notify another resource to take action when its state changes. Specify a 'resource[name]', the :action that resource should take, and then the :timer for that action. A resource may notifiy more than one resource; use a notifies statement for each resource to be notified.
A timer specifies the point during the chef-client run at which a notification is run. The following timers are available:
:before:delayed:immediate, :immediately
The syntax for notifies is:
notifies :action, 'resource[name]', :timer
ownerRuby Types: Integer, String
A string or ID that identifies the group owner by user name, including fully qualified user names such as domain\user or user@domain. If this value is not specified, existing owners remain unchanged and new owner assignments use the current user (when necessary).
pathRuby Type: String
The full path to the file, including the file name and its extension. Default value: the name of the resource block See “Syntax” section above for more information.
providerRuby Type: Chef Class
Optional. Explicitly specifies a provider.
retriesRuby Type: Integer
The number of times to catch exceptions and retry the resource. Default value: 0.
retry_delayRuby Type: Integer
The retry delay (in seconds). Default value: 2.
rightsRuby Types: Integer, String
Microsoft Windows only. The permissions for users and groups in a Microsoft Windows environment. For example: rights <permissions>, <principal>, <options> where <permissions> specifies the rights granted to the principal, <principal> is the group or user name, and <options> is a Hash with one (or more) advanced rights options.
sourceRuby Types: String, Array
Required. The location of the source file. The location of the source file may be HTTP (http://), FTP (ftp://), local (file:///), or UNC (\\host\share\file.tar.gz).
There are many ways to define the location of a source file. By using a path:
source 'http://couchdb.apache.org/img/sketch.png'
By using FTP:
source 'ftp://path/to/img/sketch.png'
By using a local path:
source 'file:///path/to/img/sketch.png'
By using a Microsoft Windows UNC:
source '\\\\path\\to\\img\\sketch.png'
By using a node attribute:
source node['nginx']['foo123']['url']
By using attributes to define paths:
source "#{node['python']['url']}/#{version}/Python-#{version}.tar.bz2" By defining multiple paths for multiple locations:
source 'http://seapower/spring.png', 'http://seapower/has_sprung.png'
By defining those same multiple paths as an array:
source ['http://seapower/spring.png', 'http://seapower/has_sprung.png']
When multiple paths are specified, the chef-client will attempt to download the files in the order listed, stopping after the first successful download.
subscribesRuby Type: Symbol, ‘Chef::Resource[String]’
A resource may listen to another resource, and then take action if the state of the resource being listened to changes. Specify a 'resource[name]', the :action to be taken, and then the :timer for that action.
A timer specifies the point during the chef-client run at which a notification is run. The following timers are available:
:before:delayed:immediate, :immediately
The syntax for subscribes is:
subscribes :action, 'resource[name]', :timer
use_conditional_getRuby Types: TrueClass, FalseClass
Enable conditional HTTP requests by using a conditional GET (with the If-Modified-Since header) or an opaque identifier (ETag). To use If-Modified-Since headers, use_last_modified must also be set to true. To use ETag headers, use_etag must also be set to true. Default value: true.
use_etagRuby Types: TrueClass, FalseClass
Enable ETag headers. Set to false to disable ETag headers. To use this setting, use_conditional_get must also be set to true. Default value: true.
use_last_modifiedRuby Types: TrueClass, FalseClass
Enable If-Modified-Since headers. Set to false to disable If-Modified-Since headers. To use this setting, use_conditional_get must also be set to true. Default value: true.
verifyRuby Types: String, Block
A block or a string that returns true or false. A string, when true is executed as a system command.
A block is arbitrary Ruby defined within the resource block by using the verify property. When a block is true, the chef-client will continue to update the file as appropriate.
For example, this should return true:
remote_file '/tmp/baz' do
verify { 1 == 1 }
end This should return true:
remote_file '/etc/nginx.conf' do
verify 'nginx -t -c %{path}'
end Warning
For releases of the chef-client prior to 12.5 (chef-client 12.4 and earlier) the correct syntax is:
remote_file '/etc/nginx.conf' do
verify 'nginx -t -c %{file}'
end See GitHub issues https://github.com/chef/chef/issues/3232 and https://github.com/chef/chef/pull/3693 for more information about these differences.
This should return true:
remote_file '/tmp/bar' do
verify { 1 == 1}
end And this should return true:
remote_file '/tmp/foo' do
verify do |path|
true
end
end Whereas, this should return false:
remote_file '/tmp/turtle' do verify '/usr/bin/false' end
If a string or a block return false, the chef-client run will stop and an error is returned.
Atomic updates are used with file-based resources to help ensure that file updates can be made when updating a binary or if disk space runs out.
Atomic updates are enabled by default. They can be managed globally using the file_atomic_update setting in the client.rb file. They can be managed on a per-resource basis using the atomic_update property that is available with the cookbook_file, file, remote_file, and template resources.
Note
On certain platforms, and after a file has been moved into place, the chef-client may modify file permissions to support features specific to those platforms. On platforms with SELinux enabled, the chef-client will fix up the security contexts after a file has been moved into the correct location by running the restorecon command. On the Microsoft Windows platform, the chef-client will create files so that ACL inheritance works as expected.
To support Microsoft Windows security, the template, file, remote_file, cookbook_file, directory, and remote_directory resources support the use of inheritance and access control lists (ACLs) within recipes.
Access Control Lists (ACLs)
The rights property can be used in a recipe to manage access control lists (ACLs), which allow permissions to be given to multiple users and groups. Use the rights property can be used as many times as necessary; the chef-client will apply them to the file or directory as required. The syntax for the rights property is as follows:
rights permission, principal, option_type => value
where
permissionUse to specify which rights are granted to the principal. The possible values are: :read, :write, read_execute, :modify, and :full_control.
These permissions are cumulative. If :write is specified, then it includes :read. If :full_control is specified, then it includes both :write and :read.
(For those who know the Microsoft Windows API: :read corresponds to GENERIC_READ; :write corresponds to GENERIC_WRITE; :read_execute corresponds to GENERIC_READ and GENERIC_EXECUTE; :modify corresponds to GENERIC_WRITE, GENERIC_READ, GENERIC_EXECUTE, and DELETE; :full_control corresponds to GENERIC_ALL, which allows a user to change the owner and other metadata about a file.)
principaluser_name, domain\user_name, or user_name@fully_qualified_domain_name. The chef-client does not need to know if a principal is a user or a group.option_typeA hash that contains advanced rights options. For example, the rights to a directory that only applies to the first level of children might look something like: rights :write, 'domain\group_name', :one_level_deep => true. Possible option types:
| Option Type | Description |
|---|---|
:applies_to_children | Specify how permissions are applied to children. Possible values: true to inherit both child directories and files; false to not inherit any child directories or files; :containers_only to inherit only child directories (and not files); :objects_only to recursively inherit files (and not child directories). |
:applies_to_self | Indicates whether a permission is applied to the parent directory. Possible values: true to apply to the parent directory or file and its children; false to not apply only to child directories and files. |
:one_level_deep | Indicates the depth to which permissions will be applied. Possible values: true to apply only to the first level of children; false to apply to all children. |
For example:
resource 'x.txt' do rights :read, 'Everyone' rights :write, 'domain\group' rights :full_control, 'group_name_or_user_name' rights :full_control, 'user_name', :applies_to_children => true end
or:
rights :read, ['Administrators','Everyone'] rights :full_control, 'Users', :applies_to_children => true rights :write, 'Sally', :applies_to_children => :containers_only, :applies_to_self => false, :one_level_deep => true
Some other important things to know when using the rights attribute:
Use the deny_rights property to deny specific rights to specific users. The ordering is independent of using the rights property. For example, it doesn’t matter if rights are granted to everyone is placed before or after deny_rights :read, ['Julian', 'Lewis'], both Julian and Lewis will be unable to read the document. For example:
resource 'x.txt' do rights :read, 'Everyone' rights :write, 'domain\group' rights :full_control, 'group_name_or_user_name' rights :full_control, 'user_name', :applies_to_children => true deny_rights :read, ['Julian', 'Lewis'] end
or:
deny_rights :full_control, ['Sally']
Inheritance
By default, a file or directory inherits rights from its parent directory. Most of the time this is the preferred behavior, but sometimes it may be necessary to take steps to more specifically control rights. The inherits property can be used to specifically tell the chef-client to apply (or not apply) inherited rights from its parent directory.
For example, the following example specifies the rights for a directory:
directory 'C:\mordor' do rights :read, 'MORDOR\Minions' rights :full_control, 'MORDOR\Sauron' end
and then the following example specifies how to use inheritance to deny access to the child directory:
directory 'C:\mordor\mount_doom' do rights :full_control, 'MORDOR\Sauron' inherits false # Sauron is the only person who should have any sort of access end
If the deny_rights permission were to be used instead, something could slip through unless all users and groups were denied.
Another example also shows how to specify rights for a directory:
directory 'C:\mordor' do rights :read, 'MORDOR\Minions' rights :full_control, 'MORDOR\Sauron' rights :write, 'SHIRE\Frodo' # Who put that there I didn't put that there end
but then not use the inherits property to deny those rights on a child directory:
directory 'C:\mordor\mount_doom' do deny_rights :read, 'MORDOR\Minions' # Oops, not specific enough end
Because the inherits property is not specified, the chef-client will default it to true, which will ensure that security settings for existing files remain unchanged.
To prevent the chef-client from re-downloading files that are already present on a node, use one of the following attributes in a recipe: use_conditional_get (default) or checksum.
use_conditional_get attribute is the default behavior of the chef-client. If the remote file is located on a server that supports ETag and/or If-Modified-Since headers, the chef-client will use a conditional GET to determine if the file has been updated. If the file has been updated, the chef-client will re-download the file.checksum attribute will ask the chef-client to compare the checksum for the local file to the one at the remote location. If they match, the chef-client will not re-download the file. Using a local checksum for comparison requires that the local checksum be the correct checksum.The desired approach just depends on the desired workflow. For example, if a node requires a new file every day, using the checksum approach would require that the local checksum be updated and/or verified every day as well, in order to ensure that the local checksum was the correct one. Using a conditional GET in this scenario will greatly simplify the management required to ensure files are being updated accurately.
Where a resource represents a piece of the system (and its desired state), a provider defines the steps that are needed to bring that piece of the system from its current state into the desired state.
The chef-client will determine the correct provider based on configuration data collected by Ohai at the start of the chef-client run. This configuration data is then mapped to a platform and an associated list of providers.
Generally, it’s best to let the chef-client choose the provider, and this is (by far) the most common approach. However, in some cases, specifying a provider may be desirable. There are two approaches:
yum_package "foo" do instead of package "foo" do, script "foo" do instead of bash "foo" do, and so on—when availableprovider property within the resource block to specify the long name of the provider as a property of a resource. For example: provider Chef::Provider::Long::Name
This resource has the following providers:
Chef::Provider::File::RemoteFile, remote_file
The following examples demonstrate various approaches for using resources in recipes. If you want to see examples of how Chef uses resources in recipes, take a closer look at the cookbooks that Chef authors and maintains: https://github.com/chef-cookbooks.
Transfer a file from a URL
remote_file '/tmp/testfile' do source 'http://www.example.com/tempfiles/testfile' mode '0755' checksum '3a7dac00b1' # A SHA256 (or portion thereof) of the file. end
Install a file from a remote location using bash
The following is an example of how to install the foo123 module for Nginx. This module adds shell-style functionality to an Nginx configuration file and does the following:
src_filepath variable# the following code sample is similar to the ``upload_progress_module``
# recipe in the ``nginx`` cookbook:
# https://github.com/chef-cookbooks/nginx
src_filename = "foo123-nginx-module-v#{
node['nginx']['foo123']['version']
}.tar.gz"
src_filepath = "#{Chef::Config['file_cache_path']}/#{src_filename}"
extract_path = "#{
Chef::Config['file_cache_path']
}/nginx_foo123_module/#{
node['nginx']['foo123']['checksum']
}"
remote_file 'src_filepath' do
source node['nginx']['foo123']['url']
checksum node['nginx']['foo123']['checksum']
owner 'root'
group 'root'
mode '0755'
end
bash 'extract_module' do
cwd ::File.dirname(src_filepath)
code <<-EOH
mkdir -p #{extract_path}
tar xzf #{src_filename} -C #{extract_path}
mv #{extract_path}/*/* #{extract_path}/
EOH
not_if { ::File.exist?(extract_path) }
end Store certain settings
The following recipe shows how an attributes file can be used to store certain settings. An attributes file is located in the attributes/ directory in the same cookbook as the recipe which calls the attributes file. In this example, the attributes file specifies certain settings for Python that are then used across all nodes against which this recipe will run.
Python packages have versions, installation directories, URLs, and checksum files. An attributes file that exists to support this type of recipe would include settings like the following:
default['python']['version'] = '2.7.1' if python['install_method'] == 'package' default['python']['prefix_dir'] = '/usr' else default['python']['prefix_dir'] = '/usr/local' end default['python']['url'] = 'http://www.python.org/ftp/python' default['python']['checksum'] = '80e387...85fd61'
and then the methods in the recipe may refer to these values. A recipe that is used to install Python will need to do the following:
version and the install_path
# the following code sample comes from the ``oc-nginx`` cookbook on |github|: https://github.com/cookbooks/oc-nginx
version = node['python']['version']
install_path = "#{node['python']['prefix_dir']}/lib/python#{version.split(/(^\d+\.\d+)/)[1]}"
remote_file "#{Chef::Config[:file_cache_path]}/Python-#{version}.tar.bz2" do
source "#{node['python']['url']}/#{version}/Python-#{version}.tar.bz2"
checksum node['python']['checksum']
mode '0755'
not_if { ::File.exist?(install_path) }
end
bash 'build-and-install-python' do
cwd Chef::Config[:file_cache_path]
code <<-EOF
tar -jxvf Python-#{version}.tar.bz2
(cd Python-#{version} && ./configure #{configure_options})
(cd Python-#{version} && make && make install)
EOF
not_if { ::File.exist?(install_path) }
end Use the platform_family? method
The following is an example of using the platform_family? method in the Recipe DSL to create a variable that can be used with other resources in the same recipe. In this example, platform_family? is being used to ensure that a specific binary is used for a specific platform before using the remote_file resource to download a file from a remote location, and then using the execute resource to install that file by running a command.
if platform_family?('rhel')
pip_binary = '/usr/bin/pip'
else
pip_binary = '/usr/local/bin/pip'
end
remote_file "#{Chef::Config[:file_cache_path]}/distribute_setup.py" do
source 'http://python-distribute.org/distribute_setup.py'
mode '0755'
not_if { File.exist?(pip_binary) }
end
execute 'install-pip' do
cwd Chef::Config[:file_cache_path]
command <<-EOF
# command for installing Python goes here
EOF
not_if { File.exist?(pip_binary) }
end where a command for installing Python might look something like:
#{node['python']['binary']} distribute_setup.py
#{::File.dirname(pip_binary)}/easy_install pip Specify local Windows file path as a valid URI
When specifying a local Microsoft Windows file path as a valid file URI, an additional forward slash (/) is required. For example:
remote_file 'file:///c:/path/to/file' do ... # other attributes end
© Chef Software, Inc.
Licensed under the Creative Commons Attribution 3.0 Unported License.
The Chef™ Mark and Chef Logo are either registered trademarks/service marks or trademarks/servicemarks of Chef, in the United States and other countries and are used with Chef Inc's permission.
We are not affiliated with, endorsed or sponsored by Chef Inc.
https://docs-archive.chef.io/release/12-13/resource_remote_file.html