baker 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- Prerequisite
13
+ Usage
14
14
  -------
15
15
 
16
- You need to set up sshkeys on the server so you can ssh into the box without passwords.
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
- On the server:
25
+ II. install chef
19
26
 
20
- You'll need to make sure to have chef installed.
27
+ Can install chef with baker itself.
21
28
 
22
- On the client:
29
+ <pre>
30
+ $ bake --setup server_name
31
+ </pre>
23
32
 
24
- First you need to be in a cookbooks project. Here's an example of a mininum cookbooks project:
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
- └── baker
28
- ├── node.json
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/baker/node.json and config/baker/solo.rb are important. These are the configurations that get passed to the chef run that will tell it which recipes to run.
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
- You need configure solo.rb to have this:
52
+ config/solo.rb looks like this:
41
53
 
42
- solo.rb:
54
+ <pre>
43
55
  file_cache_path "/tmp/baker"
44
56
  cookbook_path "/tmp/baker/recipes/cookbooks"
57
+ </pre>
45
58
 
46
- node.json will determine what recipes you'll run:
47
-
48
- config/baker/node.json:
49
-
59
+ config/node.json looks like this:
50
60
 
51
- Usage
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
- Once all that is set up, you can run baker and that will upload the recipes to the server and run them.
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 <server>
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
@@ -1,10 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require File.join(File.expand_path('../../lib/baker', __FILE__))
4
-
5
- server = ARGV[0]
6
- if server.nil? or server == ""
7
- puts "Usage: baker <server-name>"
8
- exit 1
9
- end
10
- Baker.run(:host => server)
4
+ Baker::CLI.run(ARGV)
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 = "0.1.1"
19
+ s.version = Baker::Version
18
20
  end
@@ -1,32 +1,47 @@
1
- # TODO: upload config files: dna.json and solo.rb
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
- class NotCookbookProject < RuntimeError; end
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
- @host = options[:host] || raise("need to set host")
17
- @user = options[:user]
18
- @root = options[:root] || Dir.pwd
19
- set_logger
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 set_logger
23
- @logger = if File.exist?(@root+"/log")
24
- Logger.new(@root+"/log/baker.log")
25
- else
26
- Logger.new(@root+"/baker.log")
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 on #{@host}, check /var/log/baker-chef-server.log"
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
- if !File.exist?("config/dna.json") or !File.exist?("config/solo.rb")
48
- raise "need to create a config/dna.json and config/solo.rb file, so it can be uploaded to the server that needs it"
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/dna.json > /var/log/baker-chef-server.log 2>&1"
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
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ file_cache_path "/tmp/baker"
2
+ cookbook_path "/tmp/baker/recipes/cookbooks"
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: 25
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.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-12 00:00:00 -08:00
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/baker/node.json
41
- - test/fixtures/cookbooks-valid/config/baker/solo.rb
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
- }
@@ -1,2 +0,0 @@
1
- file_cache_path "/tmp/chef-solo"
2
- cookbook_path "/tmp/chef-solo/recipes/cookbooks"