Merge pull request #2616 from dcermak/add-vagrant-publisher

Add pipeline to publish the vagrant boxes to Vagrant Cloud
This commit is contained in:
Stephan Kulow 2021-10-22 17:33:50 +02:00 committed by GitHub
commit c7c2beb46b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 166 additions and 1 deletions

View File

@ -5,7 +5,7 @@ pipelines:
lock_behavior: unlockWhenFinished
environment_variables:
OSC_CONFIG: /home/go/config/oscrc-totest-manager
RSYNC_PASSWORD: '{{SECRET:[RSYNC_FOR_COOLO][RSYNC_FOR_COOLO]}}'
RSYNC_PASSWORD: '{{SECRET:[opensuse.secrets][RSYNC_FOR_COOLO]}}'
materials:
script:
git: https://github.com/openSUSE/openSUSE-release-tools.git

View File

@ -0,0 +1,22 @@
format_version: 3
pipelines:
openSUSE.Vagrant.Publish:
group: openSUSE.Checkers
lock_behavior: unlockWhenFinished
environment_variables:
ATLAS_TOKEN: '{{SECRET:[opensuse.secrets][ATLAS_TOKEN]}}'
materials:
git:
git: https://github.com/openSUSE/opensuse-release-tools.git
timer:
spec: 0 0 0 ? * *
only_on_changes: false
stages:
- Run:
approval: manual
resources:
- obs-to-vagrantcloud
tasks:
- script: |
ruby.ruby3.0 obs-to-vagrantcloud.rb --url https://download.opensuse.org/tumbleweed/appliances/boxes/Tumbleweed.x86_64.json --organization opensuse --new-box-name Tumbleweed.x86_64 --provider libvirt
ruby.ruby3.0 obs-to-vagrantcloud.rb --url https://download.opensuse.org/tumbleweed/appliances/boxes/Tumbleweed.x86_64.json --organization opensuse --new-box-name Tumbleweed.x86_64 --provider virtualbox

143
obs-to-vagrantcloud.rb Normal file
View File

@ -0,0 +1,143 @@
# frozen_string_literal: true
require 'vagrant_cloud'
require 'down/net_http'
require 'http'
require 'optparse'
require 'optparse/uri'
require 'open-uri'
require 'fileutils'
def ensure_box_present(box_from_obs, org)
matching_boxes = org.boxes.select { |b| b.name == box_from_obs['name'] }
matching_box = nil
if matching_boxes.empty?
matching_box = org.add_box(box_from_obs['name'])
matching_box.private = false
matching_box.description = box_from_obs['description']
matching_box.short_description = box_from_obs['short_description']
elsif matching_boxes.length > 1
raise "Got #{matching_boxes.length} matching boxes, but should have gotten at most one"
else
matching_box = matching_boxes[0]
end
matching_box
end
def link_box(box_from_obs, org)
matching_box = ensure_box_present(box_from_obs, org)
matching_box.versions.each(&:delete)
matching_box.versions = []
matching_box.save
box_from_obs['versions'].each do |version|
ver = matching_box.add_version(version['version'])
ver.description = version['description']
version['providers'].each do |provider|
prov = ver.add_provider(provider['name'])
prov.url = provider['url']
end
ver.save
ver.release
end
matching_box.save
matching_box
end
##
# Uploads the box specified in the hash box_from_obs to VagrantCloud using the
# supplied organization.
def upload_non_existent_boxes(box_from_obs, organization, provider_to_upload)
matching_box = ensure_box_present(box_from_obs, organization)
box_from_obs['versions'].each do |version|
matching_versions = matching_box.versions.select { |v| v.version == version['version'] }
matching_version = nil
if matching_versions.length == 1
matching_version = matching_versions[0]
elsif matching_versions.empty?
matching_box.save
matching_version = matching_box.add_version(version['version'])
matching_version.description = version['description']
else
raise "Got #{matching_versions.length} matching versions, but should have gotten one or none"
end
provider_added = false
not_present_providers = version['providers'].select do |prov_from_obs|
matching_version.providers.select { |p| p.name == prov_from_obs['name'] }.empty?
end
unless provider_to_upload.nil?
not_present_providers = not_present_providers.select { |p| p['name'] == provider_to_upload }
end
not_present_providers.each do |provider|
prov = matching_version.add_provider(provider['name'])
begin
box_dest = Down::NetHttp.download(provider['url'], max_redirects: 20)
matching_box.save
prov.upload(path: box_dest.path)
provider_added = true
ensure
box_dest.close
box_dest.unlink
end
end
matching_version.release if provider_added && !matching_version.released?
end
matching_box
end
env_var = 'ATLAS_TOKEN'
raise "Environment variable #{env_var} is required" if ENV[env_var].nil?
options = {}
OptionParser.new do |opts|
opts.on('--url URI', 'URL to json file published on OBS') do |u|
options[:url] = u
end
opts.on('--organization ORG', 'organization/publisher of the vagrant box') do |p|
options[:publisher] = p
end
opts.on('-n NAME', '--new-box-name NAME', 'alternative name for the Vagrant box') do |n|
options[:name] = n
end
opts.on('-p PROVIDER', '--provider PROVIDER', 'only upload the supplied provider (unsupported for linking!)') do |p|
options[:provider] = p
end
opts.on('-l', '--link', 'just link the box to from OBS and don\'t upload it') do
options[:link] = true
end
end.parse!
raise 'An organization must be provided' if options[:publisher].nil?
options[:link] = false if options[:link].nil?
raise 'Linking only a single provider is not supported' if options[:link] && !options[:provider].nil?
box_json = JSON.parse(HTTP.get(options[:url]))
account = VagrantCloud::Account.new(access_token: ENV[env_var])
publisher = account.organization(name: options[:publisher])
box_json['name'] = options[:name] unless options[:name].nil?
if options[:link]
link_box(box_json, publisher)
else
upload_non_existent_boxes(box_json, publisher, options[:provider])
end