If any of you are running RVM, please run
$ rvm use system
Goals:
chef-client
on.in Python
arr = [1,2,3]
for x in arr:
print(x)
in Ruby
arr = [1,2,3]
arr.each do |x|
puts x # look ma, no parentheses!
end
Python
def sum(a,b):
return a+b
print(sum(3,5)) # prints "8"
Parentheses are not required in function calls in Ruby
def sum(a,b)
return a+b
end
puts sum 3 5 # prints "8"
Python
def foo(x):
return [ i+1 for i in x ]
Ruby
def implicit_foo(x)
x.collect { |i| i+1 } # return is implicit
end
def explicit_foo(x)
return x.collect { |i| i+1 }
end
Python
arr = []
if arr:
print("the code never gets here")
else:
fill_arr(arr)
Ruby
arr = []
if arr # this is the typecasting exception
puts "Well, this is unexpected"
else
puts "The code never gets here!"
end
nil
and false
tyepcast to a falsey
value in RubyNilClass
or FalseClass
Object
(and not through FalseClass
or NilClass
), you typecast to true
.{}, [], '', "",
.empty?
arr = []
if arr.empty?
fill_arr arr
else
puts "the code never gets here"
end
Ruby has a lot of syntactic sugar
var = "test"
%w[a b #{var}] # same as ["a", "b", '#{var}']
%W[a b #{var}] # same as ["a", "b", "test"]
1 + 2 # sugar for 1.+(2)
1.+(2) # sugar for 1.send(:+, 2)
puts key1: 34, key2: 42 # outputs "{:key1 => 34, :key2 => 42}"
In Ruby, a proc (procedure), is similar to a function in Python that has not been called, i.e
def bar():
print("hello!")
def foo(bar):
bar()
foo(bar) # prints "hello!"
in Ruby, this is:
bar = proc do
puts "hello!"
end
def foo(bar)
bar.call
end
foo bar # prints "hello!"
A block is just an unnamed proc.
def foo(&block)
block.call
end
foo do
puts "hello!"
end # prints "hello!"
The foo(&block)
declaration tells ruby that this argument takes a block which will be passed in later, and to convert that block into a proc
You will notice chef syntax looks a lot like the last slide.
package "vim" do
action :upgrade
end
def action(ac)
proc { |n| puts "apt-get #{ac} {n}"}
end
def package(n,&b) # n is just a regular old string
b.call.curry[n]
end
package "vim" do
action :upgrade
end # prints "apt-get ugprade vim"
In Chef action
and other options are actually just symbols that get processed later.
do end
and {}
are equivalent. Use do end
for multiline blocks, and {}
for single lines:
[1,2,3].inject(0) { |s,i| s += i }
{1:2, 3:4}.map do |k,v|
puts "k+v is #{k+v}"
puts "k*v is #{k*v}"
end
You need:
$ git clone git@git.osuosl.org:chef/chef-repo
$ cd chef-repo
$ echo ${PWD}/.mrconfig >> ~/.mrtust
$ mr init
$ mkdir ~/.chef
$ cp /home/jordane/.chef/encrypted_data_bag_secret ~/.chef
$ cp /home/jordane/.chef/admin.pem ~/.chef
$ cp /home/jordane/.chef/chef-validator.pem ~/.chef
knife configure -i
chef server URL: https://chef.osuosl.org:443
admin's private key: /home/you/.chef/admin.pem
validation key: /home/you/.chef/chef-validator.pem
If knife cookbook list
returns a list of cookbooks, then you did this correctly.
The major components are:
Can be defined in any of the following:
There are 4 levels of attributes:
attributes/
dir in the root of a cookbook.default['my_cookbook']['package_i_want'] = 'vim'
recipes
, but generally shouldn’t be.node.default['my_cookbook']['package_i_want'] = 'vim'
Attributes can be accessed in a recipe like the following
node['my_cookbook']['package_i_want']
resource "name" do
option "option_value"
end
action, subscribes, notifies, only_if, not_if
package "apache2" do
action :install
end
package "apache2" # the default action is :install
service "apache2" do
action [:start, :enable]
end
template "/etc/apache2/sites-available/mysite.conf" do
source "mysite.conf.erb"
owner "wwwdata"
group "wwwdata"
mode 0644 # like chmod (the 0 means octal in ruby)
notifies :restart, "service[apache2]"
variables :some_other_var => "example"
end
templates/
, usually in templates/default
. All template file names should end in .erb
<%= some_var %>
<% puts some_var %>
<%= @some_other_var %>
@some_other_var
is a variable passed from the recipe<% some_var = [1,2] %>
the next value is the first value in some_var:
<%= some_var.first %>
the next value is the sum of all values in some_var:
<% puts some_var.inject(0){ |s,i| s += i } %>
this is equivalent to the last value:
<%= some_var.inject(0){ |s,i| s += i } %>
will render as
the next value is the first value in some_var:
1
the next value is the sum of all values in some_var:
3
this is equivalent to the last value:
3
files/default/
remote_file
resourceremote_file "/root/.bashrc" do
owner "root"
group "root"
mode 0644
end
{
"name": "silk.osuosl.org",
"chef_environment": "production",
"run_list": [
"role[racktables]",
"role[jenkins_master]",
"recipe[git]",
"recipe[osl-slapd::client]"
],
}
run_list
{
"env_run_lists": {},
"run_list": [],
"chef_type": "role",
"default_attributes": {},
"json_class": "Chef::Role",
"description": "Role for all Drupal servers",
"name": "project_drupal"
}
node['chef_environment']
{
"name": "dev",
"description": "The development environment",
"json_class": "Chef::Environment",
"chef_type": "environment",
"default_attributes": {
"attr": "value"
},
"override_attributes": {}
}
{
"id": "berkshelf-osuosl-bak",
"interfaces": {
"bak": {
"device": "eth0",
"bootproto": "static",
"inet_addr": "10.1.1.31",
"bcast": "10.1.1.255",
"onboot": "yes"
}
}
}
.kitchen.yml
---
driver:
name: vagrant
provisioner:
name: chef_solo
platforms:
- name: ubuntu-12.04
- name: centos-6.4
suites:
- name: default
run_list:
- apt::default
- recipe[mycookbook]
These are the useful ones
source 'https://api.berkshelf.com'
cookbook "omnibus_updater"
cookbook "aliases", git: "git@github.com:osuosl-cookbooks/aliases"
cookbook "firewall", git: "git@github.com:osuosl-cookbooks/firewall"
cookbook "nagios", git: "git@github.com:osuosl-cookbooks/nagios"
cookbook "monitoring", git: "git@github.com:osuosl-cookbooks/monitoring"
cookbook "munin"
cookbook "osl-munin", git: "git@github.com:osuosl-cookbooks/osl-munin"
cookbook "osl-nginx", git: "git@github.com:osuosl-cookbooks/osl-nginx"
cookbook "runit", "1.5.10"
metadata
Does double duty
bundle install
to set up host development (we don’t do this)- Test-kitchen installs the gems on the VM, required for pulling in test frameworks
source 'https://rubygems.org'
# Strictly speaking, these three gems are unncessary
gem 'berkshelf'
gem 'test-kitchen'
gem 'kitchen-vagrant'
# this one installs our test framework
gem 'serverspec'
tests/integration/#{platform}/#{testframework}
require 'serverspec'
include Serverspec::Helper::Exec
include Serverspec::Helper::DetectOS
%w[haskell haskell-min].each do |p| # this is for laziness
describe package(p) do # p is haskell or haskell-min
it { should be_installed.with_version('1-4.0.el6') }
end
end
describe file('/usr/bin/ghc') do
it { should be_executable }
end