packer-config 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/.rubocop.yml +340 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +17 -0
  6. data/LICENSE +176 -0
  7. data/README.md +107 -0
  8. data/Rakefile +47 -0
  9. data/TODO.md +8 -0
  10. data/lib/packer-config.rb +181 -0
  11. data/lib/packer/builder.rb +65 -0
  12. data/lib/packer/builders/all.rb +17 -0
  13. data/lib/packer/builders/amazon.rb +214 -0
  14. data/lib/packer/builders/docker.rb +47 -0
  15. data/lib/packer/builders/virtualbox.rb +169 -0
  16. data/lib/packer/dataobject.rb +128 -0
  17. data/lib/packer/envvar.rb +27 -0
  18. data/lib/packer/macro.rb +28 -0
  19. data/lib/packer/postprocessor.rb +77 -0
  20. data/lib/packer/postprocessors/all.rb +16 -0
  21. data/lib/packer/postprocessors/docker.rb +35 -0
  22. data/lib/packer/postprocessors/vagrant.rb +47 -0
  23. data/lib/packer/provisioner.rb +86 -0
  24. data/lib/packer/provisioners/all.rb +16 -0
  25. data/lib/packer/provisioners/file.rb +36 -0
  26. data/lib/packer/provisioners/shell.rb +60 -0
  27. data/packer-config.gemspec +46 -0
  28. data/spec/integration/README.md +14 -0
  29. data/spec/integration/builds/.gitignore +4 -0
  30. data/spec/integration/centos_vagrant_spec.rb +76 -0
  31. data/spec/integration/packer_cache/.gitignore +4 -0
  32. data/spec/integration/scripts/chef.sh +199 -0
  33. data/spec/integration/scripts/cleanup.sh +17 -0
  34. data/spec/integration/scripts/fix-slow-dns.sh +13 -0
  35. data/spec/integration/scripts/hello.sh +3 -0
  36. data/spec/integration/scripts/kickstart/centos-6.5-ks.cfg +71 -0
  37. data/spec/integration/scripts/minimize.sh +9 -0
  38. data/spec/integration/scripts/sshd.sh +6 -0
  39. data/spec/integration/scripts/vagrant.sh +10 -0
  40. data/spec/integration/scripts/vmtools.sh +39 -0
  41. data/spec/packer/builder_spec.rb +39 -0
  42. data/spec/packer/builders/amazon_spec.rb +88 -0
  43. data/spec/packer/builders/docker_spec.rb +25 -0
  44. data/spec/packer/builders/virtualbox_spec.rb +44 -0
  45. data/spec/packer/dataobject_spec.rb +239 -0
  46. data/spec/packer/envvar_spec.rb +38 -0
  47. data/spec/packer/macro_spec.rb +38 -0
  48. data/spec/packer/postprocessor_spec.rb +72 -0
  49. data/spec/packer/postprocessors/docker_import_spec.rb +27 -0
  50. data/spec/packer/postprocessors/docker_push_spec.rb +27 -0
  51. data/spec/packer/postprocessors/vagrant_spec.rb +27 -0
  52. data/spec/packer/provisioner_spec.rb +78 -0
  53. data/spec/packer/provisioners/file_spec.rb +63 -0
  54. data/spec/packer/provisioners/shell_spec.rb +116 -0
  55. data/spec/packer_config_spec.rb +197 -0
  56. data/spec/spec_helper.rb +19 -0
  57. data/spec/unit_helper.rb +15 -0
  58. metadata +220 -0
@@ -0,0 +1,25 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::Builder::Docker do
18
+ let(:builder) { Packer::Builder.get_builder(Packer::Builder::DOCKER) }
19
+
20
+ describe '#initialize' do
21
+ it 'has a type of docker' do
22
+ expect(builder.data['type']).to eq(Packer::Builder::DOCKER)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,44 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::Builder::VirtualBoxISO do
18
+ let(:builder) { Packer::Builder.get_builder(Packer::Builder::VIRTUALBOX_ISO) }
19
+ let(:in_commands_strings) { [["command1", "1"], ["command2", "2"]] }
20
+ let(:in_commands_mixed) { [["command1", 1 ], ["command2", 2 ]] }
21
+ let(:out_commands_strings) { [["command1", "1"], ["command2", "2"]] }
22
+
23
+ describe '#initialize' do
24
+ it 'has a type of virtualbox-iso' do
25
+ expect(builder.data['type']).to eq(Packer::Builder::VIRTUALBOX_ISO)
26
+ end
27
+ end
28
+
29
+ describe '#vboxmanage' do
30
+ it 'builds an array of arrays of strings' do
31
+ builder.vboxmanage(in_commands_mixed)
32
+ expect( builder.data['vboxmanage'] ).to eq(out_commands_strings)
33
+ builder.data.delete('vboxmanage')
34
+ end
35
+ end
36
+
37
+ describe '#vboxmanage_post' do
38
+ it 'builds an array of arrays of strings' do
39
+ builder.vboxmanage_post(in_commands_mixed)
40
+ expect( builder.data['vboxmanage_post'] ).to eq(out_commands_strings)
41
+ builder.data.delete('vboxmanage_post')
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,239 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::DataObject do
18
+ let(:dataobject) { Packer::DataObject.new }
19
+ let(:some_string) { 'some string' }
20
+ let(:keys) { %w[key1 key2] }
21
+ let(:some_array_of_strings) { %w[value1 value2 value3] }
22
+ let(:some_array_of_ints) { [1, 2, 3] }
23
+ let(:some_hash_of_mixed) { { 'a' => 1, 'b' => 2 } }
24
+ let(:some_hash_of_strings) { { 'a' => '1', 'b' => '2' } }
25
+ let(:in_commands_strings) { [["command1", "1"], ["command2", "2"]] }
26
+ let(:in_commands_mixed) { [["command1", 1 ], ["command2", 2 ]] }
27
+ let(:out_commands_strings) { [["command1", "1"], ["command2", "2"]] }
28
+
29
+ describe "#initialize" do
30
+ it 'has a data hash' do
31
+ expect(dataobject.data).to eq({})
32
+ end
33
+ end
34
+
35
+ describe '#add_required' do
36
+ it 'tracks required settings' do
37
+ dataobject.add_required('a', 'b')
38
+ dataobject.add_required(['c', 'd'])
39
+ expect(dataobject.required).to eq(['a', 'b', ['c', 'd']])
40
+ end
41
+ end
42
+
43
+ describe '#validate' do
44
+ it 'returns true when all required settings are present' do
45
+ dataobject.add_required('key')
46
+ dataobject.__add_string('key', 'value')
47
+ expect(dataobject.validate).to be_truthy
48
+ dataobject.data = []
49
+ dataobject.required = []
50
+ end
51
+
52
+ it 'raises an error when a required setting is missing' do
53
+ dataobject.add_required('key')
54
+ expect { dataobject.validate }.to raise_error
55
+ dataobject.data = []
56
+ dataobject.required = []
57
+ end
58
+
59
+ it 'returns true when exactly one setting from an exclusive set is preset' do
60
+ dataobject.add_required(['key1', 'key2'])
61
+ dataobject.__add_string('key1', 'value')
62
+ expect(dataobject.validate).to be_truthy
63
+ dataobject.data = []
64
+ dataobject.required = []
65
+ end
66
+
67
+ it 'raises an error when no settings from an exclusive set are present' do
68
+ dataobject.add_required(['key1', 'key2'])
69
+ expect { dataobject.validate }.to raise_error
70
+ dataobject.data = []
71
+ dataobject.required = []
72
+ end
73
+
74
+ it 'raises an error when more than one setting from an exclusive set is present' do
75
+ dataobject.add_required(['key1', 'key2'])
76
+ dataobject.__add_string('key1', 'value')
77
+ dataobject.__add_string('key2', 'value')
78
+ expect { dataobject.validate }.to raise_error
79
+ dataobject.data = []
80
+ dataobject.required = []
81
+ end
82
+
83
+ it 'returns true when there are no required settings to validate' do
84
+ expect(dataobject.validate).to be_truthy
85
+ end
86
+ end
87
+
88
+ describe '#deep_copy' do
89
+ it 'retuns a full copy of the data structure' do
90
+ dataobject.__add_string('key', 'foo')
91
+ copy = dataobject.deep_copy
92
+ expect(copy).to eq(dataobject.data)
93
+ expect(copy).not_to be(dataobject.data)
94
+ copy['key'] << 'bar'
95
+ expect(copy).not_to eq(dataobject.data)
96
+ dataobject.data.delete('key')
97
+ end
98
+ end
99
+
100
+ describe "#__exclusive_key_error" do
101
+ it 'returns true when the key is exclusive' do
102
+ dataobject.data[keys[0]] = 'value'
103
+ expect(dataobject.__exclusive_key_error(keys[0], keys[1..-1])).to be_truthy
104
+ dataobject.data.delete(keys[0])
105
+ end
106
+
107
+ it 'raises an error when the key is not exclusive' do
108
+ dataobject.data[keys[0]] = 'value'
109
+ dataobject.data[keys[1]] = 'value'
110
+ expect { dataobject.__exclusive_key_error(keys[0], keys[1..-1]) }.to raise_error
111
+ dataobject.data.delete(keys)
112
+ end
113
+ end
114
+
115
+ describe '#__add_array_of_strings' do
116
+ it 'assigns an array of strings to key' do
117
+ dataobject.__add_array_of_strings('key', some_array_of_strings)
118
+ expect(dataobject.data['key']).to eq(some_array_of_strings)
119
+ dataobject.data.delete('key')
120
+ end
121
+
122
+ it 'converts an array of non-strings to strings and assigns them to key' do
123
+ dataobject.__add_array_of_strings('key', some_array_of_ints)
124
+ expect(dataobject.data['key']).to eq(some_array_of_ints.map{ |c| c.to_s })
125
+ dataobject.data.delete('key')
126
+ end
127
+
128
+ it 'raises an error if the values cannot be turned in to an Array' do
129
+ expect { dataobject.__add_array_of_strings('key', 'some string') }.to raise_error
130
+ end
131
+ end
132
+
133
+ describe "#__add_array_of_array_of_strings" do
134
+ it 'assigns an array of array of strings to key' do
135
+ dataobject.__add_array_of_array_of_strings('key', in_commands_strings)
136
+ expect(dataobject.data['key']).to eq(out_commands_strings)
137
+ dataobject.data.delete('key')
138
+ end
139
+
140
+ it 'converts non-strings to strings in the sub-arrays during assignment to key' do
141
+ dataobject.__add_array_of_array_of_strings('key', in_commands_mixed)
142
+ expect(dataobject.data['key']).to eq(out_commands_strings)
143
+ dataobject.data.delete('key')
144
+ end
145
+
146
+ it 'raises an error if the values argument is not an array' do
147
+ expect { dataobject.__add_array_of_array_of_strings('key', 'some string') }.to raise_error
148
+ end
149
+
150
+ it 'raises an error if any element in the values argument is not an array' do
151
+ expect { dataobject.__add_array_of_array_of_strings('key', [['legal'], 'illegal']) }.to raise_error
152
+ end
153
+ end
154
+
155
+ describe '#__add_string' do
156
+ it 'accepts a string' do
157
+ dataobject.__add_string('key', some_string)
158
+ expect(dataobject.data['key']).to eq(some_string)
159
+ dataobject.data.delete('key')
160
+ end
161
+
162
+ it 'converts any argument passed to a string' do
163
+ dataobject.__add_string('key', some_array_of_ints)
164
+ expect(dataobject.data['key']).to eq(some_array_of_ints.to_s)
165
+ dataobject.data.delete('key')
166
+ end
167
+ end
168
+
169
+ describe '#__add_integer' do
170
+ it 'accepts anything that can be converted to an integer with #to_i' do
171
+ dataobject.__add_integer(keys[0], 1)
172
+ dataobject.__add_integer(keys[1], "2")
173
+ expect(dataobject.data[keys[0]]).to eq(1)
174
+ expect(dataobject.data[keys[1]]).to eq(2)
175
+ dataobject.data.delete(keys)
176
+ end
177
+
178
+ it 'raises an error if the value cannot be converted to an integer with #to_i' do
179
+ expect { dataobject.__add_integer('key', StandardError.new("not convertable")) }.to raise_error
180
+ end
181
+ end
182
+
183
+ describe '#__add_boolean' do
184
+ it 'accepts any truthy value and converts it to true' do
185
+ dataobject.__add_boolean('key', some_string)
186
+ expect(dataobject.data['key']).to be_truthy
187
+ dataobject.data.delete('key')
188
+ end
189
+
190
+ it 'accepts any non-truthy value and converts it to false' do
191
+ dataobject.__add_boolean('key', false)
192
+ expect(dataobject.data['key']).to be_falsey
193
+ dataobject.data.delete('key')
194
+ end
195
+ end
196
+
197
+ describe '#__add_hash' do
198
+ it 'assigns a hash to a key' do
199
+ dataobject.__add_hash('key', some_hash_of_strings)
200
+ expect(dataobject.data['key']).to eq(some_hash_of_strings)
201
+ dataobject.data.delete('key')
202
+ end
203
+
204
+ it 'converts a hash of non-strings to strings and assigns them to key' do
205
+ dataobject.__add_hash('key', some_hash_of_mixed)
206
+ expect(dataobject.data['key']).to eq(some_hash_of_strings)
207
+ dataobject.data.delete('key')
208
+ end
209
+
210
+ it 'raises an error if the values argument is not a Hash' do
211
+ expect { dataobject.__add_hash('key', 'some string') }.to raise_error
212
+ end
213
+ end
214
+
215
+ describe '#__add_array_of_hashes' do
216
+ it 'assigns an array of hashes to a key' do
217
+ array = [some_hash_of_strings, some_hash_of_strings]
218
+ dataobject.__add_array_of_hashes('key', array)
219
+ expect(dataobject.data['key']).to eq(array)
220
+ dataobject.data.delete('key')
221
+ end
222
+
223
+ it 'converts non-strings in the hashes to strings during assignment to key' do
224
+ array = [some_hash_of_mixed, some_hash_of_mixed]
225
+ dataobject.__add_array_of_hashes('key', array)
226
+ expect(dataobject.data['key']).to eq([some_hash_of_strings, some_hash_of_strings])
227
+ dataobject.data.delete('key')
228
+ end
229
+
230
+ it 'raises an error if the values argument is not an array' do
231
+ expect { dataobject.__add_array_of_hashes('key', 'some string') }.to raise_error
232
+ end
233
+
234
+ it 'raises an error if any element in the values argument is not a Hash' do
235
+ expect { dataobject.__add_array_of_hashes('key', [some_hash_of_strings, 'illegal']) }.to raise_error
236
+ end
237
+ end
238
+
239
+ end
@@ -0,0 +1,38 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::EnvVar do
18
+ let(:envvar) do
19
+ Packer::EnvVar.new
20
+ end
21
+
22
+ it 'returns a packer.io envvar string for any method' do
23
+ expect(envvar.FOO).to eq("{{env `FOO`}}")
24
+ expect(envvar.BAR).to eq("{{env `BAR`}}")
25
+ expect(envvar.MOO).to eq("{{env `MOO`}}")
26
+ end
27
+
28
+ it 'never changes the capitalization of the env var' do
29
+ expect(envvar.foo).to eq("{{env `foo`}}")
30
+ expect(envvar.Foo).to eq("{{env `Foo`}}")
31
+ expect(envvar.fOo).to eq("{{env `fOo`}}")
32
+ end
33
+
34
+ it 'responds to anything' do
35
+ expect(envvar.respond_to? 'anything').to be_truthy
36
+ expect(envvar.respond_to? 'anything_else').to be_truthy
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::Macro do
18
+ let(:macro) do
19
+ Packer::Macro.new
20
+ end
21
+
22
+ it 'returns a packer.io macro string for any method' do
23
+ expect(macro.Foo).to eq("{{ .Foo }}")
24
+ expect(macro.Bar).to eq("{{ .Bar }}")
25
+ expect(macro.Moo).to eq("{{ .Moo }}")
26
+ end
27
+
28
+ it 'always capitalizes the first letter in the macro' do
29
+ expect(macro.foo).to eq("{{ .Foo }}")
30
+ expect(macro.Foo).to eq("{{ .Foo }}")
31
+ expect(macro.fOo).to eq("{{ .FOo }}")
32
+ end
33
+
34
+ it 'responds to anything' do
35
+ expect(macro.respond_to? 'anything').to be_truthy
36
+ expect(macro.respond_to? 'anything_else').to be_truthy
37
+ end
38
+ end
@@ -0,0 +1,72 @@
1
+ # Encoding: utf-8
2
+ # Copyright 2014 Ian Chesal
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ require 'spec_helper'
16
+
17
+ RSpec.describe Packer::PostProcessor do
18
+ POSTPROCESSOR_TYPE = 'vagrant'
19
+
20
+ let(:postprocessor) do
21
+ Packer::PostProcessor.new
22
+ end
23
+
24
+ let(:overrides) do
25
+ {
26
+ "key1" => "value1",
27
+ "key2" => "value2"
28
+ }
29
+ end
30
+
31
+ describe '.get_postprocessor' do
32
+ it 'returns a post-processor' do
33
+ expect(Packer::PostProcessor.get_postprocessor(POSTPROCESSOR_TYPE)).to be_a_kind_of(Packer::PostProcessor)
34
+ end
35
+
36
+ it 'raises an error when the post-processor type is not recognized' do
37
+ expect { Packer::PostProcessor.get_postprocessor('unknown-type') }.to raise_error
38
+ end
39
+ end
40
+
41
+ describe '#only' do
42
+ it 'adds an only exception' do
43
+ postprocessor.only('thing1')
44
+ expect(postprocessor.data['only']).to eq(%w[thing1])
45
+ postprocessor.only('thing2')
46
+ expect(postprocessor.data['only']).to eq(%w[thing1 thing2])
47
+ end
48
+ end
49
+
50
+ describe '#except' do
51
+ it 'adds an execpt exception' do
52
+ postprocessor.except('thing3')
53
+ expect(postprocessor.data['except']).to eq(%w[thing3])
54
+ postprocessor.except('thing4')
55
+ expect(postprocessor.data['except']).to eq(%w[thing3 thing4])
56
+ end
57
+ end
58
+
59
+ describe '#keep_input_artifact' do
60
+ it 'accepts any truthy value and converts it to true' do
61
+ postprocessor.keep_input_artifact('this is true')
62
+ expect(postprocessor.data['keep_input_artifact']).to be_truthy
63
+ postprocessor.data.delete('keep_input_artifact')
64
+ end
65
+
66
+ it 'accepts any non-truthy value and converts it to false' do
67
+ postprocessor.keep_input_artifact(false)
68
+ expect(postprocessor.data['keep_input_artifact']).to be_falsey
69
+ postprocessor.data.delete('keep_input_artifact')
70
+ end
71
+ end
72
+ end