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.
- checksums.yaml +7 -0
- data/.gitignore +36 -0
- data/.rubocop.yml +340 -0
- data/.travis.yml +6 -0
- data/Gemfile +17 -0
- data/LICENSE +176 -0
- data/README.md +107 -0
- data/Rakefile +47 -0
- data/TODO.md +8 -0
- data/lib/packer-config.rb +181 -0
- data/lib/packer/builder.rb +65 -0
- data/lib/packer/builders/all.rb +17 -0
- data/lib/packer/builders/amazon.rb +214 -0
- data/lib/packer/builders/docker.rb +47 -0
- data/lib/packer/builders/virtualbox.rb +169 -0
- data/lib/packer/dataobject.rb +128 -0
- data/lib/packer/envvar.rb +27 -0
- data/lib/packer/macro.rb +28 -0
- data/lib/packer/postprocessor.rb +77 -0
- data/lib/packer/postprocessors/all.rb +16 -0
- data/lib/packer/postprocessors/docker.rb +35 -0
- data/lib/packer/postprocessors/vagrant.rb +47 -0
- data/lib/packer/provisioner.rb +86 -0
- data/lib/packer/provisioners/all.rb +16 -0
- data/lib/packer/provisioners/file.rb +36 -0
- data/lib/packer/provisioners/shell.rb +60 -0
- data/packer-config.gemspec +46 -0
- data/spec/integration/README.md +14 -0
- data/spec/integration/builds/.gitignore +4 -0
- data/spec/integration/centos_vagrant_spec.rb +76 -0
- data/spec/integration/packer_cache/.gitignore +4 -0
- data/spec/integration/scripts/chef.sh +199 -0
- data/spec/integration/scripts/cleanup.sh +17 -0
- data/spec/integration/scripts/fix-slow-dns.sh +13 -0
- data/spec/integration/scripts/hello.sh +3 -0
- data/spec/integration/scripts/kickstart/centos-6.5-ks.cfg +71 -0
- data/spec/integration/scripts/minimize.sh +9 -0
- data/spec/integration/scripts/sshd.sh +6 -0
- data/spec/integration/scripts/vagrant.sh +10 -0
- data/spec/integration/scripts/vmtools.sh +39 -0
- data/spec/packer/builder_spec.rb +39 -0
- data/spec/packer/builders/amazon_spec.rb +88 -0
- data/spec/packer/builders/docker_spec.rb +25 -0
- data/spec/packer/builders/virtualbox_spec.rb +44 -0
- data/spec/packer/dataobject_spec.rb +239 -0
- data/spec/packer/envvar_spec.rb +38 -0
- data/spec/packer/macro_spec.rb +38 -0
- data/spec/packer/postprocessor_spec.rb +72 -0
- data/spec/packer/postprocessors/docker_import_spec.rb +27 -0
- data/spec/packer/postprocessors/docker_push_spec.rb +27 -0
- data/spec/packer/postprocessors/vagrant_spec.rb +27 -0
- data/spec/packer/provisioner_spec.rb +78 -0
- data/spec/packer/provisioners/file_spec.rb +63 -0
- data/spec/packer/provisioners/shell_spec.rb +116 -0
- data/spec/packer_config_spec.rb +197 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/unit_helper.rb +15 -0
- metadata +220 -0
@@ -0,0 +1,47 @@
|
|
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 'packer/builder'
|
16
|
+
require 'packer/dataobject'
|
17
|
+
|
18
|
+
module Packer
|
19
|
+
class Builder < Packer::DataObject
|
20
|
+
class Docker < Builder
|
21
|
+
def initialize
|
22
|
+
super
|
23
|
+
self.data['type'] = DOCKER
|
24
|
+
self.add_required(
|
25
|
+
'export_path',
|
26
|
+
'image'
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def export_path(path)
|
31
|
+
self.__add_string('export_path', path)
|
32
|
+
end
|
33
|
+
|
34
|
+
def image(name)
|
35
|
+
self.__add_string('image', name)
|
36
|
+
end
|
37
|
+
|
38
|
+
def pull(bool)
|
39
|
+
self.__add_boolean('pull', bool)
|
40
|
+
end
|
41
|
+
|
42
|
+
def run_command(commands)
|
43
|
+
self.__add_array_of_strings('run_command', commands)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,169 @@
|
|
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 'packer/builder'
|
16
|
+
require 'packer/dataobject'
|
17
|
+
|
18
|
+
module Packer
|
19
|
+
class Builder < Packer::DataObject
|
20
|
+
class VirtualBoxISO < Builder
|
21
|
+
def initialize
|
22
|
+
super
|
23
|
+
self.data['type'] = VIRTUALBOX_ISO
|
24
|
+
self.add_required(
|
25
|
+
'iso_checksum',
|
26
|
+
'iso_checksum_type',
|
27
|
+
'iso_url',
|
28
|
+
'ssh_username'
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def iso_checksum(checksum)
|
33
|
+
self.__add_string('iso_checksum', checksum)
|
34
|
+
end
|
35
|
+
|
36
|
+
def iso_checksum_type(type)
|
37
|
+
self.__add_string('iso_checksum_type', type)
|
38
|
+
end
|
39
|
+
|
40
|
+
def iso_url(url)
|
41
|
+
self.__add_string('iso_url', url, %w[iso_urls])
|
42
|
+
end
|
43
|
+
|
44
|
+
def iso_urls(urls)
|
45
|
+
self.__add_array_of_strings('iso_urls', urls, %[iso_url])
|
46
|
+
end
|
47
|
+
|
48
|
+
def ssh_username(username)
|
49
|
+
self.__add_string('ssh_username', username)
|
50
|
+
end
|
51
|
+
|
52
|
+
def boot_command(commands)
|
53
|
+
self.__add_array_of_strings('boot_command', commands)
|
54
|
+
end
|
55
|
+
|
56
|
+
def boot_wait(time)
|
57
|
+
self.__add_string('boot_wait',time)
|
58
|
+
end
|
59
|
+
|
60
|
+
def disk_size(megabytes)
|
61
|
+
self.__add_integer('disk_size', megabytes)
|
62
|
+
end
|
63
|
+
|
64
|
+
def export_opts(vboxmanage_export_options)
|
65
|
+
self.__add_array_of_strings('export_opts', vboxmanage_export_options)
|
66
|
+
end
|
67
|
+
|
68
|
+
def floppy_files(files)
|
69
|
+
self.__add_array_of_strings('floppy_files', files)
|
70
|
+
end
|
71
|
+
|
72
|
+
def format(format)
|
73
|
+
self.__add_string('format', format)
|
74
|
+
end
|
75
|
+
|
76
|
+
def guest_additions_mode(mode)
|
77
|
+
self.__add_string('guest_additions_mode', mode)
|
78
|
+
end
|
79
|
+
|
80
|
+
def guest_additions_path(path)
|
81
|
+
self.__add_string('guest_additions_path', path)
|
82
|
+
end
|
83
|
+
|
84
|
+
def guest_additions_sha256(checksum)
|
85
|
+
self.__add_string('guest_additions_sha256', checksum)
|
86
|
+
end
|
87
|
+
|
88
|
+
def guest_additions_url(url)
|
89
|
+
self.__add_string('guest_additions_url', url)
|
90
|
+
end
|
91
|
+
|
92
|
+
def guest_os_type(ostype)
|
93
|
+
self.__add_string('guest_os_type', ostype)
|
94
|
+
end
|
95
|
+
|
96
|
+
def hard_drive_interface(controllertype)
|
97
|
+
self.__add_string('hard_drive_interface', controllertype)
|
98
|
+
end
|
99
|
+
|
100
|
+
def headless(bool)
|
101
|
+
self.__add_boolean('headless', bool)
|
102
|
+
end
|
103
|
+
|
104
|
+
def http_directory(directory)
|
105
|
+
self.__add_string('http_directory', directory)
|
106
|
+
end
|
107
|
+
|
108
|
+
def http_port_min(port_number)
|
109
|
+
self.__add_integer('http_port_min', port_number)
|
110
|
+
end
|
111
|
+
|
112
|
+
def http_port_max(port_number)
|
113
|
+
self.__add_integer('http_port_max', port_number)
|
114
|
+
end
|
115
|
+
|
116
|
+
def output_directory(directory)
|
117
|
+
self.__add_string('output_directory', directory)
|
118
|
+
end
|
119
|
+
|
120
|
+
def shutdown_command(command)
|
121
|
+
self.__add_string('shutdown_command', command)
|
122
|
+
end
|
123
|
+
|
124
|
+
def shutdown_timeout(time)
|
125
|
+
self.__add_string('shutdown_timeout', time)
|
126
|
+
end
|
127
|
+
|
128
|
+
def ssh_host_port_min(port_number)
|
129
|
+
self.__add_integer('ssh_host_port_min', port_number)
|
130
|
+
end
|
131
|
+
|
132
|
+
def ssh_host_port_max(port_number)
|
133
|
+
self.__add_integer('ssh_host_port_max', port_number)
|
134
|
+
end
|
135
|
+
|
136
|
+
def ssh_key_path(path)
|
137
|
+
self.__add_string('ssh_key_path', path)
|
138
|
+
end
|
139
|
+
|
140
|
+
def ssh_password(password)
|
141
|
+
self.__add_string('ssh_password', password)
|
142
|
+
end
|
143
|
+
|
144
|
+
def ssh_port(port_number)
|
145
|
+
self.__add_integer('ssh_port', port_number)
|
146
|
+
end
|
147
|
+
|
148
|
+
def ssh_wait_timeout(time)
|
149
|
+
self.__add_string('ssh_wait_timeout', time)
|
150
|
+
end
|
151
|
+
|
152
|
+
def vboxmanage(array_of_commands)
|
153
|
+
self.__add_array_of_array_of_strings('vboxmanage', array_of_commands)
|
154
|
+
end
|
155
|
+
|
156
|
+
def vboxmanage_post(array_of_commands)
|
157
|
+
self.__add_array_of_array_of_strings('vboxmanage_post', array_of_commands)
|
158
|
+
end
|
159
|
+
|
160
|
+
def virtualbox_version_file(file)
|
161
|
+
self.__add_string('virtualbox_version_file', file)
|
162
|
+
end
|
163
|
+
|
164
|
+
def vm_name(name)
|
165
|
+
self.__add_string('vm_name', name)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,128 @@
|
|
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
|
+
|
16
|
+
module Packer
|
17
|
+
class DataObject
|
18
|
+
|
19
|
+
attr_accessor :data
|
20
|
+
attr_accessor :required
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
self.data = {}
|
24
|
+
self.required = []
|
25
|
+
end
|
26
|
+
|
27
|
+
class DataValidationError < StandardError
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate
|
31
|
+
self.required.each do |r|
|
32
|
+
if (r.is_a? Array) && (r.length > 0)
|
33
|
+
if r.length - (r - self.data.keys).length == 0
|
34
|
+
raise DataValidationError.new("Missing one required setting from the set #{r}")
|
35
|
+
end
|
36
|
+
if r.length - (r - self.data.keys).length > 1
|
37
|
+
raise DataValidationError.new("Found more than one exclusive setting in data from set #{r}")
|
38
|
+
end
|
39
|
+
else
|
40
|
+
if ! self.data.keys.include? r
|
41
|
+
raise DataValidationError.new("Missing required setting #{r}")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
# TODO(ianc) Also validate the data with the packer command?
|
46
|
+
true
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_required(*keys)
|
50
|
+
keys.each do |k|
|
51
|
+
self.required.push(k)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def deep_copy
|
56
|
+
Marshal.load(Marshal.dump(self.data))
|
57
|
+
end
|
58
|
+
|
59
|
+
class ExclusiveKeyError < StandardError
|
60
|
+
end
|
61
|
+
|
62
|
+
def __exclusive_key_error(key, exclusives)
|
63
|
+
exclusives.each do |e|
|
64
|
+
if self.data.has_key? e
|
65
|
+
raise ExclusiveKeyError.new("Only one of #{exclusives} can be used at a time")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
def __add_array_of_strings(key, values, exclusives = [])
|
72
|
+
self.__exclusive_key_error(key, exclusives)
|
73
|
+
raise TypeError.new() unless Array.try_convert(values)
|
74
|
+
self.data[key.to_s] = values.to_ary.map{ |c| c.to_s }
|
75
|
+
end
|
76
|
+
|
77
|
+
def __add_array_of_array_of_strings(key, values, exclusives = [])
|
78
|
+
self.__exclusive_key_error(key, exclusives)
|
79
|
+
raise TypeError.new() unless Array.try_convert(values)
|
80
|
+
self.data[key.to_s] = []
|
81
|
+
values.each do |v|
|
82
|
+
raise TypeError.new() unless Array.try_convert(v)
|
83
|
+
self.data[key.to_s].push(v.to_ary.map{ |c| c.to_s })
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def __add_array_of_hashes(key, values, exclusives = [])
|
88
|
+
self.__exclusive_key_error(key, exclusives)
|
89
|
+
raise TypeError.new() unless Array.try_convert(values)
|
90
|
+
self.data[key.to_s] = []
|
91
|
+
values.each do |v|
|
92
|
+
raise TypeError.new() unless v.is_a?(Hash)
|
93
|
+
self.data[key.to_s].push({})
|
94
|
+
v.keys.each do |k|
|
95
|
+
self.data[key.to_s][-1][k] = v[k].to_s
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def __add_string(key, data, exclusives = [])
|
101
|
+
self.__exclusive_key_error(key, exclusives)
|
102
|
+
self.data[key.to_s] = data.to_s
|
103
|
+
end
|
104
|
+
|
105
|
+
def __add_integer(key, data, exclusives = [])
|
106
|
+
self.__exclusive_key_error(key, exclusives)
|
107
|
+
self.data[key.to_s] = data.to_i
|
108
|
+
end
|
109
|
+
|
110
|
+
def __add_boolean(key, bool, exclusives = [])
|
111
|
+
self.__exclusive_key_error(key, exclusives)
|
112
|
+
if bool
|
113
|
+
self.data[key.to_s] = true
|
114
|
+
else
|
115
|
+
self.data[key.to_s] = false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def __add_hash(key, data, exclusives = [])
|
120
|
+
self.__exclusive_key_error(key, exclusives)
|
121
|
+
raise TypeError.new() unless data.is_a?(Hash)
|
122
|
+
self.data[key.to_s] = {}
|
123
|
+
data.keys.each do |k|
|
124
|
+
self.data[key.to_s][k] = data[k].to_s
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,27 @@
|
|
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
|
+
|
16
|
+
module Packer
|
17
|
+
class EnvVar
|
18
|
+
def method_missing(method_name, *args)
|
19
|
+
"{{env `#{method_name}`}}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def respond_to?(symbol, include_private=false)
|
23
|
+
# We literally respond to everything...
|
24
|
+
true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/packer/macro.rb
ADDED
@@ -0,0 +1,28 @@
|
|
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
|
+
|
16
|
+
module Packer
|
17
|
+
class Macro
|
18
|
+
def method_missing(method_name, *args)
|
19
|
+
name = method_name.to_s.slice(0,1).capitalize + method_name.to_s.slice(1..-1)
|
20
|
+
"{{ .#{name} }}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def respond_to?(symbol, include_private=false)
|
24
|
+
# We literally respond to everything...
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,77 @@
|
|
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 'packer/postprocessors/all'
|
16
|
+
require 'packer/dataobject'
|
17
|
+
|
18
|
+
module Packer
|
19
|
+
class PostProcessor < Packer::DataObject
|
20
|
+
|
21
|
+
DOCKER_IMPORT = 'docker-import'
|
22
|
+
DOCKER_PUSH = 'docker-push'
|
23
|
+
VAGRANT = 'vagrant'
|
24
|
+
|
25
|
+
VALID_POST_PROCESSOR_TYPES = [
|
26
|
+
DOCKER_IMPORT,
|
27
|
+
DOCKER_PUSH,
|
28
|
+
VAGRANT
|
29
|
+
]
|
30
|
+
|
31
|
+
class UnrecognizedPostProcessorTypeError < StandardError
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.get_postprocessor(type)
|
35
|
+
unless validate_type(type)
|
36
|
+
raise UnrecognizedPostProcessorTypeError.new("Unrecognized post-processor type #{type}")
|
37
|
+
end
|
38
|
+
{
|
39
|
+
DOCKER_IMPORT => Packer::PostProcessor::DockerImport,
|
40
|
+
DOCKER_PUSH => Packer::PostProcessor::DockerPush,
|
41
|
+
VAGRANT => Packer::PostProcessor::Vagrant
|
42
|
+
}.fetch(type).new
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.types
|
46
|
+
VALID_POST_PROCESSOR_TYPES
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize
|
50
|
+
super
|
51
|
+
self.add_required('type')
|
52
|
+
end
|
53
|
+
|
54
|
+
def only(buildname)
|
55
|
+
unless self.data.has_key? 'only'
|
56
|
+
self.data['only'] = []
|
57
|
+
end
|
58
|
+
self.data['only'] << buildname.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
def except(buildname)
|
62
|
+
unless self.data.has_key? 'except'
|
63
|
+
self.data['except'] = []
|
64
|
+
end
|
65
|
+
self.data['except'] << buildname.to_s
|
66
|
+
end
|
67
|
+
|
68
|
+
def keep_input_artifact(bool)
|
69
|
+
self.__add_boolean('keep_input_artifact', bool)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
def self.validate_type(type)
|
74
|
+
VALID_POST_PROCESSOR_TYPES.include? type
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|