baker 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +50 -21
- data/TODO +0 -26
- data/baker.log +14 -0
- data/bin/bake +1 -7
- data/gemspec.rb +3 -1
- data/lib/baker.rb +33 -17
- data/lib/cli.rb +62 -0
- data/scripts/baker_setup.sh +32 -0
- data/test/fixtures/cookbooks-valid/config/node.json +17 -0
- data/test/fixtures/cookbooks-valid/config/solo.rb +2 -0
- data/tung +34 -0
- metadata +9 -7
- data/test/fixtures/cookbooks-empty/baker.log +0 -1
- data/test/fixtures/cookbooks-valid/config/baker/node.json +0 -16
- data/test/fixtures/cookbooks-valid/config/baker/solo.rb +0 -2
data/README.markdown
CHANGED
@@ -10,23 +10,34 @@ Install
|
|
10
10
|
gem install baker --source http://gemcutter.org --no-ri --no-rdoc # sudo if you need to
|
11
11
|
</pre>
|
12
12
|
|
13
|
-
|
13
|
+
Usage
|
14
14
|
-------
|
15
15
|
|
16
|
-
|
16
|
+
I. setup ssh key
|
17
|
+
|
18
|
+
Set up your ssh key on the server so you can login into the box without a password. The gem only supports logging in via a .ssh/config shortcut. Your .ssh/config should look something like this:
|
19
|
+
|
20
|
+
Host server_name
|
21
|
+
Hostname xxx.xxx.xxx.xxx
|
22
|
+
Port 22
|
23
|
+
User root
|
17
24
|
|
18
|
-
|
25
|
+
II. install chef
|
19
26
|
|
20
|
-
|
27
|
+
Can install chef with baker itself.
|
21
28
|
|
22
|
-
|
29
|
+
<pre>
|
30
|
+
$ bake --setup server_name
|
31
|
+
</pre>
|
23
32
|
|
24
|
-
|
33
|
+
III. run chef recipes
|
25
34
|
|
35
|
+
Create a cookbooks project. Here's an example of a cookbooks project structure:
|
36
|
+
|
37
|
+
<pre>
|
26
38
|
├── config
|
27
|
-
│
|
28
|
-
│
|
29
|
-
│ └── solo.rb
|
39
|
+
│ ├── node.json
|
40
|
+
│ └── solo.rb
|
30
41
|
└── cookbooks
|
31
42
|
├── example_recipe1
|
32
43
|
│ └── recipes
|
@@ -34,26 +45,44 @@ First you need to be in a cookbooks project. Here's an example of a mininum coo
|
|
34
45
|
└── example_recipe2
|
35
46
|
└── recipes
|
36
47
|
└── default.rb
|
48
|
+
</pre>
|
37
49
|
|
38
|
-
config/
|
50
|
+
config/node.json and config/solo.rb are important. These are the configurations that get passed to the chef run that will tell it which recipes to run.
|
39
51
|
|
40
|
-
|
52
|
+
config/solo.rb looks like this:
|
41
53
|
|
42
|
-
|
54
|
+
<pre>
|
43
55
|
file_cache_path "/tmp/baker"
|
44
56
|
cookbook_path "/tmp/baker/recipes/cookbooks"
|
57
|
+
</pre>
|
45
58
|
|
46
|
-
node.json
|
47
|
-
|
48
|
-
config/baker/node.json:
|
49
|
-
|
59
|
+
config/node.json looks like this:
|
50
60
|
|
51
|
-
|
52
|
-
|
61
|
+
<pre>
|
62
|
+
{
|
63
|
+
"ec2": true,
|
64
|
+
"environment": {"name":"production"},
|
65
|
+
"mysql_root_password":"whatever",
|
66
|
+
"packages":[
|
67
|
+
{"name": "git-core"},
|
68
|
+
{"name": "curl"}
|
69
|
+
],
|
70
|
+
"gems":[
|
71
|
+
{"name": "rails", "version": "3.0.3"},
|
72
|
+
{"name": "bundler"}
|
73
|
+
],
|
74
|
+
"recipes":[
|
75
|
+
"example_recipe1",
|
76
|
+
"example_recipe2"
|
77
|
+
]
|
78
|
+
}
|
79
|
+
</pre>
|
53
80
|
|
54
|
-
|
55
|
-
Errors are logged to /var/log/baker-chef-server.log and /var/log/baker-chef-client.log.
|
81
|
+
To actually run the chef recipes, cd into the cookbooks project folder and run this command:
|
56
82
|
|
57
83
|
<pre>
|
58
|
-
bake
|
84
|
+
$ bake server_name
|
59
85
|
</pre>
|
86
|
+
|
87
|
+
After running chef you should check the /var/log/baker.chef.log on the server itself for possible errors.
|
88
|
+
|
data/TODO
CHANGED
@@ -1,28 +1,2 @@
|
|
1
1
|
* if there is an error on the server chef-solo run, how can I notify bake command on the client.
|
2
2
|
* uploading baker-client.log to server after done or on at_exit, take logger from ey-cap
|
3
|
-
|
4
|
-
#
|
5
|
-
def execute
|
6
|
-
command = "#{@opts[:chef_bin]} -j /etc/chef/dna.json -c #{chef_config} -r \"#{@recipes_url}\" > #{@chef_log} 2>&1"
|
7
|
-
@logger.debug "Running: #{command}"
|
8
|
-
if system(command)
|
9
|
-
@logger.info "Running telinit"
|
10
|
-
system("telinit q")
|
11
|
-
@logger.info "Finished #{@name} chef run"
|
12
|
-
else
|
13
|
-
@logger.error("#{@name} chef run failed. Reporting error")
|
14
|
-
raise DeployError, "#{@name} chef run failed"
|
15
|
-
end
|
16
|
-
ensure
|
17
|
-
if File.exists?(@chef_log)
|
18
|
-
FileUtils.ln_sf(@chef_log, "/var/log/chef.#{@name}.log")
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
##################################################################
|
23
|
-
|
24
|
-
@enzyme_log = Logger.new("/var/log/enzyme.log")
|
25
|
-
@stderr_log = Logger.new($stderr)
|
26
|
-
|
27
|
-
@stderr_log.send(level, message)
|
28
|
-
@enzyme_log.send(level, message)
|
data/baker.log
CHANGED
@@ -1 +1,15 @@
|
|
1
1
|
# Logfile created on Sun Jul 11 19:37:09 -0700 2010 by logger.rb/22283
|
2
|
+
I, [2011-01-15T01:51:47.994275 #20569] INFO -- : *** setting up chef
|
3
|
+
I, [2011-01-15T01:53:44.858036 #20583] INFO -- : *** setting up chef
|
4
|
+
I, [2011-01-15T01:58:52.780269 #20604] INFO -- : *** setting up chef
|
5
|
+
I, [2011-01-15T02:15:53.453185 #20690] INFO -- : *** setting up chef
|
6
|
+
I, [2011-01-15T02:16:05.445776 #20702] INFO -- : *** setting up chef
|
7
|
+
I, [2011-01-15T02:16:57.983443 #20715] INFO -- : *** setting up chef
|
8
|
+
I, [2011-01-15T02:18:03.389511 #20734] INFO -- : *** setting up chef
|
9
|
+
I, [2011-01-15T02:18:56.487040 #20748] INFO -- : *** setting up chef
|
10
|
+
I, [2011-01-15T02:21:35.250907 #20769] INFO -- : *** setting up chef
|
11
|
+
I, [2011-01-15T02:22:56.754542 #20786] INFO -- : *** setting up chef
|
12
|
+
I, [2011-01-15T02:23:59.002520 #20801] INFO -- : *** setting up chef
|
13
|
+
I, [2011-01-15T09:12:05.181993 #21256] INFO -- : *** setting up chef
|
14
|
+
I, [2011-01-15T09:16:55.445926 #21312] INFO -- : *** setting up chef
|
15
|
+
I, [2011-01-15T09:18:48.712336 #21334] INFO -- : *** setting up chef
|
data/bin/bake
CHANGED
data/gemspec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require File.expand_path("../lib/baker", __FILE__)
|
2
|
+
|
1
3
|
GEM_NAME = 'baker'
|
2
4
|
GEM_FILES = FileList['**/*'] - FileList['coverage', 'coverage/**/*', 'pkg', 'pkg/**/*']
|
3
5
|
GEM_SPEC = Gem::Specification.new do |s|
|
@@ -14,5 +16,5 @@ GEM_SPEC = Gem::Specification.new do |s|
|
|
14
16
|
s.name = GEM_NAME
|
15
17
|
s.platform = Gem::Platform::RUBY
|
16
18
|
s.require_path = "lib"
|
17
|
-
s.version =
|
19
|
+
s.version = Baker::Version
|
18
20
|
end
|
data/lib/baker.rb
CHANGED
@@ -1,32 +1,47 @@
|
|
1
|
-
# TODO: upload config files:
|
1
|
+
# TODO: upload config files: node.json and solo.rb
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'net/ssh'
|
5
|
+
require 'net/sftp'
|
5
6
|
require 'pp'
|
6
7
|
|
7
|
-
|
8
|
+
require File.expand_path('../cli', __FILE__)
|
8
9
|
|
9
10
|
class Baker
|
11
|
+
Version = "0.1.2"
|
12
|
+
|
13
|
+
class NotCookbookProject < RuntimeError; end
|
14
|
+
|
15
|
+
def self.setup(options)
|
16
|
+
@baker = Baker.new(options)
|
17
|
+
@baker.setup
|
18
|
+
end
|
10
19
|
def self.run(options)
|
11
20
|
@baker = Baker.new(options)
|
12
21
|
@baker.run
|
13
22
|
end
|
14
23
|
|
15
24
|
def initialize(options)
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@root
|
19
|
-
|
25
|
+
@user = nil
|
26
|
+
@host = options[:host] || raise("need to set host")
|
27
|
+
@root = Dir.pwd
|
28
|
+
@logger = Logger.new(File.exist?("#{@root}/log") ? "#{@root}/log/baker.log" : "#{@root}/baker.log")
|
20
29
|
end
|
21
|
-
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
30
|
+
|
31
|
+
def setup
|
32
|
+
log "*** setting up chef"
|
33
|
+
Net::SFTP.start(@host, @user) do |sftp|
|
34
|
+
sftp.upload!(
|
35
|
+
File.expand_path("../../scripts/baker_setup.sh", __FILE__),
|
36
|
+
"/tmp/baker_setup.sh"
|
37
|
+
)
|
38
|
+
end
|
39
|
+
Net::SSH.start(@host, @user) do |ssh|
|
40
|
+
remote_cmd(ssh, "bash -ex /tmp/baker_setup.sh >> /var/log/baker.setup.log 2>&1;") #
|
27
41
|
end
|
42
|
+
log "*** done setting up chef, check /var/log/baker.setup.log on #{@host} for possible errors."
|
28
43
|
end
|
29
|
-
|
44
|
+
|
30
45
|
def run
|
31
46
|
validate_cookbook_project
|
32
47
|
log "*** start running chef recipes on #{@host}"
|
@@ -34,7 +49,7 @@ class Baker
|
|
34
49
|
upload_recipes(ssh)
|
35
50
|
run_chef(ssh)
|
36
51
|
end
|
37
|
-
log "*** done running chef recipes
|
52
|
+
log "*** done running chef recipes, check /var/log/baker.chef.log on #{@host}"
|
38
53
|
end
|
39
54
|
|
40
55
|
def validate_cookbook_project
|
@@ -44,8 +59,9 @@ class Baker
|
|
44
59
|
end
|
45
60
|
|
46
61
|
def upload_recipes(ssh)
|
47
|
-
|
48
|
-
|
62
|
+
configs = %w{config/node.json config/solo.rb}
|
63
|
+
if configs.find{|x| !File.exist?(x) }
|
64
|
+
raise "Need to create #{configs.join(', ')} files, it's required for chef to run."
|
49
65
|
end
|
50
66
|
|
51
67
|
log "*** uploading chef recipes to #{@host}..."
|
@@ -66,7 +82,7 @@ class Baker
|
|
66
82
|
|
67
83
|
def run_chef(ssh)
|
68
84
|
log "*** running chef recipes on #{@host}..."
|
69
|
-
chef_cmd = "chef-solo -c /tmp/baker/recipes/config/solo.rb -j /tmp/baker/recipes/config/
|
85
|
+
chef_cmd = "chef-solo -c /tmp/baker/recipes/config/solo.rb -j /tmp/baker/recipes/config/node.json > /var/log/baker.chef.log 2>&1"
|
70
86
|
log "CHEF_CMD : #{chef_cmd}"
|
71
87
|
remote_cmd(ssh, chef_cmd)
|
72
88
|
end
|
data/lib/cli.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
class Baker
|
2
|
+
class CLI
|
3
|
+
def self.run(args)
|
4
|
+
cli = new(args)
|
5
|
+
cli.parse_options!
|
6
|
+
cli.run
|
7
|
+
end
|
8
|
+
|
9
|
+
# The array of (unparsed) command-line options
|
10
|
+
attr_reader :args
|
11
|
+
# The hash of (parsed) command-line options
|
12
|
+
attr_reader :options
|
13
|
+
|
14
|
+
def initialize(args)
|
15
|
+
@args = args.dup
|
16
|
+
end
|
17
|
+
|
18
|
+
def option_parser
|
19
|
+
# @logger = Logger.new
|
20
|
+
@option_parser ||= OptionParser.new do |opts|
|
21
|
+
opts.banner = "Usage: #{File.basename($0)} <server>"
|
22
|
+
|
23
|
+
opts.on("-s", "--setup", "sets up chef, must be ran once before you can run chef recipes.") do
|
24
|
+
options[:setup] = true
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on("-h", "--help", "Display this help message.") do
|
28
|
+
puts opts
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on("-V", "--version", "Display the baker version, and exit.") do
|
33
|
+
puts "Baker Version #{Baker::Version}"
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_options!
|
40
|
+
# defaults
|
41
|
+
@options = {:host => '', :setup => false}
|
42
|
+
|
43
|
+
if args.empty?
|
44
|
+
warn "Please specifiy the server to run the recipes on."
|
45
|
+
warn option_parser
|
46
|
+
exit 1
|
47
|
+
end
|
48
|
+
|
49
|
+
option_parser.parse!(args)
|
50
|
+
options[:host].concat(*args)
|
51
|
+
end
|
52
|
+
|
53
|
+
def run
|
54
|
+
# puts "%%% options #{options.inspect}"
|
55
|
+
if options[:setup]
|
56
|
+
Baker.setup(options)
|
57
|
+
else
|
58
|
+
Baker.run(options)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/bin/bash -ex
|
2
|
+
|
3
|
+
# this script can be ran incrementally. if the packages are already installed, it will do nothing.
|
4
|
+
|
5
|
+
# install essential libraries
|
6
|
+
type -P make &>/dev/null || {
|
7
|
+
apt-get -q -y install build-essential
|
8
|
+
}
|
9
|
+
|
10
|
+
# install ruby
|
11
|
+
type -P ruby &>/dev/null || {
|
12
|
+
apt-get update
|
13
|
+
apt-get -q -y install ruby1.8 ruby1.8-dev libopenssl-ruby
|
14
|
+
ln -s /usr/bin/ruby1.8 /usr/bin/ruby
|
15
|
+
}
|
16
|
+
|
17
|
+
# install rubygems
|
18
|
+
type -P gem &>/dev/null || {
|
19
|
+
wget http://files.rubyforge.vm.bytemark.co.uk/rubygems/rubygems-1.4.2.tgz
|
20
|
+
tar xzvf rubygems-1.4.2.tgz
|
21
|
+
cd rubygems-1.4.2 && ruby setup.rb
|
22
|
+
ln -s /usr/bin/gem1.8 /usr/bin/gem
|
23
|
+
gem update --system
|
24
|
+
rm -rf rubygems-1.4.2
|
25
|
+
rm -f rubygems-1.4.2.tgz
|
26
|
+
}
|
27
|
+
|
28
|
+
# install chef-solo
|
29
|
+
type -P chef-solo &>/dev/null || {
|
30
|
+
gem install --no-ri --no-rdoc chef
|
31
|
+
}
|
32
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"ec2": true,
|
3
|
+
"environment": {"name":"production"},
|
4
|
+
"mysql_root_password":"whatever",
|
5
|
+
"packages":[
|
6
|
+
{"name": "git-core"},
|
7
|
+
{"name": "curl"}
|
8
|
+
],
|
9
|
+
"gems":[
|
10
|
+
{"name": "rails", "version": "3.0.3"},
|
11
|
+
{"name": "bundler"}
|
12
|
+
],
|
13
|
+
"recipes":[
|
14
|
+
"example_recipe1",
|
15
|
+
"example_recipe2"
|
16
|
+
]
|
17
|
+
}
|
data/tung
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
def execute
|
3
|
+
command = "#{@opts[:chef_bin]} -j /etc/chef/node.json -c #{chef_config} -r \"#{@recipes_url}\" > #{@chef_log} 2>&1"
|
4
|
+
@logger.debug "Running: #{command}"
|
5
|
+
if system(command)
|
6
|
+
@logger.info "Running telinit"
|
7
|
+
system("telinit q")
|
8
|
+
@logger.info "Finished #{@name} chef run"
|
9
|
+
else
|
10
|
+
@logger.error("#{@name} chef run failed. Reporting error")
|
11
|
+
raise DeployError, "#{@name} chef run failed"
|
12
|
+
end
|
13
|
+
ensure
|
14
|
+
if File.exists?(@chef_log)
|
15
|
+
FileUtils.ln_sf(@chef_log, "/var/log/chef.#{@name}.log")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
##################################################################
|
20
|
+
|
21
|
+
@enzyme_log = Logger.new("/var/log/enzyme.log")
|
22
|
+
@stderr_log = Logger.new($stderr)
|
23
|
+
|
24
|
+
@stderr_log.send(level, message)
|
25
|
+
@enzyme_log.send(level, message)
|
26
|
+
|
27
|
+
##################################################################
|
28
|
+
|
29
|
+
|
30
|
+
with a new ubuntu instance:
|
31
|
+
* need to set the root password (optional)
|
32
|
+
* apt-get install -y openssh-server openssh-client
|
33
|
+
* set up .ssh/authorized_keys . .ssh 700, .ssh/authorized_keys 600
|
34
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: baker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tung Nguyen
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-15 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -32,16 +32,18 @@ files:
|
|
32
32
|
- bin/bake
|
33
33
|
- gemspec.rb
|
34
34
|
- lib/baker.rb
|
35
|
+
- lib/cli.rb
|
35
36
|
- Rakefile
|
36
37
|
- README.markdown
|
38
|
+
- scripts/baker_setup.sh
|
37
39
|
- test/baker_test.rb
|
38
|
-
- test/fixtures/cookbooks-empty/baker.log
|
39
40
|
- test/fixtures/cookbooks-valid/baker.log
|
40
|
-
- test/fixtures/cookbooks-valid/config/
|
41
|
-
- test/fixtures/cookbooks-valid/config/
|
41
|
+
- test/fixtures/cookbooks-valid/config/node.json
|
42
|
+
- test/fixtures/cookbooks-valid/config/solo.rb
|
42
43
|
- test/fixtures/cookbooks-valid/cookbooks/example_recipe1/recipes/default.rb
|
43
44
|
- test/fixtures/cookbooks-valid/cookbooks/example_recipe2/recipes/default.rb
|
44
45
|
- TODO
|
46
|
+
- tung
|
45
47
|
has_rdoc: true
|
46
48
|
homepage: http://github.com/tongueroo/baker
|
47
49
|
licenses: []
|
@@ -1 +0,0 @@
|
|
1
|
-
# Logfile created on Sun Jul 11 19:38:14 -0700 2010 by logger.rb/22283
|
@@ -1,16 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"ec2": false,
|
3
|
-
"user":"root",
|
4
|
-
"packages":[],
|
5
|
-
"gems":[],
|
6
|
-
"users":[],
|
7
|
-
"environment": {"name":"staging"},
|
8
|
-
"packages":{},
|
9
|
-
"gems_to_install":[
|
10
|
-
{"name": "sinatra", "version": "0.9.4"}
|
11
|
-
],
|
12
|
-
"recipes":[
|
13
|
-
"example_recipe1",
|
14
|
-
"example_recipe1"
|
15
|
-
]
|
16
|
-
}
|