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
data/lib/bento/delete.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'bento/common'
|
2
|
+
require 'bento/httpstuff'
|
3
|
+
|
4
|
+
class DeleteRunner
|
5
|
+
include Common
|
6
|
+
include HttpStuff
|
7
|
+
|
8
|
+
attr_reader :boxname, :version
|
9
|
+
|
10
|
+
def initialize(opts)
|
11
|
+
@boxname = opts.box
|
12
|
+
@version = opts.version
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
banner("Starting Delete...")
|
17
|
+
time = Benchmark.measure do
|
18
|
+
delete_version(boxname, version)
|
19
|
+
end
|
20
|
+
banner("Delete finished in #{duration(time.real)}.")
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def delete_version(boxname, version)
|
26
|
+
banner("Deleting version #{version} of box #{boxname}")
|
27
|
+
req = request('delete', "#{atlas_api}/box/#{atlas_org}/#{boxname}/version/#{version}", { 'access_token' => atlas_token }, { 'Content-Type' => 'application/json' })
|
28
|
+
|
29
|
+
case req.code
|
30
|
+
when '200'
|
31
|
+
banner("Version #{version} of box #{boxname} has been successfully deleted")
|
32
|
+
when '404'
|
33
|
+
warn("No box exists for this version")
|
34
|
+
else
|
35
|
+
warn("Something went wrong #{req.code}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module HttpStuff
|
4
|
+
|
5
|
+
def class_for_request(verb)
|
6
|
+
Net::HTTP.const_get(verb.to_s.capitalize)
|
7
|
+
end
|
8
|
+
|
9
|
+
def build_uri(verb, path, params = {})
|
10
|
+
if %w(delete, get).include?(verb)
|
11
|
+
path = [path, to_query_string(params)].compact.join('?')
|
12
|
+
end
|
13
|
+
|
14
|
+
# Parse the URI
|
15
|
+
uri = URI.parse(path)
|
16
|
+
|
17
|
+
# Don't merge absolute URLs
|
18
|
+
uri = URI.parse(File.join(endpoint, path)) unless uri.absolute?
|
19
|
+
|
20
|
+
# Return the URI object
|
21
|
+
uri
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_query_string(hash)
|
25
|
+
hash.map do |key, value|
|
26
|
+
"#{CGI.escape(key)}=#{CGI.escape(value)}"
|
27
|
+
end.join('&')[/.+/]
|
28
|
+
end
|
29
|
+
|
30
|
+
def request(verb, url, data = {}, headers = {})
|
31
|
+
uri = build_uri(verb, url, data)
|
32
|
+
|
33
|
+
# Build the request.
|
34
|
+
request = class_for_request(verb).new(uri.request_uri)
|
35
|
+
if %w(patch post put delete).include?(verb)
|
36
|
+
if data.respond_to?(:read)
|
37
|
+
request.content_length = data.size
|
38
|
+
request.body_stream = data
|
39
|
+
elsif data.is_a?(Hash)
|
40
|
+
request.form_data = data
|
41
|
+
else
|
42
|
+
request.body = data
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Add headers
|
47
|
+
headers.each do |key, value|
|
48
|
+
request.add_field(key, value)
|
49
|
+
end
|
50
|
+
|
51
|
+
connection = Net::HTTP.new(uri.host, uri.port)
|
52
|
+
|
53
|
+
if uri.scheme == 'https'
|
54
|
+
require 'net/https' unless defined?(Net::HTTPS)
|
55
|
+
|
56
|
+
# Turn on SSL
|
57
|
+
connection.use_ssl = true
|
58
|
+
connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
59
|
+
end
|
60
|
+
|
61
|
+
connection.start do |http|
|
62
|
+
response = http.request(request)
|
63
|
+
|
64
|
+
case response
|
65
|
+
when Net::HTTPRedirection
|
66
|
+
redirect = URI.parse(response['location'])
|
67
|
+
request(verb, redirect, data, headers)
|
68
|
+
else
|
69
|
+
response
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'bento/common'
|
2
|
+
require 'mixlib/shellout'
|
3
|
+
|
4
|
+
class NormalizeRunner
|
5
|
+
|
6
|
+
include Common
|
7
|
+
include PackerExec
|
8
|
+
|
9
|
+
attr_reader :templates, :build_timestamp, :debug, :override_version
|
10
|
+
|
11
|
+
def initialize(opts)
|
12
|
+
@templates = opts.templates
|
13
|
+
@debug = opts.debug
|
14
|
+
@modified = []
|
15
|
+
@build_timestamp = Time.now.gmtime.strftime("%Y%m%d%H%M%S")
|
16
|
+
end
|
17
|
+
|
18
|
+
def start
|
19
|
+
banner("Normalizing for templates: #{templates}")
|
20
|
+
time = Benchmark.measure do
|
21
|
+
templates.each do |template|
|
22
|
+
validate(template)
|
23
|
+
fix(template)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
if !@modified.empty?
|
27
|
+
info("")
|
28
|
+
info("The following templates were modified:")
|
29
|
+
@modified.sort.each { |template| info(" * #{template}")}
|
30
|
+
end
|
31
|
+
banner("Normalizing finished in #{duration(time.real)}.")
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def checksum(file)
|
37
|
+
Digest::MD5.file(file).hexdigest
|
38
|
+
end
|
39
|
+
|
40
|
+
def fix(template)
|
41
|
+
file = "#{template}.json"
|
42
|
+
|
43
|
+
banner("[#{template}] Fixing")
|
44
|
+
original_checksum = checksum(file)
|
45
|
+
output = %x{packer fix #{file}}
|
46
|
+
raise "[#{template}] Error fixing, exited #{$?}" if $?.exitstatus != 0
|
47
|
+
# preserve ampersands in shell commands,
|
48
|
+
# see: https://github.com/mitchellh/packer/issues/784
|
49
|
+
output.gsub!("\\u0026", "&")
|
50
|
+
File.open(file, "wb") { |dest| dest.write(output) }
|
51
|
+
fixed_checksum = checksum(file)
|
52
|
+
|
53
|
+
if original_checksum == fixed_checksum
|
54
|
+
puts("No changes made.")
|
55
|
+
else
|
56
|
+
warn("Template #{template} has been modified.")
|
57
|
+
@modified << template
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def packer_validate_cmd(template, var_file)
|
62
|
+
vars = "#{template}.variables.json"
|
63
|
+
cmd = %W[packer validate -var-file=#{var_file} #{template}.json]
|
64
|
+
cmd.insert(2, "-var-file=#{vars}") if File.exist?(vars)
|
65
|
+
cmd
|
66
|
+
end
|
67
|
+
|
68
|
+
def validate(template)
|
69
|
+
for_packer_run_with(template) do |md_file, var_file|
|
70
|
+
cmd = packer_validate_cmd(template, var_file.path)
|
71
|
+
banner("[#{template}] Validating: '#{cmd.join(' ')}'")
|
72
|
+
if debug
|
73
|
+
banner("[#{template}] DEBUG: var_file(#{var_file.path}) is:")
|
74
|
+
puts IO.read(var_file.path)
|
75
|
+
banner("[#{template}] DEBUG: md_file(#{md_file.path}) is:")
|
76
|
+
puts IO.read(md_file.path)
|
77
|
+
end
|
78
|
+
system(*cmd) or raise "[#{template}] Error validating, exited #{$?}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
module PackerExec
|
3
|
+
|
4
|
+
def for_packer_run_with(template)
|
5
|
+
Tempfile.open("#{template}-metadata.json") do |md_file|
|
6
|
+
Tempfile.open("#{template}-metadata-var-file") do |var_file|
|
7
|
+
write_box_metadata(template, md_file)
|
8
|
+
yield md_file, var_file
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def write_box_metadata(template, io)
|
14
|
+
md = BuildMetadata.new(template, build_timestamp, override_version).read
|
15
|
+
io.write(JSON.pretty_generate(md))
|
16
|
+
io.close
|
17
|
+
end
|
18
|
+
|
19
|
+
# def write_var_file(template, md_file, io)
|
20
|
+
# md = BuildMetadata.new(template, build_timestamp, override_version).read
|
21
|
+
|
22
|
+
# io.write(JSON.pretty_generate({
|
23
|
+
# box_basename: md[:box_basename],
|
24
|
+
# build_timestamp: md[:build_timestamp],
|
25
|
+
# git_revision: md[:git_revision],
|
26
|
+
# metadata: md_file.path,
|
27
|
+
# version: md[:version],
|
28
|
+
# }))
|
29
|
+
# io.close
|
30
|
+
# end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
class ProviderMetadata
|
4
|
+
|
5
|
+
def initialize(path, box_basename)
|
6
|
+
@base = File.join(path, box_basename)
|
7
|
+
end
|
8
|
+
|
9
|
+
def read
|
10
|
+
Dir.glob("#{base}.*.box").map do |file|
|
11
|
+
{
|
12
|
+
name: provider_from_file(file),
|
13
|
+
file: "#{File.basename(file)}",
|
14
|
+
checksum_type: "sha256",
|
15
|
+
checksum: shasum(file),
|
16
|
+
size: "#{size_in_mb(file)} MB",
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :base
|
24
|
+
|
25
|
+
def provider_from_file(file)
|
26
|
+
case provider = file.sub(/^.*\.([^.]+)\.box$/, '\1')
|
27
|
+
when /vmware/i then "vmware_desktop"
|
28
|
+
else provider
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def shasum(file)
|
33
|
+
Digest::SHA256.file(file).hexdigest
|
34
|
+
end
|
35
|
+
|
36
|
+
def size_in_mb(file)
|
37
|
+
size = File.size(file)
|
38
|
+
size_mb = size / MEGABYTE
|
39
|
+
size_mb.ceil.to_s
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'bento/common'
|
2
|
+
require 'mixlib/shellout'
|
3
|
+
|
4
|
+
class ReleaseRunner
|
5
|
+
include Common
|
6
|
+
include HttpStuff
|
7
|
+
|
8
|
+
attr_reader :boxname, :version
|
9
|
+
|
10
|
+
def initialize(opts)
|
11
|
+
@boxname = opts.box
|
12
|
+
@version = opts.version
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
banner("Starting Release...")
|
17
|
+
time = Benchmark.measure do
|
18
|
+
release_version(boxname, version)
|
19
|
+
end
|
20
|
+
banner("Release finished in #{duration(time.real)}.")
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def release_version(boxname, version)
|
26
|
+
case status(boxname, version)
|
27
|
+
when 'unreleased'
|
28
|
+
banner("Releasing version #{version} of box #{boxname}")
|
29
|
+
req = request('put', "#{atlas_api}/box/#{atlas_org}/#{boxname}/version/#{version}/release", { 'access_token' => atlas_token }, { 'Content-Type' => 'application/json' })
|
30
|
+
if req.code == '200'
|
31
|
+
banner("Version #{version} of box #{boxname} has been successfully released")
|
32
|
+
else
|
33
|
+
warn("Something went wrong #{req.code}")
|
34
|
+
end
|
35
|
+
when 'active'
|
36
|
+
banner("Version #{version} of box #{boxname} has already been released - nothing to do")
|
37
|
+
else
|
38
|
+
warn("Unexpected status retrieved from Atlas")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def status(boxname, version)
|
43
|
+
req = request('get', "#{atlas_api}/box/#{atlas_org}/#{boxname}/version/#{version}", { 'access_token' => atlas_token }, { 'Content-Type' => 'application/json' })
|
44
|
+
status = JSON.parse(req.body)['status']
|
45
|
+
end
|
46
|
+
end
|
data/lib/bento/revoke.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'bento/common'
|
2
|
+
require 'mixlib/shellout'
|
3
|
+
|
4
|
+
class RevokeRunner
|
5
|
+
include Common
|
6
|
+
include HttpStuff
|
7
|
+
|
8
|
+
attr_reader :boxname, :version
|
9
|
+
|
10
|
+
def initialize(opts)
|
11
|
+
@boxname = opts.box
|
12
|
+
@version = opts.version
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
banner("Starting Revoke...")
|
17
|
+
time = Benchmark.measure do
|
18
|
+
revoke_version(boxname, version)
|
19
|
+
end
|
20
|
+
banner("Revoke finished in #{duration(time.real)}.")
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def revoke_version(boxname, version)
|
26
|
+
banner("Revoking version #{version} of box #{boxname}")
|
27
|
+
req = request('put', "#{atlas_api}/box/#{atlas_org}/#{boxname}/version/#{version}/revoke", { 'access_token' => atlas_token }, { 'Content-Type' => 'application/json' })
|
28
|
+
if req.code == '200'
|
29
|
+
banner("Version #{version} of box #{boxname} has been successfully revoked")
|
30
|
+
else
|
31
|
+
banner("Something went wrong #{req.code}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/bento/test.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'bento/common'
|
2
|
+
require 'kitchen'
|
3
|
+
|
4
|
+
class TestRunner
|
5
|
+
include Common
|
6
|
+
|
7
|
+
attr_reader :shared_folder, :boxname, :provider, :box_url, :share_disabled, :provisioner
|
8
|
+
|
9
|
+
def initialize(opts)
|
10
|
+
@debug = opts.debug
|
11
|
+
@shared_folder = opts.shared_folder
|
12
|
+
@provisioner = opts.provisioner.nil? ? "shell" : opts.provisioner
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
banner("Starting testing...")
|
17
|
+
time = Benchmark.measure do
|
18
|
+
metadata_files.each do |metadata_file|
|
19
|
+
m = box_metadata(metadata_file)
|
20
|
+
destroy_all_bento
|
21
|
+
test_box(m['name'], m['providers'])
|
22
|
+
destroy_all_bento
|
23
|
+
end
|
24
|
+
end
|
25
|
+
banner("Testing finished in #{duration(time.real)}.")
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def destroy_all_bento
|
31
|
+
cmd = Mixlib::ShellOut.new("vagrant box list | grep 'bento-'")
|
32
|
+
cmd.run_command
|
33
|
+
boxes = cmd.stdout.split("\n")
|
34
|
+
|
35
|
+
boxes.each do |box|
|
36
|
+
b = box.split(' ')
|
37
|
+
rm_cmd = Mixlib::ShellOut.new("vagrant box remove --force #{b[0]} --provider #{b[1].to_s.gsub(/(,|\()/, '')}")
|
38
|
+
banner("Removing #{b[0]} for provider #{b[1].to_s.gsub(/(,|\()/, '')}")
|
39
|
+
rm_cmd.run_command
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_box(boxname, providers)
|
44
|
+
providers.each do |provider, provider_data|
|
45
|
+
|
46
|
+
if provider == 'vmware_desktop'
|
47
|
+
case RUBY_PLATFORM
|
48
|
+
when /darwin/
|
49
|
+
provider = 'vmware_fusion'
|
50
|
+
when /linux/
|
51
|
+
provider = 'vmware_workstation'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
@boxname = boxname
|
56
|
+
@provider = provider
|
57
|
+
@share_disabled = shared_folder ? false : true
|
58
|
+
@box_url = "file://#{ENV['PWD']}/builds/#{provider_data['file']}"
|
59
|
+
|
60
|
+
kitchen_cfg = ERB.new(File.read('.kitchen.yml.erb'), nil, '-').result(binding)
|
61
|
+
File.open(".kitchen.#{provider}.yml", "w") { |f| f.puts kitchen_cfg }
|
62
|
+
|
63
|
+
Kitchen.logger = Kitchen.default_file_logger
|
64
|
+
@loader = Kitchen::Loader::YAML.new(project_config: "./.kitchen.#{provider}.yml")
|
65
|
+
config = Kitchen::Config.new(loader: @loader)
|
66
|
+
config.instances.each do |instance|
|
67
|
+
instance.test(:always)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/bento/upload.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
require 'bento/common'
|
3
|
+
|
4
|
+
class UploadRunner
|
5
|
+
include Common
|
6
|
+
include HttpStuff
|
7
|
+
|
8
|
+
attr_reader :templates
|
9
|
+
|
10
|
+
def initialize(opts)
|
11
|
+
@templates = opts.templates
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
banner("Starting uploads...")
|
16
|
+
time = Benchmark.measure do
|
17
|
+
metadata_files.each do |file|
|
18
|
+
md = box_metadata(file)
|
19
|
+
create_box(md['name'])
|
20
|
+
create_box_version(md['name'], md['version'], file)
|
21
|
+
create_providers(md['name'], md['version'], md['providers'].keys)
|
22
|
+
upload_to_atlas(md['name'], md['version'], md['providers'])
|
23
|
+
#upload_to_s3(md['name'], md['version'], md['providers'])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
banner("Atlas uploads finished in #{duration(time.real)}.")
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def create_box(boxname)
|
32
|
+
req = request('get', "#{atlas_api}/box/#{atlas_org}/#{boxname}", { 'box[username]' => atlas_org, 'access_token' => atlas_token } )
|
33
|
+
if req.code.eql?('404')
|
34
|
+
if private_box?(boxname)
|
35
|
+
banner("Creating the private box #{boxname} in Atlas.")
|
36
|
+
req = request('post', "#{atlas_api}/boxes", { 'box[name]' => boxname, 'box[username]' => atlas_org, 'access_token' => atlas_token }, { 'Content-Type' => 'application/json' } )
|
37
|
+
else
|
38
|
+
banner("Creating the box #{boxname} in Atlas.")
|
39
|
+
req = request('post', "#{atlas_api}/boxes", { 'box[name]' => boxname, 'box[username]' => atlas_org, 'access_token' => atlas_token }, { 'Content-Type' => 'application/json' } )
|
40
|
+
make_public(boxname)
|
41
|
+
end
|
42
|
+
else
|
43
|
+
banner("The box #{boxname} exists in Atlas, continuing...")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def make_public(boxname)
|
48
|
+
banner("Making #{boxname} public")
|
49
|
+
req = request('put', "#{atlas_api}/box/#{atlas_org}/#{boxname}", { 'box[is_private]' => false, 'access_token' => atlas_token }, { 'Content-Type' => 'application/json' } )
|
50
|
+
banner("#{boxname} successfully made public") if req.code == '200'
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_box_version(boxname, version, md_json)
|
54
|
+
payload = {
|
55
|
+
'version[version]' => version,
|
56
|
+
'access_token' => atlas_token,
|
57
|
+
'version[description]' => File.read(md_json)
|
58
|
+
}
|
59
|
+
req = request('post', "#{atlas_api}/box/#{atlas_org}/#{boxname}/versions", payload, { 'Content-Type' => 'application/json' } )
|
60
|
+
|
61
|
+
banner("Created box version #{boxname} #{version}.") if req.code == '200'
|
62
|
+
banner("Box version #{boxname} #{version} already exists, continuing.") if req.code == '422'
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_providers(boxname, version, provider_names)
|
66
|
+
provider_names.each do |provider|
|
67
|
+
banner("Creating provider #{provider} for #{boxname} #{version}")
|
68
|
+
req = request('post', "#{atlas_api}/box/#{atlas_org}/#{boxname}/version/#{version}/providers", { 'provider[name]' => provider, 'access_token' => atlas_token }, { 'Content-Type' => 'application/json' } )
|
69
|
+
banner("Created #{provider} for #{boxname} #{version}") if req.code == '200'
|
70
|
+
banner("Provider #{provider} for #{boxname} #{version} already exists, continuing.") if req.code == '422'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def upload_to_atlas(boxname, version, providers)
|
75
|
+
providers.each do |provider, provider_data|
|
76
|
+
boxfile = provider_data['file']
|
77
|
+
req = request('get', "#{atlas_api}/box/#{atlas_org}/#{boxname}/version/#{version}/provider/#{provider}/upload?access_token=#{atlas_token}")
|
78
|
+
upload_path = JSON.parse(req.body)['upload_path']
|
79
|
+
token = JSON.parse(req.body)['token']
|
80
|
+
|
81
|
+
banner("Atlas: Uploading #{boxfile}")
|
82
|
+
info("Name: #{boxname}")
|
83
|
+
info("Version: #{version}")
|
84
|
+
info("Provider: #{provider}")
|
85
|
+
info("Upload Path: #{upload_path}")
|
86
|
+
upload_request = request('put', upload_path, File.open("builds/#{boxfile}"))
|
87
|
+
|
88
|
+
req = request('get', "#{atlas_api}/box/#{atlas_org}/#{boxname}/version/#{version}/provider/#{provider}?access_token=#{atlas_token}")
|
89
|
+
hosted_token = JSON.parse(req.body)['hosted_token']
|
90
|
+
|
91
|
+
if token == hosted_token
|
92
|
+
banner("Successful upload of box #{boxfile}")
|
93
|
+
else
|
94
|
+
banner("Failed upload due to non-matching tokens of box #{boxfile} to atlas box: #{boxname}, version: #{version}, provider: #{provider}")
|
95
|
+
warn("Code: #{req.code}")
|
96
|
+
warn("Body: #{req.body}")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def upload_to_s3(boxname, version, providers)
|
101
|
+
providers.each do |provider, provider_data|
|
102
|
+
boxfile = provider_data['file']
|
103
|
+
provider = 'vmware' if provider == 'vmware_desktop'
|
104
|
+
box_path = "vagrant/#{provider}/opscode_#{boxname}_chef-provisionerless.box"
|
105
|
+
credentials = Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'])
|
106
|
+
|
107
|
+
s3 = Aws::S3::Resource.new(credentials: credentials, endpoint: s3_endpoint)
|
108
|
+
banner("S3: Uploading #{boxfile}")
|
109
|
+
info("Name: #{boxname}")
|
110
|
+
info("Version: #{version}")
|
111
|
+
info("Provider: #{provider}")
|
112
|
+
s3_object = s3.bucket(s3_bucket).object(box_path)
|
113
|
+
s3_object.upload_file("builds/#{boxfile}", acl:'public-read')
|
114
|
+
banner("Upload Path: #{s3_object.public_url}")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|