Skip to content

Commit

Permalink
Switch to shelling out for all vagrant uploads
Browse files Browse the repository at this point in the history
The vagrant cloud gem is pretty fundamentally broken. It does not allow uploading a box that is not directly owned by the user performing the upload. Since I'm not using the bento account directly, and that seems like a horrible idea, this won't work. Instead we can just shell out to the vagrant CLI to perform the uploads. The vagrant CLI also does a much better job of this.

Other fixes:

Simplifies how we handle slugs by just using a match on the name. This means we don't have to update the slug list with the exact versions to match on every time we bump the version.

Signed-off-by: Tim Smith <[email protected]>
  • Loading branch information
tas50 committed Oct 20, 2019
1 parent 14440e4 commit aa42a14
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 45 deletions.
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ group :development do
gem "cookstyle"
gem "rake", ">= 12"
gem "mixlib-shellout", ">= 2.3.2"
gem "vagrant_cloud", "~> 2.0"
end
28 changes: 15 additions & 13 deletions builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,22 @@ public:
- 'ubuntu-18.10'
- 'ubuntu-19.04'

# slug box name: text string from standard box name to match (generally the same)
slugs:
'centos-8': 'centos-8.0'
'centos-7': 'centos-7.6'
'centos-6': 'centos-6.10'
'centos-5': 'centos-5.11'
'debian-8': 'debian-8.11'
'debian-9': 'debian-9.8'
'debian-10': 'debian-10.0'
'oracle-6': 'oracle-6.10'
'oracle-7': 'oracle-7.6'
'scientific-7': 'scientific-7.6'
'freebsd-11': 'freebsd-11.3'
'freebsd-12': 'freebsd-12.0'
'opensuse-leap-15': 'opensuse-leap-15.1'
'centos-8': 'centos-8'
'centos-7': 'centos-7'
'centos-6': 'centos-6'
'centos-5': 'centos-5'
'debian-8': 'debian-8'
'debian-9': 'debian-9'
'debian-10': 'debian-10'
'oracle-6': 'oracle-6'
'oracle-7': 'oracle-7'
'scientific-7': 'scientific-7'
'freebsd-11': 'freebsd-11'
'freebsd-12': 'freebsd-12'
'opensuse-leap-15': 'opensuse-leap-15'
'fedora-latest': 'fedora-30'

providers:
- virtualbox-iso
28 changes: 21 additions & 7 deletions lib/bento/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,11 @@
require "json"
require "tempfile"
require "yaml"
require "vagrant_cloud"
require "mixlib/shellout"

MEGABYTE = 1024.0 * 1024.0

module Common
def vc_account
raise "You must set the 'VAGRANT_CLOUD_ORG' and 'VAGRANT_CLOUD_TOKEN' tokens to interact with the Vagrant Cloud!" unless ENV["VAGRANT_CLOUD_ORG"] && ENV["VAGRANT_CLOUD_TOKEN"]
VagrantCloud::Account.new(ENV["VAGRANT_CLOUD_ORG"], ENV["VAGRANT_CLOUD_TOKEN"])
end

def banner(msg)
puts "==> #{msg}"
end
Expand All @@ -25,6 +20,25 @@ def warn(msg)
puts ">>> #{msg}"
end

#
# Shellout to vagrant CLI to see if we're logged into the cloud
#
# @return [Boolean]
#
def logged_in?
shellout = Mixlib::ShellOut.new("vagrant cloud auth whoami").run_command

if shellout.error?
error_output = !shellout.stderr.empty? ? shellout.stderr : shellout.stdout
warn("Failed to shellout to vagrant to check the login status. Error: #{error_output}")
return false
end

return true if shellout.stdout.match?(/Currently logged in/)

false
end

def duration(total)
total = 0 if total.nil?
minutes = (total / 60).to_i
Expand All @@ -37,7 +51,7 @@ def box_metadata(metadata_file)
file = File.read(metadata_file)
json = JSON.parse(file)

# metadata needed for upload: boxname, version, provider, box filename
# metadata needed for upload: boxname, version, provider, box filename
metadata["name"] = json["name"]
metadata["version"] = json["version"]
metadata["box_basename"] = json["box_basename"]
Expand Down
1 change: 1 addition & 0 deletions lib/bento/providermetadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def ver_vmware

def ver_parallels
raise "Platform is not macOS, exiting..." unless macos?

cmd = Mixlib::ShellOut.new("prlctl --version")
cmd.run_command
cmd.stdout.split(" ")[2]
Expand Down
68 changes: 45 additions & 23 deletions lib/bento/upload.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,63 @@ def initialize(opts)
@md_json = opts.md_json
end

def error_unless_logged_in
warn("You cannot upload files to vagrant cloud unless the vagrant CLI is logged in. Run 'vagrant cloud auth login' first.") unless logged_in?
end

def start
error_unless_logged_in

banner("Starting uploads...")
time = Benchmark.measure do
files = md_json ? [md_json] : metadata_files
files.each do |md_file|
upload(md_file)
upload_box(md_file)
end
end
banner("Uploads finished in #{duration(time.real)}.")
end

def upload(md_file)
puts "Attempting to upload #{md_file}"
md = box_metadata(md_file)
box_desc = "a bento box for #{md['name']}"
box = vc_account.ensure_box(md["name"], {short_description: box_desc, is_private: private_box?(md["name"])})
box_ver = box.ensure_version(md["version"], File.read(md_file))

if builds_yml["slugs"].value?(box.name)
slug_desc = "a bento box for #{builds_yml['slugs'].key(box.name)}"
slug = vc_account.ensure_box(builds_yml["slugs"].key(box.name), {short_description: slug_desc, is_private: false})
slug_ver = slug.ensure_version(md["version"], File.read(md_file))

#
# Upload all the boxes defined in the passed metadata file
#
# @param [String] md_file The path to the metadata file
#
#
def upload_box(md_file)
md_data = box_metadata(md_file)

md_data['providers'].each_pair do |prov, prov_data|
banner("Uploading bento/#{md_data['name']} version:#{md_data['version']} provider:#{prov}...")

upload_cmd = "vagrant cloud publish bento/#{md_data['name']} #{md_data['version']} #{prov} builds/#{prov_data['file']} --description '#{box_desc(md_data['name'])}' -f"
info "Would run #{upload_cmd}"

slug_name = lookup_slug(md_data['name'])
unless slug_name.nil?
banner("Uploading slug bento/#{slug_name} from #{md_data['name']} version:#{md_data['version']} provider:#{prov}...")
upload_cmd = "vagrant cloud publish bento/#{slug_name} #{md_data['version']} #{prov} builds/#{prov_data['file']} --description '#{box_desc(slug_name)}' -f"
info "Would run #{upload_cmd}"
end
end

md["providers"].each do |k, v|
provider = box_ver.ensure_provider(k, nil)
banner("Uploading #{box.name}/#{box_ver.version}/#{provider.name}...")
provider.upload_file("builds/#{v['file']}")
banner(provider.download_url.to_s)
next unless builds_yml["slugs"].value?(box.name)

slug_provider = slug_ver.ensure_provider(k, nil)
banner("Uploading #{slug.name}/#{slug_ver.version}/#{slug_provider.name}...")
slug_provider.upload_file("builds/#{v['file']}")
banner(slug_provider.download_url.to_s)
# cmd = Mixlib::ShellOut.new("packer --version")
# cmd.run_command
end

#
# Given a box name return a slug name or nil
#
# @return [String, NilClass] The slug name or nil
#
def lookup_slug(name)
builds_yml["slugs"].each_pair do |slug, match_string|
return slug if name.start_with?(match_string)
end
end

def box_desc(name)
box_desc = "#{name.tr("-", " ").capitalize} Vagrant box created with Bento by Chef"
end
end
2 changes: 1 addition & 1 deletion lib/bento/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Bento
VERSION = "1.4.0".freeze
VERSION = "2.0.0".freeze
end

0 comments on commit aa42a14

Please sign in to comment.