awsborn 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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