visor-image 0.0.3 → 0.0.4
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.
- data/bin/visor +59 -87
- data/config/server.rb +1 -0
- data/lib/image/auth.rb +108 -77
- data/lib/image/cli.rb +30 -30
- data/lib/image/client.rb +224 -125
- data/lib/image/meta.rb +57 -69
- data/lib/image/routes/delete_all_images.rb +2 -0
- data/lib/image/routes/delete_image.rb +2 -0
- data/lib/image/routes/get_image.rb +2 -0
- data/lib/image/routes/get_images.rb +3 -0
- data/lib/image/routes/get_images_detail.rb +3 -0
- data/lib/image/routes/head_image.rb +2 -0
- data/lib/image/routes/post_image.rb +4 -2
- data/lib/image/routes/put_image.rb +3 -1
- data/lib/image/server.rb +87 -65
- data/lib/image/store/cumulus.rb +2 -2
- data/lib/image/store/hdfs.rb +1 -1
- data/lib/image/store/http.rb +1 -1
- data/lib/image/store/lunacloud.rb +5 -7
- data/lib/image/store/s3.rb +2 -2
- data/lib/image/store/store.rb +1 -1
- data/lib/image/store/walrus.rb +2 -2
- data/lib/image/version.rb +1 -1
- data/spec/lib/meta_spec.rb +10 -9
- data/spec/lib/routes/delete_image_spec.rb +2 -2
- data/spec/lib/routes/get_image_spec.rb +2 -2
- data/spec/lib/routes/get_images_detail_spec.rb +6 -6
- data/spec/lib/routes/get_images_spec.rb +5 -5
- data/spec/lib/routes/head_image_spec.rb +2 -1
- data/spec/lib/routes/post_image_spec.rb +2 -2
- data/spec/lib/routes/put_image_spec.rb +2 -1
- metadata +2 -2
data/lib/image/cli.rb
CHANGED
@@ -65,30 +65,30 @@ module Visor
|
|
65
65
|
options[:address] = addr
|
66
66
|
new_opts << :address
|
67
67
|
end
|
68
|
-
opts.on("-p", "--port PORT", "
|
68
|
+
opts.on("-p", "--port PORT", "Bind to PORT number (default: #{options[:port]})") do |port|
|
69
69
|
options[:port] = port.to_i
|
70
70
|
new_opts << :port
|
71
71
|
end
|
72
|
-
opts.on("-e", "--env
|
72
|
+
opts.on("-e", "--env ENV", "Set execution environment (default: #{options[:env]})") do |env|
|
73
73
|
options[:env] = env.to_sym
|
74
74
|
new_opts << :env
|
75
75
|
end
|
76
|
-
|
77
|
-
opts.separator ""
|
78
|
-
opts.on('-l', '--log FILE', "Log to file (default: #{@options[:log_file]})") do |file|
|
79
|
-
@options[:log_file] = file
|
80
|
-
new_opts << :log_file
|
81
|
-
end
|
82
|
-
opts.on('-u', '--user USER', "Run as specified user") do |v|
|
83
|
-
@options[:user] = v
|
84
|
-
new_opts << :user
|
85
|
-
end
|
86
|
-
opts.on("-f", "--foreground", "Do not daemonize") do
|
76
|
+
opts.on("-f", "--foreground", "Do not daemonize, run in foreground") do
|
87
77
|
options[:daemonize] = false
|
88
78
|
options[:log_stdout] = true
|
89
79
|
new_opts << :daemonize
|
90
80
|
end
|
91
81
|
|
82
|
+
#opts.separator ""
|
83
|
+
#opts.on('-l', '--log FILE', "Log to file (default: #{@options[:log_file]})") do |file|
|
84
|
+
# @options[:log_file] = file
|
85
|
+
# new_opts << :log_file
|
86
|
+
#end
|
87
|
+
#opts.on('-u', '--user USER', "Run as specified user") do |v|
|
88
|
+
# @options[:user] = v
|
89
|
+
# new_opts << :user
|
90
|
+
#end
|
91
|
+
|
92
92
|
#opts.separator ""
|
93
93
|
#opts.separator "SSL options:"
|
94
94
|
#opts.on('--ssl', 'Enables SSL (default: off)') {|v| @options[:ssl] = v }
|
@@ -99,16 +99,16 @@ module Visor
|
|
99
99
|
opts.separator ""
|
100
100
|
opts.separator "Common options:"
|
101
101
|
|
102
|
-
opts.on_tail("-d", "--debug", "
|
102
|
+
opts.on_tail("-d", "--debug", "Enable debugging") do
|
103
103
|
options[:debug] = true
|
104
104
|
new_opts << :debug
|
105
105
|
end
|
106
|
-
opts.on_tail('-v', '--verbose', "Enable verbose logging") do
|
107
|
-
|
108
|
-
|
109
|
-
end
|
110
|
-
opts.on_tail("-h", "--help", "Show this message") { show_options(opts) }
|
111
|
-
opts.on_tail('-
|
106
|
+
#opts.on_tail('-v', '--verbose', "Enable verbose logging") do
|
107
|
+
# options[:verbose] = true
|
108
|
+
# new_opts << :verbose
|
109
|
+
#end
|
110
|
+
opts.on_tail("-h", "--help", "Show this help message") { show_options(opts) }
|
111
|
+
opts.on_tail('-v', '--version', "Show version") { show_version }
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
@@ -161,9 +161,9 @@ module Visor
|
|
161
161
|
# Display current server status
|
162
162
|
def status
|
163
163
|
if running?
|
164
|
-
STDERR.puts "
|
164
|
+
STDERR.puts "visor-image is running PID: #{fetch_pid} URL: #{fetch_url}"
|
165
165
|
else
|
166
|
-
STDERR.puts "
|
166
|
+
STDERR.puts "visor-image is not running."
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
@@ -171,11 +171,11 @@ module Visor
|
|
171
171
|
def stop
|
172
172
|
begin
|
173
173
|
pid = File.read(pid_file)
|
174
|
-
put_and_log :warn, "Stopping
|
174
|
+
put_and_log :warn, "Stopping visor-image with PID: #{pid.to_i} Signal: INT"
|
175
175
|
Process.kill(:INT, pid.to_i)
|
176
176
|
File.delete(url_file)
|
177
177
|
rescue
|
178
|
-
put_and_log :warn, "Cannot stop
|
178
|
+
put_and_log :warn, "Cannot stop visor-image, is it running?"
|
179
179
|
exit! 1
|
180
180
|
end
|
181
181
|
end
|
@@ -189,14 +189,14 @@ module Visor
|
|
189
189
|
write_url
|
190
190
|
launch!
|
191
191
|
rescue => e
|
192
|
-
put_and_log :warn, "Error starting
|
192
|
+
put_and_log :warn, "Error starting visor-image: #{e.message}\n#{e.backtrace.to_s}"
|
193
193
|
exit! 1
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
197
|
# Launch the server
|
198
198
|
def launch!
|
199
|
-
put_and_log :info, "Starting
|
199
|
+
put_and_log :info, "Starting visor-image at #{options[:address]}:#{options[:port]}"
|
200
200
|
debug_settings
|
201
201
|
|
202
202
|
runner = Goliath::Runner.new(opts_to_goliath, Visor::Image::Server.new)
|
@@ -243,9 +243,9 @@ module Visor
|
|
243
243
|
exit
|
244
244
|
end
|
245
245
|
|
246
|
-
# Show
|
246
|
+
# Show VISOR Image System version
|
247
247
|
def show_version
|
248
|
-
puts "
|
248
|
+
puts "visor-image #{Visor::Image::VERSION}"
|
249
249
|
exit
|
250
250
|
end
|
251
251
|
|
@@ -253,7 +253,7 @@ module Visor
|
|
253
253
|
def is_it_running?
|
254
254
|
if files_exist?(pid_file, url_file)
|
255
255
|
if running?
|
256
|
-
put_and_log :warn, "
|
256
|
+
put_and_log :warn, "visor-image is already running at #{fetch_url}"
|
257
257
|
exit! 1
|
258
258
|
else
|
259
259
|
clean
|
@@ -330,7 +330,7 @@ module Visor
|
|
330
330
|
conf_file.each { |k, v| logger.debug "#{k}: #{v}" unless k == :file }
|
331
331
|
logger.debug "**************************************************************"
|
332
332
|
|
333
|
-
logger.debug "Configurations passed from
|
333
|
+
logger.debug "Configurations passed from visor-image CLI:"
|
334
334
|
logger.debug "**************************************************************"
|
335
335
|
if new_opts.empty?
|
336
336
|
logger.debug "none"
|
data/lib/image/client.rb
CHANGED
@@ -6,37 +6,45 @@ require 'json'
|
|
6
6
|
module Visor
|
7
7
|
module Image
|
8
8
|
|
9
|
-
# The
|
10
|
-
# files operations through a
|
9
|
+
# The programming API for the VISOR Image System (VIS). This class supports all image metadata and
|
10
|
+
# files operations through a programming interface.
|
11
11
|
#
|
12
|
-
# After Instantiate a Client object its possible to directly interact with the
|
13
|
-
#
|
12
|
+
# After Instantiate a VIS Client object, its possible to directly interact with the VIS server. This API conforms
|
13
|
+
# to the tenets of the VIS server REST API {Visor::Image::Server Visor Image System server}.
|
14
|
+
#
|
15
|
+
# @note In the examples presented in this page, we will consider that the VIS server is listening in the 10.0.0.1 address and port 4568. We will also use a sample user account, with access_key "foo" and secret_key "bar".
|
14
16
|
#
|
15
17
|
class Client
|
16
18
|
include Visor::Common::Exception
|
17
19
|
include Visor::Common::Util
|
18
20
|
|
19
|
-
attr_reader :host, :port, :
|
21
|
+
attr_reader :host, :port, :access_key, :secret_key
|
20
22
|
|
21
|
-
# Initializes a new
|
23
|
+
# Initializes a new VIS programming client. VIS server settings (host and port address) and user's
|
24
|
+
# credentials should be provided for initialization or ignored (where settings will be loaded from the local VISOR configuration file).
|
22
25
|
#
|
23
|
-
# @option opts [String] :host
|
24
|
-
# @option opts [String] :port
|
25
|
-
# @option opts [String] :
|
26
|
+
# @option opts [String] :host The host address where the VIS server resides.
|
27
|
+
# @option opts [String] :port The host port where the VIS server listens.
|
28
|
+
# @option opts [String] :access_key The user access key.
|
29
|
+
# @option opts [String] :secret_key The user secret key.
|
26
30
|
#
|
27
|
-
# @example Instantiate a client with default values:
|
31
|
+
# @example Instantiate a client with default values loaded from the VISOR configuration file:
|
28
32
|
# client = Visor::Image::Client.new
|
29
33
|
#
|
30
|
-
# @example Instantiate a client with custom host and port:
|
31
|
-
# client = Visor::Image::Client.new(host: '
|
34
|
+
# @example Instantiate a client with custom host and port and with user's credentials loaded from the VISOR configuration file:
|
35
|
+
# client = Visor::Image::Client.new(host: '10.0.0.1', port: 4568)
|
36
|
+
#
|
37
|
+
# @example Instantiate a client with custom host, port and user's credentials (nothing is loaded from the VISOR configuration file):
|
38
|
+
# client = Visor::Image::Client.new(host: '10.0.0.1', port: 4568, access_key: 'foo', secret_key: 'bar')
|
39
|
+
#
|
40
|
+
# @return [Visor::Image::Client] A VIS programming client object.
|
32
41
|
#
|
33
42
|
def initialize(opts = {})
|
34
43
|
configs = Common::Config.load_config :visor_image
|
35
44
|
@host = opts[:host] || configs[:bind_host] || '0.0.0.0'
|
36
45
|
@port = opts[:port] || configs[:bind_port] || 4568
|
37
|
-
@
|
38
|
-
@
|
39
|
-
@secret_key = configs[:secret_key]
|
46
|
+
@access_key = opts[:access_key] || configs[:access_key]
|
47
|
+
@secret_key = opts[:secret_key] || configs[:secret_key]
|
40
48
|
end
|
41
49
|
|
42
50
|
# Retrieves detailed image metadata of the image with the given id.
|
@@ -46,25 +54,32 @@ module Visor
|
|
46
54
|
# @example Retrieve the image metadata with _id value:
|
47
55
|
# # wanted image _id
|
48
56
|
# id = "5e47a41e-7b94-4f65-824e-28f94e15bc6a"
|
57
|
+
#
|
49
58
|
# # ask for that image metadata
|
50
59
|
# client.head_image(id)
|
51
60
|
#
|
52
61
|
# # return example:
|
53
62
|
# {
|
54
|
-
# :_id => "
|
55
|
-
# :
|
63
|
+
# :_id => "edfa919a-0415-4d26-b54d-ae78ffc4dc79",
|
64
|
+
# :uri => "http://10.0.0.1:4568/images/edfa919a-0415-4d26-b54d-ae78ffc4dc79",
|
65
|
+
# :name => "Ubuntu 12.04 Server",
|
56
66
|
# :architecture => "x86_64",
|
57
67
|
# :access => "public",
|
58
|
-
# :uri => "http://0.0.0.0:4567/images/2cceffc6-ebc5-4741-9653-745524e7ac30",
|
59
|
-
# :format => "iso",
|
60
68
|
# :status => "available",
|
61
|
-
# :
|
69
|
+
# :format => "iso",
|
70
|
+
# :size => "732213248",
|
71
|
+
# :store => "s3",
|
72
|
+
# :location => "s3://mys3accesskey:mys3secretkey@s3.amazonaws.com/mybucket/edfa919a-0415-4d26-b54d-ae78ffc4dc79.iso",
|
73
|
+
# :created_at => "2012-06-15 21:05:20 +0100",
|
74
|
+
# :checksum => "140f3-2ba4b000-4be8328106940",
|
75
|
+
# :owner => "foo"
|
62
76
|
# }
|
63
77
|
#
|
64
78
|
# @return [Hash] The requested image metadata.
|
65
79
|
#
|
66
80
|
# @raise [NotFound] If image not found.
|
67
|
-
# @raise [
|
81
|
+
# @raise [Forbidden] If user authentication fails.
|
82
|
+
# @raise [InternalError] If VIS server was not found on the referenced host and port address.
|
68
83
|
#
|
69
84
|
def head_image(id)
|
70
85
|
path = "/images/#{id}"
|
@@ -73,20 +88,20 @@ module Visor
|
|
73
88
|
pull_meta_from_headers(res)
|
74
89
|
end
|
75
90
|
|
76
|
-
# Retrieves brief metadata of all public images.
|
91
|
+
# Retrieves brief metadata of all public and user's private images.
|
77
92
|
# Options for filtering the returned results can be passed in.
|
78
93
|
#
|
79
94
|
# @option query [String] :attribute The image attribute value to filter returned results.
|
80
95
|
# @option query [String] :sort ("_id") The image attribute to sort returned results.
|
81
96
|
# @option query [String] :dir ("asc") The direction to sort results ("asc"/"desc").
|
82
97
|
#
|
83
|
-
# @example Retrieve all
|
98
|
+
# @example Retrieve all images brief metadata:
|
84
99
|
# client.get_images
|
85
100
|
#
|
86
101
|
# # returns:
|
87
102
|
# [<all images brief metadata>]
|
88
103
|
#
|
89
|
-
# @example Retrieve all
|
104
|
+
# @example Retrieve all 32bit images brief metadata:
|
90
105
|
# client.get_images(architecture: 'i386')
|
91
106
|
#
|
92
107
|
# # returns something like:
|
@@ -95,7 +110,7 @@ module Visor
|
|
95
110
|
# {:_id => "8cb55bb6...", :architecture => "i386", :name => "Ubuntu 11.10 Desktop"}
|
96
111
|
# ]
|
97
112
|
#
|
98
|
-
# @example Retrieve all
|
113
|
+
# @example Retrieve all 64bit images brief metadata, descending sorted by their name:
|
99
114
|
# client.get_images(architecture: 'x86_64', sort: 'name', dir: 'desc')
|
100
115
|
#
|
101
116
|
# # returns something like:
|
@@ -104,11 +119,12 @@ module Visor
|
|
104
119
|
# {:_id => "069320f0...", :architecture => "x86_64", :name => "CentOS 6"}
|
105
120
|
# ]
|
106
121
|
#
|
107
|
-
# @return [Array] All
|
122
|
+
# @return [Array] All images brief metadata.
|
108
123
|
# Just {Visor::Meta::Backends::Base::BRIEF BRIEF} fields are returned.
|
109
124
|
#
|
110
|
-
# @raise [NotFound] If there are no
|
111
|
-
# @raise [
|
125
|
+
# @raise [NotFound] If there are no images registered on VISOR.
|
126
|
+
# @raise [Forbidden] If user authentication fails.
|
127
|
+
# @raise [InternalError] If VIS server was not found on the referenced host and port address.
|
112
128
|
#
|
113
129
|
def get_images(query = {})
|
114
130
|
str = build_query(query)
|
@@ -116,7 +132,7 @@ module Visor
|
|
116
132
|
do_request(req)
|
117
133
|
end
|
118
134
|
|
119
|
-
# Retrieves detailed metadata of all public images.
|
135
|
+
# Retrieves detailed metadata of all public and user's private images.
|
120
136
|
#
|
121
137
|
# @note Filtering and querying works the same as with {#get_images}. The only difference is the number
|
122
138
|
# of disclosed attributes.
|
@@ -125,16 +141,17 @@ module Visor
|
|
125
141
|
# @option query [String] :sort ("_id") The image attribute to sort returned results.
|
126
142
|
# @option query [String] :dir ("asc") The direction to sort results ("asc"/"desc").
|
127
143
|
#
|
128
|
-
# @example Retrieve all
|
144
|
+
# @example Retrieve all images detailed metadata:
|
129
145
|
# # request for it
|
130
146
|
# client.get_images_detail
|
131
|
-
# # returns an array of hashes with all
|
147
|
+
# # returns an array of hashes with all images detailed metadata.
|
132
148
|
#
|
133
|
-
# @return [Array] All
|
149
|
+
# @return [Array] All images detailed metadata.
|
134
150
|
# The {Visor::Meta::Backends::Base::DETAIL_EXC DETAIL_EXC} fields are excluded from results.
|
135
151
|
#
|
136
|
-
# @raise [NotFound] If there are no
|
137
|
-
# @raise [
|
152
|
+
# @raise [NotFound] If there are no images registered on VISOR.
|
153
|
+
# @raise [Forbidden] If user authentication fails.
|
154
|
+
# @raise [InternalError] If VIS server was not found on the referenced host and port address.
|
138
155
|
#
|
139
156
|
def get_images_detail(query = {})
|
140
157
|
str = build_query(query)
|
@@ -152,6 +169,7 @@ module Visor
|
|
152
169
|
# @example Retrieve the image file with _id value:
|
153
170
|
# # wanted image _id
|
154
171
|
# id = "5e47a41e-7b94-4f65-824e-28f94e15bc6a"
|
172
|
+
#
|
155
173
|
# # ask for that image file
|
156
174
|
# client.get_image(id) do |chunk|
|
157
175
|
# # do something with chunks as they arrive here (e.g. write to file, etc)
|
@@ -160,7 +178,8 @@ module Visor
|
|
160
178
|
# @return [Binary] The requested image file binary data.
|
161
179
|
#
|
162
180
|
# @raise [NotFound] If image not found.
|
163
|
-
# @raise [
|
181
|
+
# @raise [Forbidden] If user authentication fails.
|
182
|
+
# @raise [InternalError] If VIS server was not found on the referenced host and port address.
|
164
183
|
#
|
165
184
|
def get_image(id)
|
166
185
|
req = Net::HTTP::Get.new("/images/#{id}")
|
@@ -174,7 +193,7 @@ module Visor
|
|
174
193
|
end
|
175
194
|
end
|
176
195
|
|
177
|
-
# Register a new image on
|
196
|
+
# Register a new image on VISOR with the given metadata and optionally
|
178
197
|
# upload its file, or provide a :location parameter containing the full path to
|
179
198
|
# the already existing image file, stored somewhere.
|
180
199
|
#
|
@@ -189,68 +208,74 @@ module Visor
|
|
189
208
|
#
|
190
209
|
# @example Insert a sample image metadata:
|
191
210
|
# # sample image metadata
|
192
|
-
# meta = {:name => '
|
211
|
+
# meta = {:name => 'CentOS 6.2', :architecture => 'i386', :format => 'iso', :access => 'private'}
|
212
|
+
#
|
193
213
|
# # insert the new image metadata
|
194
214
|
# client.post_image(meta)
|
195
215
|
#
|
196
216
|
# # returns:
|
197
217
|
# {
|
198
|
-
# :_id => "
|
199
|
-
# :uri => "http://
|
200
|
-
# :name => "
|
201
|
-
# :architecture => "
|
202
|
-
# :access => "
|
218
|
+
# :_id => "7583d669-8a65-41f1-b8ae-eb34ff6b322f",
|
219
|
+
# :uri => "http://10.0.0.1:4568/images/7583d669-8a65-41f1-b8ae-eb34ff6b322f",
|
220
|
+
# :name => "CentOS 6.2",
|
221
|
+
# :architecture => "i386",
|
222
|
+
# :access => "private",
|
203
223
|
# :status => "locked",
|
204
|
-
# :
|
224
|
+
# :format => "iso",
|
225
|
+
# :created_at => "2012-06-15 21:01:21 +0100",
|
226
|
+
# :owner => "foo"
|
205
227
|
# }
|
206
228
|
#
|
207
229
|
# @example Insert a sample image metadata and provide the location of its file:
|
208
|
-
# # sample image
|
209
|
-
# meta = {:name => 'Ubuntu Server
|
210
|
-
# :store => 'http', :location => 'http://
|
230
|
+
# # sample image pointing to the latest release of Ubuntu Server distro
|
231
|
+
# meta = {:name => 'Ubuntu 12.04 Server', :architecture => 'x86_64', :format => 'iso',
|
232
|
+
# :store => 'http', :location => 'http://releases.ubuntu.com/12.04/ubuntu-12.04-desktop-amd64.iso'}
|
233
|
+
#
|
211
234
|
# # insert the new image metadata
|
212
235
|
# client.post_image(meta)
|
213
236
|
#
|
214
237
|
# # returns:
|
215
238
|
# {
|
216
|
-
# :_id => "
|
217
|
-
# :uri => "http://
|
218
|
-
# :name => "Ubuntu Server
|
239
|
+
# :_id => "edfa919a-0415-4d26-b54d-ae78ffc4dc79",
|
240
|
+
# :uri => "http://10.0.0.1:4568/images/edfa919a-0415-4d26-b54d-ae78ffc4dc79",
|
241
|
+
# :name => "Ubuntu 12.04 Server",
|
219
242
|
# :architecture => "x86_64",
|
220
243
|
# :access => "public",
|
244
|
+
# :status => "available",
|
221
245
|
# :format => "iso",
|
246
|
+
# :size => 732213248, # it will find the remote file size
|
222
247
|
# :store => "http",
|
223
|
-
# :location => "http://
|
224
|
-
# :
|
225
|
-
# :
|
226
|
-
# :
|
227
|
-
# :updated_at => "2012-02-04 16:40:04 +0000",
|
228
|
-
# :checksum => "76264-2aa4b000-4af0618f1b180" # it will also fetch the remote file checksum or etag
|
248
|
+
# :location => "http://releases.ubuntu.com/12.04/ubuntu-12.04-desktop-amd64.iso",
|
249
|
+
# :created_at => "2012-06-15 21:05:20 +0100",
|
250
|
+
# :checksum => "140f3-2ba4b000-4be8328106940", # it will also find the remote file checksum or etag
|
251
|
+
# :owner => "foo"
|
229
252
|
# }
|
230
253
|
#
|
231
254
|
# @example Insert a sample image metadata and upload its file:
|
232
255
|
# # sample image metadata
|
233
|
-
# meta = {:name => '
|
256
|
+
# meta = {:name => 'Fedora Desktop 17', :architecture => 'x86_64', :format => 'iso', :store => 'file'}
|
257
|
+
#
|
234
258
|
# # sample image file path
|
235
|
-
# file = '~/
|
259
|
+
# file = '~/Fedora-17-x86_64-Live-Desktop.iso'
|
260
|
+
#
|
236
261
|
# # insert the new image metadata and upload file
|
237
262
|
# client.post_image(meta, file)
|
238
263
|
#
|
239
264
|
# # returns:
|
240
265
|
# {
|
241
|
-
# :_id => "
|
242
|
-
# :uri => "http://
|
243
|
-
# :name => "
|
266
|
+
# :_id => "e5fe8ea5-4704-48f1-905a-f5747cf8ba5e",
|
267
|
+
# :uri => "http://10.0.0.1:4568/images/e5fe8ea5-4704-48f1-905a-f5747cf8ba5e",
|
268
|
+
# :name => "Fedora Desktop 17",
|
244
269
|
# :architecture => "x86_64",
|
245
270
|
# :access => "public",
|
271
|
+
# :status => "available",
|
246
272
|
# :format => "iso",
|
273
|
+
# :size => 676331520,
|
247
274
|
# :store => "file",
|
248
|
-
# :location => "
|
249
|
-
# :
|
250
|
-
# :
|
251
|
-
# :
|
252
|
-
# :updated_at => "2012-02-04 16:29:04 +0000",
|
253
|
-
# :checksum => "fbd9044604120a1f6cc708048a21e066"
|
275
|
+
# :location => "file:///home/foo/VMs/e5fe8ea5-4704-48f1-905a-f5747cf8ba5e.iso",
|
276
|
+
# :created_at => "2012-06-15 21:03:32 +0100",
|
277
|
+
# :checksum => "330dcb53f253acdf76431cecca0fefe7",
|
278
|
+
# :owner => "foo"
|
254
279
|
# }
|
255
280
|
#
|
256
281
|
# @return [Hash] The already inserted image metadata.
|
@@ -259,9 +284,10 @@ module Visor
|
|
259
284
|
# @raise [Invalid] If the location header is present no file content can be provided.
|
260
285
|
# @raise [Invalid] If trying to post an image file to a HTTP backend.
|
261
286
|
# @raise [Invalid] If provided store is an unsupported store backend.
|
262
|
-
# @raise [NotFound] If no image
|
263
|
-
# @raise [ConflictError] If the provided image file already exists in the backend store.
|
264
|
-
# @raise [
|
287
|
+
# @raise [NotFound] If no image file is found at the provided location.
|
288
|
+
# @raise [ConflictError] If the provided image file already exists in the target backend store.
|
289
|
+
# @raise [Forbidden] If user authentication fails.
|
290
|
+
# @raise [InternalError] If VIS server was not found on the referenced host and port address.
|
265
291
|
#
|
266
292
|
def post_image(meta, file = nil)
|
267
293
|
req = Net::HTTP::Post.new('/images')
|
@@ -290,74 +316,91 @@ module Visor
|
|
290
316
|
#
|
291
317
|
# @example Update a sample image metadata:
|
292
318
|
# # wanted image _id
|
293
|
-
# id = "
|
319
|
+
# id = "edfa919a-0415-4d26-b54d-ae78ffc4dc79."
|
320
|
+
#
|
294
321
|
# # metadata to update
|
295
|
-
# update = {:name => '
|
322
|
+
# update = {:name => 'Ubuntu 12.04', :architecture => "i386"}
|
323
|
+
#
|
296
324
|
# # update the image metadata with some new values
|
297
325
|
# client.put_image(id, update)
|
298
326
|
#
|
299
327
|
# # returns:
|
300
328
|
# {
|
301
|
-
# :_id => "
|
302
|
-
# :uri => "http://
|
303
|
-
# :name => "
|
304
|
-
# :architecture => "
|
329
|
+
# :_id => "edfa919a-0415-4d26-b54d-ae78ffc4dc79",
|
330
|
+
# :uri => "http://10.0.0.1:4568/images/edfa919a-0415-4d26-b54d-ae78ffc4dc79",
|
331
|
+
# :name => "Ubuntu 12.04",
|
332
|
+
# :architecture => "i386",
|
305
333
|
# :access => "public",
|
306
|
-
# :status => "
|
307
|
-
# :
|
308
|
-
# :
|
334
|
+
# :status => "available",
|
335
|
+
# :format => "iso",
|
336
|
+
# :size => 732213248,
|
337
|
+
# :store => "http",
|
338
|
+
# :location => "http://releases.ubuntu.com/12.04/ubuntu-12.04-desktop-amd64.iso",
|
339
|
+
# :created_at => "2012-06-15 21:05:20 +0100",
|
340
|
+
# :updated_at => "2012-06-15 21:10:36 +0100",
|
341
|
+
# :checksum => "140f3-2ba4b000-4be8328106940",
|
342
|
+
# :owner => "foo"
|
309
343
|
# }
|
310
344
|
#
|
311
|
-
# @example Update
|
345
|
+
# @example Update the image metadata and provide the location of its file. In this example,
|
346
|
+
# the image file was already stored in the local filesystem backend,
|
347
|
+
# thus it is not needed to upload the file, but rather just register that the image file is there.
|
312
348
|
# # wanted image _id
|
313
|
-
# id = "
|
349
|
+
# id = "7583d669-8a65-41f1-b8ae-eb34ff6b322f"
|
350
|
+
#
|
314
351
|
# # metadata update
|
315
352
|
# update = {:format => 'iso', :store => 'file', :location => 'file:///Users/server/debian-6.0.4-amd64.iso'}
|
353
|
+
#
|
316
354
|
# # update the image metadata with file values
|
317
355
|
# client.put_image(id, update)
|
318
356
|
#
|
319
357
|
# # returns:
|
320
358
|
# {
|
321
|
-
# :_id => "
|
322
|
-
# :uri => "http://
|
323
|
-
# :name => "
|
324
|
-
# :architecture => "
|
325
|
-
# :access => "
|
326
|
-
# :status => "
|
359
|
+
# :_id => "7583d669-8a65-41f1-b8ae-eb34ff6b322f",
|
360
|
+
# :uri => "http://10.0.0.1:4568/images/7583d669-8a65-41f1-b8ae-eb34ff6b322f",
|
361
|
+
# :name => "CentOS 6.2",
|
362
|
+
# :architecture => "i386",
|
363
|
+
# :access => "private",
|
364
|
+
# :status => "available",
|
327
365
|
# :format => "iso",
|
366
|
+
# :size => 729808896,
|
328
367
|
# :store => "file",
|
329
|
-
# :location => "file:///
|
330
|
-
# :
|
331
|
-
# :
|
332
|
-
# :
|
333
|
-
# :
|
368
|
+
# :location => "file:///home/foo/downloads/CentOS-6.2-i386-LiveCD.iso",
|
369
|
+
# :created_at => "2012-06-15 21:01:21 +0100",
|
370
|
+
# :updated_at => "2012-06-15 21:12:27 +0100",
|
371
|
+
# :checksum => "1b8441b6f4556be61c16d9750da42b3f",
|
372
|
+
# :owner => "foo"
|
334
373
|
# }
|
335
374
|
#
|
336
|
-
# @example
|
375
|
+
# @example OR update image metadata and upload its file, if it is not already in some compatible storage backend:
|
337
376
|
# # wanted image _id
|
338
|
-
# id = "
|
377
|
+
# id = "7583d669-8a65-41f1-b8ae-eb34ff6b322f"
|
378
|
+
#
|
339
379
|
# # metadata update
|
340
|
-
# update = {:format => 'iso', :store => '
|
380
|
+
# update = {:format => 'iso', :store => 'file'}
|
381
|
+
#
|
341
382
|
# # sample image file path
|
342
|
-
# file = '~/CentOS-6.2-
|
383
|
+
# file = '~/CentOS-6.2-i386-LiveCD.iso'
|
384
|
+
#
|
343
385
|
# # insert the new image metadata and upload file
|
344
386
|
# client.put_image(id, meta, file)
|
345
387
|
#
|
346
388
|
# # returns:
|
347
389
|
# {
|
348
|
-
# :_id => "
|
349
|
-
# :uri => "http://
|
390
|
+
# :_id => "7583d669-8a65-41f1-b8ae-eb34ff6b322f",
|
391
|
+
# :uri => "http://10.0.0.1:4568/images/7583d669-8a65-41f1-b8ae-eb34ff6b322f",
|
350
392
|
# :name => "CentOS 6.2",
|
351
|
-
# :architecture => "
|
352
|
-
# :access => "
|
353
|
-
# :format => "iso",
|
354
|
-
# :store => "s3",
|
355
|
-
# :location => "s3://<access_key>:<secret_key>@s3.amazonaws.com/<bucket>/d5bebdc8-66eb-4450-b8d1-d8127f50779d.iso",
|
393
|
+
# :architecture => "i386",
|
394
|
+
# :access => "private",
|
356
395
|
# :status => "available",
|
357
|
-
# :
|
358
|
-
# :
|
359
|
-
# :
|
360
|
-
# :
|
396
|
+
# :format => "iso",
|
397
|
+
# :size => 729808896,
|
398
|
+
# :store => "file",
|
399
|
+
# :location => "file:///home/foo/VMs/7583d669-8a65-41f1-b8ae-eb34ff6b322f.iso",
|
400
|
+
# :created_at => "2012-06-15 21:01:21 +0100",
|
401
|
+
# :updated_at => "2012-06-15 21:12:27 +0100",
|
402
|
+
# :checksum => "1b8441b6f4556be61c16d9750da42b3f",
|
403
|
+
# :owner => "foo"
|
361
404
|
# }
|
362
405
|
#
|
363
406
|
# @return [Hash] The already inserted image metadata.
|
@@ -370,7 +413,8 @@ module Visor
|
|
370
413
|
# @raise [NotFound] If no image data is found at the provided location.
|
371
414
|
# @raise [ConflictError] If trying to assign image file to a locked or uploading image.
|
372
415
|
# @raise [ConflictError] If the provided image file already exists in the backend store.
|
373
|
-
# @raise [
|
416
|
+
# @raise [Forbidden] If user authentication fails.
|
417
|
+
# @raise [InternalError] If VIS server was not found on the referenced host and port address.
|
374
418
|
#
|
375
419
|
def put_image(id, meta, file = nil)
|
376
420
|
req = Net::HTTP::Put.new("/images/#{id}")
|
@@ -388,42 +432,95 @@ module Visor
|
|
388
432
|
#
|
389
433
|
# @param id [String] The image's _id which will be deleted.
|
390
434
|
#
|
391
|
-
# @example Delete an image
|
435
|
+
# @example Delete an image:
|
392
436
|
# # wanted image _id
|
393
|
-
# id = "
|
437
|
+
# id = "edfa919a-0415-4d26-b54d-ae78ffc4dc79"
|
438
|
+
#
|
394
439
|
# # delete the image metadata and file
|
395
440
|
# client.delete_image(id)
|
396
441
|
#
|
397
442
|
# # returns:
|
398
443
|
# {
|
399
|
-
# :_id => "
|
400
|
-
# :uri => "http://
|
401
|
-
# :name => "Ubuntu
|
402
|
-
# :architecture => "
|
444
|
+
# :_id => "edfa919a-0415-4d26-b54d-ae78ffc4dc79",
|
445
|
+
# :uri => "http://10.0.0.1:4568/images/edfa919a-0415-4d26-b54d-ae78ffc4dc79",
|
446
|
+
# :name => "Ubuntu 12.04",
|
447
|
+
# :architecture => "i386",
|
403
448
|
# :access => "public",
|
404
|
-
# :format => "iso",
|
405
|
-
# :store => "file",
|
406
|
-
# :location => "file:///Users/server/VMs/66414330-bbb5-42be-8a0e-b336cf6665f4.iso",
|
407
449
|
# :status => "available",
|
408
|
-
# :
|
409
|
-
# :
|
410
|
-
# :
|
411
|
-
# :
|
412
|
-
# :
|
413
|
-
# :
|
450
|
+
# :format => "iso",
|
451
|
+
# :size => 732213248,
|
452
|
+
# :store => "http",
|
453
|
+
# :location => "http://releases.ubuntu.com/12.04/ubuntu-12.04-desktop-amd64.iso",
|
454
|
+
# :created_at => "2012-06-15 21:05:20 +0100",
|
455
|
+
# :updated_at => "2012-06-15 21:10:36 +0100",
|
456
|
+
# :checksum => "140f3-2ba4b000-4be8328106940",
|
457
|
+
# :owner => "foo"
|
414
458
|
# }
|
415
459
|
#
|
416
460
|
# @return [Hash] The already deleted image metadata. Useful for recover on accidental delete.
|
417
461
|
#
|
418
|
-
# @raise [NotFound] If image meta or
|
462
|
+
# @raise [NotFound] If image meta or file were not found.
|
419
463
|
# @raise [Forbidden] If user does not have permission to manipulate the image file.
|
420
|
-
# @raise [
|
464
|
+
# @raise [Forbidden] If user authentication fails.
|
465
|
+
# @raise [InternalError] If VIS server was not found on the referenced host and port address.
|
421
466
|
#
|
422
467
|
def delete_image(id)
|
423
468
|
req = Net::HTTP::Delete.new("/images/#{id}")
|
424
469
|
do_request(req)
|
425
470
|
end
|
426
471
|
|
472
|
+
# Removes images that match a specific query.
|
473
|
+
#
|
474
|
+
# @param query [Hash] A query to find images that should be deleted.
|
475
|
+
#
|
476
|
+
# @example Delete an image by queries:
|
477
|
+
# # we want to delete all 64-bit images:
|
478
|
+
# query = {architecture: 'x86_64'}
|
479
|
+
#
|
480
|
+
# # delete the image metadata and file
|
481
|
+
# client.delete_by_query(query)
|
482
|
+
#
|
483
|
+
# # returns the matched and deleted images metadata (where in this example we had only the following 64-bit images registered):
|
484
|
+
# [
|
485
|
+
# {
|
486
|
+
# :_id => "e5fe8ea5-4704-48f1-905a-f5747cf8ba5e",
|
487
|
+
# :uri => "http://10.0.0.1:4568/images/e5fe8ea5-4704-48f1-905a-f5747cf8ba5e",
|
488
|
+
# :name => "Fedora Desktop 17",
|
489
|
+
# :architecture => "x86_64",
|
490
|
+
# :access => "public",
|
491
|
+
# :status => "available",
|
492
|
+
# :format => "iso",
|
493
|
+
# :size => 676331520,
|
494
|
+
# :store => "file",
|
495
|
+
# :location => "file:///home/foo/VMs/e5fe8ea5-4704-48f1-905a-f5747cf8ba5e.iso",
|
496
|
+
# :created_at => "2012-06-15 21:03:32 +0100",
|
497
|
+
# :checksum => "330dcb53f253acdf76431cecca0fefe7",
|
498
|
+
# :owner => "foo"
|
499
|
+
# },
|
500
|
+
# {
|
501
|
+
# :_id => "edfa919a-0415-4d26-b54d-ae78ffc4dc79",
|
502
|
+
# :uri => "http://10.0.0.1:4568/images/edfa919a-0415-4d26-b54d-ae78ffc4dc79",
|
503
|
+
# :name => "Ubuntu 12.04 Server",
|
504
|
+
# :architecture => "x86_64",
|
505
|
+
# :access => "public",
|
506
|
+
# :status => "available",
|
507
|
+
# :format => "iso",
|
508
|
+
# :size => "732213248",
|
509
|
+
# :store => "s3",
|
510
|
+
# :location => "s3://mys3accesskey:mys3secretkey@s3.amazonaws.com/mybucket/edfa919a-0415-4d26-b54d-ae78ffc4dc79.iso",
|
511
|
+
# :created_at => "2012-06-15 21:05:20 +0100",
|
512
|
+
# :checksum => "140f3-2ba4b000-4be8328106940",
|
513
|
+
# :owner => "foo"
|
514
|
+
# }
|
515
|
+
# ]
|
516
|
+
#
|
517
|
+
# @return [Hash] The already deleted image metadata. Useful for recover on accidental delete.
|
518
|
+
#
|
519
|
+
# @raise [NotFound] If image meta or file were not found.
|
520
|
+
# @raise [Forbidden] If user does not have permission to manipulate the image file.
|
521
|
+
# @raise [Forbidden] If user authentication fails.
|
522
|
+
# @raise [InternalError] If VIS server was not found on the referenced host and port address.
|
523
|
+
#
|
427
524
|
def delete_by_query(query)
|
428
525
|
result = []
|
429
526
|
images = get_images(query)
|
@@ -440,7 +537,7 @@ module Visor
|
|
440
537
|
# Prepare headers for request
|
441
538
|
def prepare_headers(req)
|
442
539
|
sign_request(access_key, secret_key, req.method, req.path, req)
|
443
|
-
req['User-Agent'] = '
|
540
|
+
req['User-Agent'] = 'VISOR Image System client'
|
444
541
|
req['Accept'] = "application/json"
|
445
542
|
end
|
446
543
|
|
@@ -473,6 +570,8 @@ module Visor
|
|
473
570
|
raise Forbidden, parse_response(res)
|
474
571
|
when Net::HTTPInternalServerError then
|
475
572
|
raise InternalError, parse_response(res)
|
573
|
+
when Net::HTTPServiceUnavailable then
|
574
|
+
raise InternalError, parse_response(res)
|
476
575
|
end
|
477
576
|
end
|
478
577
|
|