provisionator 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +1 -0
- data/lib/provisionator.rb +3 -0
- data/lib/provisionator/capistrano/elasticsearch.rb +7 -0
- data/lib/provisionator/capistrano/provision.rb +5 -0
- data/lib/provisionator/capistrano/sidekiq.rb +28 -0
- data/lib/provisionator/capistrano/unicorn.rb +19 -0
- data/lib/provisionator/ec2_launcher.rb +106 -0
- data/lib/provisionator/ec2_userdata.rb +132 -0
- data/lib/provisionator/version.rb +3 -0
- data/provisionator.gemspec +24 -0
- metadata +108 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 cmaitchison
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Provisionator
|
2
|
+
|
3
|
+
Launch EC2 instances with a user data script that:
|
4
|
+
- mounts EBS volumes
|
5
|
+
- installs Ruby 2.0
|
6
|
+
- installs Chef and executes a chef-solo recipes
|
7
|
+
- deploys the latest release of code upon provisioning, capistrano style.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'provisionator'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install provisionator
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
1. Fork it
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Capistrano::Configuration.instance.load do
|
2
|
+
before "deploy:update_code", "sidekiq:quiet"
|
3
|
+
after "deploy:stop", "sidekiq:stop"
|
4
|
+
after "deploy:start", "sidekiq:start"
|
5
|
+
before "deploy:restart", "sidekiq:restart"
|
6
|
+
|
7
|
+
namespace :sidekiq do
|
8
|
+
desc "Quiet sidekiq (stop accepting new work)"
|
9
|
+
task :quiet, :roles => :app, :on_no_matching_servers => :continue do
|
10
|
+
run "/usr/sbin/service sidekiq quiet"
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Stop sidekiq"
|
14
|
+
task :stop, :roles => :app, :on_no_matching_servers => :continue do
|
15
|
+
run "sudo /usr/bin/monit stop sidekiq"
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Start sidekiq"
|
19
|
+
task :start, :roles => :app, :on_no_matching_servers => :continue do
|
20
|
+
run "sudo /usr/bin/monit start sidekiq"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Restart sidekiq"
|
24
|
+
task :restart, :roles => :app, :on_no_matching_servers => :continue do
|
25
|
+
run "sudo /usr/bin/monit restart sidekiq"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
namespace :deploy do
|
3
|
+
task :start, :roles => :app, :except => { :no_release => true } do
|
4
|
+
run "sudo /usr/bin/monit start unicorn"
|
5
|
+
end
|
6
|
+
|
7
|
+
task :stop, :roles => :app, :except => { :no_release => true } do
|
8
|
+
run "sudo /usr/bin/monit stop unicorn"
|
9
|
+
end
|
10
|
+
|
11
|
+
task :reload, :roles => :app, :except => { :no_release => true } do
|
12
|
+
run "sudo /usr/bin/monit reload unicorn"
|
13
|
+
end
|
14
|
+
|
15
|
+
task :restart, :roles => :app, :except => { :no_release => true } do
|
16
|
+
run "sudo /usr/bin/monit restart unicorn"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
require 'provisionator/ec2_userdata'
|
3
|
+
|
4
|
+
module Provisionator
|
5
|
+
class Ec2Launcher
|
6
|
+
|
7
|
+
def self.launch options={}
|
8
|
+
new(options).launch
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize options={}
|
12
|
+
options[:instance_type] ||= ENV['P_INSTANCE_TYPE'] || 'm1.small'
|
13
|
+
options[:no_release] ||= ENV['P_NO_RELEASE']
|
14
|
+
options[:ec2_region] ||= ENV['P_EC2_REGION'] || 'us-east-1'
|
15
|
+
options[:ec2_endpoint] ||= ENV['P_EC2_ENDPOINT'] || "ec2.#{options[:ec2_region]}.amazonaws.com"
|
16
|
+
options[:ami_id] ||= ENV['P_AMI_ID']
|
17
|
+
options[:ebs_volumes] ||= []
|
18
|
+
options[:key_name] ||= ENV['P_KEY_NAME']
|
19
|
+
options[:security_groups] ||= ENV['P_SECURITY_GROUPS'].try(:split, ',')
|
20
|
+
options[:availability_zones] ||= ENV['P_AVAILABILITY_ZONES'].try(:split, ',') || ["us-east-1a","us-east-1b","us-east-1c"]
|
21
|
+
options[:instance_count] ||= ENV['P_INSTANCE_COUNT'].try(:to_i) || 1
|
22
|
+
options[:load_balancer_name] ||= ENV['P_LOAD_BALANCER_NAME']
|
23
|
+
|
24
|
+
[:app_name, :chef_node_definition, :ami_id, :key_name, :security_groups].each do |option|
|
25
|
+
raise "option ':#{option}' is required" if options[option].nil?
|
26
|
+
end
|
27
|
+
@options = options
|
28
|
+
end
|
29
|
+
|
30
|
+
def launch
|
31
|
+
puts "Launching #{@options[:instance_count]} #{@options[:instance_type]} instance/s..."
|
32
|
+
|
33
|
+
instances = launch_instances
|
34
|
+
wait_for_instances instances
|
35
|
+
register_with_load_balancer instances
|
36
|
+
|
37
|
+
instances.each do |instance|
|
38
|
+
puts "Launched instance #{instance.id}, status: #{instance.status}, public dns: #{instance.dns_name}, public ip: #{instance.ip_address}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def register_with_load_balancer instances
|
45
|
+
if @options[:load_balancer_name]
|
46
|
+
puts "Registering with load balancer..."
|
47
|
+
elb.register_instances_with_load_balancer(
|
48
|
+
load_balancer_name: @options[:load_balancer_name],
|
49
|
+
instances: instances.map{|i| {instance_id: i.id}}
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def wait_for_instances instances
|
55
|
+
puts "Waiting for instances to boot..."
|
56
|
+
sleep 1 until instances.all?{|instance| instance.status != :pending}
|
57
|
+
end
|
58
|
+
|
59
|
+
def launch_instances
|
60
|
+
(1..@options[:instance_count]).map do
|
61
|
+
availability_zone = @options[:availability_zones].rotate!.first
|
62
|
+
instance_options = {
|
63
|
+
image_id: @options[:ami_id],
|
64
|
+
availability_zone: availability_zone,
|
65
|
+
key_name: @options[:key_name],
|
66
|
+
security_groups: @options[:security_groups],
|
67
|
+
instance_type: @options[:instance_type],
|
68
|
+
user_data: user_data,
|
69
|
+
count: 1
|
70
|
+
}
|
71
|
+
instance_options.merge!(block_device_mappings: block_device_mappings) if block_device_mappings.keys.any?
|
72
|
+
puts instance_options.inspect
|
73
|
+
instance = ec2.instances.create(instance_options)
|
74
|
+
|
75
|
+
instance.tags['Name'] = "#{@options[:chef_node_definition]}-#{availability_zone.split('').last}-#{instance.id}"
|
76
|
+
puts "Launching instance '#{instance.id}' in availability_zone '#{availability_zone}...'"
|
77
|
+
instance
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def ec2
|
82
|
+
@ec2 ||= AWS::EC2.new(:ec2_endpoint => @options[:ec2_endpoint])
|
83
|
+
end
|
84
|
+
|
85
|
+
def elb
|
86
|
+
@elb ||= AWS::ELB::Client.new(:ec2_endpoint => @options[:ec2_endpoint])
|
87
|
+
end
|
88
|
+
|
89
|
+
def user_data attributes={}
|
90
|
+
@user_data ||= Provisionator::Ec2Userdata.new(@options).render
|
91
|
+
end
|
92
|
+
|
93
|
+
def block_device_mappings
|
94
|
+
@block_device_mappings ||= begin
|
95
|
+
available_device_mappings = ("/dev/sdf".."/dev/sdp").to_a
|
96
|
+
@options[:ebs_volumes].inject({}) do |mappings, ebs_volume|
|
97
|
+
mappings[available_device_mappings.shift] = {
|
98
|
+
volume_size: ebs_volume[:size],
|
99
|
+
delete_on_termination: ebs_volume[:delete_on_termination]
|
100
|
+
}
|
101
|
+
mappings
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Provisionator
|
4
|
+
class Ec2Userdata
|
5
|
+
def initialize options={}
|
6
|
+
[:app_name, :chef_node_definition, :chef_repo, :config_repo, :app_repo].each do |option|
|
7
|
+
raise "option ':#{option}' is required" if options[option].nil?
|
8
|
+
end
|
9
|
+
|
10
|
+
options[:chef_solo_rb_path] ||= "/home/ubuntu/.#{options[:app_name]}/provision/chef/solo.rb"
|
11
|
+
options[:chef_node_definition_base_file] ||= "/home/ubuntu/.#{options[:app_name]}/provision/chef/base.json"
|
12
|
+
options[:chef_node_definition_file] ||= "/home/ubuntu/.#{options[:app_name]}/provision/chef/#{options[:chef_node_definition]}.json"
|
13
|
+
options[:ruby_patch] ||= 'p195'
|
14
|
+
options[:ebs_mount_paths] = ebs_mount_paths(options[:ebs_volumes]) if options[:ebs_volumes]
|
15
|
+
@options = options
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def ebs_mount_paths ebs_volumes
|
20
|
+
available_device_mappings = ("/dev/xvdf".."/dev/xvdp").to_a
|
21
|
+
ebs_volumes.map do |ebs_volume|
|
22
|
+
[available_device_mappings.shift, ebs_volume[:mount_location]]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def render
|
27
|
+
ERB.new(template).result(binding)
|
28
|
+
end
|
29
|
+
|
30
|
+
def template
|
31
|
+
<<-TEMPLATE
|
32
|
+
#!/bin/bash -xe
|
33
|
+
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
|
34
|
+
|
35
|
+
<% if @options[:ebs_mount_paths] %>
|
36
|
+
<% @options[:ebs_mount_paths].each do |device, mount_point| %>
|
37
|
+
mkfs.ext4 <%= device %>
|
38
|
+
mkdir -p -m 000 <%= mount_point %>
|
39
|
+
echo "<%= device %> <%= mount_point %> auto noatime 0 0" >> /etc/fstab
|
40
|
+
mount <%= device %> <%= mount_point %>
|
41
|
+
<% end %>
|
42
|
+
<% end %>
|
43
|
+
|
44
|
+
apt-get update
|
45
|
+
apt-get upgrade -y
|
46
|
+
ntpdate ntp.ubuntu.com
|
47
|
+
export LC_CTYPE=en_US.UTF-8
|
48
|
+
export LANG=en_US.UTF-8
|
49
|
+
unset LC_ALL
|
50
|
+
|
51
|
+
echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config
|
52
|
+
echo "UserKnownHostsFile=/dev/null" >> /etc/ssh/ssh_config
|
53
|
+
echo "gem: --no-ri --no-rdoc" >> /etc/skel/.gemrc
|
54
|
+
echo "gem: --no-ri --no-rdoc" >> /root/.gemrc
|
55
|
+
echo "gem: --no-ri --no-rdoc" >> /home/ubuntu/.gemrc
|
56
|
+
echo "gem: --no-ri --no-rdoc" >> /etc/gemrc
|
57
|
+
|
58
|
+
#install ruby
|
59
|
+
RUBY_PATCH=<%= @options[:ruby_patch] %>
|
60
|
+
function install_ruby {
|
61
|
+
apt-get -y install build-essential zlib1g-dev libssl-dev libreadline-dev libyaml-dev libcurl4-openssl-dev
|
62
|
+
cd /tmp
|
63
|
+
wget ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-$RUBY_PATCH.tar.gz
|
64
|
+
tar -xvzf ruby-2.0.0-$RUBY_PATCH.tar.gz
|
65
|
+
cd ruby-2.0.0-$RUBY_PATCH/
|
66
|
+
./configure --prefix=/usr/local
|
67
|
+
make
|
68
|
+
make install
|
69
|
+
}
|
70
|
+
ruby -v | grep 2.0.0$RUBY_PATCH || install_ruby
|
71
|
+
|
72
|
+
#install ruby 2.0 compatible version of chef
|
73
|
+
cd /tmp
|
74
|
+
curl -o chef.tar.gz -L https://api.github.com/repos/opscode/chef/tarball/CHEF-3935
|
75
|
+
tar -xvzf chef.tar.gz
|
76
|
+
cd opscode-chef-634ad58
|
77
|
+
gem build chef.gemspec
|
78
|
+
gem install chef-11.4.0.gem
|
79
|
+
gem install ruby-shadow
|
80
|
+
mkdir -p /var/cache/chef
|
81
|
+
chown ubuntu:ubuntu /var/cache/chef
|
82
|
+
|
83
|
+
apt-get install git-core -y
|
84
|
+
|
85
|
+
gem install bundler
|
86
|
+
|
87
|
+
cd /home/ubuntu
|
88
|
+
|
89
|
+
<% if @options[:ssh_key] %>
|
90
|
+
mkdir -p /home/ubuntu/.ssh
|
91
|
+
echo "<%= @options[:ssh_key] %>" > /home/ubuntu/.ssh/id_rsa
|
92
|
+
chown -R ubuntu:ubuntu /home/ubuntu/.ssh
|
93
|
+
chmod 400 /home/ubuntu/.ssh/id_rsa
|
94
|
+
<% end %>
|
95
|
+
|
96
|
+
APP_NAME=<%= @options[:app_name] %>
|
97
|
+
APP_PATH=<%= @options[:app_path] || "/u/apps/#{@options[:app_name]}" %>
|
98
|
+
|
99
|
+
su ubuntu -c 'git clone <%= @options[:chef_repo] %> /home/ubuntu/.chef'
|
100
|
+
su ubuntu -c 'git clone <%= @options[:config_repo] %> /home/ubuntu/.config'
|
101
|
+
su ubuntu -c 'git clone <%= @options[:app_repo] %> /home/ubuntu/.<%= @options[:app_name] %>'
|
102
|
+
|
103
|
+
ln -s /home/ubuntu/.config/s3search/production/app.sh /etc/profile.d/$APP_NAME.sh
|
104
|
+
|
105
|
+
. /etc/profile.d/$APP_NAME.sh
|
106
|
+
|
107
|
+
chef-solo -c <%= @options[:chef_solo_rb_path] %> -j <%= @options[:chef_node_definition_base_file] %> -l debug
|
108
|
+
|
109
|
+
<% unless @options[:no_release] %>
|
110
|
+
mkdir -p $APP_PATH $APP_PATH/releases $APP_PATH/shared $APP_PATH/shared/system $APP_PATH/shared/log $APP_PATH/shared/pids $APP_PATH/shared/sockets
|
111
|
+
chmod g+w $APP_PATH $APP_PATH/releases $APP_PATH/shared $APP_PATH/shared/system $APP_PATH/shared/log $APP_PATH/shared/pids $APP_PATH/shared/sockets
|
112
|
+
chown -R ubuntu:ubuntu /u/
|
113
|
+
su ubuntu -c "git clone -q git@github.com:sodalis/s3search.git $APP_PATH/shared/cached-copy"
|
114
|
+
$(cd $APP_PATH/shared/cached-copy && APP_REVISION=$(git rev-parse HEAD))
|
115
|
+
cp -RPp $APP_PATH/shared/cached-copy $APP_PATH/releases/20130516070710
|
116
|
+
echo $APP_REVISION > $APP_PATH/releases/20130516070710/REVISION
|
117
|
+
ln -s $APP_PATH/releases/20130516070710 $APP_PATH/current
|
118
|
+
rm -R $APP_PATH/current/log
|
119
|
+
ln -s $APP_PATH/shared/log/ $APP_PATH/current/log
|
120
|
+
mkdir $APP_PATH/current/tmp
|
121
|
+
ln -s $APP_PATH/shared/pids/ $APP_PATH/current/tmp/pids
|
122
|
+
bundle install --gemfile $APP_PATH/releases/20130516070710/Gemfile --path $APP_PATH/shared/bundle --deployment --without development test
|
123
|
+
chown -R ubuntu:ubuntu /u/
|
124
|
+
<% end %>
|
125
|
+
|
126
|
+
echo <%= @options[:chef_node_definition] %> > /home/ubuntu/.chef_node_definition
|
127
|
+
chown ubuntu:ubuntu /home/ubuntu/.chef_node_definition
|
128
|
+
chef-solo -c <%= @options[:chef_solo_rb_path] %> -j <%= @options[:chef_node_definition_file] %> -l debug
|
129
|
+
TEMPLATE
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'provisionator/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "provisionator"
|
8
|
+
spec.version = Provisionator::VERSION
|
9
|
+
spec.authors = ["cmaitchison"]
|
10
|
+
spec.email = ["cmaitchison@gmail.com"]
|
11
|
+
spec.description = %q{To the cloud!}
|
12
|
+
spec.summary = %q{To the cloud!}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'aws-sdk'
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: provisionator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- cmaitchison
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: aws-sdk
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.3'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.3'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: To the cloud!
|
63
|
+
email:
|
64
|
+
- cmaitchison@gmail.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- Gemfile
|
71
|
+
- LICENSE.txt
|
72
|
+
- README.md
|
73
|
+
- Rakefile
|
74
|
+
- lib/provisionator.rb
|
75
|
+
- lib/provisionator/capistrano/elasticsearch.rb
|
76
|
+
- lib/provisionator/capistrano/provision.rb
|
77
|
+
- lib/provisionator/capistrano/sidekiq.rb
|
78
|
+
- lib/provisionator/capistrano/unicorn.rb
|
79
|
+
- lib/provisionator/ec2_launcher.rb
|
80
|
+
- lib/provisionator/ec2_userdata.rb
|
81
|
+
- lib/provisionator/version.rb
|
82
|
+
- provisionator.gemspec
|
83
|
+
homepage: ''
|
84
|
+
licenses:
|
85
|
+
- MIT
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.8.23
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: To the cloud!
|
108
|
+
test_files: []
|