cookbook_file
Use the cookbook_file resource to transfer files from a sub-directory of COOKBOOK_NAME/files/ to a specified path located on a host that is running the chef-client. The file is selected according to file specificity, which allows different source files to be used based on the hostname, host platform (operating system, distro, or as appropriate), or platform version. Files that are located in the COOKBOOK_NAME/files/default sub-directory may be used on any platform.
During a chef-client run, the checksum for each local file is calculated and then compared against the checksum for the same file as it currently exists in the cookbook on the Chef server. A file is not transferred when the checksums match. Only files that require an update are transferred from the Chef server to a node.
Syntax
A cookbook_file resource block manages files by using files that exist within a cookbook’s /files directory. For example, to write the home page for an Apache website:
cookbook_file '/var/www/customers/public_html/index.php' do source '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 -
'index.php'is a file in the/filesdirectory in a cookbook that is used to create that file (the contents of the file in the cookbook will become the contents of the file on the node) -
owner,group, andmodedefine the permissions
The full syntax for all of the properties that are available to the cookbook_file resource is:
cookbook_file 'name' do atomic_update TrueClass, FalseClass backup FalseClass, Integer cookbook String force_unlink TrueClass, FalseClass group String, Integer 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::CookbookFile rights Hash source String, Array subscribes # see description action Symbol # defaults to :create if not specified end
where
-
cookbook_fileis the resource -
nameis the name of the resource block -
:actionidentifies the steps the chef-client will take to bring the node into the desired state -
atomic_update,backup,cookbook,force_unlink,group,inherits,manage_symlink_source,mode,owner,path,provider,rights, andsourceare 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.
Actions
This resource has the following actions:
:create- Default. Create a file. If a file already exists (but does not match), update that file to match.
:create_if_missing- Create a file only if the file does not exist. When the file exists, nothing happens.
:delete- Delete a file.
:nothing- Define this resource block to do nothing until notified by another resource to take action. When this resource is notified, this resource block is either run immediately or it is queued up to be run at the end of the chef-client run.
:touch- Touch a file. This updates the access (atime) and file modification (mtime) times for a file. (This action may be used with this resource, but is typically only used with the file resource.)
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.
Properties
This resource has the following properties:
atomic_update-
Ruby Types: TrueClass, FalseClass
Perform atomic file updates on a per-resource basis. Set to
truefor atomic file updates. Set tofalsefor non-atomic file updates. This setting overridesfile_atomic_update, which is a global setting found in the client.rb file. Default value:true. backup-
Ruby Types: FalseClass, Integer
The number of backups to be kept in
/var/chef/backup(for UNIX- and Linux-based platforms) orC:/chef/backup(for the Microsoft Windows platform). Set tofalseto prevent backups from being kept. Default value:5. cookbook-
Ruby Type: String
The cookbook in which a file is located (if it is not located in the current cookbook). The default value is the current cookbook.
force_unlink-
Ruby 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
truefor the chef-client delete the non-file target and replace it with the specified file. Set tofalsefor the chef-client to raise an error. Default value:false. group-
Ruby Types: Integer, String
A string or ID that identifies the group owner by group name, including fully qualified group names such as
domain\grouporgroup@domain. If this value is not specified, existing groups remain unchanged and new group assignments use the defaultPOSIXgroup (if available). ignore_failure-
Ruby Types: TrueClass, FalseClass
Continue running a recipe if a resource fails for any reason. Default value:
false. inherits-
Ruby Types: TrueClass, FalseClass
Microsoft Windows only. Whether a file inherits rights from its parent directory. Default value:
true. manage_symlink_source-
Ruby Types: TrueClass, FalseClass, NilClass
Cause the chef-client to detect and manage the source file for a symlink. Possible values:
nil,true, orfalse. When this value is set tonil, the chef-client will manage a symlink’s source file and emit a warning. When this value is set totrue, the chef-client will manage a symlink’s source file and not emit a warning. Default value:nil. The default value will be changed tofalsein a future version. mode-
Ruby Types: Integer, String
A quoted 3-5 character string that defines the octal mode. For example:
'755','0755', or00755. Ifmodeis not specified and if the file already exists, the existing mode on the file is used. Ifmodeis not specified, the file does not exist, and the:createaction 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 themaskvalue. 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', or00755. If the value is specified as a quoted string, it works exactly as if thechmodcommand 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, use01777or'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', or00755. Values up to'0777'are allowed (no sticky bits) and mean the same in Microsoft Windows as they do in UNIX, where4equalsGENERIC_READ,2equalsGENERIC_WRITE, and1equalsGENERIC_EXECUTE. This property cannot be used to set:full_control. This property has no effect if not specified, but when it andrightsare both specified, the effects are cumulative. notifies-
Ruby Type: Symbol, ‘Chef::Resource[String]’
A resource may notify another resource to take action when its state changes. Specify a
'resource[name]', the:actionthat resource should take, and then the:timerfor that action. A resource may notifiy more than one resource; use anotifiesstatement 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:
:delayed- Default. Specifies that a notification should be queued up, and then executed at the very end of the chef-client run.
-
:immediate,:immediately - Specifies that a notification should be run immediately, per resource notified.
The syntax for
notifiesis:notifies :action, 'resource[name]', :timer
owner-
Ruby Types: Integer, String
A string or ID that identifies the group owner by user name, including fully qualified user names such as
domain\useroruser@domain. If this value is not specified, existing owners remain unchanged and new owner assignments use the current user (when necessary). path-
Ruby Type: String
The path to the destination at which a file is to be created. Default value: the
nameof the resource block For example:file.txt.Microsoft Windows: A path that begins with a forward slash (
/) will point to the root of the current working directory of the chef-client process. This path can vary from system to system. Therefore, using a path that begins with a forward slash (/) is not recommended. provider-
Ruby Type: Chef Class
Optional. Explicitly specifies a provider.
retries-
Ruby Type: Integer
The number of times to catch exceptions and retry the resource. Default value:
0. retry_delay-
Ruby Type: Integer
The retry delay (in seconds). Default value:
2. rights-
Ruby 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. source-
Ruby Types: String, Array
The name of the file in
COOKBOOK_NAME/files/defaultor the path to a file located inCOOKBOOK_NAME/files. The path must include the file name and its extension. Can be used to distribute specific files to specific platforms. See “File Specificity” below for more information. See “Syntax” section above for more information. subscribes-
Ruby 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:actionto be taken, and then the:timerfor that action.A timer specifies the point during the chef-client run at which a notification is run. The following timers are available:
:delayed- Default. Specifies that a notification should be queued up, and then executed at the very end of the chef-client run.
-
:immediate,:immediately - Specifies that a notification should be run immediately, per resource notified.
The syntax for
subscribesis:subscribes :action, 'resource[name]', :timer
Note
Use the owner and right properties and avoid the group and mode properties whenever possible. The group and mode properties are not true Microsoft Windows concepts and are provided more for backward compatibility than for best practice.
Atomic File Updates
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.
Windows File Security
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
permission-
Use 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
:writeis specified, then it includes:read. If:full_controlis specified, then it includes both:writeand:read.(For those who know the Microsoft Windows API:
:readcorresponds toGENERIC_READ;:writecorresponds toGENERIC_WRITE;:read_executecorresponds toGENERIC_READandGENERIC_EXECUTE;:modifycorresponds toGENERIC_WRITE,GENERIC_READ,GENERIC_EXECUTE, andDELETE;:full_controlcorresponds toGENERIC_ALL, which allows a user to change the owner and other metadata about a file.) principal- Use to specify a group or user name. This is identical to what is entered in the login box for Microsoft Windows, such as
user_name,domain\user_name, oruser_name@fully_qualified_domain_name. The chef-client does not need to know if a principal is a user or a group. option_type-
A 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_childrenSpecify how permissions are applied to children. Possible values: trueto inherit both child directories and files;falseto not inherit any child directories or files;:containers_onlyto inherit only child directories (and not files);:objects_onlyto recursively inherit files (and not child directories).:applies_to_selfIndicates whether a permission is applied to the parent directory. Possible values: trueto apply to the parent directory or file and its children;falseto not apply only to child directories and files.:one_level_deepIndicates the depth to which permissions will be applied. Possible values: trueto apply only to the first level of children;falseto 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:
- Only inherited rights remain. All existing explicit rights on the object are removed and replaced.
- If rights are not specified, nothing will be changed. The chef-client does not clear out the rights on a file or directory if rights are not specified.
- Changing inherited rights can be expensive. Microsoft Windows will propagate rights to all children recursively due to inheritance. This is a normal aspect of Microsoft Windows, so consider the frequency with which this type of action is necessary and take steps to control this type of action if performance is the primary consideration.
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.
Providers
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:
- Use a more specific short name—
yum_package "foo" doinstead ofpackage "foo" do,script "foo" doinstead ofbash "foo" do, and so on—when available - Use the
providerproperty 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::CookbookFile,cookbook_file - The default provider for all platforms.
File Specificity
A cookbook is frequently designed to work across many platforms and is often required to distribute a specific file to a specific platform. A cookbook can be designed to support the distribution of files across platforms, while ensuring that the correct file ends up on each system.
The pattern for file specificity depends on two things: the lookup path and the source attribute. The first pattern that matches is used:
- /host-$fqdn/$source
- /$platform-$platform_version/$source
- /$platform/$source
- /default/$source
A cookbook may have a /files directory structure like this:
files/ host-foo.example.com ubuntu-10.04 ubuntu-10 ubuntu redhat-5.8 redhat-6.4 ... default
and a resource that looks something like the following:
cookbook_file '/usr/local/bin/apache2_module_conf_generate.pl' do source 'apache2_module_conf_generate.pl' mode '0755' owner 'root' group 'root' end
This resource is matched in the same order as the /files directory structure. For a node that is running Ubuntu 10.04, the second item would be the matching item and the location to which the file identified in the cookbook_file resource would be distributed:
host-foo.example.com/apache2_module_conf_generate.pl ubuntu-10.04/apache2_module_conf_generate.pl ubuntu-10/apache2_module_conf_generate.pl ubuntu/apache2_module_conf_generate.pl default/apache2_module_conf_generate.pl
If the apache2_module_conf_generate.pl file was located in the cookbook directory under files/host-foo.example.com/, the specified file(s) would only be copied to the machine with the domain name foo.example.com.
Host Notation
The naming of folders within cookbook directories must literally match the host notation used for file specificity matching. For example, if a host is named foo.example.com, the folder must be named host-foo.example.com.
Examples
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
cookbook_file 'file.txt' do mode '0755' end
Handle cookbook_file and yum_package resources in the same recipe
When a cookbook_file resource and a yum_package resource are both called from within the same recipe, use the flush_cache attribute to dump the in-memory Yum cache, and then use the repository immediately to ensure that the correct package is installed:
cookbook_file '/etc/yum.repos.d/custom.repo' do source 'custom' mode '0755' end yum_package 'only-in-custom-repo' do action :install flush_cache [ :before ] end
Install repositories from a file, trigger a command, and force the internal cache to reload
The following example shows how to install new Yum repositories from a file, where the installation of the repository triggers a creation of the Yum cache that forces the internal cache for the chef-client to reload:
execute 'create-yum-cache' do
command 'yum -q makecache'
action :nothing
end
ruby_block 'reload-internal-yum-cache' do
block do
Chef::Provider::Package::Yum::YumCache.instance.reload
end
action :nothing
end
cookbook_file '/etc/yum.repos.d/custom.repo' do
source 'custom'
mode '0755'
notifies :run, 'execute[create-yum-cache]', :immediately
notifies :create, 'ruby_block[reload-internal-yum-cache]', :immediately
end Use a case statement
The following example shows how a case statement can be used to handle a situation where an application needs to be installed on multiple platforms, but where the install directories are different paths, depending on the platform:
cookbook_file 'application.pm' do
path case node['platform']
when 'centos','redhat'
'/usr/lib/version/1.2.3/dir/application.pm'
when 'arch'
'/usr/share/version/core_version/dir/application.pm'
else
'/etc/version/dir/application.pm'
end
source "application-#{node['languages']['perl']['version']}.pm"
owner 'root'
group 'root'
mode '0755'
end Manage dotfiles
The following example shows using the directory and cookbook_file resources to manage dotfiles. The dotfiles are defined by a JSON data structure similar to:
"files": {
".zshrc": {
"mode": '0755',
"source": "dot-zshrc"
},
".bashrc": {
"mode": '0755',
"source": "dot-bashrc"
},
".bash_profile": {
"mode": '0755',
"source": "dot-bash_profile"
},
} and then the following resources manage the dotfiles:
if u.has_key?('files')
u['files'].each do |filename, file_data|
directory "#{home_dir}/#{File.dirname(filename)}" do
recursive true
mode '0755'
end if file_data['subdir']
cookbook_file "#{home_dir}/#{filename}" do
source "#{u['id']}/#{file_data['source']}"
owner 'u['id']'
group 'group_id'
mode 'file_data['mode']'
ignore_failure true
backup 0
end
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/11-18/resource_cookbook_file.html