gersberms 1.0.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.
@@ -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: []