rightimage_tools 0.2.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -1
- data/Rakefile +4 -23
- data/VERSION +1 -1
- data/bin/azure_api +31 -0
- data/bin/azure_migrate +174 -0
- data/bin/azure_publish +213 -0
- data/bin/image_mover +2 -2
- data/bin/mci_merge +10 -4
- data/bin/mci_report +232 -0
- data/bin/mcicp +52 -0
- data/bin/report_tool +404 -0
- data/bin/update_mcis +65 -0
- data/bin/update_s3_index +30 -4
- data/lib/azure_helper.rb +90 -0
- data/lib/mci.rb +95 -71
- data/lib/s3_html_indexer.rb +171 -52
- data/lib/util.rb +8 -7
- data/spec/mci_spec.rb +4 -10
- data/ui/build/empty_bucket_index.html +81 -0
- data/ui/build/index-to.html +241 -0
- data/ui/build/report_viewer.html +397 -0
- metadata +68 -42
data/Gemfile
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
2
|
|
3
3
|
gem "rest_connection"
|
4
|
+
gem "right_api_client"
|
4
5
|
gem "right_aws"
|
5
6
|
|
6
7
|
# Add dependencies to develop your gem here.
|
7
8
|
# Include everything needed to run rake, tests, features, etc.
|
8
9
|
group :development do
|
9
10
|
gem "rspec", "~> 2.3.0"
|
10
|
-
gem "bundler", "~> 1.
|
11
|
+
# gem "bundler", "~> 1.1.4"
|
11
12
|
gem "jeweler", "~> 1.6.4"
|
12
13
|
gem "rcov", ">= 0"
|
13
14
|
gem "flexmock"
|
15
|
+
gem "json", "~> 1.7.5"
|
14
16
|
end
|
data/Rakefile
CHANGED
@@ -22,7 +22,10 @@ Jeweler::Tasks.new do |gem|
|
|
22
22
|
gem.license = "MIT"
|
23
23
|
gem.summary = %Q{A set of tools to support the building of RightImages}
|
24
24
|
gem.files = %w(LICENSE.txt VERSION README.rdoc Rakefile Gemfile) + FileList["{bin,lib,spec}/**/*"].to_a
|
25
|
-
|
25
|
+
# Include built ui files while ignoring their sources.
|
26
|
+
# Used to include report_viewer.html.
|
27
|
+
gem.files.include FileList["ui/build/**/*"].to_a
|
28
|
+
gem.executables = %w(image_mover mci_merge report_tool update_s3_index)
|
26
29
|
gem.description = gem.summary
|
27
30
|
gem.email = "peter.schroeter@rightscale.com"
|
28
31
|
gem.authors = ["Peter Schroeter"]
|
@@ -30,25 +33,3 @@ Jeweler::Tasks.new do |gem|
|
|
30
33
|
end
|
31
34
|
Jeweler::RubygemsDotOrgTasks.new
|
32
35
|
|
33
|
-
require 'rspec/core'
|
34
|
-
require 'rspec/core/rake_task'
|
35
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
36
|
-
spec.pattern = FileList['spec/**/*_spec.rb']
|
37
|
-
end
|
38
|
-
|
39
|
-
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
40
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
41
|
-
spec.rcov = true
|
42
|
-
end
|
43
|
-
|
44
|
-
task :default => :spec
|
45
|
-
|
46
|
-
require 'rake/rdoctask'
|
47
|
-
Rake::RDocTask.new do |rdoc|
|
48
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
49
|
-
|
50
|
-
rdoc.rdoc_dir = 'rdoc'
|
51
|
-
rdoc.title = "rightimage_tools #{version}"
|
52
|
-
rdoc.rdoc_files.include('README*')
|
53
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
54
|
-
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/bin/azure_api
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ruby-debug'
|
4
|
+
require 'right_cloud_api'
|
5
|
+
require File.expand_path("../../lib/azure_helper",__FILE__)
|
6
|
+
require 'cloud/azure/storage/manager'
|
7
|
+
require 'uri'
|
8
|
+
require 'yaml'
|
9
|
+
|
10
|
+
include AzureHelper
|
11
|
+
|
12
|
+
account = ARGV.shift
|
13
|
+
cmd = ARGV.shift
|
14
|
+
params = {}
|
15
|
+
ARGV.each do |p|
|
16
|
+
(k,v) = p.split(/[=:]/)
|
17
|
+
params[k] = v
|
18
|
+
end
|
19
|
+
|
20
|
+
unless account && cmd
|
21
|
+
puts "USAGE: azure_api <account> <api_command> [param1=value1] [param2=value2]"
|
22
|
+
puts "EXAMPLE: azure_api rightscalewestus ListBlobs Container=rightimage-linux"
|
23
|
+
exit 1
|
24
|
+
end
|
25
|
+
|
26
|
+
password = lookup_password(account)
|
27
|
+
endpoint = "https://#{account}.blob.core.windows.net"
|
28
|
+
|
29
|
+
@azure = RightScale::CloudApi::Azure::Storage::Manager.new(account, password, endpoint, :api_version=>'2012-02-12')
|
30
|
+
puts "CALLING #{cmd} WITH #{params.inspect}"
|
31
|
+
api_dump(@azure,cmd,params)
|
data/bin/azure_migrate
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ruby-debug'
|
4
|
+
require 'right_cloud_api'
|
5
|
+
require 'cloud/azure/storage/manager'
|
6
|
+
require File.expand_path("../../lib/azure_helper",__FILE__)
|
7
|
+
require 'uri'
|
8
|
+
require 'yaml'
|
9
|
+
|
10
|
+
include AzureHelper
|
11
|
+
|
12
|
+
class CopyState
|
13
|
+
attr_accessor :account
|
14
|
+
attr_accessor :api
|
15
|
+
attr_accessor :state
|
16
|
+
def initialize(api, account, state = "pending")
|
17
|
+
@api = api
|
18
|
+
@account = account
|
19
|
+
@state = state
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
url_src = ARGV.shift
|
24
|
+
url_dst = ARGV.shift
|
25
|
+
image_name = ARGV.shift
|
26
|
+
unless url_src =~ /^http/ and url_dst =~ /^http|^(linux|rswin|mswin|windows)$/
|
27
|
+
puts <<-EOF
|
28
|
+
USAGE: azure_migrate URL_TO_SRC_BLOB URL_TO_DEST_BLOB
|
29
|
+
USAGE: azure_migrate URL_TO_SRC_BLOB <linux|rswin|mswin> <image name>
|
30
|
+
if URL_TO_DEST_BLOB is 'windows' or 'linux', program will copy
|
31
|
+
image to all linux or windows image accounts. 'rswin' for rightscale
|
32
|
+
accounts (for testing), and mswin is microsoft (official publish)
|
33
|
+
also acceptable parameters
|
34
|
+
For the first usage you might use this for migrating to non-standard
|
35
|
+
accounts, such as test or services
|
36
|
+
Second usage is preferred for a publishing type event
|
37
|
+
EXAMPLE: azure_migrate https://linuxros.blob.core.windows.net/vm-images/RightImage-CentOS-6.2-x64-v5.8.8.1.vhd https://rightscalewestus.blob.core.windows.net/vm-images/RightImage-CentOS-6.2-x64-v5.8.8.1.vhd
|
38
|
+
EXAMPLE: azure_migrate https://linuxros.blob.core.windows.net/vm-images/RightImage-CentOS-6.2-x64-v5.8.8.1.vhd linux RightImage-CentOS-6.2-x64-v5.8.8.1.vhd
|
39
|
+
EXAMPLE: azure_migrate http://ds1p6hm133skyrl.blob.core.windows.net/vhds/1vqtgdr5.xwr20120719072616.vhd rswin RightImage-Windows-2008R2-SP1-x64-sqlsvr2012-v5.8.8.vhd
|
40
|
+
EOF
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
|
44
|
+
# This function takes an url to a blob and grants read access to it
|
45
|
+
# by signing a request for read access with the account's shared key
|
46
|
+
# The request is made using GET parameters described in bits hash
|
47
|
+
def generate_shared_access_key(url)
|
48
|
+
(account,password,endpoint,container,blob) = parse_url(url)
|
49
|
+
|
50
|
+
url_new = url.dup
|
51
|
+
t = Time.now.utc
|
52
|
+
# t1 = Time.now.utc + (60*60*24)
|
53
|
+
# fmt = '%Y-%m-%d'
|
54
|
+
t1 = Time.now.utc + (3600*8)
|
55
|
+
fmt = '%Y-%m-%dT%H:%MZ'
|
56
|
+
sig_fields = ["sp","st","se","crsrc","si", "sv"]
|
57
|
+
get_param_fields = ["sp","st","se","sr", "sv", "sig"]
|
58
|
+
bits = {
|
59
|
+
'sp' => 'r', # grant holder of this url read access
|
60
|
+
'sr' => 'b', # for a blob
|
61
|
+
'crsrc' => "/#{account}/#{container}/#{blob}", # denoted by this resource
|
62
|
+
'st' => t.strftime(fmt), # starting now
|
63
|
+
'se' => t1.strftime(fmt), # and ending in 8 hours
|
64
|
+
'sv' => '2012-02-12' #api version, required
|
65
|
+
}
|
66
|
+
header = sig_fields.map {|b| bits[b] || ""}.join("\x0A")
|
67
|
+
header = header.toutf8 if header.respond_to?(:toutf8)
|
68
|
+
# Now sign the request with the shared key
|
69
|
+
bits["sig"] = Base64.encode64(HMAC::SHA256.new(Base64.decode64(password)).update(URI.decode(header)).digest).chomp
|
70
|
+
get_params = get_param_fields.map do |p|
|
71
|
+
p+"="+URI.escape(bits[p], Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
72
|
+
end
|
73
|
+
url_new << "?" << get_params.join("&")
|
74
|
+
# puts "HEADER: ---------------"
|
75
|
+
puts header
|
76
|
+
puts "-----------------------"
|
77
|
+
puts "URL: #{url}"
|
78
|
+
puts "SIGNATURE: #{bits["sig"]}"
|
79
|
+
puts "URL_SIGNED: #{url_new}"
|
80
|
+
return url_new
|
81
|
+
end
|
82
|
+
|
83
|
+
if url_dst == "linux"
|
84
|
+
account_names = RS_LINUX_ACCOUNTS
|
85
|
+
container = "rightimage-linux"
|
86
|
+
blob = image_name
|
87
|
+
elsif url_dst == "windows"
|
88
|
+
account_names = RS_LINUX_ACCOUNTS + RS_WINDOWS_ACCOUNTS
|
89
|
+
container = "rightimage-windows"
|
90
|
+
blob = image_name
|
91
|
+
elsif url_dst == "rswin"
|
92
|
+
account_names = RS_LINUX_ACCOUNTS
|
93
|
+
container = "rightimage-windows"
|
94
|
+
blob = image_name
|
95
|
+
elsif url_dst == "mswin"
|
96
|
+
account_names = RS_WINDOWS_ACCOUNTS
|
97
|
+
container = "rightimage-windows"
|
98
|
+
blob = image_name
|
99
|
+
else
|
100
|
+
(account,password,endpoint,container,blob) = parse_url(url_dst)
|
101
|
+
account_names = [account]
|
102
|
+
end
|
103
|
+
|
104
|
+
if url_dst =~ /^linux|^rswin|^mswin/
|
105
|
+
raise "Destination vhd name must be supplied when using mass copy" unless image_name and image_name =~ /./
|
106
|
+
raise "Image name must end in .vhd" unless image_name and image_name =~ /.vhd/
|
107
|
+
end
|
108
|
+
|
109
|
+
transfers = account_names.map do |account|
|
110
|
+
password = lookup_password(account)
|
111
|
+
endpoint = "https://#{account}.blob.core.windows.net"
|
112
|
+
CopyState.new(
|
113
|
+
RightScale::CloudApi::Azure::Storage::Manager.new(account, password, endpoint, :api_version=>'2012-02-12'),
|
114
|
+
account
|
115
|
+
)
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
url_src_signed = generate_shared_access_key(url_src)
|
120
|
+
puts "COPYING #{url_src}"
|
121
|
+
transfers.each do |t|
|
122
|
+
puts "TO #{t.account}/#{container}/#{blob}"
|
123
|
+
begin
|
124
|
+
t.api.GetBlobProperties('Container' => container, 'Blob' => blob)
|
125
|
+
rescue
|
126
|
+
end
|
127
|
+
if t.api.response.code.to_s =~ /^2/
|
128
|
+
puts "Blob already exists for #{t.account}, polling status"
|
129
|
+
else
|
130
|
+
puts "Running CopyBlob command for #{t.account} then polling status"
|
131
|
+
api_dump(t.api, "CopyBlob","Container"=>container,"Blob"=>blob,"Source"=>url_src_signed)
|
132
|
+
if t.api.response.code.to_s !~ /^2/
|
133
|
+
raise "ERROR account #{t.account} response code for CopyBlob not in 2xx range"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
240.times do
|
139
|
+
transfers.each_with_index do |t,i|
|
140
|
+
t.api.GetBlobProperties('Container' => container, 'Blob' => blob)
|
141
|
+
status = t.api.response.headers["x-ms-copy-status"].first
|
142
|
+
if t.api.response.code.to_s !~ /^2/
|
143
|
+
raise "ERROR account #{t.account} container #{container} blob #{blob} response code for GetBlobProperties not in 2xx range"
|
144
|
+
end
|
145
|
+
progress = t.api.response.headers["x-ms-copy-progress"].first
|
146
|
+
if progress =~ /[0-9]+\/[0-9]+/
|
147
|
+
(a,b) = progress.split("/")
|
148
|
+
progress = sprintf("%3s%" % [(a.to_i*100/b.to_i).to_s])
|
149
|
+
end
|
150
|
+
if status =~ /success/
|
151
|
+
progress = "DONE"
|
152
|
+
elsif status =~ /fail/
|
153
|
+
progress = "FAIL"
|
154
|
+
end
|
155
|
+
case status
|
156
|
+
when /fail/ then t.state = :failure
|
157
|
+
when /success/ then t.state = :success
|
158
|
+
when /pending/ then t.state = :pending
|
159
|
+
else t.state = :unknown
|
160
|
+
end
|
161
|
+
print "#{t.account.sub("rightscale","")}[#{progress}] "
|
162
|
+
print "\n" if (i % RS_LINUX_ACCOUNTS.size == (RS_LINUX_ACCOUNTS.size - 1))
|
163
|
+
end
|
164
|
+
# print "\n"
|
165
|
+
break unless transfers.find {|t| t.state == :pending }
|
166
|
+
sleep 30
|
167
|
+
end
|
168
|
+
if transfers.all? { |t| t.state == :success }
|
169
|
+
puts "ALL successful!"
|
170
|
+
exit 0
|
171
|
+
else
|
172
|
+
puts "ERROR occurred, or we timed out, maybe run this command again"
|
173
|
+
exit 1
|
174
|
+
end
|
data/bin/azure_publish
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#require 'ruby-debug'
|
4
|
+
require 'right_cloud_api'
|
5
|
+
require 'cloud/azure/storage/manager'
|
6
|
+
require File.expand_path("../../lib/azure_helper",__FILE__)
|
7
|
+
require 'uri'
|
8
|
+
require 'yaml'
|
9
|
+
require 'json'
|
10
|
+
require 'pp'
|
11
|
+
|
12
|
+
include AzureHelper
|
13
|
+
|
14
|
+
def deregister_image(accounts, image_name)
|
15
|
+
images = registered_images(image_name)
|
16
|
+
if images.size == 0
|
17
|
+
puts "Found no images matching name or blob"
|
18
|
+
else
|
19
|
+
puts "Found images to deregister: "
|
20
|
+
images.each_with_index do |image, i|
|
21
|
+
puts (i+1).to_s + ") Name: " + image['Name']
|
22
|
+
puts "Location: " + image['Location']
|
23
|
+
puts "Blob: " + image['MediaLink'].to_s if image['MediaLink']
|
24
|
+
puts #{i['Name']} #{i['MediaLink'].to_s} #{i['Location']}"
|
25
|
+
end
|
26
|
+
print "Proceed? [yes|no] "
|
27
|
+
proceed = STDIN.gets
|
28
|
+
if proceed =~ /^[yY]/
|
29
|
+
images.each_with_index do |image, i|
|
30
|
+
`azure vm image delete #{image['Name']}`
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def registered_images(image_name)
|
37
|
+
images = JSON.parse(`azure vm image list --json`.chomp)
|
38
|
+
registered = []
|
39
|
+
image_name = image_name.sub(".vhd","").downcase
|
40
|
+
images.each do |i|
|
41
|
+
# pp i
|
42
|
+
link_name = i["MediaLink"].to_s.dup
|
43
|
+
name = i["Name"].dup
|
44
|
+
link_name = link_name.sub(".vhd","").downcase
|
45
|
+
name = name.sub(".vhd","").downcase
|
46
|
+
AZURE_LINUX_LOCATIONS.values.each do |location|
|
47
|
+
link_name = link_name.sub(location.sub(" ","-"),"")
|
48
|
+
name = name.sub(location.sub(" ","-"),"")
|
49
|
+
end
|
50
|
+
# p "L #{link_name} IM #{image_name} N #{name}"
|
51
|
+
if link_name == image_name or
|
52
|
+
link_name.split("/").last == image_name or
|
53
|
+
name == image_name
|
54
|
+
registered << i
|
55
|
+
end
|
56
|
+
end
|
57
|
+
return registered
|
58
|
+
end
|
59
|
+
|
60
|
+
def register_image(accounts, container, image_url)
|
61
|
+
images = JSON.parse(`azure vm image list --json`)
|
62
|
+
accounts.each do |account, api|
|
63
|
+
next if account =~ /win$/
|
64
|
+
image_name = image_url.split("/").last
|
65
|
+
image_name = image_name.sub(".vhd","")
|
66
|
+
regional_image_url = "https://#{account}.blob.core.windows.net/#{container}/#{image_name}.vhd"
|
67
|
+
name_with_region = image_name + "-" + AZURE_LINUX_LOCATIONS[account].gsub(" ","-")
|
68
|
+
image_name_clean = image_name.gsub(/[_-]/," ")
|
69
|
+
|
70
|
+
if registered_images(name_with_region).size > 0
|
71
|
+
puts "Image #{name_with_region} already registered"
|
72
|
+
else
|
73
|
+
begin
|
74
|
+
results = api.GetBlobMetadata('Container' => container, 'Blob'=>"#{image_name}.vhd")
|
75
|
+
is_public = false
|
76
|
+
if api.response.headers.key?("x-ms-meta-rs_public")
|
77
|
+
is_public = true
|
78
|
+
end
|
79
|
+
found_image = true
|
80
|
+
rescue
|
81
|
+
found_image = false
|
82
|
+
end
|
83
|
+
if found_image
|
84
|
+
unless is_public
|
85
|
+
puts "WARNING: Image for region #{account} is not public, registering anyways"
|
86
|
+
end
|
87
|
+
puts "azure vm image create --label \"#{image_name_clean}\" --os #{OS_TYPE} --blob-url \"#{regional_image_url}\" \"#{name_with_region}\""
|
88
|
+
puts `azure vm image create --label \"#{image_name_clean}\" --os #{OS_TYPE} --blob-url \"#{regional_image_url}\" \"#{name_with_region}\"`
|
89
|
+
else
|
90
|
+
puts "Could not find image #{regional_image_url} for account #{account}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def list_images(accounts, container)
|
97
|
+
accounts.each do |account, api|
|
98
|
+
results = api.ListBlobs('Container' => container)
|
99
|
+
if results['EnumerationResults']['Blobs']
|
100
|
+
blobs = results['EnumerationResults']['Blobs']['Blob']
|
101
|
+
else
|
102
|
+
blobs = []
|
103
|
+
end
|
104
|
+
if blobs.class == Hash
|
105
|
+
blobs = [blobs]
|
106
|
+
end
|
107
|
+
puts "=================== #{account} ====================="
|
108
|
+
blobs.each do |blob|
|
109
|
+
name = blob["Name"]
|
110
|
+
# no on-the-fly images
|
111
|
+
next if name =~ /os-i-[0-9a-f]{8,12}$/
|
112
|
+
|
113
|
+
ispublic = 'NOT_PUBLISHED'
|
114
|
+
results = api.GetBlobMetadata('Container'=>container,"Blob"=>name)
|
115
|
+
ispublic = "PUBLISHED" if api.response.headers.key?('x-ms-meta-rs_public')
|
116
|
+
# header = header.first if header.respond_to? "first"
|
117
|
+
# puts "RES"+results.response.inspect
|
118
|
+
puts "NAME #{name} ====== #{ispublic}"
|
119
|
+
puts "URL https://#{account}.blob.core.windows.net/#{container}/#{name}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def set_public(accounts, container, image, publicize=true)
|
125
|
+
accounts.each do |account, api|
|
126
|
+
found_image = false
|
127
|
+
begin
|
128
|
+
results = api.GetBlobMetadata('Container' => container, 'Blob'=>image)
|
129
|
+
is_public = false
|
130
|
+
if api.response.headers.key?("x-ms-meta-rs_public")
|
131
|
+
is_public = true
|
132
|
+
end
|
133
|
+
found_image = true
|
134
|
+
rescue
|
135
|
+
puts "#{account} image #{image} not found"
|
136
|
+
end
|
137
|
+
# api_dump(api, "GetBlobProperties", {'Container' => container, 'Blob' => blob})
|
138
|
+
# api_dump(api, "GetBlobMetadata", {'Container' => container, 'Blob' => blob})
|
139
|
+
if found_image
|
140
|
+
if publicize && !is_public
|
141
|
+
timestamp = Time.now.gmtime.to_s
|
142
|
+
puts "#{account} ADDING KEY: x-ms-meta-rs_public: #{timestamp}"
|
143
|
+
api.SetBlobMetadata('Container' => container, 'Blob' => image, 'Metadata'=>{"rs_public"=>timestamp})
|
144
|
+
# api_dump(api, "SetBlobMetadata", 'Container' => container, 'Blob' => image, 'Metadata'=>{"rs_public"=>timestamp})
|
145
|
+
elsif !publicize && is_public
|
146
|
+
puts "#{account} REMOVING KEY: x-ms-meta-rs_public: #{timestamp}"
|
147
|
+
api.SetBlobMetadata('Container' => container, 'Blob' => image, 'Metadata'=>{})
|
148
|
+
# api_dump(api, "SetBlobMetadata", 'Container' => container, 'Blob' => image, 'Metadata'=>{})
|
149
|
+
elsif publicize && is_public
|
150
|
+
puts "#{account} image #{image} already public"
|
151
|
+
else #!publicize %% !is_public
|
152
|
+
puts "#{account} image #{image} for already NOT public"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
cmd = ARGV.shift
|
159
|
+
platform = ARGV.shift
|
160
|
+
options = ARGV.dup
|
161
|
+
#pp options
|
162
|
+
unless cmd and cmd != "help"
|
163
|
+
puts <<-EOF
|
164
|
+
USAGE: azure_publish COMMAND [COMMAND OPTIONS]
|
165
|
+
USAGE: COMMAND set_public <linux|windows> <image_name.vhd>
|
166
|
+
USAGE: COMMAND unset_public <linux|windows> <image_name.vhd>
|
167
|
+
USAGE: COMMAND list_images <linux|windows>
|
168
|
+
USAGE: COMMAND register_image <linux|windows> <image_name.vhd>
|
169
|
+
USAGE: COMMAND deregister_image <linux|windows> <image_name.vhd|url_to_blob>
|
170
|
+
EXAMPLE: azure_publish list_images linux
|
171
|
+
EXAMPLE: azure_publish set_public linux RightImage-CentOS-6.2-x64-v5.8.8.1.vhd
|
172
|
+
EXAMPLE: azure_publish register_image linux RightImage-CentOS-6.2-x64-v5.8.8.1
|
173
|
+
EOF
|
174
|
+
exit 1
|
175
|
+
end
|
176
|
+
|
177
|
+
if platform == "linux"
|
178
|
+
account_names = RS_LINUX_ACCOUNTS
|
179
|
+
container = "rightimage-linux"
|
180
|
+
OS_TYPE = "linux"
|
181
|
+
# (a,p,ep,c,blob) = parse_url(url_src)
|
182
|
+
elsif platform == "windows"
|
183
|
+
account_names = RS_LINUX_ACCOUNTS + RS_WINDOWS_ACCOUNTS
|
184
|
+
container = "rightimage-windows"
|
185
|
+
OS_TYPE = "windows"
|
186
|
+
elsif platform == "rswin"
|
187
|
+
account_names = RS_LINUX_ACCOUNTS
|
188
|
+
container = "rightimage-windows"
|
189
|
+
OS_TYPE = "windows"
|
190
|
+
# (a,p,ep,c,blob) = parse_url(url_src)
|
191
|
+
elsif platform == "mswin"
|
192
|
+
account_names = RS_WINDOWS_ACCOUNTS
|
193
|
+
container = "rightimage-windows"
|
194
|
+
OS_TYPE = "windows"
|
195
|
+
# (a,p,ep,c,blob) = parse_url(url_src)
|
196
|
+
end
|
197
|
+
|
198
|
+
accounts = account_names.map do |account|
|
199
|
+
password = lookup_password(account)
|
200
|
+
endpoint = "https://#{account}.blob.core.windows.net"
|
201
|
+
[account, RightScale::CloudApi::Azure::Storage::Manager.new(account, password, endpoint, :api_version=>'2012-02-12')]
|
202
|
+
end
|
203
|
+
|
204
|
+
case cmd
|
205
|
+
when "list_images" then list_images(accounts, container)
|
206
|
+
when "set_public" then set_public(accounts, container, options[0], true)
|
207
|
+
when "unset_public" then set_public(accounts, container, options[0], false)
|
208
|
+
when "deregister_image" then deregister_image(accounts, options[0])
|
209
|
+
when "register_image" then register_image(accounts, container, options[0])
|
210
|
+
else raise "Unknown cmd #{cmd}"
|
211
|
+
end
|
212
|
+
|
213
|
+
|