awsborn 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.mdown CHANGED
@@ -16,8 +16,8 @@ that are not running.
16
16
  require 'awsborn'
17
17
 
18
18
  # If not set, will be picked up from ENV['AMAZON_ACCESS_KEY_ID']
19
- # and ENV['AMAZON_SECRET_ACCESS_KEY'].
20
19
  Awsborn.access_key_id = 'AAAAAAAAAAAA'
20
+ # Can be picked up from ENV['AMAZON_SECRET_ACCESS_KEY'] or Keychain (OS X)
21
21
  Awsborn.secret_access_key = 'KKKKKKKKKKKK'
22
22
 
23
23
  # Logs to `awsborn.log` in current dir with level INFO by default.
@@ -155,6 +155,71 @@ This is what we use with the AMI above:
155
155
  echo 'Bootstrapping Chef - done'
156
156
  echo '-------------------------'
157
157
 
158
+ ## Running with Chef Solo
159
+
160
+ Awsborn integrates with [Chef Solo](http://github.com/opscode/chef). An example from reality:
161
+
162
+ Awsborn.access_key_id = 'AKIAJHL53MPX7LPCKIFQ'
163
+
164
+ class LogServer < Awsborn::Server
165
+ instance_type :m1_small
166
+ image_id 'ami-2fc2e95b', :sudo_user => 'ubuntu'
167
+ security_group 'Basic web'
168
+ keys '../keys/*'
169
+ bootstrap_script 'chef-bootstrap.sh'
170
+ monitor true
171
+
172
+ cluster do
173
+ domain 'releware.net'
174
+ server :log_a, :zone => :eu_west_1a, :disk => {:sdf => "vol-a857b8c1"}, :ip => 'log-a'
175
+ server :log_b, :zone => :eu_west_1b, :disk => {:sdf => "vol-aa57b8c3"}, :ip => 'log-b'
176
+ end
177
+
178
+ def chef_dna
179
+ {
180
+ :user => "lumberjack",
181
+ :host => host_name,
182
+ :users => [
183
+ {
184
+ :username => "lumberjack",
185
+ :authorized_keys => key_data,
186
+ :gid => 1001,
187
+ :uid => 1001,
188
+ :sudo => true,
189
+ }
190
+ ],
191
+ :packages => %w[
192
+ vim
193
+ heirloom-mailx
194
+ ],
195
+ :gems => [
196
+ "rake"
197
+ ],
198
+ :ebs_volumes => [
199
+ {:device => "sdf", :path => "/apps"}
200
+ ],
201
+ :recipes => [
202
+ "packages",
203
+ "users",
204
+ "sudo",
205
+ "openssh",
206
+ "ec2-ebs",
207
+ "git",
208
+ "gems",
209
+ ]
210
+ }
211
+ end
212
+ end
213
+
214
+ Just add a `Rakefile` in the same directory:
215
+
216
+ require 'awsborn'
217
+ include Awsborn::Chef::Rake
218
+ require './servers'
219
+
220
+ You are now able to run `rake` to start all servers and run Chef on each of them.
221
+ See `rake -T` for more options.
222
+
158
223
  ## Bugs and surprising features
159
224
 
160
225
  No bugs are known at this time.
data/Rakefile CHANGED
@@ -11,6 +11,7 @@ begin
11
11
  gem.homepage = "http://github.com/icehouse/awsborn"
12
12
  gem.authors = ["David Vrensk"]
13
13
  gem.add_dependency "icehouse-right_aws", ">= 1.11.0"
14
+ gem.add_dependency "json_pure", ">= 1.2.3"
14
15
  gem.add_development_dependency "rspec", ">= 1.2.9"
15
16
  gem.add_development_dependency "webmock", ">= 0.9.1"
16
17
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
@@ -3,7 +3,7 @@ module Awsborn
3
3
  class ServerError < StandardError ; end
4
4
 
5
5
  class << self
6
- attr_writer :access_key_id, :secret_access_key, :logger
6
+ attr_writer :access_key_id, :secret_access_key, :logger, :remote_chef_path
7
7
  attr_accessor :verbose
8
8
 
9
9
  Awsborn.verbose = true
@@ -13,7 +13,27 @@ module Awsborn
13
13
  end
14
14
 
15
15
  def secret_access_key
16
- @secret_access_key ||= ENV['AMAZON_SECRET_ACCESS_KEY']
16
+ unless @secret_access_key
17
+ @secret_access_key = ENV['AMAZON_SECRET_ACCESS_KEY']
18
+ if @secret_access_key.to_s == ''
19
+ @secret_access_key = secret_access_key_from_keychain(access_key_id)
20
+ end
21
+ end
22
+ @secret_access_key
23
+ end
24
+
25
+ def secret_access_key_from_keychain (key_id)
26
+ @credentials ||= {}
27
+ unless @credentials[key_id]
28
+ dump = `security -q find-generic-password -a "#{key_id}" -g 2>&1`
29
+ secret_key = dump[/password: "(.*)"/, 1]
30
+ @credentials[key_id] = secret_key
31
+ end
32
+ @credentials[key_id]
33
+ end
34
+
35
+ def remote_chef_path
36
+ @remote_chef_path ||= '/etc/chef'
17
37
  end
18
38
 
19
39
  def logger
@@ -0,0 +1,30 @@
1
+ module Awsborn
2
+ class GitBranch
3
+
4
+ attr_reader :branch
5
+
6
+ def initialize (branch)
7
+ require 'git'
8
+ @branch = branch
9
+ end
10
+
11
+ def file (path)
12
+ path, file = File.split(path)
13
+
14
+ repo = Git.open(root)
15
+ tree = repo.branches[branch].gcommit.gtree
16
+ path.each { |dir| tree = tree.subtrees[dir] }
17
+ tree.blobs[file].contents
18
+ end
19
+
20
+ protected
21
+
22
+ def root
23
+ dir = File.expand_path('.')
24
+ while dir != '/'
25
+ return dir if File.directory?(File.join(dir, '.git'))
26
+ dir = File.dirname(dir)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,64 @@
1
+ module Awsborn
2
+ module Chef
3
+ module Rake
4
+
5
+ def default_cluster
6
+ default_klass = Awsborn::Server.children.first
7
+ default_klass.clusters.first
8
+ end
9
+
10
+ desc "Start all servers (if needed) and deploy with chef"
11
+ task :default => [:start, :cook]
12
+
13
+ desc "Start all servers"
14
+ task :start do
15
+ default_cluster.launch
16
+ end
17
+
18
+ desc "Run chef on all servers"
19
+ task :cook => [:check_syntax] do
20
+ default_cluster.each do |server|
21
+ server.cook
22
+ end
23
+ end
24
+
25
+ desc "Check your cookbooks and config files for syntax errors"
26
+ task :check_syntax do
27
+ Dir["**/*.rb"].each do |recipe|
28
+ RakeFileUtils.verbose(false) do
29
+ sh %{ruby -c #{recipe} > /dev/null} do |ok, res|
30
+ raise "Syntax error in #{recipe}" if not ok
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ desc "Create a new cookbook (with cookbook=name)"
37
+ task :new_cookbook do
38
+ create_cookbook("cookbooks")
39
+ end
40
+
41
+ def create_cookbook(dir)
42
+ raise "Must provide a cookbook=" unless ENV["cookbook"]
43
+ puts "** Creating cookbook #{ENV["cookbook"]}"
44
+ sh "mkdir -p #{File.join(dir, ENV["cookbook"], "attributes")}"
45
+ sh "mkdir -p #{File.join(dir, ENV["cookbook"], "recipes")}"
46
+ sh "mkdir -p #{File.join(dir, ENV["cookbook"], "definitions")}"
47
+ sh "mkdir -p #{File.join(dir, ENV["cookbook"], "libraries")}"
48
+ sh "mkdir -p #{File.join(dir, ENV["cookbook"], "files", "default")}"
49
+ sh "mkdir -p #{File.join(dir, ENV["cookbook"], "templates", "default")}"
50
+
51
+ unless File.exists?(File.join(dir, ENV["cookbook"], "recipes", "default.rb"))
52
+ open(File.join(dir, ENV["cookbook"], "recipes", "default.rb"), "w") do |file|
53
+ file.puts <<-EOH
54
+ #
55
+ # Cookbook Name:: #{ENV["cookbook"]}
56
+ # Recipe:: default
57
+ #
58
+ EOH
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -8,7 +8,11 @@ module Awsborn
8
8
  end
9
9
 
10
10
  class << self
11
- attr_accessor :logger
11
+ attr_accessor :logger, :children, :clusters
12
+ def inherited (klass)
13
+ @children ||= []
14
+ @children << klass
15
+ end
12
16
  def image_id (*args)
13
17
  unless args.empty?
14
18
  @image_id = args.first
@@ -42,7 +46,9 @@ module Awsborn
42
46
  end
43
47
 
44
48
  def cluster (&block)
45
- ServerCluster.build self, &block
49
+ @clusters ||= []
50
+ @clusters << ServerCluster.build(self, &block)
51
+ @clusters.last
46
52
  end
47
53
  def logger
48
54
  @logger ||= Awsborn.logger
@@ -163,6 +169,25 @@ module Awsborn
163
169
  end
164
170
  end
165
171
 
172
+ def cook
173
+ upload_cookbooks
174
+ run_chef
175
+ end
176
+
177
+ def upload_cookbooks
178
+ logger.info "Uploading cookbooks to #{host_name}"
179
+ File.open("config/dna.json", "w") { |f| f.write(chef_dna.to_json) }
180
+ sh "rsync -rl --delete --exclude '.*' ./ root@#{host_name}:#{Awsborn.remote_chef_path}"
181
+ ensure
182
+ File.delete("config/dna.json")
183
+ end
184
+
185
+ def run_chef
186
+ logger.info "Running chef on #{host_name}"
187
+ # Absolute path to config files to avoid a nasty irrational bug.
188
+ sh "ssh root@#{host_name} \"cd #{Awsborn.remote_chef_path}; chef-solo -c #{Awsborn.remote_chef_path}/config/solo.rb -j #{Awsborn.remote_chef_path}/config/dna.json\""
189
+ end
190
+
166
191
  def ec2
167
192
  @ec2 ||= Ec2.new(zone)
168
193
  end
data/lib/awsborn.rb CHANGED
@@ -4,6 +4,7 @@ require 'tempfile'
4
4
 
5
5
  require 'rubygems'
6
6
  require 'right_aws'
7
+ require 'json'
7
8
 
8
9
  # %w[
9
10
  # awsborn
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- - 1
9
- version: 0.2.1
7
+ - 3
8
+ - 0
9
+ version: 0.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - David Vrensk
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-15 00:00:00 +02:00
17
+ date: 2010-04-19 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -32,9 +32,23 @@ dependencies:
32
32
  type: :runtime
33
33
  version_requirements: *id001
34
34
  - !ruby/object:Gem::Dependency
35
- name: rspec
35
+ name: json_pure
36
36
  prerelease: false
37
37
  requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 1
43
+ - 2
44
+ - 3
45
+ version: 1.2.3
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
38
52
  requirements:
39
53
  - - ">="
40
54
  - !ruby/object:Gem::Version
@@ -44,11 +58,11 @@ dependencies:
44
58
  - 9
45
59
  version: 1.2.9
46
60
  type: :development
47
- version_requirements: *id002
61
+ version_requirements: *id003
48
62
  - !ruby/object:Gem::Dependency
49
63
  name: webmock
50
64
  prerelease: false
51
- requirement: &id003 !ruby/object:Gem::Requirement
65
+ requirement: &id004 !ruby/object:Gem::Requirement
52
66
  requirements:
53
67
  - - ">="
54
68
  - !ruby/object:Gem::Version
@@ -58,7 +72,7 @@ dependencies:
58
72
  - 1
59
73
  version: 0.9.1
60
74
  type: :development
61
- version_requirements: *id003
75
+ version_requirements: *id004
62
76
  description: Awsborn lets you define and launch a server cluster on Amazon EC2.
63
77
  email: david@icehouse.se
64
78
  executables: []
@@ -80,7 +94,9 @@ files:
80
94
  - lib/awsborn/ec2.rb
81
95
  - lib/awsborn/extensions/object.rb
82
96
  - lib/awsborn/extensions/proc.rb
97
+ - lib/awsborn/git_branch.rb
83
98
  - lib/awsborn/known_hosts_updater.rb
99
+ - lib/awsborn/rake.rb
84
100
  - lib/awsborn/server.rb
85
101
  - lib/awsborn/server_cluster.rb
86
102
  - spec/awsborn_spec.rb