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
data/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# packer-config
|
2
|
+
|
3
|
+
A Ruby model that lets you build [Packer](http://packer.io) configurations in Ruby.
|
4
|
+
|
5
|
+
Building the Packer JSON configurations in raw JSON can be quite an adventure.
|
6
|
+
There's limited facilities for variable expansion and absolutely no support for
|
7
|
+
nice things like comments. I decided it would just be easier to have an object
|
8
|
+
model to build the Packer configurations in that would easily write to the
|
9
|
+
correct JSON format. It also saved me having to remember the esoteric Packer
|
10
|
+
syntax for referencing variables and whatnot in the JSON.
|
11
|
+
|
12
|
+
Bonus: you can really go to town with templates when it's all done it Ruby.
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
gem install packer-config
|
17
|
+
|
18
|
+
## Examples
|
19
|
+
|
20
|
+
### Packing a Vagrant Basebox from a CentOS ISO Using VirtualBox
|
21
|
+
|
22
|
+
This example is based on the integration test [spec/integration/centos_vagrant_spec.rb](spec/integration/centos_vagrant_spec.rb). It produces a Vagrant Basebox that's provisionable with [Chef](http://www.getchef.com/) and the packer config and provisioning is taken from the [Bento](https://github.com/opscode/bento) project from the OpsCode crew.
|
23
|
+
|
24
|
+
OS = 'centos-6.5'
|
25
|
+
|
26
|
+
pconfig = Packer::Config.new "#{OS}-vagrant.json"
|
27
|
+
pconfig.description "#{OS} VirtualBox Vagrant"
|
28
|
+
pconfig.add_variable 'mirror', 'http://mirrors.kernel.org/centos'
|
29
|
+
pconfig.add_variable 'my_version', '0.0.1'
|
30
|
+
pconfig.add_variable 'chef_version', 'latest'
|
31
|
+
|
32
|
+
builder = pconfig.add_builder Packer::Builder::VIRTUALBOX_ISO
|
33
|
+
builder.boot_command ["<tab> text ks=http://#{pconfig.macro.HTTPIP}:#{pconfig.macro.HTTPPort}/#{OS}-ks.cfg<enter><wait>"]
|
34
|
+
builder.boot_wait '10s'
|
35
|
+
builder.disk_size 40960
|
36
|
+
builder.guest_additions_path "VBoxGuestAdditions_#{pconfig.macro.Version}.iso"
|
37
|
+
builder.guest_os_type "RedHat_64"
|
38
|
+
builder.http_directory "scripts/kickstart"
|
39
|
+
builder.iso_checksum '32c7695b97f7dcd1f59a77a71f64f2957dddf738'
|
40
|
+
builder.iso_checksum_type 'sha1'
|
41
|
+
builder.iso_url "#{pconfig.variable 'mirror'}/6.5/isos/x86_64/CentOS-6.5-x86_64-bin-DVD1.iso"
|
42
|
+
builder.output_directory "#{OS}-x86_64-virtualbox"
|
43
|
+
builder.shutdown_command "echo 'vagrant'|sudo -S /sbin/halt -h -p"
|
44
|
+
builder.ssh_password "vagrant"
|
45
|
+
builder.ssh_port 22
|
46
|
+
builder.ssh_username "vagrant"
|
47
|
+
builder.ssh_wait_timeout "10000s"
|
48
|
+
builder.vboxmanage [
|
49
|
+
[
|
50
|
+
"modifyvm",
|
51
|
+
pconfig.macro.Name,
|
52
|
+
"--memory",
|
53
|
+
"480"
|
54
|
+
],
|
55
|
+
[
|
56
|
+
"modifyvm",
|
57
|
+
pconfig.macro.Name,
|
58
|
+
"--cpus",
|
59
|
+
"1"
|
60
|
+
]
|
61
|
+
]
|
62
|
+
builder.virtualbox_version_file ".vbox_version"
|
63
|
+
builder.vm_name "packer-#{OS}-x86_64"
|
64
|
+
|
65
|
+
provisioner = pconfig.add_provisioner Packer::Provisioner::FILE
|
66
|
+
provisioner.source 'scripts/hello.sh'
|
67
|
+
provisioner.destination '/home/vagrant/hello.sh'
|
68
|
+
|
69
|
+
provisioner = pconfig.add_provisioner Packer::Provisioner::SHELL
|
70
|
+
provisioner.scripts [
|
71
|
+
'scripts/fix-slow-dns.sh',
|
72
|
+
'scripts/sshd.sh',
|
73
|
+
'scripts/vagrant.sh',
|
74
|
+
'scripts/vmtools.sh',
|
75
|
+
'scripts/chef.sh',
|
76
|
+
'scripts/cleanup.sh',
|
77
|
+
'scripts/minimize.sh'
|
78
|
+
]
|
79
|
+
provisioner.environment_vars [
|
80
|
+
"CHEF_VERSION=#{pconfig.variable 'chef_version'}",
|
81
|
+
"MY_VERSION=#{pconfig.variable 'my_version'}"
|
82
|
+
]
|
83
|
+
provisioner.execute_command "echo 'vagrant' | #{pconfig.macro.Vars} sudo -S -E bash '#{pconfig.macro.Path}'"
|
84
|
+
|
85
|
+
postprocessor = pconfig.add_postprocessor Packer::PostProcessor::VAGRANT
|
86
|
+
postprocessor.output File.join('builds', pconfig.macro.Provider, "#{OS}-x86_64-#{pconfig.variable 'my_version'}.box")
|
87
|
+
|
88
|
+
pconfig.validate
|
89
|
+
pconfig.build
|
90
|
+
|
91
|
+
## Development
|
92
|
+
|
93
|
+
### Continuous Integration
|
94
|
+
|
95
|
+
I'm using Travis CI to build and test on every push to the public github repository. You can find the Travis CI page for this project here: https://travis-ci.org/ianchesal/packer-config/
|
96
|
+
|
97
|
+
### Branching in Git
|
98
|
+
|
99
|
+
I'm using [git-flow](http://nvie.com/posts/a-successful-git-branching-model/) for development in git via github. I've loved the branching model git-flow proposed from day one and the addon to git makes it very intuitive and easy to follow. I generally don't push my `feature/*` branches to the public repository; I do keep `development` and `master` up to date here though.
|
100
|
+
|
101
|
+
### TODO Work
|
102
|
+
|
103
|
+
Please see [TODO.md](TODO.md) for the short list of big things I thought worth writing down.
|
104
|
+
|
105
|
+
## Contact Me
|
106
|
+
|
107
|
+
Questions or comments about `packer-config`? Hit me up at ian.chesal@gmail.com or ianc@squareup.com.
|
data/Rakefile
ADDED
@@ -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
|
+
|
16
|
+
require 'rubocop/rake_task'
|
17
|
+
require 'rspec/core/rake_task'
|
18
|
+
require 'fileutils'
|
19
|
+
|
20
|
+
RuboCop::RakeTask.new(:lint)
|
21
|
+
|
22
|
+
task :default => [:lint, 'test:spec']
|
23
|
+
|
24
|
+
task :build => ['test:spec'] do
|
25
|
+
`gem build packer-config.gemspec`
|
26
|
+
end
|
27
|
+
|
28
|
+
namespace :test do
|
29
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
30
|
+
t.pattern = Dir['spec/**/*_spec.rb'].reject{ |f| f['/integration'] }
|
31
|
+
end
|
32
|
+
|
33
|
+
RSpec::Core::RakeTask.new(:integration) do |t|
|
34
|
+
t.pattern = "spec/integration/**/*_spec.rb"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
CLEAN = FileList['deployment_dir/**/*'].exclude('*.txt')
|
39
|
+
|
40
|
+
task :clean do
|
41
|
+
FileList['spec/integration/packer_cache/*'].each do |f|
|
42
|
+
FileUtils.rm_f(f)
|
43
|
+
end
|
44
|
+
Dir.glob('spec/integration/builds/*').select {|f| File.directory? f}.each do |d|
|
45
|
+
FileUtils.rm_rf(d)
|
46
|
+
end
|
47
|
+
end
|
data/TODO.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# TODO
|
2
|
+
|
3
|
+
* Add an option to Packer::Config#validate to run the configuration through packer's `validate` command
|
4
|
+
* Add spec tests for every method on every sub-class. Found during integration testing that some methods on the sub-classes had typos in the `__*` method calls. Spec tests would have caught this.
|
5
|
+
* Look in to something like VCR to drive the tests of the child classes -- there's a lot of repetitive testing that could be done on them.
|
6
|
+
* Add missing builders, provisioners and post-processors. I only implemented the builders, provisioners and post-processors that I'm currently using.
|
7
|
+
* Refactor the child classes. I get the feeling that these could be implemented in some better, templated, type of way
|
8
|
+
* Building can take a long time. Look in to a way to query the state of a build. Maybe return the stdout from it on query.
|
@@ -0,0 +1,181 @@
|
|
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 'json'
|
16
|
+
require 'open3'
|
17
|
+
require 'packer/dataobject'
|
18
|
+
require 'packer/builder'
|
19
|
+
require 'packer/provisioner'
|
20
|
+
require 'packer/postprocessor'
|
21
|
+
require 'packer/macro'
|
22
|
+
require 'packer/envvar'
|
23
|
+
|
24
|
+
module Packer
|
25
|
+
class Config < Packer::DataObject
|
26
|
+
|
27
|
+
VERSION = '0.0.2'
|
28
|
+
|
29
|
+
attr_accessor :builders
|
30
|
+
attr_accessor :postprocessors
|
31
|
+
attr_accessor :provisioners
|
32
|
+
attr_accessor :packer
|
33
|
+
attr_accessor :packer_options
|
34
|
+
attr_reader :macro
|
35
|
+
attr_reader :envvar
|
36
|
+
attr_reader :output_file
|
37
|
+
|
38
|
+
def initialize(file)
|
39
|
+
super()
|
40
|
+
self.data['variables'] = {}
|
41
|
+
self.output_file = file
|
42
|
+
self.builders = []
|
43
|
+
self.provisioners = []
|
44
|
+
self.postprocessors = []
|
45
|
+
self.packer = 'packer'
|
46
|
+
self.packer_options = []
|
47
|
+
self.macro = Macro.new
|
48
|
+
self.envvar = EnvVar.new
|
49
|
+
end
|
50
|
+
|
51
|
+
def validate
|
52
|
+
super
|
53
|
+
if self.builders.length == 0
|
54
|
+
raise DataValidationError.new("At least one builder is required")
|
55
|
+
end
|
56
|
+
self.builders.each do |thing|
|
57
|
+
thing.validate
|
58
|
+
end
|
59
|
+
self.provisioners.each do |thing|
|
60
|
+
thing.validate
|
61
|
+
end
|
62
|
+
self.postprocessors.each do |thing|
|
63
|
+
thing.validate
|
64
|
+
end
|
65
|
+
self.write
|
66
|
+
Dir.chdir(File.dirname(self.output_file)) do
|
67
|
+
cmd = [self.packer, 'validate', File.basename(self.output_file)].join(' ')
|
68
|
+
stdout, stderr, status = Open3.capture3(cmd)
|
69
|
+
raise PackerBuildError.new(stderr) unless status == 0
|
70
|
+
end
|
71
|
+
self.delete
|
72
|
+
end
|
73
|
+
|
74
|
+
class DumpError < StandardError
|
75
|
+
end
|
76
|
+
|
77
|
+
def dump(format='json', pretty=false)
|
78
|
+
data_copy = self.deep_copy
|
79
|
+
data_copy['builders'] = []
|
80
|
+
self.builders.each do |thing|
|
81
|
+
data_copy['builders'].push(thing.deep_copy)
|
82
|
+
end
|
83
|
+
if self.provisioners.length > 0
|
84
|
+
data_copy['provisioners'] = []
|
85
|
+
self.provisioners.each do |thing|
|
86
|
+
data_copy['provisioners'].push(thing.deep_copy)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
if self.postprocessors.length > 0
|
90
|
+
data_copy['post-processors'] = []
|
91
|
+
self.postprocessors.each do |thing|
|
92
|
+
data_copy['post-processors'].push(thing.deep_copy)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
case format
|
96
|
+
when 'json'
|
97
|
+
if pretty
|
98
|
+
JSON.pretty_generate(data_copy)
|
99
|
+
else
|
100
|
+
data_copy.to_json
|
101
|
+
end
|
102
|
+
else
|
103
|
+
raise DumpError.new("Unrecognized format #{format} use one of ['json']")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def write(format='json')
|
108
|
+
File.write(self.output_file, self.dump(format))
|
109
|
+
end
|
110
|
+
|
111
|
+
def delete
|
112
|
+
File.delete(self.output_file)
|
113
|
+
end
|
114
|
+
|
115
|
+
class PackerBuildError < StandardError
|
116
|
+
end
|
117
|
+
|
118
|
+
def build
|
119
|
+
self.validate
|
120
|
+
self.write
|
121
|
+
Dir.chdir(File.dirname(self.output_file)) do
|
122
|
+
cmd = [self.packer, 'build', self.packer_options, File.basename(self.output_file)].join(' ')
|
123
|
+
stdout, stderr, status = Open3.capture3(cmd)
|
124
|
+
raise PackerBuildError.new(stderr) unless status == 0
|
125
|
+
end
|
126
|
+
self.delete
|
127
|
+
end
|
128
|
+
|
129
|
+
def description(description)
|
130
|
+
self.__add_string('description', description)
|
131
|
+
end
|
132
|
+
|
133
|
+
def min_packer_version(version)
|
134
|
+
self.__add_string('min_packer_version', version)
|
135
|
+
end
|
136
|
+
|
137
|
+
def variables
|
138
|
+
self.data['variables']
|
139
|
+
end
|
140
|
+
|
141
|
+
def add_builder(type)
|
142
|
+
builder = Packer::Builder.get_builder(type)
|
143
|
+
self.builders.push(builder)
|
144
|
+
builder
|
145
|
+
end
|
146
|
+
|
147
|
+
def add_provisioner(type)
|
148
|
+
provisioner = Packer::Provisioner.get_provisioner(type)
|
149
|
+
self.provisioners.push(provisioner)
|
150
|
+
provisioner
|
151
|
+
end
|
152
|
+
|
153
|
+
def add_postprocessor(type)
|
154
|
+
postprocessor = Packer::PostProcessor.get_postprocessor(type)
|
155
|
+
self.postprocessors.push(postprocessor)
|
156
|
+
postprocessor
|
157
|
+
end
|
158
|
+
|
159
|
+
def add_variable(name, value)
|
160
|
+
variables_copy = Marshal.load(Marshal.dump(self.variables))
|
161
|
+
variables_copy[name.to_s] = value.to_s
|
162
|
+
self.__add_hash('variables', variables_copy)
|
163
|
+
end
|
164
|
+
|
165
|
+
class UndefinedVariableError < StandardError
|
166
|
+
end
|
167
|
+
|
168
|
+
def variable(name)
|
169
|
+
unless self.variables.has_key? name
|
170
|
+
raise UndefinedVariableError.new("No variable named #{name} has been defined -- did you forget to call add_variable?")
|
171
|
+
end
|
172
|
+
"{{user `#{name}`}}"
|
173
|
+
end
|
174
|
+
|
175
|
+
private
|
176
|
+
attr_writer :output_file
|
177
|
+
attr_writer :macro
|
178
|
+
attr_writer :envvar
|
179
|
+
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,65 @@
|
|
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/builders/all'
|
16
|
+
|
17
|
+
module Packer
|
18
|
+
class Builder < DataObject
|
19
|
+
|
20
|
+
AMAZON_EBS = 'amazon-ebs'
|
21
|
+
AMAZON_INSTANCE = 'amazon-instance'
|
22
|
+
DOCKER = 'docker'
|
23
|
+
VIRTUALBOX_ISO = 'virtualbox-iso'
|
24
|
+
|
25
|
+
VALID_BUILDER_TYPES = [
|
26
|
+
AMAZON_EBS,
|
27
|
+
AMAZON_INSTANCE,
|
28
|
+
DOCKER,
|
29
|
+
VIRTUALBOX_ISO
|
30
|
+
]
|
31
|
+
|
32
|
+
class UnrecognizedBuilderTypeError < StandardError
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.get_builder(type)
|
36
|
+
unless validate_type(type)
|
37
|
+
raise UnrecognizedBuilderTypeError.new("Unrecognized builder type #{type}")
|
38
|
+
end
|
39
|
+
{
|
40
|
+
AMAZON_EBS => Packer::Builder::Amazon::EBS,
|
41
|
+
AMAZON_INSTANCE => Packer::Builder::Amazon::Instance,
|
42
|
+
DOCKER => Packer::Builder::Docker,
|
43
|
+
VIRTUALBOX_ISO => Packer::Builder::VirtualBoxISO
|
44
|
+
}.fetch(type).new
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.types
|
48
|
+
VALID_BUILDER_TYPES
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize
|
52
|
+
super
|
53
|
+
self.add_required('type')
|
54
|
+
end
|
55
|
+
|
56
|
+
def name(name)
|
57
|
+
self.__add_string('name', name)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def self.validate_type(type)
|
62
|
+
VALID_BUILDER_TYPES.include? type
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,17 @@
|
|
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/builders/amazon'
|
16
|
+
require 'packer/builders/docker'
|
17
|
+
require 'packer/builders/virtualbox'
|
@@ -0,0 +1,214 @@
|
|
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 Amazon < Builder
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
super
|
24
|
+
self.add_required(
|
25
|
+
'ami_name',
|
26
|
+
'instance_type',
|
27
|
+
'region',
|
28
|
+
'source_ami',
|
29
|
+
'ssh_username'
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def access_key(key)
|
34
|
+
self.__add_string('access_key', key)
|
35
|
+
end
|
36
|
+
|
37
|
+
def ami_name(name)
|
38
|
+
self.__add_string('ami_name', name)
|
39
|
+
end
|
40
|
+
|
41
|
+
def instance_type(type)
|
42
|
+
self.__add_string('instance_type', type)
|
43
|
+
end
|
44
|
+
|
45
|
+
def region(name)
|
46
|
+
self.__add_string('region', name)
|
47
|
+
end
|
48
|
+
|
49
|
+
def source_ami(name)
|
50
|
+
self.__add_string('source_ami', name)
|
51
|
+
end
|
52
|
+
|
53
|
+
def ssh_username(username)
|
54
|
+
self.__add_string('ssh_username', username)
|
55
|
+
end
|
56
|
+
|
57
|
+
def secret_key(key)
|
58
|
+
self.__add_string('secret_key', key)
|
59
|
+
end
|
60
|
+
|
61
|
+
def ami_block_device_mappings(mappings)
|
62
|
+
self.__add_array_of_hashes('ami_block_device_mappings', mappings)
|
63
|
+
end
|
64
|
+
|
65
|
+
def ami_description(description)
|
66
|
+
self.__add_string('ami_description', description)
|
67
|
+
end
|
68
|
+
|
69
|
+
def ami_groups(groups)
|
70
|
+
self.__add_array_of_strings('ami_groups', groups)
|
71
|
+
end
|
72
|
+
|
73
|
+
def ami_product_codes(codes)
|
74
|
+
self.__add_array_of_strings('ami_product_codes', codes)
|
75
|
+
end
|
76
|
+
|
77
|
+
def ami_regions(regions)
|
78
|
+
self.__add_array_of_strings('ami_regions', regions)
|
79
|
+
end
|
80
|
+
|
81
|
+
def ami_users(users)
|
82
|
+
self.__add_array_of_strings('ami_users', users)
|
83
|
+
end
|
84
|
+
|
85
|
+
def ami_virtualization_type(type)
|
86
|
+
self.__add_string('ami_virtualization_type', type)
|
87
|
+
end
|
88
|
+
|
89
|
+
def associate_public_ip_address(bool)
|
90
|
+
self.__add_boolean('associate_public_ip_address', bool)
|
91
|
+
end
|
92
|
+
|
93
|
+
def availability_zone(zone)
|
94
|
+
self.__add_string('availability_zone', zone)
|
95
|
+
end
|
96
|
+
|
97
|
+
def enhanced_networking(bool)
|
98
|
+
self.__add_boolean('enhanced_networking', bool)
|
99
|
+
end
|
100
|
+
|
101
|
+
def iam_instance_profile(profile)
|
102
|
+
self.__add_string('iam_instance_profile', profile)
|
103
|
+
end
|
104
|
+
|
105
|
+
def launch_block_device_mappings(mappings)
|
106
|
+
self.__add_array_of_hashes('launch_block_device_mappings', mappings)
|
107
|
+
end
|
108
|
+
|
109
|
+
def run_tags(tags)
|
110
|
+
self.__add_hash('run_tags', tags)
|
111
|
+
end
|
112
|
+
|
113
|
+
def security_group_id(id)
|
114
|
+
self.__add_string('security_group_id', id, %w[security_group_ids])
|
115
|
+
end
|
116
|
+
|
117
|
+
def security_group_ids(ids)
|
118
|
+
self.__add_array_of_strings('security_group_ids', ids, %w[security_group_id])
|
119
|
+
end
|
120
|
+
|
121
|
+
def ssh_port(port)
|
122
|
+
self.__add_integer('ssh_port', port)
|
123
|
+
end
|
124
|
+
|
125
|
+
def ssh_private_key_file(file)
|
126
|
+
self.__add_string('ssh_private_key_file', file)
|
127
|
+
end
|
128
|
+
|
129
|
+
def ssh_timeout(time)
|
130
|
+
self.__add_string('ssh_timeout', time)
|
131
|
+
end
|
132
|
+
|
133
|
+
def subnet_id(id)
|
134
|
+
self.__add_string('subnet_id', id)
|
135
|
+
end
|
136
|
+
|
137
|
+
def tags(tags)
|
138
|
+
self.__add_hash('tags', tags)
|
139
|
+
end
|
140
|
+
|
141
|
+
def temporary_key_pair_name(name)
|
142
|
+
self.__add_string('temporary_key_pair_name', name)
|
143
|
+
end
|
144
|
+
|
145
|
+
def user_data(data)
|
146
|
+
self.__add_string('user_data', data)
|
147
|
+
end
|
148
|
+
|
149
|
+
def user_data_file(file)
|
150
|
+
self.__add_string('user_data_file', file)
|
151
|
+
end
|
152
|
+
|
153
|
+
def vpc_id(id)
|
154
|
+
self.__add_string('vpc_id', id)
|
155
|
+
end
|
156
|
+
|
157
|
+
class EBS < Amazon
|
158
|
+
def initialize
|
159
|
+
super
|
160
|
+
self.data['type'] = AMAZON_EBS
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
class Instance < Amazon
|
165
|
+
def initialize
|
166
|
+
super
|
167
|
+
self.data['type'] = AMAZON_INSTANCE
|
168
|
+
self.add_required(
|
169
|
+
'account_id',
|
170
|
+
's3_bucket',
|
171
|
+
'x509_cert_path',
|
172
|
+
'x509_key_path'
|
173
|
+
)
|
174
|
+
end
|
175
|
+
|
176
|
+
def account_id(id)
|
177
|
+
self.__add_string('account_id', id)
|
178
|
+
end
|
179
|
+
|
180
|
+
def s3_bucket(bucket)
|
181
|
+
self.__add_string('s3_bucket', bucket)
|
182
|
+
end
|
183
|
+
|
184
|
+
def x509_cert_path(path)
|
185
|
+
self.__add_string('x509_cert_path', path)
|
186
|
+
end
|
187
|
+
|
188
|
+
def x509_key_path(path)
|
189
|
+
self.__add_string('x509_key_path', path)
|
190
|
+
end
|
191
|
+
|
192
|
+
def bundle_destination(directory)
|
193
|
+
self.__add_string('bundle_destination', directory)
|
194
|
+
end
|
195
|
+
|
196
|
+
def bundle_prefix(prefix)
|
197
|
+
self.__add_string('bundle_prefix', prefix)
|
198
|
+
end
|
199
|
+
|
200
|
+
def bundle_upload_command(command)
|
201
|
+
self.__add_string('bundle_upload_command', command)
|
202
|
+
end
|
203
|
+
|
204
|
+
def bundle_vol_command(command)
|
205
|
+
self.__add_string('bundle_vol_command', command)
|
206
|
+
end
|
207
|
+
|
208
|
+
def x509_upload_path(path)
|
209
|
+
self.__add_string('x509_upload_path', path)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|