bento-ya 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|