image_builder 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rubocop.yml +16 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +32 -0
  7. data/Rakefile +29 -0
  8. data/bin/image_builder +234 -0
  9. data/image_builder.gemspec +30 -0
  10. data/lib/image_builder.rb +38 -0
  11. data/lib/image_builder/backends/backend_base.rb +10 -0
  12. data/lib/image_builder/backends/packer.rb +109 -0
  13. data/lib/image_builder/builders/aws_base.rb +101 -0
  14. data/lib/image_builder/builders/aws_chroot.rb +33 -0
  15. data/lib/image_builder/builders/aws_ebs.rb +15 -0
  16. data/lib/image_builder/builders/aws_instance.rb +45 -0
  17. data/lib/image_builder/builders/builder_base.rb +12 -0
  18. data/lib/image_builder/builders/null.rb +39 -0
  19. data/lib/image_builder/post_processors/compress.rb +24 -0
  20. data/lib/image_builder/post_processors/post_processors_base.rb +10 -0
  21. data/lib/image_builder/post_processors/vagrant.rb +41 -0
  22. data/lib/image_builder/provisioners/chef_base.rb +96 -0
  23. data/lib/image_builder/provisioners/chef_client.rb +115 -0
  24. data/lib/image_builder/provisioners/chef_solo.rb +33 -0
  25. data/lib/image_builder/provisioners/file.rb +26 -0
  26. data/lib/image_builder/provisioners/provisioner_base.rb +10 -0
  27. data/lib/image_builder/provisioners/shell.rb +47 -0
  28. data/lib/image_builder/version.rb +4 -0
  29. data/spec/aws_chroot_builder_spec.rb +30 -0
  30. data/spec/aws_ebs_builder_spec.rb +30 -0
  31. data/spec/aws_instance_builder_spec.rb +30 -0
  32. data/spec/chef_client_provisioner_spec.rb +32 -0
  33. data/spec/chef_solo_provisioner_spec.rb +28 -0
  34. data/spec/compress_postprocessor_spec.rb +15 -0
  35. data/spec/fixtures/test-knife.rb +40 -0
  36. data/spec/null_builder_spec.rb +21 -0
  37. data/spec/packer_backend_spec.rb +145 -0
  38. data/spec/vagrant_postprocessor_spec.rb +20 -0
  39. metadata +236 -0
@@ -0,0 +1,28 @@
1
+ require_relative '../lib/image_builder/provisioners/chef_solo.rb'
2
+
3
+ describe ImageBuilder::Provisioners::Chef::Solo do
4
+ before(:each) do
5
+ @obj = ImageBuilder::Provisioners::Chef::Solo.new
6
+ end
7
+
8
+ it 'has the expected default attributes' do
9
+ expect(@obj.prevent_sudo).to be false
10
+ expect(@obj.skip_install).to be false
11
+ end
12
+
13
+ it 'loads the expected parameters from a file as a class method' do
14
+ # @obj.from_file(::File.join(::File.dirname(__FILE__), 'fixtures', 'test-knife.rb'))
15
+ obj = ImageBuilder::Provisioners::Chef::Solo.from_file(::File.join(::File.dirname(__FILE__), 'fixtures', 'test-knife.rb'))
16
+
17
+ expect(obj.encrypted_data_bag_secret_path).to eql ENV['ENCRYPTED_DATA_BAG_SECRET']
18
+ expect(obj.cookbook_paths).to_not be_empty
19
+ end
20
+
21
+ it 'has the correct packer type' do
22
+ expect(@obj.type).to eql 'chef-solo'
23
+ end
24
+
25
+ it 'implements packer_hash()' do
26
+ expect(@obj.respond_to? :packer_hash).to be true
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ require_relative '../lib/image_builder/post_processors/compress.rb'
2
+
3
+ describe ImageBuilder::PostProcessors::Compress do
4
+ before(:each) do
5
+ @obj = ImageBuilder::PostProcessors::Compress.new
6
+ end
7
+
8
+ it 'has the correct packer type' do
9
+ expect(@obj.type).to eql 'compress'
10
+ end
11
+
12
+ it 'implements packer_hash()' do
13
+ expect(@obj.respond_to? :packer_hash).to be true
14
+ end
15
+ end
@@ -0,0 +1,40 @@
1
+ #This knife.rb rile is intended to be used with gem 'knife-block'
2
+ current_dir = File.dirname(__FILE__)
3
+ user = ENV['OPSCODE_USER'] || ENV['USER']
4
+ log_level :info
5
+ log_location STDOUT
6
+ node_name user
7
+ client_key "#{current_dir}/#{user}.pem"
8
+ validation_client_name "chef-validator"
9
+ validation_key "/dev/null"
10
+ chef_server_url "https://chef.chefserver.com/"
11
+ cache_type 'BasicFile'
12
+ cache_options(:path => "#{current_dir}/checksums")
13
+ cookbook_path ["#{current_dir}/../cookbooks", "~/chef/cookbooks"]
14
+
15
+ # all your credentials are belong to us
16
+ encrypted_data_bag_secret ENV['ENCRYPTED_DATA_BAG_SECRET']
17
+ knife[:encrypted_data_bag_secret] = ENV['ENCRYPTED_DATA_BAG_SECRET']
18
+ knife[:secret_file] = ENV['ENCRYPTED_DATA_BAG_SECRET']
19
+
20
+ knife[:vault_mode] = 'client'
21
+
22
+ # Amazon Web Services
23
+ knife[:aws_access_key_id] = ENV['AWS_ACCESS_KEY_ID']
24
+ knife[:aws_secret_access_key] = ENV['AWS_SECRET_ACCESS_KEY']
25
+ knife[:aws_ssh_key_id] = ENV['AWS_SSH_KEY_ID']
26
+
27
+ # HP Cloud Services
28
+ knife[:hp_account_id] = ENV['HP_ACCOUNT_ID']
29
+ knife[:hp_secret_key] = ENV['HP_SECRET_KEY']
30
+ knife[:hp_tenant_id] = ENV['HP_TENANT_ID']
31
+
32
+ # OpenStack
33
+ knife[:openstack_username] = ENV['OS_USERNAME']
34
+ knife[:openstack_password] = ENV['OS_PASSWORD']
35
+ knife[:openstack_auth_url] = ENV['OS_AUTH_URL']
36
+ knife[:openstack_tenant] = ENV['OS_TENANT']
37
+
38
+ # Rackspace Cloud
39
+ knife[:rackspace_api_username] = ENV['RACKSPACE_USERNAME']
40
+ knife[:rackspace_api_key] = ENV['RACKSPACE_API_KEY']
@@ -0,0 +1,21 @@
1
+ require_relative '../lib/image_builder/builders/null.rb'
2
+
3
+ describe ImageBuilder::Builders::Null do
4
+ before(:each) do
5
+ @obj = ImageBuilder::Builders::Null.new
6
+ end
7
+
8
+ it 'has the expected default attributes' do
9
+ expect(@obj.host).to eql '127.0.0.1'
10
+ expect(@obj.port).to eql 22
11
+ expect(@obj.ssh_username).to eql ENV['USER']
12
+ end
13
+
14
+ it 'has the correct packer type' do
15
+ expect(@obj.type).to eql 'null'
16
+ end
17
+
18
+ it 'implements packer_hash()' do
19
+ expect(@obj.respond_to? :packer_hash).to be true
20
+ end
21
+ end
@@ -0,0 +1,145 @@
1
+ require_relative '../lib/image_builder/backends/packer.rb'
2
+ require_relative '../lib/image_builder/builders/null.rb'
3
+ require_relative '../lib/image_builder/provisioners/shell.rb'
4
+ require_relative '../lib/image_builder/post_processors/compress.rb'
5
+
6
+ require 'json'
7
+
8
+ describe ImageBuilder::Backends::Packer do
9
+ ImageBuilder::Backends::Packer.packer_path = '~/packer/packer'
10
+
11
+ before(:each) do
12
+ @obj = ImageBuilder::Backends::Packer.new
13
+ end
14
+
15
+ it 'correctly populates a description' do
16
+ @obj.description = 'My Description'
17
+
18
+ hash = JSON.parse(@obj.to_json)
19
+ expect(hash['description']).to eql 'My Description'
20
+ end
21
+
22
+ it 'correctly sets a min packer version' do
23
+ @obj.min_packer_version = '0.9.10'
24
+
25
+ hash = JSON.parse(@obj.to_json)
26
+ expect(hash['min_packer_version']).to eql '0.9.10'
27
+ end
28
+
29
+ it 'correctly populates user variables' do
30
+ @obj.add_variable('foo', 'bar') # foo=bar
31
+ @obj.add_variable('baz') # baz=""
32
+
33
+ hash = JSON.parse(@obj.to_json)
34
+
35
+ expect(hash.key? 'variables').to be true
36
+ expect(hash['variables']['foo']).to eql 'bar'
37
+ expect(hash['variables']['baz']).to eql ''
38
+ end
39
+
40
+ it 'correctly adds a default builder' do
41
+ @obj.add_builder(ImageBuilder::Builders::Null.new)
42
+
43
+ hash = JSON.parse(@obj.to_json)
44
+
45
+ expect(hash.key? 'builders').to be true
46
+ expect(hash['builders']).to be_an_instance_of Array
47
+ expect(hash['builders'].size).to eql 1
48
+
49
+ builder = hash['builders'][0]
50
+
51
+ expect(builder['type']).to eql 'null'
52
+ expect(builder['host']).to eql '127.0.0.1'
53
+ expect(builder['port']).to eql 22
54
+ expect(builder['ssh_username']).to eql ENV['USER']
55
+ end
56
+
57
+ it 'correctly adds a simple provisioner' do
58
+ prov = ImageBuilder::Provisioners::Shell.new
59
+ prov.script = '/my/script'
60
+
61
+ @obj.add_provisioner(prov)
62
+
63
+ hash = JSON.parse(@obj.to_json)
64
+
65
+ expect(hash.key? 'provisioners').to be true
66
+ expect(hash['provisioners']).to be_an_instance_of Array
67
+ expect(hash['provisioners'].size).to eql 1
68
+
69
+ provisioner = hash['provisioners'][0]
70
+
71
+ expect(provisioner['type']).to eql 'shell'
72
+ expect(provisioner['script']).to eql '/my/script'
73
+ end
74
+
75
+ it 'correctly adds a simple post-processor' do
76
+ post = ImageBuilder::PostProcessors::Compress.new
77
+ post.output = '/my/artifact.bz2'
78
+
79
+ @obj.add_post_processor(post)
80
+
81
+ hash = JSON.parse(@obj.to_json)
82
+
83
+ expect(hash.key? 'post-processors').to be true
84
+ expect(hash['post-processors']).to be_an_instance_of Array
85
+ expect(hash['post-processors'].size).to eql 1
86
+
87
+ procs = hash['post-processors'][0]
88
+
89
+ expect(procs['type']).to eql 'compress'
90
+ expect(procs['output']).to eql '/my/artifact.bz2'
91
+ end
92
+
93
+ it 'fails if no builders are specified' do
94
+ pro = ImageBuilder::Provisioners::Shell.new
95
+ pro.script = '/dev/null'
96
+
97
+ @obj.add_variable('foo', 'bar')
98
+ @obj.add_provisioner(pro)
99
+
100
+ # NOTE: When dealing with exception matching, need to use expect{} vs expect()
101
+ expect { @obj.validate }.to raise_error(RuntimeError)
102
+ end
103
+
104
+ it 'successfully validates a simple & valid configuration' do
105
+ @obj.add_builder(ImageBuilder::Builders::Null.new)
106
+ expect { @obj.validate }.to_not raise_error
107
+ expect(@obj.validate).to be true
108
+ end
109
+
110
+ it 'successfully validates a complex & valid configuration' do
111
+ prov1 = ImageBuilder::Provisioners::Shell.new
112
+ prov1.script = '/dev/null' # validation will test for the existance of this file!
113
+
114
+ prov2 = ImageBuilder::Provisioners::Shell.new
115
+ prov2.inline = ['true']
116
+
117
+ post = ImageBuilder::PostProcessors::Compress.new
118
+ post.output = '/var/tmp/my-image.gz'
119
+
120
+ @obj.description = 'test'
121
+ @obj.add_variable('foo')
122
+ @obj.add_variable('bar', 'baz')
123
+ @obj.add_builder(ImageBuilder::Builders::Null.new)
124
+ @obj.add_provisioner(prov1)
125
+ @obj.add_provisioner(prov2)
126
+ @obj.add_post_processor(post)
127
+
128
+ expect { @obj.validate }.to_not raise_error
129
+ expect(@obj.validate).to be true
130
+ end
131
+
132
+ it 'successfully builds from a vaild configuration' do
133
+ # This test assumes that ssh is running on your local machine, and
134
+ # that you have pubkey authentication setup using the default id_rsa
135
+ # private key name.
136
+ prov = ImageBuilder::Provisioners::Shell.new
137
+ prov.inline = ['true']
138
+
139
+ @obj.description = 'simple packer build'
140
+ @obj.add_builder(ImageBuilder::Builders::Null.new)
141
+ @obj.add_provisioner(prov)
142
+
143
+ expect { @obj.build }.to_not raise_error
144
+ end
145
+ end
@@ -0,0 +1,20 @@
1
+ require_relative '../lib/image_builder/post_processors/vagrant.rb'
2
+
3
+ describe ImageBuilder::PostProcessors::Vagrant do
4
+ before(:each) do
5
+ @obj = ImageBuilder::PostProcessors::Vagrant.new
6
+ end
7
+
8
+ it 'has the expected default attributes' do
9
+ expect(@obj.compression_level).to eql 6
10
+ expect(@obj.keep_input_artifact).to be false
11
+ end
12
+
13
+ it 'has the correct packer type' do
14
+ expect(@obj.type).to eql 'vagrant'
15
+ end
16
+
17
+ it 'implements packer_hash()' do
18
+ expect(@obj.respond_to? :packer_hash).to be true
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,236 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: image_builder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Mike Morris
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mixlib-shellout
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: commander
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: cloudutil
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: chef
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '11.12'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: '11.12'
125
+ description: |
126
+ # ImageBuilder
127
+
128
+ A gem to build operating system images for various platforms. At initial release, this gem supports
129
+ building images using packer to build images for the AWS platform
130
+
131
+ ## Installation
132
+
133
+ Add this line to your application's Gemfile:
134
+
135
+ gem 'image_builder'
136
+
137
+ And then execute:
138
+
139
+ $ bundle
140
+
141
+ Or install it yourself as:
142
+
143
+ $ gem install image_builder
144
+
145
+ ## Usage
146
+
147
+ This is how you use the gem, should probably write something useful here.
148
+ But since it's just a library gem that basically just wraps the packer utility,
149
+ read this code, and the packer documentation to figure out what to do
150
+
151
+ ## Contributing
152
+
153
+ 1. Fork it ( https://github.com/[my-github-username]/image_builder/fork )
154
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
155
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
156
+ 4. Push to the branch (`git push origin my-new-feature`)
157
+ 5. Create a new Pull Request
158
+ email:
159
+ - michael.m.morris@pearson.com
160
+ executables:
161
+ - image_builder
162
+ extensions: []
163
+ extra_rdoc_files: []
164
+ files:
165
+ - .gitignore
166
+ - .rubocop.yml
167
+ - Gemfile
168
+ - LICENSE.txt
169
+ - README.md
170
+ - Rakefile
171
+ - bin/image_builder
172
+ - image_builder.gemspec
173
+ - lib/image_builder.rb
174
+ - lib/image_builder/backends/backend_base.rb
175
+ - lib/image_builder/backends/packer.rb
176
+ - lib/image_builder/builders/aws_base.rb
177
+ - lib/image_builder/builders/aws_chroot.rb
178
+ - lib/image_builder/builders/aws_ebs.rb
179
+ - lib/image_builder/builders/aws_instance.rb
180
+ - lib/image_builder/builders/builder_base.rb
181
+ - lib/image_builder/builders/null.rb
182
+ - lib/image_builder/post_processors/compress.rb
183
+ - lib/image_builder/post_processors/post_processors_base.rb
184
+ - lib/image_builder/post_processors/vagrant.rb
185
+ - lib/image_builder/provisioners/chef_base.rb
186
+ - lib/image_builder/provisioners/chef_client.rb
187
+ - lib/image_builder/provisioners/chef_solo.rb
188
+ - lib/image_builder/provisioners/file.rb
189
+ - lib/image_builder/provisioners/provisioner_base.rb
190
+ - lib/image_builder/provisioners/shell.rb
191
+ - lib/image_builder/version.rb
192
+ - spec/aws_chroot_builder_spec.rb
193
+ - spec/aws_ebs_builder_spec.rb
194
+ - spec/aws_instance_builder_spec.rb
195
+ - spec/chef_client_provisioner_spec.rb
196
+ - spec/chef_solo_provisioner_spec.rb
197
+ - spec/compress_postprocessor_spec.rb
198
+ - spec/fixtures/test-knife.rb
199
+ - spec/null_builder_spec.rb
200
+ - spec/packer_backend_spec.rb
201
+ - spec/vagrant_postprocessor_spec.rb
202
+ homepage: ''
203
+ licenses:
204
+ - MIT
205
+ metadata: {}
206
+ post_install_message:
207
+ rdoc_options: []
208
+ require_paths:
209
+ - lib
210
+ required_ruby_version: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - '>='
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ required_rubygems_version: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - '>='
218
+ - !ruby/object:Gem::Version
219
+ version: '0'
220
+ requirements: []
221
+ rubyforge_project:
222
+ rubygems_version: 2.2.2
223
+ signing_key:
224
+ specification_version: 4
225
+ summary: A gem to create operating system images using various methods
226
+ test_files:
227
+ - spec/aws_chroot_builder_spec.rb
228
+ - spec/aws_ebs_builder_spec.rb
229
+ - spec/aws_instance_builder_spec.rb
230
+ - spec/chef_client_provisioner_spec.rb
231
+ - spec/chef_solo_provisioner_spec.rb
232
+ - spec/compress_postprocessor_spec.rb
233
+ - spec/fixtures/test-knife.rb
234
+ - spec/null_builder_spec.rb
235
+ - spec/packer_backend_spec.rb
236
+ - spec/vagrant_postprocessor_spec.rb