packer-config 0.0.3

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.
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