toquen 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # Toquen
2
+ ![A Toque](http://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/William_Orpen_Le_Chef_de_l%27H%C3%B4tel_Chatham%2C_Paris.jpg/97px-William_Orpen_Le_Chef_de_l%27H%C3%B4tel_Chatham%2C_Paris.jpg)
2
3
 
3
4
  **Toquen** combines [Capistrano 3](http://www.capistranorb.com), [Chef](http://www.getchef.com), and [AWS instance tags](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html) into one bundle of joy. Instance roles are stored in AWS tags and **Toquen** can suck those out, put them into data bags for chef, and create stages in capistrano. You can then selectively run chef on individual servers or whole roles that contain many servers with simple commands.
4
5
 
5
6
  ## Installation
7
+ Before beginning, you should already understand how [chef-solo](http://docs.opscode.com/chef_solo.html) works and have some cookbooks, roles defined, and at least a folder for data_bags (even if it's empty). The rest of this guide assumes you have these ready as well as an AWS PEM key and [access credentials](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSGettingStartedGuide/AWSCredentials.html).
6
8
 
7
9
  Generally, it's easiest if you start off in an empty directory. First, create a file named *Gemfile* that contains these lines:
8
10
 
@@ -30,7 +32,7 @@ Then, run:
30
32
 
31
33
  $ cap update_roles
32
34
 
33
- This will create a data_bag named *servers* that contains one item per server name, as well as create stages per server and role for use in capistrano.
35
+ This will create a data_bag named *servers* in your data_bags path that contains one item per server name, as well as create stages per server and role for use in capistrano.
34
36
 
35
37
  ## Server Bootstrapping
36
38
  Bootstrapping a server will perform all of the following:
@@ -43,11 +45,15 @@ Bootstrapping a server will perform all of the following:
43
45
 
44
46
  You can bootstrap a single server by using:
45
47
 
46
- $ cap server-<server name> update_roles
48
+ $ cap server-<server name> bootstrap
47
49
 
48
- Or a all the servers with a given role with:
50
+ Or a all the servers with a given role:
51
+
52
+ $ cap <role name> bootstrap
53
+
54
+ Or on all servers:
49
55
 
50
- $ cap <role name> update_roles
56
+ $ cap all bootstrap
51
57
 
52
58
  A lockfile is created after the first bootstrapping so that the full bootstrap process is only run once per server.
53
59
 
@@ -60,10 +66,14 @@ Or a all the servers with a given role with:
60
66
 
61
67
  $ cap <role name> cook
62
68
 
69
+ Or on all servers:
70
+
71
+ $ cap all cook
72
+
63
73
  ## Updating Roles
64
- If you change the roles of any servers you will need to run:
74
+ If you change the roles of any servers on AWS (or add any new ones) you will need to run:
65
75
 
66
- $ bundle exec cap update_roles
76
+ $ cap update_roles
67
77
 
68
78
  This will update the *servers* data_bag as well as the capistrano stages.
69
79
 
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require "bundler/gem_tasks"
2
2
  require 'rdoc/task'
3
3
 
4
4
  RDoc::Task.new("doc") { |rdoc|
5
- rdoc.title = "Capistrano + AWS + Chef-Solo"
5
+ rdoc.title = "Toquen: Capistrano + AWS + Chef-Solo"
6
6
  rdoc.rdoc_dir = 'docs'
7
7
  rdoc.rdoc_files.include('README.md')
8
8
  rdoc.rdoc_files.include('lib/**/*.rb')
@@ -0,0 +1,15 @@
1
+ require 'erb'
2
+
3
+ module Toquen
4
+ module Bootstrapper
5
+ def self.generate_script(host)
6
+ # host is available via the binding
7
+ hosttype = fetch(:hosttype, 'ubuntu')
8
+ path = File.expand_path("../templates/#{hosttype}_bootstrap.erb", __FILE__)
9
+ raise "Bootstrap process for #{hosttype} does not exist!" unless File.exists?(path)
10
+ rubygems_version = fetch(:rubygems_version, '2.1.11')
11
+ user = fetch(:ssh_options)[:user]
12
+ StringIO.new ERB.new(File.read(path)).result(binding)
13
+ end
14
+ end
15
+ end
@@ -8,62 +8,21 @@ task :update_roles do
8
8
 
9
9
  aws = Toquen::AWSProxy.new
10
10
  aws.server_details.each do |details|
11
- run_locally { info "Updating local details for #{details[:name]} (#{details[:external_ip]})" }
12
-
13
- open("#{fetch(:chef_data_bags_path)}/servers/#{details[:name]}.json", 'w') { |f|
14
- f.write JSON.dump(details)
15
- }
16
- details[:roles].each { |role| roles[role] += [details[:external_ip]] }
17
- roles['all'] += [details[:external_ip]]
18
-
19
- open("config/deploy/server-#{details[:name]}.rb", 'w') { |f|
20
- f.write("# This file will be overwritten by toquen! Don't put anything here.\n")
21
- f.write("set :stage, 'server-#{details[:name]}'.intern\n")
22
- (details[:roles] + ["server-#{details[:name]}"]).each { |role|
23
- f.write("role '#{role}'.intern, %w{#{details[:external_ip]}}\n")
24
- }
25
- f.write("set :filter, :roles => %w{server-#{details[:name]}}\n")
26
- }
11
+ details[:roles].each { |role| roles[role] += [details] }
12
+ roles['all'] += [details]
13
+ Toquen::LocalWriter.create_databag_item details
14
+ Toquen::LocalWriter.create_stage "server-#{details[:name]}", [details]
27
15
  end
28
16
 
29
- roles.keys.each do |name|
30
- open("config/deploy/#{name}.rb", 'w') { |f|
31
- f.write("# This file will be overwritten by toquen! Don't put anything here.\n")
32
- f.write("set :stage, '#{name}'.intern\n")
33
- roles.each { |n,ips|
34
- f.write("role '#{n}'.intern, %w{#{ips.reject(&:nil?).join(' ')}}\n")
35
- }
36
- f.write("set :filter, :roles => %w{#{name}}\n")
37
- }
38
- end
17
+ roles.each { |name, servers| Toquen::Writer.create_stage name, servers }
39
18
  end
40
19
 
41
20
  desc "bootstrap a server so that it can run chef"
42
21
  task :bootstrap do
43
- rgems = "rubygems-#{fetch(:rubygems_version, '2.1.11')}"
44
22
  on roles(:all), in: :parallel do |host|
45
23
  info "Bootstrapping #{host}..."
46
- code = <<-EOF
47
- #!/bin/bash
48
- if [ -e "/home/#{fetch(:ssh_options)[:user]}/bootstrap.lock" ]; then exit 0; fi
49
- DEBIAN_FRONTEND=noninteractive apt-get -y update
50
- DEBIAN_FRONTEND=noninteractive apt-get -y upgrade
51
- DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade
52
- DEBIAN_FRONTEND=noninteractive apt-get -y install ruby1.9.3 ruby-dev automake make
53
- update-alternatives --set ruby /usr/bin/ruby1.9.1
54
- cd /usr/src
55
- rm -rf rubygems*
56
- wget -q http://production.cf.rubygems.org/rubygems/#{rgems}.tgz
57
- tar -zxf #{rgems}.tgz
58
- cd /usr/src/#{rgems}
59
- ruby setup.rb
60
- gem install --no-rdoc --no-ri chef bundler
61
- touch /home/#{fetch(:ssh_options)[:user]}/bootstrap.lock
62
- echo "Rebooting now, standby..."
63
- reboot
64
- EOF
65
24
  fname = "/home/#{fetch(:ssh_options)[:user]}/bootstrap.sh"
66
- upload! StringIO.new(code), fname
25
+ upload! Toquen::Bootstrapper.generate_script(host), fname
67
26
  sudo "sh #{fname}"
68
27
  end
69
28
  end
@@ -0,0 +1,22 @@
1
+ module Toquen
2
+ module LocalWriter
3
+ def self.create_databag_item(details)
4
+ open("#{fetch(:chef_data_bags_path)}/servers/#{details[:name]}.json", 'w') do |f|
5
+ f.write JSON.dump(details)
6
+ end
7
+ end
8
+
9
+ def self.create_stage(name, servers)
10
+ run_locally { info "Creating stage '#{name}' with servers: #{servers.map { |s| s[:name] }.join(', ')}" }
11
+ open("config/deploy/#{name}.rb", 'w') do |f|
12
+ f.write("# This file will be overwritten by toquen! Don't put anything here.\n")
13
+ f.write("set :stage, '#{name}'.intern\n")
14
+ servers.each { |details|
15
+ rstring = (details[:roles] + [ "all", "server-#{details[:name]}" ]).join(' ')
16
+ f.write("server '#{details[:external_ip]}', roles: %w{#{rstring}}, awsname: '#{details[:name]}'\n")
17
+ }
18
+ f.write("set :filter, roles: %w{#{name}}\n")
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+ if [ -e "/home/<%= user %>/bootstrap.lock" ]; then exit 0; fi
3
+ DEBIAN_FRONTEND=noninteractive apt-get -y update
4
+ DEBIAN_FRONTEND=noninteractive apt-get -y upgrade
5
+ DEBIAN_FRONTEND=noninteractive apt-get -y dist-upgrade
6
+ DEBIAN_FRONTEND=noninteractive apt-get -y install ruby1.9.3 ruby-dev automake make
7
+ update-alternatives --set ruby /usr/bin/ruby1.9.1
8
+ echo "127.0.0.1 <%= host.properties.awsname %>" >> /etc/hosts
9
+ echo "<%= host.properties.awsname %>" > /etc/hostname
10
+ hostname "<%= host.properties.awsname %>"
11
+ cd /usr/src
12
+ rm -rf rubygems*
13
+ wget -q http://production.cf.rubygems.org/rubygems/rubygems-<%= rubygems_version %>.tgz
14
+ tar -zxf rubygems-<%= rubygems_version %>.tgz.tgz
15
+ cd /usr/src/rubygems-<%= rubygems_version %>
16
+ ruby setup.rb
17
+ gem install --no-rdoc --no-ri chef bundler
18
+ touch /home/<%= user %>/bootstrap.lock
19
+ echo "Rebooting now, standby..."
20
+ reboot
@@ -1,3 +1,3 @@
1
1
  module Toquen
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/toquen.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "toquen/version"
2
2
  require "toquen/aws"
3
+ require "toquen/local_writer"
4
+ require "toquen/bootstrapper"
3
5
  require "toquen/capistrano"
4
6
 
5
7
  module Toquen
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: toquen
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Brian Muller
@@ -62,8 +62,11 @@ files:
62
62
  - Rakefile
63
63
  - lib/toquen.rb
64
64
  - lib/toquen/aws.rb
65
+ - lib/toquen/bootstrapper.rb
65
66
  - lib/toquen/capistrano.rb
67
+ - lib/toquen/local_writer.rb
66
68
  - lib/toquen/templates/deploy.rb
69
+ - lib/toquen/templates/ubuntu_bootstrap.erb
67
70
  - lib/toquen/version.rb
68
71
  - toquen.gemspec
69
72
  homepage: https://github.com/bmuller/toquen
@@ -79,7 +82,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
79
82
  requirements:
80
83
  - - ">="
81
84
  - !ruby/object:Gem::Version
82
- hash: 695670950495976934
85
+ hash: -1421927206197467486
83
86
  segments:
84
87
  - 0
85
88
  version: "0"
@@ -88,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
91
  requirements:
89
92
  - - ">="
90
93
  - !ruby/object:Gem::Version
91
- hash: 695670950495976934
94
+ hash: -1421927206197467486
92
95
  segments:
93
96
  - 0
94
97
  version: "0"