vagrant-packer-plugin 0.8.0
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 +20 -0
- data/Gemfile +11 -0
- data/README.md +30 -0
- data/Rakefile +3 -0
- data/files/instance-templates/allinone-community.json +13 -0
- data/files/ks/ks-centos.cfg +82 -0
- data/files/packer/chef-alfresco-provisioner.json +9 -0
- data/files/packer/selinux-permissive-provisioner.json +4 -0
- data/files/packer/vagrantbox-postprocessor.json +6 -0
- data/files/stack-templates/community-allinone.json +32 -0
- data/lib/vagrant-packer-plugin.rb +10 -0
- data/lib/vagrant-packer-plugin/command.rb +125 -0
- data/lib/vagrant-packer-plugin/commons/engine.rb +93 -0
- data/lib/vagrant-packer-plugin/config.rb +32 -0
- data/lib/vagrant-packer-plugin/patches/dataobject.rb +16 -0
- data/lib/vagrant-packer-plugin/patches/runner.rb +51 -0
- data/lib/vagrant-packer-plugin/plugin.rb +21 -0
- data/lib/vagrant-packer-plugin/support/packer_build_images.rb +16 -0
- data/lib/vagrant-packer-plugin/support/packer_commands.rb +44 -0
- data/lib/vagrant-packer-plugin/utils/downloader.rb +32 -0
- data/lib/vagrant-packer-plugin/utils/packer_interface.rb +120 -0
- data/lib/vagrant-packer-plugin/utils/unpacker.rb +37 -0
- data/lib/vagrant-packer-plugin/version.rb +5 -0
- data/pkg/vagrant-packer-plugin-0.5.0.gem +0 -0
- data/spk.gemspec +29 -0
- metadata +183 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9edb2c3ae76e73c18b9e4e9ae8441f1a6d081009
|
4
|
+
data.tar.gz: 302fcabf688888a6b60ed7d98d064587478cd6a3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0087a22b554eba6191daa03addcd3b3cb8d0ac3c3f7d3284386ace0a271ed88b5a7804c2cdffd3af5787879607b3e8c0b64cfd1500bdde2e3fa8d58a533be71a
|
7
|
+
data.tar.gz: 38fa0e9e98248ec3ecbc9b3337ab0becd4f2a2c754b5954b09715b994e9a3d9554c32daa42ff1b793ff2f97e2da06e46920b2ff578c10a868f48e59e82d7847d
|
data/.gitignore
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
**/alf_data_shared
|
2
|
+
**/maven_repos/private.json
|
3
|
+
*.lock
|
4
|
+
dev/Berksfile.dev
|
5
|
+
.vagrant
|
6
|
+
*.box
|
7
|
+
Gemfile.lock
|
8
|
+
vendor-cookbooks
|
9
|
+
packer_cache
|
10
|
+
output-virtualbox-iso
|
11
|
+
*.lic
|
12
|
+
*.tar
|
13
|
+
bootstrap-data
|
14
|
+
license
|
15
|
+
|
16
|
+
# Ignore Packer builders
|
17
|
+
*-builder.json
|
18
|
+
|
19
|
+
# Ignore gem builds
|
20
|
+
# pkg
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Vagrant Packer plugin
|
2
|
+
|
3
|
+
## What Is
|
4
|
+
Vagrant Packer plugin allows to compose Packer templates and run them using vagrant and `Vagrantfile`; it also helps using Chef as provisioner.
|
5
|
+
|
6
|
+
## Install
|
7
|
+
- Install [Vagrant](https://www.vagrantup.com/downloads.html)
|
8
|
+
- Install [Packer (0.8.6+)](https://www.packer.io/downloads.html)
|
9
|
+
- Install Vagrant Packer plugin
|
10
|
+
```
|
11
|
+
curl -L --no-sessionid https://github.com/Alfresco/vagrant-packer-plugin/blob/master/pkg/vagrant-packer-plugin-0.5.0.gem > ~/.vagrant.d/vagrant-packer-plugin-0.5.0.gem
|
12
|
+
vagrant plugin install ~/.vagrant.d/vagrant-packer-plugin-0.5.0.gem
|
13
|
+
```
|
14
|
+
|
15
|
+
## Use
|
16
|
+
Define the following `Vagrantfile` and run `vagrant up` from the same folder
|
17
|
+
```
|
18
|
+
Vagrant.configure("2") do |config|
|
19
|
+
config.packer_build.instance_templates = ["instance1.json","instance2.json"]
|
20
|
+
config.packer_build.ks_template = "https://raw.githubusercontent.com/Alfresco/alfresco-spk/master/ks/ks-centos.cfg"
|
21
|
+
end
|
22
|
+
```
|
23
|
+
|
24
|
+
Type `vagrant packer-build -h` for more info on configuration.
|
25
|
+
|
26
|
+
## Local testing
|
27
|
+
Build Vagrant Packer plugin locally
|
28
|
+
```
|
29
|
+
rm Gemfile.lock ; bundle ; rake build ; vagrant plugin install pkg/vagrant-packer-plugin-0.5.0.gem
|
30
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"name": "allinone-community",
|
3
|
+
"nginx" : {
|
4
|
+
"use_nossl_config" : true,
|
5
|
+
"disable_nginx_init" : true
|
6
|
+
},
|
7
|
+
"alfresco" : {
|
8
|
+
"skip_certificate_creation" : true,
|
9
|
+
"public_protocol" : "http",
|
10
|
+
"public_portssl" : "80"
|
11
|
+
},
|
12
|
+
"run_list": ["alfresco::default"]
|
13
|
+
}
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# Copied from https://github.com/chef/bento/blob/master/http/centos-7.1/ks.cfg
|
2
|
+
|
3
|
+
install
|
4
|
+
cdrom
|
5
|
+
lang en_US.UTF-8
|
6
|
+
keyboard us
|
7
|
+
network --bootproto=dhcp
|
8
|
+
rootpw vagrant
|
9
|
+
firewall --disabled
|
10
|
+
selinux --permissive
|
11
|
+
timezone UTC
|
12
|
+
unsupported_hardware
|
13
|
+
bootloader --location=mbr
|
14
|
+
text
|
15
|
+
skipx
|
16
|
+
zerombr
|
17
|
+
clearpart --all --initlabel
|
18
|
+
autopart
|
19
|
+
auth --enableshadow --passalgo=sha512 --kickstart
|
20
|
+
firstboot --disabled
|
21
|
+
reboot
|
22
|
+
user --name=vagrant --plaintext --password vagrant
|
23
|
+
|
24
|
+
%packages --nobase --ignoremissing --excludedocs
|
25
|
+
# vagrant needs this to copy initial files via scp
|
26
|
+
openssh-clients
|
27
|
+
sudo
|
28
|
+
kernel-headers
|
29
|
+
kernel-devel
|
30
|
+
gcc
|
31
|
+
make
|
32
|
+
perl
|
33
|
+
wget
|
34
|
+
nfs-utils
|
35
|
+
net-tools
|
36
|
+
bzip2
|
37
|
+
-fprintd-pam
|
38
|
+
-intltool
|
39
|
+
|
40
|
+
# unnecessary firmware
|
41
|
+
-aic94xx-firmware
|
42
|
+
-atmel-firmware
|
43
|
+
-b43-openfwwf
|
44
|
+
-bfa-firmware
|
45
|
+
-ipw2100-firmware
|
46
|
+
-ipw2200-firmware
|
47
|
+
-ivtv-firmware
|
48
|
+
-iwl100-firmware
|
49
|
+
-iwl105-firmware
|
50
|
+
-iwl135-firmware
|
51
|
+
-iwl1000-firmware
|
52
|
+
-iwl2000-firmware
|
53
|
+
-iwl2030-firmware
|
54
|
+
-iwl3160-firmware
|
55
|
+
-iwl3945-firmware
|
56
|
+
-iwl4965-firmware
|
57
|
+
-iwl5000-firmware
|
58
|
+
-iwl5150-firmware
|
59
|
+
-iwl6000-firmware
|
60
|
+
-iwl6000g2a-firmware
|
61
|
+
-iwl6000g2b-firmware
|
62
|
+
-iwl6050-firmware
|
63
|
+
-iwl7260-firmware
|
64
|
+
-libertas-usb8388-firmware
|
65
|
+
-libertas-sd8686-firmware
|
66
|
+
-libertas-sd8787-firmware
|
67
|
+
-ql2100-firmware
|
68
|
+
-ql2200-firmware
|
69
|
+
-ql23xx-firmware
|
70
|
+
-ql2400-firmware
|
71
|
+
-ql2500-firmware
|
72
|
+
-rt61pci-firmware
|
73
|
+
-rt73usb-firmware
|
74
|
+
-xorg-x11-drv-ati-firmware
|
75
|
+
-zd1211-firmware
|
76
|
+
%end
|
77
|
+
|
78
|
+
%post
|
79
|
+
# sudo
|
80
|
+
echo "%vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant
|
81
|
+
sed -i "s/^[^#].*requiretty/#Defaults requiretty/" /etc/sudoers
|
82
|
+
%end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
{
|
2
|
+
"type": "chef-solo",
|
3
|
+
"execute_command" : "cd /tmp/packer-chef-solo && ln -s cookbooks-0 cookbooks && {{if .Sudo}}sudo {{end}}chef-client --no-color -z -j {{.JsonPath}}",
|
4
|
+
"install_command": "bash -c 'curl -L https://www.opscode.com/chef/install.sh| bash -s -- -v 12.5.1'",
|
5
|
+
"prevent_sudo": true,
|
6
|
+
"skip_install": false,
|
7
|
+
"cookbook_paths": ["./cookbooks"],
|
8
|
+
"run_list": ["alfresco::default"]
|
9
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
{
|
2
|
+
"alfresco-allinone" : {
|
3
|
+
"_images" : {
|
4
|
+
"provisioners" : {
|
5
|
+
"selinux-permissive" : "packer/selinux-permissive-provisioner.json",
|
6
|
+
"chef-alfresco" : "packer/chef-alfresco-provisioner.json"
|
7
|
+
},
|
8
|
+
"builders" : {
|
9
|
+
"virtualbox-ovf" : "packer/virtualbox-ovf-builder.json"
|
10
|
+
},
|
11
|
+
"postprocessors" : {
|
12
|
+
"vagrantbox" : "packer/vagrantbox-postprocessor.json"
|
13
|
+
},
|
14
|
+
"variables" : {
|
15
|
+
"vagrant_output_file" : "alfresco-community-5.1.c-ea-{{timestamp}}",
|
16
|
+
"iso_url" : "http://mirror.amsiohosting.net/centos.org/7.2.1511/isos/x86_64/CentOS-7-x86_64-Minimal-1511.iso",
|
17
|
+
"iso_checksum" : "f90e4d28fa377669b2db16cbcb451fcb9a89d2460e3645993e30e137ac37d284",
|
18
|
+
"iso_checksum_type" : "sha256",
|
19
|
+
"ssh_username" : "root",
|
20
|
+
"ssh_password" : "vagrant",
|
21
|
+
"ks_path" : "ks.cfg",
|
22
|
+
"http_directory" : "../",
|
23
|
+
"guest_os_type" : "RedHat_64",
|
24
|
+
"headless" : "false",
|
25
|
+
"output_directory": "vbox-output",
|
26
|
+
"vm_name": "alfresco-community-5.1.c-ea-{{timestamp}}",
|
27
|
+
"ami_description" : "Alfresco Community 5.1.c-EA - Allinone Server - {{timestamp}}",
|
28
|
+
"ami_name" : "Alfresco Community 5.1.c-EA - Allinone Server - {{timestamp}}"
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require_relative 'config'
|
2
|
+
|
3
|
+
require 'vagrant-packer-plugin/utils/downloader'
|
4
|
+
require 'vagrant-packer-plugin/commons/engine'
|
5
|
+
require 'vagrant-packer-plugin/support/packer_build_images'
|
6
|
+
require 'vagrant-packer-plugin/support/packer_commands'
|
7
|
+
|
8
|
+
require 'berkshelf'
|
9
|
+
require 'optparse'
|
10
|
+
require 'fileutils'
|
11
|
+
module VagrantPlugins
|
12
|
+
module PackerBuild
|
13
|
+
class Command < Vagrant.plugin('2', :command)
|
14
|
+
|
15
|
+
def initialize(args, env)
|
16
|
+
@params = VagrantPlugins::PackerBuild::Config.new
|
17
|
+
if env.vagrantfile.config.packer_build.is_a?(VagrantPlugins::PackerBuild::Config)
|
18
|
+
@params = env.vagrantfile.config.packer_build
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.synopsis
|
23
|
+
'Build immutable images using Packer'
|
24
|
+
end
|
25
|
+
|
26
|
+
def execute
|
27
|
+
OptionParser.new do |opts|
|
28
|
+
opts.banner = "Usage: vagrant packer-build "\
|
29
|
+
"[-b|--box-url] "\
|
30
|
+
"[-n|--box-name] "\
|
31
|
+
"[-c|--cookbooks-url] "\
|
32
|
+
"[-d|--databags-url] "\
|
33
|
+
"[-k|--ks-template] "\
|
34
|
+
"[-B|--berksfile] "\
|
35
|
+
"[-i|--instance-templates] "\
|
36
|
+
"[-D|--packer-debug] "\
|
37
|
+
"[-w|--why-run] "
|
38
|
+
|
39
|
+
opts.separator ""
|
40
|
+
|
41
|
+
opts.on("-b", "--box-url [URL]", String, "Url of the template box for the virtual machine") do |box_url|
|
42
|
+
@params.box_url = box_url
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on("-n", "--box-name [NAME]", String, "Name of the stack virtual machines") do |box_name|
|
46
|
+
@params.box_name = box_name
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on("-c", "--cookbooks-url [URL]", String, "URL resolving Berkshelf (Cookbook repo) tar.gz archive") do |cookbooks_url|
|
50
|
+
@params.cookbooks_url = cookbooks_url
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on("-d", "--databags-url [URL]", String, "URL resolving Chef databags tar.gz archive") do |databags_url|
|
54
|
+
@params.databags_url = databags_url
|
55
|
+
end
|
56
|
+
|
57
|
+
opts.on("-k", "--ks-template [PATH]", String, "URL resolving the ks template for the machine (only used by Vagrant Box Image building)") do |ks_template|
|
58
|
+
@params.ks_template = ks_template
|
59
|
+
end
|
60
|
+
|
61
|
+
opts.on("-B", "--berksfile [PATH]", String, "path resolving the Berksfile)") do |berksfile|
|
62
|
+
@params.berksfile = berksfile
|
63
|
+
end
|
64
|
+
|
65
|
+
opts.on("-i", "--instance-templates [PATH1],[PATH2]", String, "URL resolving the instance templates") do |instance_templates|
|
66
|
+
@params.instance_templates = instance_templates
|
67
|
+
end
|
68
|
+
|
69
|
+
opts.on("-D", "--packer-debug", "true, to run packer in debug mode; default is false") do |debug|
|
70
|
+
@params.debug = debug
|
71
|
+
end
|
72
|
+
|
73
|
+
opts.on("-w", "--why-run", "Why run mode will just test configuration but will not run or build anything") do |why_run|
|
74
|
+
@params.why_run = why_run
|
75
|
+
end
|
76
|
+
end.parse!
|
77
|
+
|
78
|
+
@params.finalize!
|
79
|
+
|
80
|
+
# this code will be run only if the command wasn't asking for helpls
|
81
|
+
@engine = VagrantPlugins::PackerBuild::Commons::Engine.new
|
82
|
+
@engine.create_work_dir(@params.work_dir)
|
83
|
+
|
84
|
+
if @params.ks_template
|
85
|
+
Downloader.get(@params.ks_template, "#{@params.work_dir}/ks.cfg" )
|
86
|
+
end
|
87
|
+
|
88
|
+
# Invoke Berkshelf, if Berksfile is configured
|
89
|
+
if @params.berksfile
|
90
|
+
@engine.invoke_berkshelf(@params.work_dir, "cookbooks")
|
91
|
+
end
|
92
|
+
|
93
|
+
# Download Chef cookbooks via URL or path
|
94
|
+
if @params.cookbooks_url
|
95
|
+
@engine.get_artifact(@params.work_dir, @params.cookbooks_url, "cookbooks")
|
96
|
+
end
|
97
|
+
|
98
|
+
# Download Chef databags via URL or path
|
99
|
+
if @params.databags_url
|
100
|
+
@engine.get_artifact(@params.work_dir, @params.databags_url, "databags", @params)
|
101
|
+
end
|
102
|
+
|
103
|
+
# TODO - why saving attributes in single files if we have the instance-template nodes that have it all?
|
104
|
+
# if @params.berksfile || @params.cookbooks_url
|
105
|
+
# chef_items = @engine.get_chef_items(nodes, @params.work_dir, @params.cookbooks_url, @params.databags_url)
|
106
|
+
# end
|
107
|
+
|
108
|
+
if !@params.why_run
|
109
|
+
nodes = @engine.get_instance_templates(@params.work_dir, @params.instance_templates)
|
110
|
+
PackerBuildImages.new(@params, @engine, nodes).execute!
|
111
|
+
else
|
112
|
+
abort("Why run mode selected - not continuing")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def validate
|
117
|
+
errors = ""
|
118
|
+
if @params.instance_templates.nil? or @params.instance_templates.empty?
|
119
|
+
errors << "You must provide at least one instance template"
|
120
|
+
end
|
121
|
+
errors
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'vagrant-packer-plugin/utils/downloader'
|
2
|
+
require 'vagrant-packer-plugin/utils/unpacker'
|
3
|
+
require 'json/merge_patch'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'json'
|
6
|
+
require 'yaml'
|
7
|
+
require 'open3'
|
8
|
+
require 'pry'
|
9
|
+
|
10
|
+
module VagrantPlugins
|
11
|
+
module PackerBuild
|
12
|
+
module Commons
|
13
|
+
class Engine
|
14
|
+
|
15
|
+
def fetch_cookbook_version
|
16
|
+
result = ""
|
17
|
+
begin
|
18
|
+
result = open("#{Dir.pwd}/metadata.rb").grep(/version/).first.split(" ").last.gsub(/\"/,'')
|
19
|
+
rescue
|
20
|
+
end
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def create_work_dir(work_dir)
|
26
|
+
FileUtils.mkdir_p("#{work_dir}")
|
27
|
+
puts "[packer-info] Created #{work_dir} folder\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def get_instance_templates(work_dir, instance_templates)
|
32
|
+
json_ret = {}
|
33
|
+
instance_templates.each_with_index do |instance_template,index|
|
34
|
+
node_name = JSON.parse(File.read(instance_template))['name']
|
35
|
+
json_ret[instance_template] = get_json(work_dir, "attributes-#{node_name}.json", instance_template)
|
36
|
+
end
|
37
|
+
return json_ret
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_json(work_dir, file_name, url)
|
41
|
+
Downloader.get(url, "#{work_dir}/#{file_name}")
|
42
|
+
return JSON.parse(File.read("#{work_dir}/#{file_name}"))
|
43
|
+
end
|
44
|
+
|
45
|
+
# Not needed anymore
|
46
|
+
# def get_chef_items(nodes, work_dir, cookbooks_url, databags_url)
|
47
|
+
# nodes.each do |filename,node|
|
48
|
+
# node['_local'] = {}
|
49
|
+
#
|
50
|
+
# attr_file = File.open("#{work_dir}/attributes-#{node['name']}.json", 'w')
|
51
|
+
# attr_file.write(node.to_json)
|
52
|
+
# attr_file.close()
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
|
56
|
+
def get_node_attrs(work_dir, chef_node_name)
|
57
|
+
box_attrs = File.read("#{work_dir}/attributes-#{chef_node_name}.json")
|
58
|
+
return JSON.parse(box_attrs)
|
59
|
+
end
|
60
|
+
|
61
|
+
def invoke_berkshelf(work_dir, path_name)
|
62
|
+
puts "[packer-info] Trying to delete Berksfile.lock"
|
63
|
+
begin
|
64
|
+
File.delete("#{Dir.pwd}/Berksfile.lock")
|
65
|
+
puts "[packer-info] local Berksfile.lock removed!"
|
66
|
+
rescue Errno::ENOENT
|
67
|
+
puts "[packer-info] File not found, continuing normally.."
|
68
|
+
end
|
69
|
+
|
70
|
+
puts "[packer-info] Packaging Chef Cookbooks repo with berks vendor..."
|
71
|
+
Berkshelf::Cli.start(["vendor","#{work_dir}/#{path_name}"])
|
72
|
+
# TODO - consider also params.berksfile, but not working yet
|
73
|
+
# Berkshelf::Cli.start(["package",@params.cookbooks_url.split('/')[-1],"-b #{@params.berksfile}"])
|
74
|
+
end
|
75
|
+
|
76
|
+
def get_artifact(work_dir, url, artifact_name, params=nil)
|
77
|
+
# Download and uncompress Chef artifacts (in a Berkshelf package format)
|
78
|
+
if url and url.length != 0
|
79
|
+
Downloader.get(url, "#{work_dir}/#{artifact_name}.tar.gz",params)
|
80
|
+
FileUtils.rm_rf("#{work_dir}/#{artifact_name}")
|
81
|
+
Unpacker.tar("#{artifact_name}.tar.gz", work_dir)
|
82
|
+
print "Unpacked #{work_dir}/#{artifact_name}.tar.gz into #{work_dir}\n"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def yaml_to_json(yaml)
|
87
|
+
data = YAML::load(yaml)
|
88
|
+
return JSON.dump(data)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
module VagrantPlugins
|
3
|
+
module PackerBuild
|
4
|
+
class Config < Vagrant.plugin(2, :config)
|
5
|
+
attr_accessor :work_dir, :debug, :box_url, :box_name, :cookbooks_url, :databags_url, :databags_username, :databags_password, :instance_templates, :pre_commands, :post_commands, :env_vars, :ks_template, :berksfile, :why_run
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@work_dir = UNSET_VALUE
|
9
|
+
@box_url = UNSET_VALUE
|
10
|
+
@box_name = UNSET_VALUE
|
11
|
+
@cookbooks_url = UNSET_VALUE
|
12
|
+
@databags_url = UNSET_VALUE
|
13
|
+
@databags_username = UNSET_VALUE
|
14
|
+
@databags_password = UNSET_VALUE
|
15
|
+
@ks_template = UNSET_VALUE
|
16
|
+
@berksfile = UNSET_VALUE
|
17
|
+
end
|
18
|
+
|
19
|
+
def finalize!
|
20
|
+
@work_dir = "#{Dir.home}/.vagrant.d/data/packer-plugin" if @work_dir == UNSET_VALUE
|
21
|
+
@box_url = 'http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-7.2_chef-provisionerless.box' if @box_url == UNSET_VALUE
|
22
|
+
@box_name = "opscode_centos-7.2" if @box_name == UNSET_VALUE
|
23
|
+
@cookbooks_url = nil if @cookbooks_url == UNSET_VALUE
|
24
|
+
@databags_url = nil if @databags_url == UNSET_VALUE
|
25
|
+
@databags_username = nil if @databags_username == UNSET_VALUE
|
26
|
+
@databags_password = nil if @databags_password == UNSET_VALUE
|
27
|
+
@ks_template = "" if @ks_template == UNSET_VALUE
|
28
|
+
@berksfile = nil if @berksfile == UNSET_VALUE
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Packer
|
4
|
+
class DataObject
|
5
|
+
def __add_array_of_strings(key, values, exclusives = [])
|
6
|
+
self.__exclusive_key_error(key, exclusives)
|
7
|
+
if Array.try_convert(values)
|
8
|
+
#adding var as array of string - #{key.to_s}=#{values.to_ary.map(&:to_s)}
|
9
|
+
self.data[key.to_s] = values.to_ary.map(&:to_s)
|
10
|
+
else
|
11
|
+
#adding var as string - #{key.to_s}=#{values}"
|
12
|
+
self.data[key.to_s] = values
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'vagrant-packer-plugin/patches/dataobject'
|
2
|
+
require 'open3'
|
3
|
+
require 'shellwords'
|
4
|
+
|
5
|
+
module Packer
|
6
|
+
class Runner
|
7
|
+
class CommandExecutionError < StandardError
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.run!(*args, quiet: false)
|
11
|
+
cmd = Shellwords.shelljoin(args.flatten)
|
12
|
+
|
13
|
+
debug = cmd.include? '-debug'
|
14
|
+
|
15
|
+
status = 0
|
16
|
+
stdout = ''
|
17
|
+
stderr = ''
|
18
|
+
if quiet && !debug
|
19
|
+
# Run without streaming std* to any screen
|
20
|
+
stdout, stderr, status = Open3.capture3(cmd)
|
21
|
+
else
|
22
|
+
# Run but stream as well as capture stdout to the screen
|
23
|
+
# see: http://stackoverflow.com/a/1162850/83386
|
24
|
+
Open3.popen3(cmd) do |std_in, std_out, std_err, thread|
|
25
|
+
# read each stream from a new thread
|
26
|
+
Thread.new do
|
27
|
+
until (raw = std_out.getc).nil? do
|
28
|
+
stdout << raw
|
29
|
+
$stdout.write "#{raw}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
Thread.new do
|
33
|
+
until (raw_line = std_err.gets).nil? do
|
34
|
+
stderr << raw_line
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Thread.new do
|
39
|
+
std_in.puts $stdin.gets while thread.alive?
|
40
|
+
end
|
41
|
+
|
42
|
+
thread.join # don't exit until the external process is done
|
43
|
+
status = thread.value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
raise CommandExecutionError.new(stderr) unless status == 0
|
47
|
+
stdout
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module PackerBuild
|
3
|
+
class Plugin < Vagrant.plugin('2')
|
4
|
+
name "vagrant-packer-plugin"
|
5
|
+
|
6
|
+
description <<-DESC
|
7
|
+
|
8
|
+
DESC
|
9
|
+
|
10
|
+
config 'packer_build' do
|
11
|
+
require_relative 'config'
|
12
|
+
Config
|
13
|
+
end
|
14
|
+
|
15
|
+
command 'packer-build' do
|
16
|
+
require_relative 'command'
|
17
|
+
Command
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'vagrant-packer-plugin/utils/packer_interface'
|
2
|
+
|
3
|
+
class PackerBuildImages
|
4
|
+
def initialize(params, engine, chef_items)
|
5
|
+
@params = params
|
6
|
+
@chef_items = chef_items
|
7
|
+
@engine = engine
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute!
|
11
|
+
packer = PackerInterface.new(@params, @engine)
|
12
|
+
packer_defs = packer.get_defs(@chef_items)
|
13
|
+
packer.run_defs(packer_defs)
|
14
|
+
puts "Images built! Bye for now."
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class PackerCommands
|
2
|
+
|
3
|
+
def initialize(params, engine, file_list, env_vars, mode)
|
4
|
+
@params = params
|
5
|
+
@engine = engine
|
6
|
+
@file_list = file_list
|
7
|
+
@env_vars = env_vars
|
8
|
+
@mode = mode
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute!
|
12
|
+
validate
|
13
|
+
commands_final = []
|
14
|
+
@file_list.each { |file| commands_final << @engine.get_json(@params.work_dir, file.split('/')[-1], file) }
|
15
|
+
|
16
|
+
command_sh = @env_vars
|
17
|
+
commands_final.each do |commands|
|
18
|
+
commands.each do |command|
|
19
|
+
puts "[packer-#{@mode}] #{command[0]}"
|
20
|
+
puts "[packer-#{@mode}] DEBUG: #{command[1]}"
|
21
|
+
command_sh += command[1] + "\n"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
command_file = "/tmp/#{@mode}-commands.sh"
|
25
|
+
File.open(command_file, 'w') { |file| file.write(command_sh) }
|
26
|
+
FileUtils.chmod(0755, command_file);
|
27
|
+
stdout, stderr, status = Open3.capture3(command_file)
|
28
|
+
puts "[packer-#{@mode}] RET: #{status}, ERR: #{stderr}, OUT: #{stdout}"
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def validate
|
34
|
+
print @engine
|
35
|
+
|
36
|
+
raise ArgumentError.new("Params should be an instance of VagrantPlugins::PackerBuild::Config") if !@params.is_a?(VagrantPlugins::PackerBuild::Config)
|
37
|
+
raise ArgumentError.new("Engine should be an instance of VagrantPlugins::PackerBuild::Commons::Engine") if !@engine.is_a?(VagrantPlugins::PackerBuild::Commons::Engine)
|
38
|
+
# raise ArgumentError.new("File list needs to be an Array, and cannot be empty") if !@file_list.is_a?(Array) or @file_list.empty?
|
39
|
+
raise ArgumentError.new("Environment variables should be a string and cannot be empty") if !@env_vars.is_a?(String)
|
40
|
+
raise ArgumentError.new("Mode should be either pre or post") if !["pre","post"].include?(@mode)
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'openssl'
|
3
|
+
|
4
|
+
class Downloader
|
5
|
+
def self.get(file, destination, params=nil)
|
6
|
+
if params.nil? or params.databags_username.nil?
|
7
|
+
file = file.gsub("file://", "")
|
8
|
+
file_path = file.gsub("$PWD", "#{Dir.pwd}")
|
9
|
+
puts "[packer-build] #{file_path} to #{destination}"
|
10
|
+
open(file_path) {|f|
|
11
|
+
File.open(destination,"wb") do |file|
|
12
|
+
file.puts f.read
|
13
|
+
end
|
14
|
+
}
|
15
|
+
else
|
16
|
+
self.get_with_auth(file, destination, params.databags_username, params.databags_password)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.get_with_auth(file, destination,user, password)
|
21
|
+
puts "[packer-build] retrieving with authentication"
|
22
|
+
file = file.gsub("file://", "")
|
23
|
+
file_path = file.gsub("$PWD", "#{Dir.pwd}")
|
24
|
+
puts "[packer-build] #{file_path} to #{destination}"
|
25
|
+
open(file_path, :http_basic_authentication => [user, password], :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE) {|f|
|
26
|
+
File.open(destination,"wb") do |file|
|
27
|
+
file.puts f.read
|
28
|
+
end
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'packer-config'
|
2
|
+
require 'json/merge_patch'
|
3
|
+
require 'vagrant-packer-plugin/patches/runner'
|
4
|
+
require 'vagrant-packer-plugin/patches/dataobject'
|
5
|
+
require 'vagrant-packer-plugin/utils/downloader'
|
6
|
+
require 'pry'
|
7
|
+
|
8
|
+
class PackerInterface
|
9
|
+
def initialize(params, engine)
|
10
|
+
@params = params
|
11
|
+
@engine = engine
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_defs(nodes)
|
15
|
+
packer_defs = {}
|
16
|
+
nodes.each do |_node_name,node|
|
17
|
+
node_name = node['name']
|
18
|
+
pconfig = Packer::Config.new "#{@params.work_dir}/#{node_name}-packer.json"
|
19
|
+
pconfig.description "VirtualBox vagrant for #{node_name}"
|
20
|
+
|
21
|
+
# => Building the packer config object variables
|
22
|
+
node['_images']['variables'].each {|variable_name, value| pconfig.add_variable "#{variable_name}", "#{value}"}
|
23
|
+
# => Building the packer config components: Builders, Provisioners and PostProcessors
|
24
|
+
parametrize(pconfig, "Builder", parse_packer_elements(node, node_name, 'builder', 'builders'))
|
25
|
+
parametrize(pconfig, "Provisioner", parse_packer_elements(node, node_name, 'provisioner', 'provisioners'))
|
26
|
+
parametrize(pconfig, "PostProcessor", parse_packer_elements(node, node_name, 'postprocessor', 'postprocessors'))
|
27
|
+
ENV['COOKBOOK_VERSION'] = @engine.fetch_cookbook_version
|
28
|
+
|
29
|
+
pconfig.validate
|
30
|
+
packer_defs[node_name] = pconfig
|
31
|
+
end
|
32
|
+
|
33
|
+
return packer_defs
|
34
|
+
end
|
35
|
+
|
36
|
+
def run_defs(packer_defs)
|
37
|
+
# Summarise Packer suites and ask for confirmation before running it
|
38
|
+
print "[packer-info] Running the following Packer templates:\n"
|
39
|
+
packer_defs.each do |packer_definition, packer|
|
40
|
+
print "[packer-info] Building #{packer_definition}-packer.json\n"
|
41
|
+
packer.packer_options << "-debug" if @params.debug
|
42
|
+
packer.build
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# packer_element can be 'provisioners' or 'builders'; it's used to parse JSON input structure
|
49
|
+
# packer_element_type can be 'provisioner' or 'builder'; it's used to name files
|
50
|
+
def parse_packer_elements(node, node_name, packer_element_type, packer_element)
|
51
|
+
urls = node['_images'][packer_element]
|
52
|
+
ret = "["
|
53
|
+
if urls
|
54
|
+
urls.each do |element_name,url|
|
55
|
+
packer_filename = "#{@params.work_dir}/#{element_name}-#{packer_element_type}.json"
|
56
|
+
Downloader.get(url, packer_filename)
|
57
|
+
element = File.read(packer_filename)
|
58
|
+
elementJson = JSON.parse(element)
|
59
|
+
|
60
|
+
# Inject Chef attributes JSON into the chef-solo provisioner
|
61
|
+
if elementJson['type'] == 'chef-solo'
|
62
|
+
element = inject_chef_attributes(node['name'], element_name, elementJson)
|
63
|
+
end
|
64
|
+
ret += element + ","
|
65
|
+
end
|
66
|
+
ret = ret[0..-2]
|
67
|
+
end
|
68
|
+
ret += "]"
|
69
|
+
return ret
|
70
|
+
end
|
71
|
+
|
72
|
+
def inject_chef_attributes(node_name, provisioner_name, json_provisioner)
|
73
|
+
node_url = "#{@params.work_dir}/attributes-#{node_name}.json"
|
74
|
+
node_url_content = File.read(node_url)
|
75
|
+
json_provisioner['json'] = JSON.parse(node_url_content)
|
76
|
+
json_provisioner['json']['_images'] = {} if json_provisioner['json']['_images']
|
77
|
+
return json_provisioner.to_json
|
78
|
+
end
|
79
|
+
|
80
|
+
def parametrize(packer, type, components)
|
81
|
+
JSON.parse(components).each do |component|
|
82
|
+
class_name = "Packer::#{type}::#{component['type'].upcase.gsub('-','_')}"
|
83
|
+
config = packer.send("add_#{type.downcase}", Object.const_get(class_name))
|
84
|
+
|
85
|
+
# Little bit difficult to understand without knowing what is the .send command in ruby
|
86
|
+
# Basically this iterate through the entire json object and add the variable to the packer config.
|
87
|
+
# Since the keys of the json object are the same name of the packer config method, i can call them iteratively
|
88
|
+
# For example config.send("output_file", "example.box") is equal to config.output_file "example.box"
|
89
|
+
component.each do |key, value|
|
90
|
+
config.send("#{key}", value) if key != "type"
|
91
|
+
end
|
92
|
+
|
93
|
+
if type == "Provisioner" and component['type'] == "chef-solo"
|
94
|
+
config.required = ["type"]
|
95
|
+
|
96
|
+
if packer.variables["run_list"]
|
97
|
+
config.run_list packer.variables["run_list"].split(",")
|
98
|
+
else
|
99
|
+
config.run_list component["json"]["run_list"]
|
100
|
+
end
|
101
|
+
|
102
|
+
if @params.databags_url
|
103
|
+
config.data_bags_path "#{@params.work_dir}/data_bags"
|
104
|
+
end
|
105
|
+
|
106
|
+
if @params.berksfile || @params.cookbooks_url
|
107
|
+
config.cookbook_paths ["#{@params.work_dir}/cookbooks"]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# => The current chef-solo provisioner has a bug in which will not start as it requires an empty array to start
|
112
|
+
# => this is a bug, and a pull request is on it's way to solve this problem
|
113
|
+
|
114
|
+
# => We don't specify a communicator, and packer-config require one. So if it's not required, we will use ssh
|
115
|
+
if type == "Builder"
|
116
|
+
config.communicator "ssh" if component["communicator"].nil?
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#This class manage unpacking formats
|
2
|
+
#Since the formats are many (and not only tar), this class is expected to be a good target for refactoring in metaprogramming
|
3
|
+
#End of this class should be something like Unpacker.send("#{format}", file)
|
4
|
+
|
5
|
+
require "rubygems/package"
|
6
|
+
require 'zlib'
|
7
|
+
|
8
|
+
|
9
|
+
class Unpacker
|
10
|
+
TAR_LONGLINK = '././@LongLink'
|
11
|
+
def self.tar(file, destination)
|
12
|
+
puts "[packer-build] unpacking #{file} to #{destination}"
|
13
|
+
Gem::Package::TarReader.new( Zlib::GzipReader.open "#{destination}/#{file}" ) do |tar|
|
14
|
+
dest = nil
|
15
|
+
tar.each do |entry|
|
16
|
+
if entry.full_name == TAR_LONGLINK
|
17
|
+
dest = File.join destination, entry.read.strip
|
18
|
+
next
|
19
|
+
end
|
20
|
+
dest ||= File.join destination, entry.full_name
|
21
|
+
if entry.directory?
|
22
|
+
File.delete dest if File.file? dest
|
23
|
+
FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false
|
24
|
+
elsif entry.file?
|
25
|
+
FileUtils.rm_rf dest if File.directory? dest
|
26
|
+
File.open dest, "wb" do |f|
|
27
|
+
f.print entry.read
|
28
|
+
end
|
29
|
+
FileUtils.chmod entry.header.mode, dest, :verbose => false
|
30
|
+
elsif entry.header.typeflag == '2' #Symlink!
|
31
|
+
File.symlink entry.header.linkname, dest
|
32
|
+
end
|
33
|
+
dest = nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
Binary file
|
data/spk.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path('../lib/vagrant-packer-plugin/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "vagrant-packer-plugin"
|
5
|
+
spec.version = VagrantPlugins::PackerBuild::VERSION
|
6
|
+
spec.authors = ["Enzo Rivello", "Maurizio Pillitu"]
|
7
|
+
spec.email = ["enzo.rivello@alfresco.com"]
|
8
|
+
spec.homepage = "https://github.com/alfresco/vagrant-packer-plugin"
|
9
|
+
|
10
|
+
spec.summary = %q{Write a short summary, because Rubygems requires one.}
|
11
|
+
spec.description = %q{Write a longer description or delete this line.}
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
14
|
+
spec.add_runtime_dependency 'berkshelf', '~> 4.0.1'
|
15
|
+
spec.add_runtime_dependency 'json-merge_patch', '~> 1.1'
|
16
|
+
spec.add_runtime_dependency 'pry', '~> 0.10.3'
|
17
|
+
spec.add_runtime_dependency "packer-config", "~> 1.5.0"
|
18
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
19
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
20
|
+
spec.add_development_dependency 'yard', '~> 0.8.7.6'
|
21
|
+
spec.add_development_dependency 'rspec', '~> 3.4'
|
22
|
+
|
23
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
24
|
+
spec.bindir = "exe"
|
25
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
|
+
spec.require_paths = ["lib"]
|
27
|
+
|
28
|
+
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vagrant-packer-plugin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Enzo Rivello
|
8
|
+
- Maurizio Pillitu
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-03-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: berkshelf
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 4.0.1
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 4.0.1
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: json-merge_patch
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.1'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.1'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: pry
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 0.10.3
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 0.10.3
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: packer-config
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.5.0
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.5.0
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: bundler
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '1.10'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '1.10'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rake
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '10.0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '10.0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: yard
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - "~>"
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 0.8.7.6
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 0.8.7.6
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: rspec
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "~>"
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '3.4'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - "~>"
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '3.4'
|
126
|
+
description: Write a longer description or delete this line.
|
127
|
+
email:
|
128
|
+
- enzo.rivello@alfresco.com
|
129
|
+
executables: []
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".gitignore"
|
134
|
+
- Gemfile
|
135
|
+
- README.md
|
136
|
+
- Rakefile
|
137
|
+
- files/instance-templates/allinone-community.json
|
138
|
+
- files/ks/ks-centos.cfg
|
139
|
+
- files/packer/chef-alfresco-provisioner.json
|
140
|
+
- files/packer/selinux-permissive-provisioner.json
|
141
|
+
- files/packer/vagrantbox-postprocessor.json
|
142
|
+
- files/stack-templates/community-allinone.json
|
143
|
+
- lib/vagrant-packer-plugin.rb
|
144
|
+
- lib/vagrant-packer-plugin/command.rb
|
145
|
+
- lib/vagrant-packer-plugin/commons/engine.rb
|
146
|
+
- lib/vagrant-packer-plugin/config.rb
|
147
|
+
- lib/vagrant-packer-plugin/patches/dataobject.rb
|
148
|
+
- lib/vagrant-packer-plugin/patches/runner.rb
|
149
|
+
- lib/vagrant-packer-plugin/plugin.rb
|
150
|
+
- lib/vagrant-packer-plugin/support/packer_build_images.rb
|
151
|
+
- lib/vagrant-packer-plugin/support/packer_commands.rb
|
152
|
+
- lib/vagrant-packer-plugin/utils/downloader.rb
|
153
|
+
- lib/vagrant-packer-plugin/utils/packer_interface.rb
|
154
|
+
- lib/vagrant-packer-plugin/utils/unpacker.rb
|
155
|
+
- lib/vagrant-packer-plugin/version.rb
|
156
|
+
- pkg/vagrant-packer-plugin-0.5.0.gem
|
157
|
+
- spk.gemspec
|
158
|
+
homepage: https://github.com/alfresco/vagrant-packer-plugin
|
159
|
+
licenses:
|
160
|
+
- MIT
|
161
|
+
metadata: {}
|
162
|
+
post_install_message:
|
163
|
+
rdoc_options: []
|
164
|
+
require_paths:
|
165
|
+
- lib
|
166
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0'
|
171
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ">="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
requirements: []
|
177
|
+
rubyforge_project:
|
178
|
+
rubygems_version: 2.4.5.1
|
179
|
+
signing_key:
|
180
|
+
specification_version: 4
|
181
|
+
summary: Write a short summary, because Rubygems requires one.
|
182
|
+
test_files: []
|
183
|
+
has_rdoc:
|