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