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,16 @@
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_relative 'docker'
16
+ require_relative 'vagrant'
@@ -0,0 +1,35 @@
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/postprocessor'
16
+ require 'packer/dataobject'
17
+
18
+ module Packer
19
+ class PostProcessor < Packer::DataObject
20
+ class DockerImport < PostProcessor
21
+ def initialize
22
+ super
23
+ self.data['type'] = DOCKER_IMPORT
24
+ self.add_required('repository')
25
+ end
26
+ end
27
+
28
+ class DockerPush < PostProcessor
29
+ def initialize
30
+ super
31
+ self.data['type'] = DOCKER_PUSH
32
+ end
33
+ end
34
+ end
35
+ end
@@ -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/postprocessor'
16
+ require 'packer/dataobject'
17
+
18
+ module Packer
19
+ class PostProcessor < Packer::DataObject
20
+ class Vagrant < PostProcessor
21
+ def initialize
22
+ super()
23
+ self.data['type'] = VAGRANT
24
+ end
25
+
26
+ def compression_level(level)
27
+ self.__add_integer('compression_level', level)
28
+ end
29
+
30
+ def include(files)
31
+ self.__add_array_of_strings('include', files)
32
+ end
33
+
34
+ def keep_input_artifact(bool)
35
+ self.__add_boolean('keep_input_artifact', bool)
36
+ end
37
+
38
+ def output(file)
39
+ self.__add_string('output', file)
40
+ end
41
+
42
+ def vagrantfile_template(file)
43
+ self.__add_string('vagrantfile_template', file)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,86 @@
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/provisioners/all'
16
+ require 'packer/dataobject'
17
+
18
+ module Packer
19
+ class Provisioner < Packer::DataObject
20
+
21
+ SHELL = 'shell'
22
+ FILE = 'file'
23
+
24
+ VALID_PROVISIONER_TYPES = [
25
+ SHELL,
26
+ FILE
27
+ ]
28
+
29
+ class UnrecognizedProvisionerTypeError < StandardError
30
+ end
31
+
32
+ def self.get_provisioner(type)
33
+ unless validate_type(type)
34
+ raise UnrecognizedProvisionerTypeError.new("Unrecognized provisioner type #{type}")
35
+ end
36
+ {
37
+ SHELL => Packer::Provisioner::Shell,
38
+ FILE => Packer::Provisioner::File,
39
+ }.fetch(type).new
40
+ end
41
+
42
+ def self.types
43
+ VALID_PROVISIONER_TYPES
44
+ end
45
+
46
+ def initialize
47
+ super
48
+ self.add_required('type')
49
+ end
50
+
51
+ def only(buildname)
52
+ unless self.data.has_key? 'only'
53
+ self.data['only'] = []
54
+ end
55
+ self.data['only'] << buildname.to_s
56
+ end
57
+
58
+ def except(buildname)
59
+ unless self.data.has_key? 'except'
60
+ self.data['except'] = []
61
+ end
62
+ self.data['except'] << buildname.to_s
63
+ end
64
+
65
+ def pause_before(duration)
66
+ self.data["pause_before"] = duration.to_s
67
+ end
68
+
69
+ def override(builddefinition, values)
70
+ raise TypeError.new() unless values.is_a?(Hash)
71
+ unless self.data.has_key? 'override'
72
+ self.data['override'] = {}
73
+ end
74
+ if self.data.has_key? @data['override'][builddefinition]
75
+ self.data['override'][builddefinition].merge! values
76
+ else
77
+ self.data['override'][builddefinition] = values
78
+ end
79
+ end
80
+
81
+ private
82
+ def self.validate_type(type)
83
+ VALID_PROVISIONER_TYPES.include? type
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,16 @@
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_relative 'file'
16
+ require_relative 'shell'
@@ -0,0 +1,36 @@
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/provisioner'
16
+ require 'packer/dataobject'
17
+
18
+ module Packer
19
+ class Provisioner < Packer::DataObject
20
+ class File < Provisioner
21
+ def initialize
22
+ super
23
+ self.data['type'] = FILE
24
+ self.add_required('source', 'destination')
25
+ end
26
+
27
+ def source(filename)
28
+ self.__add_string('source', filename)
29
+ end
30
+
31
+ def destination(filename)
32
+ self.__add_string('destination', filename)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,60 @@
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/provisioner'
16
+ require 'packer/dataobject'
17
+
18
+ module Packer
19
+ class Provisioner < Packer::DataObject
20
+ class Shell < Provisioner
21
+ def initialize
22
+ super
23
+ self.data['type'] = SHELL
24
+ self.add_required(['inline', 'script', 'scripts'])
25
+ end
26
+
27
+ def inline(commands)
28
+ self.__add_array_of_strings('inline', commands, %w[script scripts])
29
+ end
30
+
31
+ def script(filename)
32
+ self.__add_string('script', filename, %w[inline scripts])
33
+ end
34
+
35
+ def scripts(filenames)
36
+ self.__add_array_of_strings('scripts', filenames, %w[inline script])
37
+ end
38
+
39
+ def binary(bool)
40
+ self.__add_boolean('binary', bool, [])
41
+ end
42
+
43
+ def environment_vars(envpairs)
44
+ self.__add_array_of_strings('environment_vars', envpairs)
45
+ end
46
+
47
+ def execute_command(command)
48
+ self.__add_string('execute_command', command)
49
+ end
50
+
51
+ def inline_shebang(command)
52
+ self.__add_string('inline_shebang', command)
53
+ end
54
+
55
+ def remote_path(command)
56
+ self.__add_string('remote_path', command)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,46 @@
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
+ Gem::Specification.new do |spec|
17
+ spec.name = "packer-config"
18
+ spec.version = "0.0.3"
19
+ # For deploying alpha versions via Travis CI
20
+ spec.version = "#{spec.version}-alpha-#{ENV['TRAVIS_BUILD_NUMBER']}" if ENV['TRAVIS']
21
+ spec.authors = ["Ian Chesal"]
22
+ spec.email = ["ian.chesal@gmail.colm"]
23
+ spec.summary = 'An object model to build packer.io configurations in Ruby.'
24
+ spec.description = <<-END
25
+ Building the Packer JSON configurations in raw JSON can be quite an adventure.
26
+ There's limited facilities for variable expansion and absolutely no support for
27
+ nice things like comments. I decided it would just be easier to have an object
28
+ model to build the Packer configurations in that would easily write to the
29
+ correct JSON format. It also saved me having to remember the esoteric Packer
30
+ syntax for referencing variables and whatnot in the JSON.
31
+ END
32
+ spec.homepage = "https://github.com/ianchesal/packer-config"
33
+ spec.license = "Apache 2.0"
34
+
35
+ spec.files = `git ls-files -z`.split("\x0")
36
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
37
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
38
+ spec.require_paths = ["lib"]
39
+
40
+ spec.add_development_dependency "bundler", "~> 1.6"
41
+ spec.add_development_dependency "rake", "~> 10.3"
42
+ spec.add_development_dependency "rspec", "~> 3.0"
43
+ spec.add_development_dependency "rspec-mocks", "~> 3.0"
44
+ spec.add_development_dependency "fakefs", "~> 0.5"
45
+ spec.add_development_dependency "rubocop", "~> 0.24"
46
+ end
@@ -0,0 +1,14 @@
1
+ # Integration Testing packer-config
2
+
3
+ You can run the integration tests via the Rakefile with:
4
+
5
+ bundle exec rake test:integration
6
+
7
+ The integration tests actually run Packer builds and can take some time to run. As of now I've only run them on an OS X system but, in theory, they should run on any system where the `packer` command and VirtualBox are available.
8
+
9
+ The provisioning and kickstart scripts are largely taken from the [OpsCode Bento](https://github.com/opscode/bento) project which is most awesome and you should check it out.
10
+
11
+ ## Requirements
12
+
13
+ * [Packer.io](http://www.packer.io/downloads.html)
14
+ * [VirtualBox](https://www.virtualbox.org/wiki/Downloads)
@@ -0,0 +1,4 @@
1
+ # Ignore everything in this directory
2
+ *
3
+ # Except this file
4
+ !.gitignore
@@ -0,0 +1,76 @@
1
+ # Encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Packer::Config do
5
+ it 'can build a centos-6.5 Vagrant base box' do
6
+ OS = 'centos-6.5'
7
+
8
+ pconfig = Packer::Config.new "#{OS}-vagrant.json"
9
+ pconfig.description "#{OS} VirtualBox Vagrant"
10
+ pconfig.add_variable 'mirror', 'http://mirrors.kernel.org/centos'
11
+ pconfig.add_variable 'my_version', '0.0.1'
12
+ pconfig.add_variable 'chef_version', 'latest'
13
+
14
+ builder = pconfig.add_builder Packer::Builder::VIRTUALBOX_ISO
15
+ builder.boot_command ["<tab> text ks=http://#{pconfig.macro.HTTPIP}:#{pconfig.macro.HTTPPort}/#{OS}-ks.cfg<enter><wait>"]
16
+ builder.boot_wait '10s'
17
+ builder.disk_size 40960
18
+ builder.guest_additions_path "VBoxGuestAdditions_#{pconfig.macro.Version}.iso"
19
+ builder.guest_os_type "RedHat_64"
20
+ builder.http_directory "scripts/kickstart"
21
+ builder.iso_checksum '32c7695b97f7dcd1f59a77a71f64f2957dddf738'
22
+ builder.iso_checksum_type 'sha1'
23
+ builder.iso_url "#{pconfig.variable 'mirror'}/6.5/isos/x86_64/CentOS-6.5-x86_64-bin-DVD1.iso"
24
+ builder.output_directory "#{OS}-x86_64-virtualbox"
25
+ builder.shutdown_command "echo 'vagrant'|sudo -S /sbin/halt -h -p"
26
+ builder.ssh_password "vagrant"
27
+ builder.ssh_port 22
28
+ builder.ssh_username "vagrant"
29
+ builder.ssh_wait_timeout "10000s"
30
+ builder.vboxmanage [
31
+ [
32
+ "modifyvm",
33
+ pconfig.macro.Name,
34
+ "--memory",
35
+ "480"
36
+ ],
37
+ [
38
+ "modifyvm",
39
+ pconfig.macro.Name,
40
+ "--cpus",
41
+ "1"
42
+ ]
43
+ ]
44
+ builder.virtualbox_version_file ".vbox_version"
45
+ builder.vm_name "packer-#{OS}-x86_64"
46
+
47
+ provisioner = pconfig.add_provisioner Packer::Provisioner::FILE
48
+ provisioner.source 'scripts/hello.sh'
49
+ provisioner.destination '/home/vagrant/hello.sh'
50
+
51
+ provisioner = pconfig.add_provisioner Packer::Provisioner::SHELL
52
+ provisioner.scripts [
53
+ 'scripts/fix-slow-dns.sh',
54
+ 'scripts/sshd.sh',
55
+ 'scripts/vagrant.sh',
56
+ 'scripts/vmtools.sh',
57
+ 'scripts/chef.sh',
58
+ 'scripts/cleanup.sh',
59
+ 'scripts/minimize.sh'
60
+ ]
61
+ provisioner.environment_vars [
62
+ "CHEF_VERSION=#{pconfig.variable 'chef_version'}",
63
+ "MY_VERSION=#{pconfig.variable 'my_version'}"
64
+ ]
65
+ provisioner.execute_command "echo 'vagrant' | #{pconfig.macro.Vars} sudo -S -E bash '#{pconfig.macro.Path}'"
66
+
67
+ postprocessor = pconfig.add_postprocessor Packer::PostProcessor::VAGRANT
68
+ postprocessor.output File.join('builds', pconfig.macro.Provider, "#{OS}-x86_64-#{pconfig.variable 'my_version'}.box")
69
+
70
+ Dir.chdir('spec/integration')
71
+ expect(pconfig.validate).to be_truthy
72
+ expect(pconfig.build).to be_truthy
73
+ Dir.chdir('../..')
74
+ end
75
+ end
76
+