问题
I am new to Chef and Ruby
I need to pass two variables to Chef on the command line and have those variables available in a recipe.
How I can capture these values and get them in Chef?
I need something like this:
before_deploy command
execute param1 param2
deploy{ param1/param2}
Where param1
and param2
get their values at run-time from the command-line.
回答1:
When you provision the machine by running
chef-solo
or
chef-client
you cannot provide any arguments to these commands that can be visible to recipes. Chef recipes work only with attributes. Good thing (or not so good) is that attributes can be set from many different places: roles, nodes, environments and json file.
The workaround that is nearest to your request is
- Create a json-file on the machine
- Pass it when running
chef-client
orchef-solo
- Use attributes in the recipe
For example: apache config.
create json file: my_attrs.json
{
"apache": {
"listen_port": "81",
"listen_path": "/myapp"
}
}
and then use them in your recipe:
node[:apache][:listen_port]
node[:apache][:listen_path]
Run chef-client
or chef-solo
with -j
flag.
chef-solo -j my_attrs.json
If my_attrs.json is on some remote server, then you can provide a url.
chef-solo -j http://remote.host/path/my_attrs.json
回答2:
If your file is named example.rb
ruby example.rb argument1 argument2
Then
ARGV.each do|a|
puts "Argument: #{a}"
end
Output:
Argument: argument1
Argument: argument2
回答3:
You can set variables inside recipes by calling commands
nodename = `cat /etc/chef/client.rb | grep "node_name" | sed -e 's/\<node_name\>//g' | sed '/^$/d;s/[[:blank:]]//g' | sed 's/\"//g'`
And then use the variable for other chef blocks
execute "echo nodename for node #{nodename}"
command "echo #{nodename}"
action :run
only_if {nodename == "node1"}
end
This will get the node.name attribute from the client.rb file without asking for it to the chef server.
来源:https://stackoverflow.com/questions/14730833/how-i-can-capture-values-in-command-line-and-add-to-recipe