官术网_书友最值得收藏!

Definitions

Sometimes, you find that you are creating something repeatedly and, similar to a configuration template, you need a template to generate objects of a given type. Some examples of this might be Apache virtual hosts, a specific type of application, or anything else that is repeated a lot. This is where definitions come in, and they are stored in the definitions directory inside of a cookbook.

Definitions are loaded and available as named resources just as other resources such as packages, files, and so on are; the only difference is that there is no provider. You can think of them as resources and providers all in one. Subsequently, they are much more rigid and limited in scope than a normal resource would be. Here is an example definition to install Python libraries using pip and a requirements.txt file:

define :pip_requirements , :action => :run do
    name = params[:name]
    requirements_file = params[:requirements_file]
    pip = params[:pip]
    user = params[:user]
    group = params[:group]
    
    if params[:action] == :run
      script "pip_install_#{name}" do 
        interpreter "bash"
        user "#{user}"
        group "#{group}"
        code <<-EOH
        #{pip} install -r #{requirements_file}
        EOH
        only_if { File.exists?("#{requirements_file}") and File.exists?("#{pip}") }
      end         
   end
end 

Here, we are declaring a new type of definition, a pip_requirements object. This looks and behaves similarly to a resource, except that it is much simpler (and less flexible) than a resource. It has some attributes, which are loaded via the special params argument, and contains a little bit of logic wrapped around a script resource. Let's take a look at how it would be used and then see how it works:

pip_requirements "my_requirements" do
  pip "#{virtualenv}/bin/pip"
  user node[:app][:user]
  group node[:app][:group]
  requirements_file "#{node[:app][:src_dir]}/requirements.txt"
end

Here you see what looks like a resource, but is in fact a definition. As mentioned earlier, these look very similar because they behave alike. However, you must have likely noticed that the definition of pip_requirements itself did not have any sort of abstraction; there is no pluggable provider, no validation, it doesn't subclass the Resource class, among other differences. Definitions provide you with a mechanism to declare reusable chunks of code that your recipes would otherwise duplicate so that your recipe can again describe the what, not the how.

The previous example tells us that we have a pip_requirements object and that we want to pass some parameters to it, namely, the path to pip, the user and group to run pip as, and the requirements.txt file to load. These are brought into the definition through the params argument and can be accessed as any other variable data. In this case, the definition says to run bash as the specified user and group and that the script should run the equivalent of the following:

 pip install -r /path/to/requirements.txt

This will happen only if pip and the /path/to/requirements.txt file exist (as indicated by the only_if guard). By creating such a definition, it can be reused any time you need to install Python modules from a specific requirements.txt file on your host.

主站蜘蛛池模板: 固原市| 文山县| 武隆县| 靖西县| 崇仁县| 翼城县| 九寨沟县| 临邑县| 昆山市| 拉萨市| 平度市| 海南省| 昭苏县| 清徐县| 苏尼特右旗| 漾濞| 衡东县| 黄陵县| 门头沟区| 石台县| 新巴尔虎右旗| 广州市| 息烽县| 洛阳市| 清丰县| 鱼台县| 邵阳市| 东乌珠穆沁旗| 泰宁县| 奉贤区| 朔州市| 吉木乃县| 体育| 渭南市| 霍林郭勒市| 蒙山县| 郓城县| 麦盖提县| 英德市| 卓资县| 黎平县|