gersberms 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8abab76e1434ecebc2ffc47517386f6b8d05d536
4
+ data.tar.gz: f95ed711dac01e689ee309e62e50c52daa9c73e3
5
+ SHA512:
6
+ metadata.gz: 498254fec3073a66f3049db28e29f7e6bddf6cde9004eb439af8e5a5a397c35af9262e947c997e1182cdd85114f20a7f9b805886ee304ed843398c24857fdbd8
7
+ data.tar.gz: b44efaf64dba7ae4b5c13d477de7b3261dca8715dffae653cbdd05315f4e1207bc8c860fec17bd057b83139a4131956ac03ccc7d0cea5555856dd6767e271d09
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'pry'
4
+ gem 'rspec'
5
+
6
+ gemspec
@@ -0,0 +1,139 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ gersberms (1.0.0)
5
+ aws-sdk (~> 1.0)
6
+ berkshelf (~> 3.2)
7
+ net-scp (~> 1.2)
8
+ net-ssh (~> 2.9)
9
+ rake (~> 10.4)
10
+ thor (~> 0.19)
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ addressable (2.3.8)
16
+ aws-sdk (1.64.0)
17
+ aws-sdk-v1 (= 1.64.0)
18
+ aws-sdk-v1 (1.64.0)
19
+ json (~> 1.4)
20
+ nokogiri (>= 1.4.4)
21
+ berkshelf (3.2.3)
22
+ addressable (~> 2.3.4)
23
+ berkshelf-api-client (~> 1.2)
24
+ buff-config (~> 1.0)
25
+ buff-extensions (~> 1.0)
26
+ buff-shell_out (~> 0.1)
27
+ celluloid (~> 0.16.0)
28
+ celluloid-io (~> 0.16.1)
29
+ cleanroom (~> 1.0)
30
+ faraday (~> 0.9.0)
31
+ minitar (~> 0.5.4)
32
+ octokit (~> 3.0)
33
+ retryable (~> 2.0)
34
+ ridley (~> 4.0)
35
+ solve (~> 1.1)
36
+ thor (~> 0.19)
37
+ berkshelf-api-client (1.2.1)
38
+ faraday (~> 0.9.0)
39
+ buff-config (1.0.1)
40
+ buff-extensions (~> 1.0)
41
+ varia_model (~> 0.4)
42
+ buff-extensions (1.0.0)
43
+ buff-ignore (1.1.1)
44
+ buff-ruby_engine (0.1.0)
45
+ buff-shell_out (0.2.0)
46
+ buff-ruby_engine (~> 0.1.0)
47
+ celluloid (0.16.0)
48
+ timers (~> 4.0.0)
49
+ celluloid-io (0.16.2)
50
+ celluloid (>= 0.16.0)
51
+ nio4r (>= 1.1.0)
52
+ cleanroom (1.0.0)
53
+ coderay (1.1.0)
54
+ dep-selector-libgecode (1.0.2)
55
+ dep_selector (1.0.3)
56
+ dep-selector-libgecode (~> 1.0)
57
+ ffi (~> 1.9)
58
+ diff-lcs (1.2.5)
59
+ erubis (2.7.0)
60
+ faraday (0.9.1)
61
+ multipart-post (>= 1.2, < 3)
62
+ ffi (1.9.8)
63
+ hashie (2.1.2)
64
+ hitimes (1.2.2)
65
+ json (1.8.2)
66
+ method_source (0.8.2)
67
+ mini_portile (0.6.2)
68
+ minitar (0.5.4)
69
+ mixlib-authentication (1.3.0)
70
+ mixlib-log
71
+ mixlib-log (1.6.0)
72
+ multipart-post (2.0.0)
73
+ net-http-persistent (2.9.4)
74
+ net-scp (1.2.1)
75
+ net-ssh (>= 2.6.5)
76
+ net-ssh (2.9.2)
77
+ nio4r (1.1.0)
78
+ nokogiri (1.6.6.2)
79
+ mini_portile (~> 0.6.0)
80
+ octokit (3.8.0)
81
+ sawyer (~> 0.6.0, >= 0.5.3)
82
+ pry (0.10.1)
83
+ coderay (~> 1.1.0)
84
+ method_source (~> 0.8.1)
85
+ slop (~> 3.4)
86
+ rake (10.4.2)
87
+ retryable (2.0.1)
88
+ ridley (4.1.2)
89
+ addressable
90
+ buff-config (~> 1.0)
91
+ buff-extensions (~> 1.0)
92
+ buff-ignore (~> 1.1)
93
+ buff-shell_out (~> 0.1)
94
+ celluloid (~> 0.16.0)
95
+ celluloid-io (~> 0.16.1)
96
+ erubis
97
+ faraday (~> 0.9.0)
98
+ hashie (>= 2.0.2, < 3.0.0)
99
+ json (>= 1.7.7)
100
+ mixlib-authentication (>= 1.3.0)
101
+ net-http-persistent (>= 2.8)
102
+ retryable (>= 2.0.0)
103
+ semverse (~> 1.1)
104
+ varia_model (~> 0.4)
105
+ rspec (3.2.0)
106
+ rspec-core (~> 3.2.0)
107
+ rspec-expectations (~> 3.2.0)
108
+ rspec-mocks (~> 3.2.0)
109
+ rspec-core (3.2.3)
110
+ rspec-support (~> 3.2.0)
111
+ rspec-expectations (3.2.1)
112
+ diff-lcs (>= 1.2.0, < 2.0)
113
+ rspec-support (~> 3.2.0)
114
+ rspec-mocks (3.2.1)
115
+ diff-lcs (>= 1.2.0, < 2.0)
116
+ rspec-support (~> 3.2.0)
117
+ rspec-support (3.2.2)
118
+ sawyer (0.6.0)
119
+ addressable (~> 2.3.5)
120
+ faraday (~> 0.8, < 0.10)
121
+ semverse (1.2.1)
122
+ slop (3.6.0)
123
+ solve (1.2.1)
124
+ dep_selector (~> 1.0)
125
+ semverse (~> 1.1)
126
+ thor (0.19.1)
127
+ timers (4.0.1)
128
+ hitimes
129
+ varia_model (0.4.0)
130
+ buff-extensions (~> 1.0)
131
+ hashie (>= 2.0.2, < 3.0.0)
132
+
133
+ PLATFORMS
134
+ ruby
135
+
136
+ DEPENDENCIES
137
+ gersberms!
138
+ pry
139
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Joseph Glanville <jpg@jpg.id.au>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,79 @@
1
+ # Gersberms
2
+
3
+ Build AMIs the right way with chef-solo and Berkshelf.
4
+
5
+ ## Installation
6
+
7
+ For now Gersberms is not yet released on RubyGems.org, so currently you will need to install from
8
+ Github.
9
+
10
+ ## Usage
11
+
12
+ Gersberms can be used via the CLI, as a library or as a Rake task.
13
+
14
+ All of the following are equivalent
15
+
16
+ ### CLI
17
+
18
+ To use the CLI you must create a YAML formatted config file.
19
+
20
+ ```yaml
21
+ ssh_user: ubuntu
22
+ base_ami: ami-950b62af
23
+ type: t2.micro
24
+ ami_name: example-ami
25
+ security_groups:
26
+ - example_security_group
27
+ runlist:
28
+ - example_cookbook::default
29
+ json:
30
+ example_cookbook:
31
+ example_attribute: example_value
32
+ ```
33
+
34
+ Which you can then use with the `bake` command like so:
35
+
36
+ ```
37
+ gersberms bake --config=config.yml
38
+ ```
39
+
40
+ ### Library
41
+ ```ruby
42
+ require 'gersberms'
43
+
44
+ config = {
45
+ ssh_user: 'ubuntu',
46
+ base_ami: 'ami-950b62af'
47
+ instance_type: 't2.micro',
48
+ ami_name: 'example-ami',
49
+ security_groups: ['example_security_group'],
50
+ runlist: ['example_cookbook::default'],
51
+ json: {
52
+ example_cookbook: {
53
+ example_attribute: "example_value"
54
+ }
55
+ }
56
+ }
57
+
58
+ Gersberms.bake(config)
59
+ ```
60
+
61
+ ### Rake Task
62
+
63
+ ```ruby
64
+ require 'gersberms/rake_task'
65
+
66
+ Gersberms::RakeTask.new(:ami) do |ami|
67
+ ami.ssh_user = 'ubuntu'
68
+ ami.base_ami = 'ami-950b62af'
69
+ ami.instance_type = 't2.micro'
70
+ ami.ami_name = 'example-ami'
71
+ ami.security_groups = ['example_security_group']
72
+ ami.runlist = ['example_cookbook::default']
73
+ ami.json = {
74
+ example_cookbook: {
75
+ example_attribute: 'example_value'
76
+ }
77
+ }
78
+ end
79
+ ```
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gersberms/cli'
3
+
4
+ Gersberms::CLI.start(ARGV)
@@ -0,0 +1,11 @@
1
+ ssh_user: ubuntu
2
+ base_ami: ami-950b62af
3
+ type: t2.micro
4
+ ami_name: example-ami
5
+ security_groups:
6
+ - example_security_group
7
+ runlist:
8
+ - example_cookbook::default
9
+ json:
10
+ example_cookbook:
11
+ example_attribute: example_value
@@ -0,0 +1,27 @@
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
+ require 'gersberms/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.required_rubygems_version = Gem::Requirement.new('> 0') if s.respond_to? :required_rubygems_version=
6
+ s.version = Gersberms::VERSION
7
+ s.name = 'gersberms'
8
+ s.summary = 'Build AMIs with Chef and Berkshelf'
9
+ s.description = 'Gersberms is a simple system for building AWS EC2 AMIs using Chef and Berkshelf'
10
+ s.homepage = 'http://github.com/josephglanville/gersberms'
11
+ s.authors = ['Joseph Glanville']
12
+ s.email = 'jpg@jpg.id.au'
13
+ s.date = '2014-08-15'
14
+ s.default_executable = 'gersberms'
15
+ s.license = 'MIT'
16
+ s.files = `git ls-files | grep -v -E '(^test|^\.git|client.rb)'`.split
17
+ s.test_files = `git ls-files | grep ^test`.split
18
+ s.require_paths = ['lib']
19
+ s.executables = ['gersberms']
20
+
21
+ s.add_dependency('berkshelf', '~> 3.2')
22
+ s.add_dependency('aws-sdk', '~> 1.0')
23
+ s.add_dependency('net-ssh', '~> 2.9')
24
+ s.add_dependency('net-scp', '~> 1.2')
25
+ s.add_dependency('rake', '~> 10.4')
26
+ s.add_dependency('thor', '~> 0.19')
27
+ end
@@ -0,0 +1,7 @@
1
+ require 'gersberms/gersberms'
2
+ module Gersberms
3
+ def self.bake(*args)
4
+ gersberms = Gersberms.new(*args)
5
+ gersberms.bake
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ require 'gersberms'
2
+
3
+ module Gersberms
4
+ class CLI < Thor
5
+ desc 'bake', 'Create AMI using specified configuration file'
6
+ option :config, type: :string, required: true
7
+ def bake
8
+ cfg = YAML.load_file(options[:config])
9
+ cfg = cfg.each_with_object({}) { |(k, v), m| m[k.to_sym] = v }
10
+ baker = Gersberms.new(cfg)
11
+ baker.bake
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,244 @@
1
+ require 'aws-sdk'
2
+ require 'berkshelf'
3
+ require 'json'
4
+ require 'net/ssh'
5
+ require 'net/scp'
6
+
7
+ module Gersberms
8
+ class Gersberms
9
+ attr_accessor :options, :key_pair, :image
10
+
11
+ CHEF_PATH = '/tmp/gersberms-chef'
12
+
13
+ DEFAULT_OPTIONS = {
14
+ # Instance options
15
+ ssh_user: 'ubuntu',
16
+ base_ami: 'ami-950b62af',
17
+ instance_type: 't2.micro',
18
+ public_address: true,
19
+ security_groups: nil,
20
+ subnet: nil,
21
+ # Chef options
22
+ berksfile: 'Berksfile',
23
+ vendor_path: 'vendor/cookbooks',
24
+ runlist: [],
25
+ json: {},
26
+ # AMI options
27
+ ami_name: 'gersberms-ami',
28
+ tags: [],
29
+ accounts: [],
30
+ # Additional files or directories to upload
31
+ # files: [{ source: '.', destination: '/tmp/staging' }]
32
+ files: [],
33
+ # Gersberms options
34
+ logger: Logger.new(STDOUT),
35
+ max_ssh_attempts: 60
36
+ }
37
+
38
+ def initialize(options = {})
39
+ @ec2 = AWS::EC2.new
40
+ @options = DEFAULT_OPTIONS.merge(options)
41
+ end
42
+
43
+ def logger
44
+ @options[:logger]
45
+ end
46
+
47
+ # TODO(jpg): move this
48
+ def rand
49
+ ('a'..'z').to_a.shuffle[0, 8].join
50
+ end
51
+
52
+ def create_keypair
53
+ name = 'gersberms-' + rand
54
+ logger.info "Creating keypair: #{name}"
55
+ @key_pair = @ec2.key_pairs.create(name)
56
+ end
57
+
58
+ def create_instance
59
+ logger.info 'Creating instance'
60
+ create_options = {
61
+ image_id: @options[:base_ami],
62
+ instance_type: @options[:instance_type],
63
+ count: 1,
64
+ key_pair: @key_pair,
65
+ associate_public_ip_address: @options[:public_address]
66
+ }
67
+ create_options[:security_group_ids] = @options[:security_groups] if @options[:security_groups]
68
+ create_options[:subnet] = @options[:subnet] if @options[:subnet]
69
+ @instance = @ec2.instances.create(create_options)
70
+ sleep 1 until @instance.exists?
71
+ logger.info "Launched instance #{@instance.id}, waiting to become running"
72
+ sleep 1 until @instance.status == :running
73
+ wait_for_ssh
74
+ logger.info 'Instance now running'
75
+ end
76
+
77
+ def wait_for_ssh
78
+ cmd('true')
79
+ end
80
+
81
+ def ssh(&block)
82
+ attempts = 0
83
+ Net::SSH.start(
84
+ @instance.public_ip_address,
85
+ @options[:ssh_user],
86
+ key_data: [@key_pair.private_key],
87
+ &block
88
+ )
89
+ rescue Timeout::Error, Errno::EHOSTUNREACH, Errno::ECONNREFUSED => e
90
+ sleep 1
91
+ attempts += 1
92
+ retry unless attempts > @options[:max_ssh_attempts]
93
+ logger.error "Exceeded max SSH attempts: #{@options[:max_ssh_attempts]}"
94
+ raise
95
+ end
96
+
97
+ def cmd(command)
98
+ ssh do |s|
99
+ s.exec!(command)
100
+ end
101
+ end
102
+
103
+ def chef_path(*args)
104
+ args.unshift(CHEF_PATH)
105
+ File.join(*args)
106
+ end
107
+
108
+ def chef_config
109
+ # TODO(jpg): unindent
110
+ StringIO.new <<-EOF
111
+ file_cache_path "/var/chef/cache"
112
+ file_backup_path "/var/chef/backup"
113
+ cookbook_path ['#{chef_path('cookbooks')}']
114
+ if Chef::VERSION.to_f < 11.8
115
+ role_path nil
116
+ else
117
+ role_path []
118
+ end
119
+ log_level :info
120
+ verbose_logging false
121
+ encrypted_data_bag_secret nil
122
+ http_proxy nil
123
+ http_proxy_user nil
124
+ http_proxy_pass nil
125
+ https_proxy nil
126
+ https_proxy_user nil
127
+ https_proxy_pass nil
128
+ no_proxy nil
129
+ EOF
130
+ end
131
+
132
+ def chef_json
133
+ StringIO.new(JSON.pretty_generate(@options[:json]))
134
+ end
135
+
136
+ def install_chef
137
+ logger.info 'Installing Chef'
138
+ # TODO(jpg): means to force upgrade of Chef etc.
139
+ cmd('which chef-solo || curl -L https://www.opscode.com/chef/install.sh | sudo bash')
140
+ end
141
+
142
+ def upload_files
143
+ return unless @options[:files].count > 1
144
+ puts 'Uploading files'
145
+ ssh do |s|
146
+ @options[:files].each do |f|
147
+ s.scp.upload!(f[:source], f[:destination], recursive: true)
148
+ end
149
+ end
150
+ end
151
+
152
+ def upload_cookbooks
153
+ logger.info 'Vendoring cookbooks'
154
+ berksfile = Berkshelf::Berksfile.from_file(@options[:berksfile])
155
+ berksfile.vendor(@options[:vendor_path])
156
+ ssh do |s|
157
+ logger.debug "Creating #{CHEF_PATH}"
158
+ s.exec!("mkdir -p #{CHEF_PATH}")
159
+ logger.debug "Creating #{chef_path('solo.rb')}"
160
+ s.scp.upload!(chef_config, chef_path('solo.rb'))
161
+ logger.debug "Uploading cookbooks to #{chef_path('cookbooks')}"
162
+ s.scp.upload!(@options[:vendor_path], chef_path('cookbooks'), recursive: true)
163
+ logger.debug "Create #{chef_path('node.json')}"
164
+ s.scp.upload!(chef_json, chef_path('node.json'))
165
+ logger.debug s.exec!("cat #{chef_path('node.json')}")
166
+ end
167
+ end
168
+
169
+ def run_chef
170
+ logger.info 'Running Chef'
171
+ command = 'sudo chef-solo'
172
+ command += " --config #{chef_path('solo.rb')}"
173
+ command += " --json-attributes #{chef_path('node.json')}"
174
+ command += " --override-runlist '#{@options[:runlist].join(',')}'"
175
+ logger.debug command
176
+ output = cmd(command)
177
+ logger.debug 'Chef output:'
178
+ logger.debug output
179
+ end
180
+
181
+ def create_ami
182
+ logger.info "Creating AMI: #{@options[:ami_name]}"
183
+ @image = @instance.create_image(@options[:ami_name])
184
+ @options[:tags].each do |tag|
185
+ logger.info "Adding tag to AMI: #{tag}"
186
+ @image.add_tag(tag)
187
+ end
188
+
189
+ if @options[:share_accounts]
190
+ logger.info "Sharing AMI with: #{@options[:share_accounts]}"
191
+ @image.permissions.add(*@options[:share_accounts])
192
+ end
193
+
194
+ logger.debug "Waiting until AMI: #{@options[:ami_name]} exists"
195
+ sleep 1 until @image.exists?
196
+
197
+ logger.debug "Waiting until AMI: #{@options[:ami_name]} becomes available"
198
+ sleep 1 until @image.state == :available
199
+
200
+ logger.info "AMI #{@image.id} created sucessfully"
201
+ end
202
+
203
+ def stop_instance
204
+ logger.info "Stopping instance: #{@instance.id}"
205
+ @instance.stop
206
+ sleep 1 until @instance.status == :stopped
207
+ end
208
+
209
+ def destroy_instance
210
+ return unless @instance
211
+ logger.info "Destroying instance: #{@instance.id}"
212
+ @instance.terminate
213
+ sleep 1 until @instance.status == :terminated
214
+ end
215
+
216
+ def destroy_keypair
217
+ logger.info "Destroying keypair: #{@key_pair.name}"
218
+ @key_pair.delete if @key_pair
219
+ end
220
+
221
+ def preflight
222
+ fail "AMI #{@options[:ami_name]} already exists" if @ec2.images[@options[:ami_name]].exists?
223
+ end
224
+
225
+ def bake
226
+ preflight
227
+ create_keypair
228
+ create_instance
229
+ install_chef
230
+ upload_cookbooks
231
+ upload_files
232
+ run_chef
233
+ stop_instance
234
+ create_ami
235
+ destroy_instance
236
+ destroy_keypair
237
+ @image.id
238
+ rescue => e
239
+ logger.error "Failed!: #{e.message} \n#{e.backtrace.join("\n")}"
240
+ destroy_instance
241
+ destroy_keypair
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,52 @@
1
+ require 'gersberms'
2
+ require 'rake'
3
+ require 'rake/tasklib'
4
+
5
+ module Gersberms
6
+ # Provides a custom rake task.
7
+ #
8
+ # First require this file:
9
+ # require 'gersberms/rake_task'
10
+ #
11
+ # Then you can configure the task like so.
12
+ # Gersberms::RakeTask.new(:ami) do |ami|
13
+ # ami.ssh_user = 'ubuntu'
14
+ # ami.base_ami = 'ami-950b62af'
15
+ # ami.instance_type = 't2.micro'
16
+ # ami.security_groups = ['example_security_group']
17
+ # ami.subnet = 'example_subnet'
18
+ # ami.berksfile = 'Berksfile'
19
+ # ami.vendor_path = 'vendor/cookbooks'
20
+ # ami.runlist = ['example_cookbook::example_recipe']
21
+ # ami.json = {
22
+ # example_cookbook: {
23
+ # example_attribute: 'example_value'
24
+ # }
25
+ # }
26
+ # ami.ami_name = 'example-ami'
27
+ # ami.tags = ['example_tag']
28
+ # ami.accounts = ['example_account_id']
29
+ # end
30
+ #
31
+ # The name you pass into the constructor will be the name of the task itself.
32
+ # ie. rake ami for the above example
33
+ class RakeTask < Rake::TaskLib
34
+ ATTRS = [:ssh_user, :base_ami, :instance_type, :security_groups, :accounts,
35
+ :subnet, :berksfile, :vendor_path, :runlist, :json, :ami_name, :tags]
36
+ attr_accessor(*ATTRS)
37
+
38
+ def initialize(*task_args, &task_block)
39
+ task_block.call(*[self, task_args].slice(0, task_block.arity)) if task_block
40
+
41
+ desc 'Build AMI using Gersberms' unless Rake.application.last_comment
42
+ task @name do
43
+ baker = Gersberms.new(to_h)
44
+ baker.bake
45
+ end
46
+ end
47
+
48
+ def to_h
49
+ ATTRS.each_with_object({}) { m[k] = send(k) }.delete_if { |k, v| v.nil? }
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ module Gersberms
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gersberms
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Joseph Glanville
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: berkshelf
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: net-ssh
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.9'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: net-scp
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.4'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: thor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.19'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.19'
97
+ description: Gersberms is a simple system for building AWS EC2 AMIs using Chef and
98
+ Berkshelf
99
+ email: jpg@jpg.id.au
100
+ executables:
101
+ - gersberms
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - Gemfile
106
+ - Gemfile.lock
107
+ - LICENSE
108
+ - README.md
109
+ - bin/gersberms
110
+ - examples/config.yml
111
+ - gersberms.gemspec
112
+ - lib/gersberms.rb
113
+ - lib/gersberms/cli.rb
114
+ - lib/gersberms/gersberms.rb
115
+ - lib/gersberms/rake_task.rb
116
+ - lib/gersberms/version.rb
117
+ homepage: http://github.com/josephglanville/gersberms
118
+ licenses:
119
+ - MIT
120
+ metadata: {}
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">"
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 2.4.3
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: Build AMIs with Chef and Berkshelf
141
+ test_files: []