bento-ya 0.1.4 → 1.0.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/.travis.yml +19 -0
- data/CHANGELOG.md +20 -1
- data/Gemfile +11 -2
- data/README.md +1 -1
- data/Rakefile +22 -1
- data/bento-ya.gemspec +4 -5
- data/bin/bento +1 -1
- data/lib/bento.rb +2 -2
- data/lib/bento/build.rb +19 -13
- data/lib/bento/buildmetadata.rb +10 -10
- data/lib/bento/cli.rb +47 -64
- data/lib/bento/common.rb +55 -17
- data/lib/bento/delete.rb +6 -6
- data/lib/bento/normalize.rb +5 -6
- data/lib/bento/packerexec.rb +0 -1
- data/lib/bento/providermetadata.rb +26 -12
- data/lib/bento/release.rb +7 -7
- data/lib/bento/revoke.rb +7 -7
- data/lib/bento/test.rb +15 -11
- data/lib/bento/upload.rb +19 -10
- data/lib/bento/version.rb +1 -1
- data/templates/bootstrap.sh.erb +1 -0
- data/templates/kitchen.yml.erb +3 -3
- metadata +11 -26
- data/lib/bento/build_remote.rb +0 -116
- data/lib/bento/httpstuff.rb +0 -73
- data/lib/bento/vagrantcloud.rb +0 -138
data/lib/bento/build_remote.rb
DELETED
@@ -1,116 +0,0 @@
|
|
1
|
-
require 'buildkit'
|
2
|
-
|
3
|
-
class BuildRemoteRunner
|
4
|
-
include Common
|
5
|
-
|
6
|
-
attr_reader :bento_version, :dry_run, :platforms, :queue, :token, :s3_endpoint, :s3_bucket
|
7
|
-
|
8
|
-
def initialize(opts)
|
9
|
-
@dry_run = opts.dry_run
|
10
|
-
@bento_version = opts.override_version
|
11
|
-
@platforms = opts.platforms
|
12
|
-
@org = ENV['BUILDKITE_ORG']
|
13
|
-
@queue = ENV['BUILDKITE_QUEUE']
|
14
|
-
@token = ENV['BUILDKITE_TOKEN']
|
15
|
-
@s3_endpoint ||= ENV['BENTO_S3_ENDPOINT'] # 'https://s3.amazonaws.com''
|
16
|
-
@s3_bucket ||= ENV['BENTO_S3_BUCKET'] # 'opscode-vm-bento''
|
17
|
-
end
|
18
|
-
|
19
|
-
def start
|
20
|
-
msg_pre = dry_run ? "DRY RUN: " : ""
|
21
|
-
|
22
|
-
banner("#{msg_pre}Scheduling builds for Bento Version: #{bento_version}")
|
23
|
-
time = Benchmark.measure do
|
24
|
-
builds['public'].each do |platform, versions|
|
25
|
-
versions.each do |version, archs|
|
26
|
-
archs.each do |arch|
|
27
|
-
builds['providers'].each do |provider|
|
28
|
-
build(platform, version, arch, provider, bento_version, dry_run)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
banner("#{msg_pre}Scheduling finished in #{duration(time.real)}.")
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def bk_uri
|
40
|
-
"v1/organizations/#{org}"
|
41
|
-
end
|
42
|
-
|
43
|
-
def bento_upload
|
44
|
-
"1"
|
45
|
-
end
|
46
|
-
|
47
|
-
def build(platform, version, arch, provider, bento_version, dry_run)
|
48
|
-
plat = platform.include?('omnios') ? "#{platform}-#{version}" : "#{platform}-#{version}-#{arch}"
|
49
|
-
atlas_name = /(.*)64/.match(arch) ? plat.chomp("-#{arch}") : plat
|
50
|
-
no_shared = builds['no_shared_folder'].include?("#{platform}-#{version}-#{arch}-#{provider}") || builds['no_shared_folder'].include?("#{platform}-#{version}-#{arch}-all")
|
51
|
-
test_shared = no_shared ? "0" : "1"
|
52
|
-
unless builds['broken'].include?("#{plat}-#{provider}") || builds['broken'].include?("#{plat}-all")
|
53
|
-
build = {
|
54
|
-
"commit"=> "HEAD",
|
55
|
-
"branch"=> "master",
|
56
|
-
"message"=> "#{plat}-#{provider}",
|
57
|
-
"env"=> {
|
58
|
-
"ATLAS_ORG" => atlas_org,
|
59
|
-
"ATLAS_TOKEN" => atlas_token,
|
60
|
-
"ATLAS_NAME" => atlas_name,
|
61
|
-
"AWS_ACCESS_KEY_ID" => ENV['AWS_ACCESS_KEY_ID'],
|
62
|
-
"AWS_SECRET_ACCESS_KEY" => ENV['AWS_SECRET_ACCESS_KEY'],
|
63
|
-
"AWS_REGION" => 'us-east-1',
|
64
|
-
"BENTO_TEST_SHARED_FOLDER" => test_shared,
|
65
|
-
"BENTO_UPLOAD" => bento_upload,
|
66
|
-
"BENTO_VERSION" => bento_version,
|
67
|
-
"BENTO_S3_ENDPOINT" => s3_endpoint,
|
68
|
-
"BENTO_S3_BUCKET" => s3_bucket,
|
69
|
-
"BENTO_PROVIDERS" => provider,
|
70
|
-
"PLATFORM" => plat,
|
71
|
-
}
|
72
|
-
}
|
73
|
-
puts " - #{plat}-#{provider}"
|
74
|
-
client.post("/#{bk_uri}/projects/bento-#{provider.chomp('-iso')}/builds", build) unless dry_run
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def client
|
79
|
-
Buildkit.new(token: token)
|
80
|
-
end
|
81
|
-
|
82
|
-
def create_project
|
83
|
-
project = {
|
84
|
-
"name"=> project,
|
85
|
-
"repository"=>"git@github.com:chef/bento.git",
|
86
|
-
"env"=>{"BUILDKITE_BIN_PATH" => "/usr/local/opt/buildkite-agent/bin"},
|
87
|
-
"steps"=>
|
88
|
-
[{"type"=>"script",
|
89
|
-
"name"=>"build",
|
90
|
-
"command"=>"build.sh",
|
91
|
-
"agent_query_rules"=>["queue=#{queue}"]
|
92
|
-
}
|
93
|
-
]
|
94
|
-
}
|
95
|
-
|
96
|
-
puts "Creating Project #{project['name']}"
|
97
|
-
client.post("/#{bk_uri}/projects", project)
|
98
|
-
end
|
99
|
-
|
100
|
-
def delete_project
|
101
|
-
banner("Deleting Project #{project['name']}")
|
102
|
-
client.delete("/#{bk_uri}/projects/#{project}")
|
103
|
-
end
|
104
|
-
|
105
|
-
def get_builders(provider)
|
106
|
-
organization = client.organization(org)
|
107
|
-
agents = organization.rels[:agents].get.data
|
108
|
-
|
109
|
-
banner("Available Builders for provider: #{provider}")
|
110
|
-
agents.each do |agent|
|
111
|
-
if agent[:meta_data].include? "#{provider.chomp('-iso')}=true"
|
112
|
-
puts " - #{agent[:name]}"
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
data/lib/bento/httpstuff.rb
DELETED
@@ -1,73 +0,0 @@
|
|
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
|
data/lib/bento/vagrantcloud.rb
DELETED
@@ -1,138 +0,0 @@
|
|
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 box_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
|