Chef template and using it in a loop - ruby

How to write this in a loop.
I am very new to ruby so struggling with the approach.
I am trying to create a response file and then update the fixpack for IHS (IBM HTTP Server)
#Install the fix pack for IHS
template "/tmp/ihs-fixpack-response1.txt" do
source "ihs-fixpack-response.erb"
mode 0755
owner "root"
group "root"
variables({
:fixpack => "7.0.0-WS-IHS-LinuxX32-FP0000019.pak",
:product_path => node[:websphere][:ihs][:ihs_path]
})
end
# code for installing Fixpack
bash "ihs/was-updateinstaller" do
user "root"
code %(#{node[:websphere][:ihs][:ihs_updi_path]}/update.sh -options "/tmp/ihs-fixpack-response1.txt" -silent)
end
#Install the fix pack for the plugin.
template "/tmp/ihs-fixpack-response2.txt" do
source "ihs-fixpack-response.erb"
mode 0755
owner "root"
group "root"
variables({
:fixpack => "7.0.0-WS-PLG-LinuxX32-FP0000019.pak",
:product_path => node[:websphere][:ihs][:ihs_wasPluginPath]
})
end
# code for installing Fixpack
bash "ihs/was-updateinstaller" do
user "root"
code %(#{node[:websphere][:ihs][:ihs_updi_path]}/update.sh -options "/tmp/ihs-fixpack-response2.txt" -silent)
end

I believe this will do what you want:
[ [ "7.0.0-WS-IHS-LinuxX32-FP0000019.pak", node[:websphere][:ihs][:ihs_path] ],
[ "7.0.0-WS-PLG-LinuxX32-FP0000019.pak", node[:websphere][:ihs][:ihs_wasPluginPath] ]
].zip(1..2).each do |vars, i|
template "/tmp/ihs-fixpack-response#{i}.txt" do
source "ihs-fixpack-response.erb"
mode 0755
owner "root"
group "root"
variables({
:fixpack => vars.first,
:product_path => vars.last
})
end
bash "ihs/was-updateinstaller" do
user "root"
code %(#{node[:websphere][:ihs][:ihs_updi_path]}/update.sh -options "/tmp/ihs-fixpack-response#{i}.txt" -silent)
end
end

Related

How do i define variable within a template cookbook

I am trying to edit the existing user_management cookbook on the supermarket to include sudoers. I seem to be having problems properly defining the sudoers_groups variable within the template.
Link to default cookbook
https://github.com/FFIN/user_management/blob/master/recipes/default.rb
Here is what my vault looks like.
knife vault show testusers john
action: create
comment: John Smith
dbpass: secret
gid: john
id: john
password: $1$d$xKNtrFrifo6f7tLFW1xh750
shell: /bin/bash
sudo_pwdless: true
sudoer: false
sudoer_group:
command: ALL
name: admin
sudo_pwdless: false
command: ALL
name: wheel
sudo_pwdless: false
command: ALL
name: sysadmin
sudo_pwdless: true
uid: 1002
username: john`
Here is the template section of my recipe
sudoer_users = Array.new()
if user['sudoer']
command = user['command'] ? user['command'] : 'ALL'
hash = { :uname => user['username'], :command => command, :sudo_pwdless => user['sudo_pwdless'] }
sudoer_users.push(hash)
end
template "/etc/sudoers" do
source 'sudoers.erb'
mode '0440'
owner 'root'
group node['root_group']
variables(
:sudoers_users => sudoer_users,
:sudoers_groups => node[:testcookbook][:testusers][:sudoer_group]
)
only_if { sudoer_users }
end
When i run the recipe, i get the following error
Recipe Compile Error in /var/chef/cache/cookbooks/newuser/recipes/default.rb ============================================. ==================================== NoMethodError
-------------`
undefined method [] for nil:NilClass
template "/etc/sudoers" do
61: source 'sudoers.erb'
62: mode '0440'
63: owner 'root'
64: group node['root_group']
65: variables(
66: :sudoers_users => sudoer_users,
67>> :sudoers_groups => node[ :testcookbook][ :testusers][ :sudoer_group]
68: )
69: only_if { sudoer_users }
70: end
My question is how do i go about defining the sudoers_group variable so that it only iterates the sudoer_group section within the vault?
Unfortunately Ruby doesn't give us enough info to check which is undefined, but either node[:testcookbook] or node[:testcookbook][:testusers] is unset/undefined. Double check where you are setting the sudoer_group value because it is likely either misformatted or not uploaded to the Chef Server.
Here is what i did to finally resolve the issue.
I added the following as part of my variables in attributes/default.rb.
default['testcookbook']['testusers']['sudoer_group'] = [
{"name" => "admin", "sudo_pwdless" => false, "command" => "ALL"},
{"name" => "wheel", "sudo_pwdless" => false, "command" => "ALL"},
{"name" => "sysadmin", "sudo_pwdless" => true, "command" => "ALL"}
]`

Add logs in different directory using daemon in ruby

I am using daemon to wrap my script and has specified logs location into that :
Script looks like this :
#!/usr/local/bin/ruby
require 'rubygems'
require 'daemons'
Daemons.run_proc(
'script_test', # name of daemon
:log_output => true,
:output_logfilename => "script-test.log",
:logfilename => "script-test.log"
) do
exec 'ruby /opt/script-test/script-test.rb'
end
Problem is my logs are storing in same directory where my script is present. I have to add my logs to different directory such as /var/log/script-test and later have to rotate those logs weekly.
Provide me with a solution so that i can store the logs of script in /var/log directory.
Make sure you are using an absolute path instead of a relative path
For example:
:output_logfilename => "/var/log/script-test.log",
:logfilename => "/var/log/script-test.log"
In order to logrotate your logs, (assuming Linux) add the following to your logrotate config to rotate on a weekly basis:
/var/log/script-test.log {
weekly
missingok
compress
notifempty
copytruncate
}
It worked for me with this configuration as :
Daemons.run_proc(
'script-test', # name of daemon
:log_output => true,
:dir_mode => :normal,
:dir => "/var/log",
:output_logfilename => "script-test.log",
:logfilename => "script-test.log"
) do
exec 'ruby /opt/script-test/script-test.rb'
end

Write users to .htpasswd in chef recipe

In a chef recipe invoked by chef-solo / vagrant I'm trying to write a .htpasswd file from an object of users.
I specify the users in vagrantfile like this...
chef.json = {
:apache => {
...
:my_users => {
:john => "test",
:matt => "test2"
}
...
My chef recipe looks like this at the moment:
file "/etc/apache2/.htpasswd" do
content "john:n5MfEoHOIQkKg"
owner "#{node['apache']['user']}"
group "#{node['apache']['group']}"
mode '0644'
action :create
end
As you can see I have hard coded John's credentials in there - however, I'm not a Ruby dev and I'm missing some very basic knowledge here...
How can I write all user credentials in the node['apache']['my_users'] attribute (defined in the chef.json) in a loop into the file while creating the password hash for each clear text password?
Note: I'm trying to avoid using a template for this simple file.
I got this working using the LWRP Charlie suggested.
First step is to modify the definition of users to be a proper array:
chef.json = {
:apache => {
...
:my_users => [
{ :username => "john", :password => "test1" },
{ :username => "matt", :password => "test2" }
]
...
I include the htpasswd dependency to metadata and bershelf.
Then in my recipe I create the users in a loop using the htpasswd call:
node[:apache][:my_users].each do |user|
htpasswd "/etc/apache2/.htpasswd" do
user user['username']
password user['password']
end
end
The htpasswd man page looks like it uses MD5 hashing on the passwords.
Perhaps you can generate md5 hashes in your recipe's Ruby code?
You can do it the native way, it requires htpasswd to be installed:
execute 'set password' do
sensitive true
command "htpasswd -cb /etc/htpasswd.users #{user} #{password}"
creates '/etc/htpasswd.users'
end
file '/etc/htpasswd.users' do
owner 'www-data'
group 'www-data'
mode 0o600
end

Chef looking in wrong folder for template

Here's my setup
cookbooks /
supervisord /
definitions /
supervisord_group.erb
templates /
process_group.conf.erb
my_app /
recipes /
default.rb
In cookbooks/supervisord/definitions/supervisord_group.erb I have this:
define :supervisord_group, :programs => [], :enable => true do
include_recipe "supervisord::install"
if params[:enable]
template "#{node[:supervisord][:conf_dir]}/#{params[:name]}_group.conf" do
source "process_group.conf.erb"
variables({
:name => params[:name],
:programs => params[:programs].join(",")
})
owner node[:user]
group node[:group]
mode 0755
end
end
end
In cookbooks/my_app/recipes/default.rb I have this:
supervisord_group "myapps" do
programs ["test1", "test2"]
end
The problem is that when I run it I get an error that it's unable to find the template process_group.erb.conf. Here's the output:
Cookbook 'my_app' (0.0.0) does not contain a file at any of these locations:
templates/ubuntu-10.04/process_group.conf.erb
templates/ubuntu/process_group.conf.erb
templates/default/process_group.conf.erb
If my supervisord_group definition is the one referencing the template why is it expecting the my_app cookbook to have it? Any ideas?
So it looks like there is a not-so-clearly-documented property of the template provider that allows you to specify the cookbook that the template lives in. You have to add cookbook "supervisord" to the template setup for it to find it properly.
Thanks to this question

How to set an environment variable on a server with puppet?

I'm starting to use puppet in my current project and I'm having some issues.
I'm using a recipe to install jruby, but I want to set a environment variable (in this case, JRUBY_HOME and modify the PATH to include JRUBY_HOME/bin) after it finishes installing jruby.
Here's the recipe:
class jruby {
$jruby_home = "/opt/jruby"
exec { "download_jruby":
command => "wget http://jruby.org.s3.amazonaws.com/downloads/1.7.0.RC2/jruby-bin-1.7.0.RC2.tar.gz",
path => $path,
timeout => 0,
unless => "ls /opt | grep jruby-1.7.0",
require => Package["openjdk-7-jre-headless"]
}
exec { "unpack_jruby" :
command => "tar -zxf jruby-bin-1.7.0.RC2.tar.gz -C /opt",
path => $path,
creates => "${jruby_home}-1.7.0.RC2",
require => Exec["download_jruby"]
}
file { $jruby_home:
ensure => link,
target => "${jruby_home}-1.7.0.RC2",
require => Exec["unpack_jruby"]
}
}
So, what's the best way to add /opt/jruby as JRUBY_HOME and then add JRUBY_HOME/bin to PATH?
Solved it:
# init.pp
$jruby_sh = "/etc/profile.d/jruby.sh"
file { $jruby_sh:
ensure => present,
source => "puppet:///modules/jruby/jruby.sh",
owner => "root",
group => "root",
mode => 644,
require => File[$jruby_home]
}
# jruby.sh
export JRUBY_HOME=/opt/jruby
export PATH=$PATH:$JRUBY_HOME/bin

Resources