bento-ya 0.0.1
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 +50 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +3 -0
- data/LICENSE +201 -0
- data/README.md +40 -0
- data/Rakefile +1 -0
- data/bento-ya.gemspec +28 -0
- data/bin/bento +17 -0
- data/lib/bento.rb +2 -0
- data/lib/bento/build.rb +86 -0
- data/lib/bento/build_remote.rb +112 -0
- data/lib/bento/buildmetadata.rb +70 -0
- data/lib/bento/cli.rb +228 -0
- data/lib/bento/common.rb +160 -0
- data/lib/bento/delete.rb +38 -0
- data/lib/bento/httpstuff.rb +73 -0
- data/lib/bento/normalize.rb +81 -0
- data/lib/bento/packerexec.rb +31 -0
- data/lib/bento/providermetadata.rb +41 -0
- data/lib/bento/release.rb +46 -0
- data/lib/bento/revoke.rb +34 -0
- data/lib/bento/test.rb +71 -0
- data/lib/bento/upload.rb +118 -0
- data/lib/bento/version.rb +3 -0
- metadata +125 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'buildkit'
|
2
|
+
|
3
|
+
class BuildRemoteRunner
|
4
|
+
include Common
|
5
|
+
|
6
|
+
attr_reader :bento_version, :dry_run, :platforms, :queue, :token, :s3_endpoint, :s3_bucket
|
7
|
+
|
8
|
+
def initialize(opts)
|
9
|
+
@dry_run = opts.dry_run
|
10
|
+
@bento_version = opts.override_version
|
11
|
+
@platforms = opts.platforms
|
12
|
+
@org = ENV['BUILDKITE_ORG']
|
13
|
+
@queue = ENV['BUILDKITE_QUEUE']
|
14
|
+
@token = ENV['BUILDKITE_TOKEN']
|
15
|
+
@s3_endpoint ||= ENV['BENTO_S3_ENDPOINT'] # 'https://s3.amazonaws.com''
|
16
|
+
@s3_bucket ||= ENV['BENTO_S3_BUCKET'] # 'opscode-vm-bento''
|
17
|
+
end
|
18
|
+
|
19
|
+
def start
|
20
|
+
msg_pre = dry_run ? "DRY RUN: " : ""
|
21
|
+
|
22
|
+
banner("#{msg_pre}Scheduling builds for Bento Version: #{bento_version}")
|
23
|
+
time = Benchmark.measure do
|
24
|
+
builds['public'].each do |platform, versions|
|
25
|
+
versions.each do |version, archs|
|
26
|
+
archs.each do |arch|
|
27
|
+
builds['providers'].each do |provider|
|
28
|
+
build(platform, version, arch, provider, bento_version, dry_run)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
banner("#{msg_pre}Scheduling finished in #{duration(time.real)}.")
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def bk_uri
|
40
|
+
"v1/organizations/#{org}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def build(platform, version, arch, provider, bento_version, dry_run)
|
44
|
+
plat = platform.include?('omnios') ? "#{platform}-#{version}" : "#{platform}-#{version}-#{arch}"
|
45
|
+
atlas_name = /(.*)64/.match(arch) ? plat.chomp("-#{arch}") : plat
|
46
|
+
no_shared = builds['no_shared_folder'].include?("#{platform}-#{version}-#{arch}-#{provider}") || builds['no_shared_folder'].include?("#{platform}-#{version}-#{arch}-all")
|
47
|
+
test_shared = no_shared ? "0" : "1"
|
48
|
+
unless builds['broken'].include?("#{plat}-#{provider}") || builds['broken'].include?("#{plat}-all")
|
49
|
+
build = {
|
50
|
+
"commit"=> "HEAD",
|
51
|
+
"branch"=> "master",
|
52
|
+
"message"=> "#{plat}-#{provider}",
|
53
|
+
"env"=> {
|
54
|
+
"ATLAS_ORG" => atlas_org,
|
55
|
+
"ATLAS_TOKEN" => atlas_token,
|
56
|
+
"ATLAS_NAME" => atlas_name,
|
57
|
+
"AWS_ACCESS_KEY_ID" => ENV['AWS_ACCESS_KEY_ID'],
|
58
|
+
"AWS_SECRET_ACCESS_KEY" => ENV['AWS_SECRET_ACCESS_KEY'],
|
59
|
+
"AWS_REGION" => 'us-east-1',
|
60
|
+
"BENTO_TEST_SHARED_FOLDER" => test_shared,
|
61
|
+
"BENTO_UPLOAD" => bento_upload,
|
62
|
+
"BENTO_VERSION" => bento_version,
|
63
|
+
"BENTO_S3_ENDPOINT" => s3_endpoint,
|
64
|
+
"BENTO_S3_BUCKET" => s3_bucket,
|
65
|
+
"BENTO_PROVIDERS" => provider,
|
66
|
+
"PLATFORM" => plat,
|
67
|
+
}
|
68
|
+
}
|
69
|
+
puts " - #{plat}-#{provider}"
|
70
|
+
client.post("/#{bk_uri}/projects/bento-#{provider.chomp('-iso')}/builds", build) unless dry_run
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def client
|
75
|
+
Buildkit.new(token: token)
|
76
|
+
end
|
77
|
+
|
78
|
+
def create_project
|
79
|
+
project = {
|
80
|
+
"name"=> project,
|
81
|
+
"repository"=>"git@github.com:chef/bento.git",
|
82
|
+
"env"=>{"BUILDKITE_BIN_PATH" => "/usr/local/opt/buildkite-agent/bin"},
|
83
|
+
"steps"=>
|
84
|
+
[{"type"=>"script",
|
85
|
+
"name"=>"build",
|
86
|
+
"command"=>"build.sh",
|
87
|
+
"agent_query_rules"=>["queue=#{queue}"]
|
88
|
+
}
|
89
|
+
]
|
90
|
+
}
|
91
|
+
|
92
|
+
puts "Creating Project #{project['name']}"
|
93
|
+
client.post("/#{bk_uri}/projects", project)
|
94
|
+
end
|
95
|
+
|
96
|
+
def delete_project
|
97
|
+
banner("Deleting Project #{project['name']}")
|
98
|
+
client.delete("/#{bk_uri}/projects/#{project}")
|
99
|
+
end
|
100
|
+
|
101
|
+
def get_builders(provider)
|
102
|
+
organization = client.organization(org)
|
103
|
+
agents = organization.rels[:agents].get.data
|
104
|
+
|
105
|
+
banner("Available Builders for provider: #{provider}")
|
106
|
+
agents.each do |agent|
|
107
|
+
if agent[:meta_data].include? "#{provider.chomp('-iso')}=true"
|
108
|
+
puts " - #{agent[:name]}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'bento/common'
|
2
|
+
|
3
|
+
class BuildMetadata
|
4
|
+
include Common
|
5
|
+
|
6
|
+
def initialize(template, build_timestamp, override_version)
|
7
|
+
@template = template
|
8
|
+
@build_timestamp = build_timestamp
|
9
|
+
@override_version = override_version
|
10
|
+
end
|
11
|
+
|
12
|
+
def read
|
13
|
+
{
|
14
|
+
name: name,
|
15
|
+
version: version,
|
16
|
+
build_timestamp: build_timestamp,
|
17
|
+
git_revision: git_revision,
|
18
|
+
#git_status: git_clean? ? "clean" : "dirty"
|
19
|
+
box_basename: box_basename,
|
20
|
+
template: template_vars.fetch("template", UNKNOWN),
|
21
|
+
cpus: cpus.to_s,
|
22
|
+
memory: memory.to_s,
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
UNKNOWN = "__unknown__".freeze
|
29
|
+
|
30
|
+
attr_reader :template, :build_timestamp, :override_version
|
31
|
+
|
32
|
+
def box_basename
|
33
|
+
"#{name.gsub("/", "__")}-#{version}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def git_revision
|
37
|
+
sha = %x{git rev-parse HEAD}.strip
|
38
|
+
end
|
39
|
+
|
40
|
+
def git_clean?
|
41
|
+
%x{git status --porcelain}.strip.empty?
|
42
|
+
end
|
43
|
+
|
44
|
+
def merged_vars
|
45
|
+
@merged_vars ||= begin
|
46
|
+
if File.exist?("#{template}.variables.json")
|
47
|
+
template_vars.merge(JSON.load(IO.read("#{template}.variables.json")))
|
48
|
+
else
|
49
|
+
template_vars
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def name
|
55
|
+
merged_vars.fetch("name", template)
|
56
|
+
end
|
57
|
+
|
58
|
+
def template_vars
|
59
|
+
@template_vars ||= JSON.load(IO.read("#{template}.json")).fetch("variables")
|
60
|
+
end
|
61
|
+
|
62
|
+
def version
|
63
|
+
if override_version
|
64
|
+
override_version
|
65
|
+
else
|
66
|
+
merged_vars.fetch("version", "#{UNKNOWN}.TIMESTAMP").
|
67
|
+
rpartition(".").first.concat(".#{build_timestamp}")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/bento/cli.rb
ADDED
@@ -0,0 +1,228 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
require 'bento/common'
|
5
|
+
require 'bento/build'
|
6
|
+
require 'bento/build_remote'
|
7
|
+
require 'bento/delete'
|
8
|
+
require 'bento/normalize'
|
9
|
+
require 'bento/release'
|
10
|
+
require 'bento/revoke'
|
11
|
+
require 'bento/test'
|
12
|
+
require 'bento/upload'
|
13
|
+
|
14
|
+
|
15
|
+
class Options
|
16
|
+
|
17
|
+
NAME = File.basename($0).freeze
|
18
|
+
|
19
|
+
def self.parse(args)
|
20
|
+
options = OpenStruct.new
|
21
|
+
options.templates = calculate_templates("*.json")
|
22
|
+
|
23
|
+
global = OptionParser.new do |opts|
|
24
|
+
opts.banner = "Usage: #{NAME} [SUBCOMMAND [options]]"
|
25
|
+
opts.separator ""
|
26
|
+
opts.separator <<-COMMANDS.gsub(/^ {8}/, "")
|
27
|
+
build : build one or more templates
|
28
|
+
build_remote : build one or more templates via buildkite
|
29
|
+
help : prints this help message
|
30
|
+
list : list all templates in project
|
31
|
+
normalize : normalize one or more templates
|
32
|
+
test : test one or more builds with kitchen
|
33
|
+
upload : upload one or more builds to Atlas and S3
|
34
|
+
release : release a version of a box on Atlas
|
35
|
+
revoke : revoke a version of a box on Atlas
|
36
|
+
delete : delete a version of a box from Atlas
|
37
|
+
COMMANDS
|
38
|
+
end
|
39
|
+
|
40
|
+
platforms_argv_proc = proc { |options|
|
41
|
+
options.platforms = builds['public'] unless args.empty?
|
42
|
+
}
|
43
|
+
|
44
|
+
templates_argv_proc = proc { |options|
|
45
|
+
options.templates = calculate_templates(args) unless args.empty?
|
46
|
+
|
47
|
+
options.templates.each do |t|
|
48
|
+
if !File.exists?("#{t}.json")
|
49
|
+
$stderr.puts "File #{t}.json does not exist for template '#{t}'"
|
50
|
+
exit(1)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
}
|
54
|
+
|
55
|
+
box_version_argv_proc = proc { |options|
|
56
|
+
options.box = ARGV[0]
|
57
|
+
options.version = ARGV[1]
|
58
|
+
}
|
59
|
+
|
60
|
+
subcommand = {
|
61
|
+
help: {
|
62
|
+
parser: OptionParser.new {},
|
63
|
+
argv: proc { |options|
|
64
|
+
puts global
|
65
|
+
exit(0)
|
66
|
+
}
|
67
|
+
},
|
68
|
+
build: {
|
69
|
+
class: BuildRunner,
|
70
|
+
parser: OptionParser.new { |opts|
|
71
|
+
opts.banner = "Usage: #{NAME} build [options] TEMPLATE[ TEMPLATE ...]"
|
72
|
+
|
73
|
+
opts.on("-n", "--dry-run", "Dry run (what would happen)") do |opt|
|
74
|
+
options.dry_run = opt
|
75
|
+
end
|
76
|
+
|
77
|
+
opts.on("-d", "--[no-]debug", "Run packer with debug output") do |opt|
|
78
|
+
options.debug = opt
|
79
|
+
end
|
80
|
+
|
81
|
+
opts.on("-o BUILDS", "--only BUILDS", "Only build some Packer builds") do |opt|
|
82
|
+
options.builds = opt
|
83
|
+
end
|
84
|
+
|
85
|
+
opts.on("-e BUILDS", "--except BUILDS", "Build all Packer builds except these") do |opt|
|
86
|
+
options.except = opt
|
87
|
+
end
|
88
|
+
|
89
|
+
opts.on("-m MIRROR", "--mirror MIRROR", "Look for isos at MIRROR") do |opt|
|
90
|
+
options.mirror = opt
|
91
|
+
end
|
92
|
+
|
93
|
+
opts.on("-H", "--headless", "Run providers as headless") do |opt|
|
94
|
+
options.headless = opt
|
95
|
+
end
|
96
|
+
|
97
|
+
opts.on("-v VERSION", "--version VERSION", "Override the version set in the template") do |opt|
|
98
|
+
options.override_version = opt
|
99
|
+
end
|
100
|
+
},
|
101
|
+
argv: templates_argv_proc
|
102
|
+
},
|
103
|
+
build_remote: {
|
104
|
+
class: BuildRemoteRunner,
|
105
|
+
parser: OptionParser.new { |opts|
|
106
|
+
opts.banner = "Usage: #{NAME} build_remote [options] [PLATFORM ...]"
|
107
|
+
|
108
|
+
opts.on("-v VERSION", "--version VERSION", "Override the version set in the template") do |opt|
|
109
|
+
options.override_version = opt
|
110
|
+
end
|
111
|
+
|
112
|
+
opts.on("--dry-run", "Show me what you got") do |opt|
|
113
|
+
options.dry_run = opt
|
114
|
+
end
|
115
|
+
},
|
116
|
+
argv: platforms_argv_proc
|
117
|
+
},
|
118
|
+
list: {
|
119
|
+
class: ListRunner,
|
120
|
+
parser: OptionParser.new { |opts|
|
121
|
+
opts.banner = "Usage: #{NAME} list [TEMPLATE ...]"
|
122
|
+
},
|
123
|
+
argv: templates_argv_proc
|
124
|
+
},
|
125
|
+
normalize: {
|
126
|
+
class: NormalizeRunner,
|
127
|
+
parser: OptionParser.new { |opts|
|
128
|
+
opts.banner = "Usage: #{NAME} normalize TEMPLATE[ TEMPLATE ...]"
|
129
|
+
|
130
|
+
opts.on("-d", "--[no-]debug", "Run packer with debug output") do |opt|
|
131
|
+
options.debug = opt
|
132
|
+
end
|
133
|
+
},
|
134
|
+
argv: templates_argv_proc
|
135
|
+
},
|
136
|
+
test: {
|
137
|
+
class: TestRunner,
|
138
|
+
parser: OptionParser.new { |opts|
|
139
|
+
opts.banner = "Usage: #{NAME} test [options]"
|
140
|
+
|
141
|
+
opts.on("-f", "--shared-folder", "Enable shared folder") do |opt|
|
142
|
+
options.shared_folder = opt
|
143
|
+
end
|
144
|
+
|
145
|
+
opts.on("-p", "--provisioner PROVISIONER", "Use a specfic provisioner") do |opt|
|
146
|
+
options.provisioner = opt
|
147
|
+
end
|
148
|
+
},
|
149
|
+
argv: Proc.new {}
|
150
|
+
},
|
151
|
+
upload: {
|
152
|
+
class: UploadRunner,
|
153
|
+
parser: OptionParser.new { |opts|
|
154
|
+
opts.banner = "Usage: #{NAME} upload"
|
155
|
+
},
|
156
|
+
argv: box_version_argv_proc
|
157
|
+
},
|
158
|
+
release: {
|
159
|
+
class: ReleaseRunner,
|
160
|
+
parser: OptionParser.new { |opts|
|
161
|
+
opts.banner = "Usage: #{NAME} release BOX VERSION"
|
162
|
+
},
|
163
|
+
argv: box_version_argv_proc
|
164
|
+
},
|
165
|
+
revoke: {
|
166
|
+
class: RevokeRunner,
|
167
|
+
parser: OptionParser.new { |opts|
|
168
|
+
opts.banner = "Usage: #{NAME} revoke BOX VERSION"
|
169
|
+
},
|
170
|
+
argv: box_version_argv_proc
|
171
|
+
},
|
172
|
+
delete: {
|
173
|
+
class: DeleteRunner,
|
174
|
+
parser: OptionParser.new { |opts|
|
175
|
+
opts.banner = "Usage: #{NAME} delete BOX VERSION"
|
176
|
+
},
|
177
|
+
argv: box_version_argv_proc
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
global.order!
|
182
|
+
command = args.empty? ? :help : ARGV.shift.to_sym
|
183
|
+
subcommand.fetch(command).fetch(:parser).order!
|
184
|
+
subcommand.fetch(command).fetch(:argv).call(options)
|
185
|
+
|
186
|
+
options.command = command
|
187
|
+
options.klass = subcommand.fetch(command).fetch(:class)
|
188
|
+
|
189
|
+
options
|
190
|
+
end
|
191
|
+
|
192
|
+
def self.calculate_templates(globs)
|
193
|
+
Array(globs).
|
194
|
+
map { |glob| result = Dir.glob(glob); result.empty? ? glob : result }.
|
195
|
+
flatten.
|
196
|
+
sort.
|
197
|
+
delete_if { |file| file =~ /\.variables\./ }.
|
198
|
+
map { |template| template.sub(/\.json$/, '') }
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
class ListRunner
|
203
|
+
|
204
|
+
include Common
|
205
|
+
|
206
|
+
attr_reader :templates
|
207
|
+
|
208
|
+
def initialize(opts)
|
209
|
+
@templates = opts.templates
|
210
|
+
end
|
211
|
+
|
212
|
+
def start
|
213
|
+
templates.each { |template| puts template }
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
class Runner
|
218
|
+
|
219
|
+
attr_reader :options
|
220
|
+
|
221
|
+
def initialize(options)
|
222
|
+
@options = options
|
223
|
+
end
|
224
|
+
|
225
|
+
def start
|
226
|
+
options.klass.new(options).start
|
227
|
+
end
|
228
|
+
end
|
data/lib/bento/common.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'json'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
MEGABYTE = 1024.0 * 1024.0
|
8
|
+
|
9
|
+
module Common
|
10
|
+
|
11
|
+
def banner(msg)
|
12
|
+
puts "==> #{msg}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def info(msg)
|
16
|
+
puts " #{msg}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def warn(msg)
|
20
|
+
puts ">>> #{msg}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def duration(total)
|
24
|
+
total = 0 if total.nil?
|
25
|
+
minutes = (total / 60).to_i
|
26
|
+
seconds = (total - (minutes * 60))
|
27
|
+
format("%dm%.2fs", minutes, seconds)
|
28
|
+
end
|
29
|
+
|
30
|
+
def box_metadata(metadata_file)
|
31
|
+
metadata = Hash.new
|
32
|
+
file = File.read(metadata_file)
|
33
|
+
json = JSON.parse(file)
|
34
|
+
|
35
|
+
# metadata needed for upload: boxname, version, provider, box filename
|
36
|
+
metadata['name'] = json['name']
|
37
|
+
metadata['version'] = json['version']
|
38
|
+
metadata['box_basename'] = json['box_basename']
|
39
|
+
metadata['tool_versions'] = json['box_basename']
|
40
|
+
metadata['providers'] = Hash.new
|
41
|
+
json['providers'].each do |provider|
|
42
|
+
metadata['providers'][provider['name']] = provider.reject { |k, _| k == 'name' }
|
43
|
+
end
|
44
|
+
metadata
|
45
|
+
end
|
46
|
+
|
47
|
+
def metadata_files
|
48
|
+
@metadata_files ||= compute_metadata_files
|
49
|
+
end
|
50
|
+
|
51
|
+
def compute_metadata_files
|
52
|
+
`ls builds/*.json`.split("\n")
|
53
|
+
end
|
54
|
+
|
55
|
+
def atlas_api
|
56
|
+
@atlas_api ||= 'https://atlas.hashicorp.com/api/v1'
|
57
|
+
end
|
58
|
+
|
59
|
+
def atlas_org
|
60
|
+
@atlas_org ||= ENV['ATLAS_ORG']
|
61
|
+
end
|
62
|
+
|
63
|
+
def atlas_token
|
64
|
+
@atlas_token ||= ENV['ATLAS_TOKEN']
|
65
|
+
end
|
66
|
+
|
67
|
+
def bento_upload
|
68
|
+
"1"
|
69
|
+
end
|
70
|
+
|
71
|
+
def bento_version
|
72
|
+
@bento_version ||= ENV['BENTO_VERSION']
|
73
|
+
end
|
74
|
+
|
75
|
+
def cpus
|
76
|
+
1
|
77
|
+
end
|
78
|
+
|
79
|
+
def memory
|
80
|
+
1024
|
81
|
+
end
|
82
|
+
|
83
|
+
def builds
|
84
|
+
YAML.load(File.read("builds.yml"))
|
85
|
+
end
|
86
|
+
|
87
|
+
def private_box?(boxname)
|
88
|
+
proprietary_os_list = %w(macosx sles solaris windows)
|
89
|
+
proprietary_os_list.any? { |p| boxname.include?(p) }
|
90
|
+
end
|
91
|
+
|
92
|
+
def tool_versions
|
93
|
+
tool_versions = Hash.new
|
94
|
+
path = File.join('/Applications/VMware\ Fusion.app/Contents/Library')
|
95
|
+
fusion_cmd = File.join(path, "vmware-vmx -v")
|
96
|
+
ver_hash = {
|
97
|
+
packer: "packer --version",
|
98
|
+
vagrant: "vagrant --version",
|
99
|
+
parallels: "prlctl --version",
|
100
|
+
virtualbox: "VBoxManage --version",
|
101
|
+
vmware_fusion: fusion_cmd
|
102
|
+
}
|
103
|
+
ver_hash.each do |tool, command|
|
104
|
+
cmd = Mixlib::ShellOut.new(command)
|
105
|
+
cmd.run_command
|
106
|
+
case tool
|
107
|
+
when /parallels/
|
108
|
+
ver = cmd.stdout.split(' ')[2]
|
109
|
+
# hash = cmd.stdout.split(' ')[3]
|
110
|
+
# ver = "#{semver} #{hash}"
|
111
|
+
when /fusion/
|
112
|
+
ver = cmd.stderr.split(' ')[5]
|
113
|
+
# hash = cmd.stderr.split(' ')[6].gsub(/^build-/,'')
|
114
|
+
# ver = "#{semver} \(#{hash}\)"
|
115
|
+
when /vagrant/
|
116
|
+
semver = cmd.stdout.split(' ')[1]
|
117
|
+
ver = "#{semver}"
|
118
|
+
when /virtualbox/
|
119
|
+
ver = cmd.stdout.split('r')[0]
|
120
|
+
# hash = cmd.stdout.split('r')[1].gsub(/\n/,'')
|
121
|
+
# ver = "#{semver} \(#{hash}\)"
|
122
|
+
else
|
123
|
+
ver = cmd.stdout.split("\n")[0]
|
124
|
+
end
|
125
|
+
tool_versions[tool] = ver
|
126
|
+
end
|
127
|
+
tool_versions
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# module PackerExec
|
132
|
+
|
133
|
+
# def for_packer_run_with(template)
|
134
|
+
# Tempfile.open("#{template}-metadata.json") do |md_file|
|
135
|
+
# Tempfile.open("#{template}-metadata-var-file") do |var_file|
|
136
|
+
# write_box_metadata(template, md_file)
|
137
|
+
# yield md_file, var_file
|
138
|
+
# end
|
139
|
+
# end
|
140
|
+
# end
|
141
|
+
|
142
|
+
# def write_box_metadata(template, io)
|
143
|
+
# md = BuildMetadata.new(template, build_timestamp, override_version).read
|
144
|
+
# io.write(JSON.pretty_generate(md))
|
145
|
+
# io.close
|
146
|
+
# end
|
147
|
+
|
148
|
+
# # def write_var_file(template, md_file, io)
|
149
|
+
# # md = BuildMetadata.new(template, build_timestamp, override_version).read
|
150
|
+
|
151
|
+
# # io.write(JSON.pretty_generate({
|
152
|
+
# # box_basename: md[:box_basename],
|
153
|
+
# # build_timestamp: md[:build_timestamp],
|
154
|
+
# # git_revision: md[:git_revision],
|
155
|
+
# # metadata: md_file.path,
|
156
|
+
# # version: md[:version],
|
157
|
+
# # }))
|
158
|
+
# # io.close
|
159
|
+
# # end
|
160
|
+
# end
|