vagrant-packer-plugin 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|