bento-ya 0.0.3 → 0.1.0
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 +4 -4
- data/bento-ya.gemspec +0 -2
- data/lib/bento/build.rb +15 -12
- data/lib/bento/build_remote.rb +5 -1
- data/lib/bento/buildmetadata.rb +16 -4
- data/lib/bento/cli.rb +16 -4
- data/lib/bento/common.rb +1 -60
- data/lib/bento/delete.rb +4 -20
- data/lib/bento/providermetadata.rb +34 -5
- data/lib/bento/release.rb +4 -28
- data/lib/bento/revoke.rb +4 -16
- data/lib/bento/test.rb +12 -28
- data/lib/bento/upload.rb +10 -101
- data/lib/bento/vagrantcloud.rb +138 -0
- data/lib/bento/version.rb +1 -1
- data/templates/kitchen.yml.erb +26 -0
- metadata +5 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f73a2d8eb35d7b9b7bda761031ebccb9ad537a4a
|
4
|
+
data.tar.gz: c4faa62cb9707c09619ecff27791d5ae30653d34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 194180e9dcd65151a7945c58e829a0c45b00dae6415d867546ef139d2f32b4d9f90162c1466fe19af341e18729fb7c4654e8661278d767091a2a64df38e643cb
|
7
|
+
data.tar.gz: 439513b89ff61c471ae63dc89261dd2efb4bfe05eff52020d09c001d8c1cf4be089eed8ad1387d963fb5603080b15e9868fcaa154c910ad3292ef8c2b4e87afe
|
data/bento-ya.gemspec
CHANGED
data/lib/bento/build.rb
CHANGED
@@ -9,7 +9,8 @@ class BuildRunner
|
|
9
9
|
include Common
|
10
10
|
include PackerExec
|
11
11
|
|
12
|
-
attr_reader :templates, :dry_run, :debug, :builds, :except, :mirror, :
|
12
|
+
attr_reader :templates, :dry_run, :debug, :builds, :except, :mirror, :headed,
|
13
|
+
:override_version, :build_timestamp, :cpus, :mem
|
13
14
|
|
14
15
|
def initialize(opts)
|
15
16
|
@templates = opts.templates
|
@@ -18,9 +19,11 @@ class BuildRunner
|
|
18
19
|
@builds = opts.builds ||= "parallels-iso,virtualbox-iso,vmware-iso"
|
19
20
|
@except = opts.except
|
20
21
|
@mirror = opts.mirror
|
21
|
-
@
|
22
|
+
@headed = opts.headed ||= false
|
22
23
|
@override_version = opts.override_version
|
23
24
|
@build_timestamp = Time.now.gmtime.strftime("%Y%m%d%H%M%S")
|
25
|
+
@cpus = opts.cpus
|
26
|
+
@mem = opts.mem
|
24
27
|
end
|
25
28
|
|
26
29
|
def start
|
@@ -52,10 +55,14 @@ class BuildRunner
|
|
52
55
|
cmd.insert(2, "-only=#{builds}") if builds
|
53
56
|
cmd.insert(2, "-except=#{except}") if except
|
54
57
|
# Build the command line in the correct order and without spaces as future input for the splat operator.
|
58
|
+
cmd.insert(2, "cpus=#{cpus}") if cpus
|
59
|
+
cmd.insert(2, "-var") if cpus
|
60
|
+
cmd.insert(2, "memory=#{mem}") if mem
|
61
|
+
cmd.insert(2, "-var") if mem
|
55
62
|
cmd.insert(2, "mirror=#{mirror}") if mirror
|
56
63
|
cmd.insert(2, "-var") if mirror
|
57
|
-
cmd.insert(2, "headless=true")
|
58
|
-
cmd.insert(2, "-var")
|
64
|
+
cmd.insert(2, "headless=true") unless headed
|
65
|
+
cmd.insert(2, "-var") unless headed
|
59
66
|
cmd.insert(2, "-debug") if debug
|
60
67
|
cmd.insert(0, "echo") if dry_run
|
61
68
|
cmd
|
@@ -65,16 +72,12 @@ class BuildRunner
|
|
65
72
|
md = BuildMetadata.new(template, build_timestamp, override_version).read
|
66
73
|
path = File.join("#{Dir.pwd}/builds")
|
67
74
|
filename = File.join(path, "#{md[:box_basename]}.metadata.json")
|
68
|
-
|
69
75
|
md[:providers] = ProviderMetadata.new(path, md[:box_basename]).read
|
70
|
-
md[:
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
builders.each do |b|
|
75
|
-
md[:build_times][b] = buildtime
|
76
|
+
md[:providers].each do |p|
|
77
|
+
p[:build_time] = buildtime
|
78
|
+
p[:build_cpus] = cpus unless cpus.nil?
|
79
|
+
p[:build_mem] = mem unless mem.nil?
|
76
80
|
end
|
77
|
-
|
78
81
|
|
79
82
|
if dry_run
|
80
83
|
banner("(Dry run) Metadata file contents would be something similar to:")
|
data/lib/bento/build_remote.rb
CHANGED
@@ -40,6 +40,10 @@ class BuildRemoteRunner
|
|
40
40
|
"v1/organizations/#{org}"
|
41
41
|
end
|
42
42
|
|
43
|
+
def bento_upload
|
44
|
+
"1"
|
45
|
+
end
|
46
|
+
|
43
47
|
def build(platform, version, arch, provider, bento_version, dry_run)
|
44
48
|
plat = platform.include?('omnios') ? "#{platform}-#{version}" : "#{platform}-#{version}-#{arch}"
|
45
49
|
atlas_name = /(.*)64/.match(arch) ? plat.chomp("-#{arch}") : plat
|
@@ -109,4 +113,4 @@ class BuildRemoteRunner
|
|
109
113
|
end
|
110
114
|
end
|
111
115
|
end
|
112
|
-
end
|
116
|
+
end
|
data/lib/bento/buildmetadata.rb
CHANGED
@@ -15,11 +15,11 @@ class BuildMetadata
|
|
15
15
|
version: version,
|
16
16
|
build_timestamp: build_timestamp,
|
17
17
|
git_revision: git_revision,
|
18
|
-
|
18
|
+
git_status: git_clean? ? "clean" : "dirty",
|
19
19
|
box_basename: box_basename,
|
20
20
|
template: template_vars.fetch("template", UNKNOWN),
|
21
|
-
|
22
|
-
|
21
|
+
packer: packer_ver,
|
22
|
+
vagrant: vagrant_ver,
|
23
23
|
}
|
24
24
|
end
|
25
25
|
|
@@ -67,4 +67,16 @@ class BuildMetadata
|
|
67
67
|
rpartition(".").first.concat(".#{build_timestamp}")
|
68
68
|
end
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
|
+
def packer_ver
|
72
|
+
cmd = Mixlib::ShellOut.new("packer --version")
|
73
|
+
cmd.run_command
|
74
|
+
cmd.stdout.split("\n")[0]
|
75
|
+
end
|
76
|
+
|
77
|
+
def vagrant_ver
|
78
|
+
cmd = Mixlib::ShellOut.new("vagrant --version")
|
79
|
+
cmd.run_command
|
80
|
+
cmd.stdout.split(' ')[1]
|
81
|
+
end
|
82
|
+
end
|
data/lib/bento/cli.rb
CHANGED
@@ -57,6 +57,10 @@ class Options
|
|
57
57
|
options.version = ARGV[1]
|
58
58
|
}
|
59
59
|
|
60
|
+
md_json_argv_proc = proc { |options|
|
61
|
+
options.md_json = ARGV[0]
|
62
|
+
}
|
63
|
+
|
60
64
|
subcommand = {
|
61
65
|
help: {
|
62
66
|
parser: OptionParser.new {},
|
@@ -90,8 +94,16 @@ class Options
|
|
90
94
|
options.mirror = opt
|
91
95
|
end
|
92
96
|
|
93
|
-
opts.on("-
|
94
|
-
options.
|
97
|
+
opts.on("-C cpus", "--cpus CPUS", "# of CPUs per provider") do |opt|
|
98
|
+
options.cpus = opt
|
99
|
+
end
|
100
|
+
|
101
|
+
opts.on("-M MEMORY", "--memory MEMORY", "Memory (MB) per provider") do |opt|
|
102
|
+
options.mem = opt
|
103
|
+
end
|
104
|
+
|
105
|
+
opts.on("-H", "--headed", "Display provider UI windows") do |opt|
|
106
|
+
options.headed = opt
|
95
107
|
end
|
96
108
|
|
97
109
|
opts.on("-v VERSION", "--version VERSION", "Override the version set in the template") do |opt|
|
@@ -153,7 +165,7 @@ class Options
|
|
153
165
|
parser: OptionParser.new { |opts|
|
154
166
|
opts.banner = "Usage: #{NAME} upload"
|
155
167
|
},
|
156
|
-
argv:
|
168
|
+
argv: md_json_argv_proc
|
157
169
|
},
|
158
170
|
release: {
|
159
171
|
class: ReleaseRunner,
|
@@ -225,4 +237,4 @@ class Runner
|
|
225
237
|
def start
|
226
238
|
options.klass.new(options).start
|
227
239
|
end
|
228
|
-
end
|
240
|
+
end
|
data/lib/bento/common.rb
CHANGED
@@ -36,7 +36,7 @@ module Common
|
|
36
36
|
metadata['name'] = json['name']
|
37
37
|
metadata['version'] = json['version']
|
38
38
|
metadata['box_basename'] = json['box_basename']
|
39
|
-
metadata['
|
39
|
+
metadata['tools'] = json['tools']
|
40
40
|
metadata['providers'] = Hash.new
|
41
41
|
json['providers'].each do |provider|
|
42
42
|
metadata['providers'][provider['name']] = provider.reject { |k, _| k == 'name' }
|
@@ -52,34 +52,10 @@ module Common
|
|
52
52
|
`ls builds/*.json`.split("\n")
|
53
53
|
end
|
54
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
55
|
def bento_version
|
72
56
|
@bento_version ||= ENV['BENTO_VERSION']
|
73
57
|
end
|
74
58
|
|
75
|
-
def cpus
|
76
|
-
1
|
77
|
-
end
|
78
|
-
|
79
|
-
def memory
|
80
|
-
1024
|
81
|
-
end
|
82
|
-
|
83
59
|
def builds
|
84
60
|
YAML.load(File.read("builds.yml"))
|
85
61
|
end
|
@@ -88,39 +64,4 @@ module Common
|
|
88
64
|
proprietary_os_list = %w(macosx sles solaris windows)
|
89
65
|
proprietary_os_list.any? { |p| boxname.include?(p) }
|
90
66
|
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
|
-
begin
|
106
|
-
cmd.run_command
|
107
|
-
case tool
|
108
|
-
when /parallels/
|
109
|
-
ver = cmd.stdout.split(' ')[2]
|
110
|
-
when /fusion/
|
111
|
-
ver = cmd.stderr.split(' ')[5]
|
112
|
-
when /vagrant/
|
113
|
-
ver = cmd.stdout.split(' ')[1]
|
114
|
-
when /virtualbox/
|
115
|
-
ver = cmd.stdout.split('r')[0]
|
116
|
-
else
|
117
|
-
ver = cmd.stdout.split("\n")[0]
|
118
|
-
end
|
119
|
-
tool_versions[tool] = ver
|
120
|
-
rescue
|
121
|
-
tool_versions[tool] = 'None'
|
122
|
-
end
|
123
|
-
end
|
124
|
-
tool_versions
|
125
|
-
end
|
126
67
|
end
|
data/lib/bento/delete.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'bento/common'
|
2
|
-
require 'bento/
|
2
|
+
require 'bento/vagrantcloud'
|
3
3
|
|
4
4
|
class DeleteRunner
|
5
5
|
include Common
|
6
|
-
include
|
6
|
+
include VgCloud
|
7
7
|
|
8
8
|
attr_reader :boxname, :version
|
9
9
|
|
@@ -15,24 +15,8 @@ class DeleteRunner
|
|
15
15
|
def start
|
16
16
|
banner("Starting Delete...")
|
17
17
|
time = Benchmark.measure do
|
18
|
-
|
18
|
+
box_delete_version(boxname, version)
|
19
19
|
end
|
20
20
|
banner("Delete finished in #{duration(time.real)}.")
|
21
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
|
22
|
+
end
|
@@ -10,6 +10,7 @@ class ProviderMetadata
|
|
10
10
|
Dir.glob("#{base}.*.box").map do |file|
|
11
11
|
{
|
12
12
|
name: provider_from_file(file),
|
13
|
+
version: version(provider_from_file(file)),
|
13
14
|
file: "#{File.basename(file)}",
|
14
15
|
checksum_type: "sha256",
|
15
16
|
checksum: shasum(file),
|
@@ -23,10 +24,7 @@ class ProviderMetadata
|
|
23
24
|
attr_reader :base
|
24
25
|
|
25
26
|
def provider_from_file(file)
|
26
|
-
|
27
|
-
when /vmware/i then "vmware_desktop"
|
28
|
-
else provider
|
29
|
-
end
|
27
|
+
file.sub(/^.*\.([^.]+)\.box$/, '\1')
|
30
28
|
end
|
31
29
|
|
32
30
|
def shasum(file)
|
@@ -38,4 +36,35 @@ class ProviderMetadata
|
|
38
36
|
size_mb = size / MEGABYTE
|
39
37
|
size_mb.ceil.to_s
|
40
38
|
end
|
41
|
-
|
39
|
+
|
40
|
+
def version(provider)
|
41
|
+
case provider
|
42
|
+
when /vmware/
|
43
|
+
ver_fusion
|
44
|
+
when /virtualbox/
|
45
|
+
ver_vbox
|
46
|
+
when /parallels/
|
47
|
+
ver_parallels
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def ver_fusion
|
52
|
+
path = File.join('/Applications/VMware\ Fusion.app/Contents/Library')
|
53
|
+
fusion_cmd = File.join(path, "vmware-vmx -v")
|
54
|
+
cmd = Mixlib::ShellOut.new(fusion_cmd)
|
55
|
+
cmd.run_command
|
56
|
+
cmd.stderr.split(' ')[5]
|
57
|
+
end
|
58
|
+
|
59
|
+
def ver_parallels
|
60
|
+
cmd = Mixlib::ShellOut.new("prlctl --version")
|
61
|
+
cmd.run_command
|
62
|
+
cmd.stdout.split(' ')[2]
|
63
|
+
end
|
64
|
+
|
65
|
+
def ver_vbox
|
66
|
+
cmd = Mixlib::ShellOut.new("VBoxManage --version")
|
67
|
+
cmd.run_command
|
68
|
+
cmd.stdout.split('r')[0]
|
69
|
+
end
|
70
|
+
end
|
data/lib/bento/release.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'bento/common'
|
2
|
-
require '
|
2
|
+
require 'bento/vagrantcloud'
|
3
3
|
|
4
4
|
class ReleaseRunner
|
5
5
|
include Common
|
6
|
-
include
|
6
|
+
include VgCloud
|
7
7
|
|
8
8
|
attr_reader :boxname, :version
|
9
9
|
|
@@ -15,32 +15,8 @@ class ReleaseRunner
|
|
15
15
|
def start
|
16
16
|
banner("Starting Release...")
|
17
17
|
time = Benchmark.measure do
|
18
|
-
|
18
|
+
box_release_version(boxname, version)
|
19
19
|
end
|
20
20
|
banner("Release finished in #{duration(time.real)}.")
|
21
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
|
22
|
+
end
|
data/lib/bento/revoke.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'bento/common'
|
2
|
-
require '
|
2
|
+
require 'bento/vagrantcloud'
|
3
3
|
|
4
4
|
class RevokeRunner
|
5
5
|
include Common
|
6
|
-
include
|
6
|
+
include VgCloud
|
7
7
|
|
8
8
|
attr_reader :boxname, :version
|
9
9
|
|
@@ -15,20 +15,8 @@ class RevokeRunner
|
|
15
15
|
def start
|
16
16
|
banner("Starting Revoke...")
|
17
17
|
time = Benchmark.measure do
|
18
|
-
|
18
|
+
box_revoke_version(boxname, version)
|
19
19
|
end
|
20
20
|
banner("Revoke finished in #{duration(time.real)}.")
|
21
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
|
22
|
+
end
|
data/lib/bento/test.rb
CHANGED
@@ -16,9 +16,8 @@ class TestRunner
|
|
16
16
|
banner("Starting testing...")
|
17
17
|
time = Benchmark.measure do
|
18
18
|
metadata_files.each do |metadata_file|
|
19
|
-
m = box_metadata(metadata_file)
|
20
19
|
destroy_all_bento
|
21
|
-
test_box(
|
20
|
+
test_box(metadata_file)
|
22
21
|
destroy_all_bento
|
23
22
|
end
|
24
23
|
end
|
@@ -40,32 +39,17 @@ class TestRunner
|
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
43
|
-
def test_box(
|
44
|
-
|
42
|
+
def test_box(md_json)
|
43
|
+
md = box_metadata(md_json)
|
44
|
+
@boxname = md['name']
|
45
|
+
@providers = md['providers']
|
46
|
+
@share_disabled = shared_folder ? false : true
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
-
|
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 }
|
48
|
+
t_dir = "#{File.expand_path("../../", File.dirname(__FILE__))}/templates"
|
49
|
+
kitchen_cfg = ERB.new(File.read(t_dir + '/kitchen.yml.erb'), nil, '-').result(binding)
|
50
|
+
File.open(".kitchen.yml", "w") { |f| f.puts kitchen_cfg }
|
62
51
|
|
63
|
-
|
64
|
-
|
65
|
-
config = Kitchen::Config.new(loader: @loader)
|
66
|
-
config.instances.each do |instance|
|
67
|
-
instance.test(:always)
|
68
|
-
end
|
69
|
-
end
|
52
|
+
kitchen_test = Mixlib::ShellOut.new("kitchen test", :timeout => 900, live_stream: STDOUT)
|
53
|
+
kitchen_test.run_command
|
70
54
|
end
|
71
|
-
end
|
55
|
+
end
|
data/lib/bento/upload.rb
CHANGED
@@ -1,118 +1,27 @@
|
|
1
|
-
require 'aws-sdk'
|
2
1
|
require 'bento/common'
|
2
|
+
require 'bento/vagrantcloud'
|
3
3
|
|
4
4
|
class UploadRunner
|
5
5
|
include Common
|
6
|
-
include
|
6
|
+
include VgCloud
|
7
7
|
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :md_json
|
9
9
|
|
10
10
|
def initialize(opts)
|
11
|
-
@
|
11
|
+
@md_json = opts.md_json
|
12
12
|
end
|
13
13
|
|
14
14
|
def start
|
15
15
|
banner("Starting uploads...")
|
16
16
|
time = Benchmark.measure do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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' } )
|
17
|
+
if md_json.nil?
|
18
|
+
metadata_files.each do |md_file|
|
19
|
+
box_upload(md_file)
|
20
|
+
end
|
37
21
|
else
|
38
|
-
|
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}")
|
22
|
+
box_upload(md_json)
|
115
23
|
end
|
116
24
|
end
|
25
|
+
banner("Atlas uploads finished in #{duration(time.real)}.")
|
117
26
|
end
|
118
27
|
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'bento/common'
|
2
|
+
require 'bento/httpstuff'
|
3
|
+
|
4
|
+
module VgCloud
|
5
|
+
include Common
|
6
|
+
include HttpStuff
|
7
|
+
|
8
|
+
def vgc_api
|
9
|
+
@vgc_api ||= 'https://vagrantcloud.com/api/v1'
|
10
|
+
end
|
11
|
+
|
12
|
+
def vgc_org
|
13
|
+
@vgc_org ||= ENV['ATLAS_ORG']
|
14
|
+
end
|
15
|
+
|
16
|
+
def vgc_token
|
17
|
+
@vgc_token ||= ENV['ATLAS_TOKEN']
|
18
|
+
end
|
19
|
+
|
20
|
+
def box_create(boxname)
|
21
|
+
req = request('get', "#{vgc_api}/box/#{vgc_org}/#{boxname}", { 'box[username]' => vgc_org, 'access_token' => vgc_token } )
|
22
|
+
if req.code.eql?('404')
|
23
|
+
req = request('post', "#{vgc_api}/boxes", { 'box[name]' => boxname, 'box[username]' => vgc_org, 'access_token' => vgc_token }, { 'Content-Type' => 'application/json' } )
|
24
|
+
box_set_public(boxname) unless private_box?(boxname)
|
25
|
+
else
|
26
|
+
banner("The box #{boxname} exists in Atlas, continuing...")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def box_create_providers(boxname, version, provider_names)
|
31
|
+
provider_names.each do |provider|
|
32
|
+
banner("Creating provider #{provider} for #{boxname} #{version}")
|
33
|
+
req = request('post', "#{vgc_api}/box/#{vgc_org}/#{boxname}/version/#{version}/providers", { 'provider[name]' => provider, 'access_token' => vgc_token }, { 'Content-Type' => 'application/json' } )
|
34
|
+
banner("Created #{provider} for #{boxname} #{version}") if req.code == '200'
|
35
|
+
banner("Provider #{provider} for #{boxname} #{version} already exists, continuing.") if req.code == '422'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def box_create_version(boxname, version, md_json)
|
40
|
+
payload = {
|
41
|
+
'version[version]' => version,
|
42
|
+
'access_token' => vgc_token,
|
43
|
+
'version[description]' => File.read(md_json)
|
44
|
+
}
|
45
|
+
req = request('post', "#{vgc_api}/box/#{vgc_org}/#{boxname}/versions", payload, { 'Content-Type' => 'application/json' } )
|
46
|
+
|
47
|
+
banner("Created box version #{boxname} #{version}.") if req.code == '200'
|
48
|
+
banner("Box version #{boxname} #{version} already exists, continuing.") if req.code == '422'
|
49
|
+
end
|
50
|
+
|
51
|
+
def box_delete_version(boxname, version)
|
52
|
+
banner("Deleting version #{version} of box #{boxname}")
|
53
|
+
req = request('delete', "#{vgc_api}/box/#{vgc_org}/#{boxname}/version/#{version}", { 'access_token' => vgc_token }, { 'Content-Type' => 'application/json' })
|
54
|
+
|
55
|
+
case req.code
|
56
|
+
when '200'
|
57
|
+
banner("Version #{version} of box #{boxname} has been successfully deleted")
|
58
|
+
when '404'
|
59
|
+
warn("No box exists for this version")
|
60
|
+
else
|
61
|
+
warn("Something went wrong #{req.code}")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def box_release_version(boxname, version)
|
66
|
+
case status(boxname, version)
|
67
|
+
when 'unreleased'
|
68
|
+
banner("Releasing version #{version} of box #{boxname}")
|
69
|
+
req = request('put', "#{vgc_api}/box/#{vgc_org}/#{boxname}/version/#{version}/release", { 'access_token' => vgc_token }, { 'Content-Type' => 'application/json' })
|
70
|
+
if req.code == '200'
|
71
|
+
banner("Version #{version} of box #{boxname} has been successfully released")
|
72
|
+
else
|
73
|
+
warn("Something went wrong #{req.code}")
|
74
|
+
end
|
75
|
+
when 'active'
|
76
|
+
banner("Version #{version} of box #{boxname} has already been released - nothing to do")
|
77
|
+
else
|
78
|
+
warn("Unexpected status retrieved from Atlas")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def box_revoke_version(boxname, version)
|
83
|
+
banner("Revoking version #{version} of box #{boxname}")
|
84
|
+
req = request('put', "#{vgc_api}/box/#{vgc_org}/#{boxname}/version/#{version}/revoke", { 'access_token' => vgc_token }, { 'Content-Type' => 'application/json' })
|
85
|
+
if req.code == '200'
|
86
|
+
banner("Version #{version} of box #{boxname} has been successfully revoked")
|
87
|
+
else
|
88
|
+
banner("Something went wrong #{req.code}")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def box_status(boxname, version)
|
93
|
+
req = request('get', "#{vgc_api}/box/#{vgc_org}/#{boxname}/version/#{version}", { 'access_token' => vgc_token }, { 'Content-Type' => 'application/json' })
|
94
|
+
status = JSON.parse(req.body)['status']
|
95
|
+
end
|
96
|
+
|
97
|
+
def box_set_public(boxname)
|
98
|
+
banner("Making #{boxname} public")
|
99
|
+
req = request('put', "#{vgc_api}/box/#{vgc_org}/#{boxname}", { 'box[is_private]' => false, 'access_token' => vgc_token }, { 'Content-Type' => 'application/json' } )
|
100
|
+
banner("#{boxname} successfully made public") if req.code == '200'
|
101
|
+
end
|
102
|
+
|
103
|
+
def box_upload(md_file)
|
104
|
+
md = box_metadata(md_file)
|
105
|
+
boxname = md['name']
|
106
|
+
version = md['version']
|
107
|
+
providers = md['providers']
|
108
|
+
|
109
|
+
box_create(boxname)
|
110
|
+
box_create_version(boxname, version, md_file)
|
111
|
+
box_create_providers(boxname, version, providers.keys)
|
112
|
+
|
113
|
+
providers.each do |provider, provider_data|
|
114
|
+
boxfile = provider_data['file']
|
115
|
+
req = request('get', "#{vgc_api}/box/#{vgc_org}/#{boxname}/version/#{version}/provider/#{provider}/upload?access_token=#{vgc_token}")
|
116
|
+
upload_path = JSON.parse(req.body)['upload_path']
|
117
|
+
token = JSON.parse(req.body)['token']
|
118
|
+
|
119
|
+
banner("Vagrant Cloud: Uploading #{boxfile}")
|
120
|
+
info("Name: #{boxname}")
|
121
|
+
info("Version: #{version}")
|
122
|
+
info("Provider: #{provider}")
|
123
|
+
|
124
|
+
upload_request = request('put', upload_path, File.open("builds/#{boxfile}"))
|
125
|
+
|
126
|
+
req = request('get', "#{vgc_api}/box/#{vgc_org}/#{boxname}/version/#{version}/provider/#{provider}?access_token=#{vgc_token}")
|
127
|
+
hosted_token = JSON.parse(req.body)['hosted_token']
|
128
|
+
|
129
|
+
if token == hosted_token
|
130
|
+
banner("Successful upload of box #{boxfile}")
|
131
|
+
else
|
132
|
+
banner("Failed upload due to non-matching tokens of box #{boxfile} to atlas box: #{boxname}, version: #{version}, provider: #{provider}")
|
133
|
+
warn("Code: #{req.code}")
|
134
|
+
warn("Body: #{req.body}")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
data/lib/bento/version.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
---
|
2
|
+
provisioner:
|
3
|
+
name: <%= @provisioner %>
|
4
|
+
|
5
|
+
platforms:
|
6
|
+
<% @providers.each do |k,v| -%>
|
7
|
+
- name: <%= @boxname + '-' + k %>
|
8
|
+
driver:
|
9
|
+
name: vagrant
|
10
|
+
<% if k == 'vmware' -%>
|
11
|
+
<% if RUBY_PLATFORM.match(/darwin/) -%>
|
12
|
+
provider: <%= k + '_fusion' %>
|
13
|
+
<% else -%>
|
14
|
+
provider: <%= k + '_workstation' %>
|
15
|
+
<% end -%>
|
16
|
+
<% else -%>
|
17
|
+
provider: <%= k %>
|
18
|
+
<% end -%>
|
19
|
+
box: bento-<%= @boxname %>
|
20
|
+
box_url: file://<%= ENV['PWD'] %>/builds/<%= v['file'] %>
|
21
|
+
synced_folders:
|
22
|
+
- [".", "/vagrant", "disabled: <%= @share_disabled %>"]
|
23
|
+
|
24
|
+
<% end -%>
|
25
|
+
suites:
|
26
|
+
- name: default
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bento-ya
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Seth Thomas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -24,34 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '11.2'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: test-kitchen
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.14'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.14'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: aws-sdk
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '2.6'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '2.6'
|
55
27
|
- !ruby/object:Gem::Dependency
|
56
28
|
name: buildkit
|
57
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,7 +69,9 @@ files:
|
|
97
69
|
- lib/bento/revoke.rb
|
98
70
|
- lib/bento/test.rb
|
99
71
|
- lib/bento/upload.rb
|
72
|
+
- lib/bento/vagrantcloud.rb
|
100
73
|
- lib/bento/version.rb
|
74
|
+
- templates/kitchen.yml.erb
|
101
75
|
homepage: https://github.com/cheeseplus/bento-ya
|
102
76
|
licenses:
|
103
77
|
- Apache-2.0
|
@@ -118,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
92
|
version: '0'
|
119
93
|
requirements: []
|
120
94
|
rubyforge_project:
|
121
|
-
rubygems_version: 2.6.
|
95
|
+
rubygems_version: 2.6.11
|
122
96
|
signing_key:
|
123
97
|
specification_version: 4
|
124
98
|
summary: A RubyGem for managing chef/bento builds
|