visor-image 0.0.1
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 +423 -0
- data/bin/visor-image +10 -0
- data/config/server.rb +14 -0
- data/lib/image/auth.rb +147 -0
- data/lib/image/cli.rb +397 -0
- data/lib/image/client.rb +490 -0
- data/lib/image/meta.rb +219 -0
- data/lib/image/routes/delete_all_images.rb +40 -0
- data/lib/image/routes/delete_image.rb +62 -0
- data/lib/image/routes/get_image.rb +78 -0
- data/lib/image/routes/get_images.rb +54 -0
- data/lib/image/routes/get_images_detail.rb +54 -0
- data/lib/image/routes/head_image.rb +51 -0
- data/lib/image/routes/post_image.rb +189 -0
- data/lib/image/routes/put_image.rb +205 -0
- data/lib/image/server.rb +307 -0
- data/lib/image/store/cumulus.rb +126 -0
- data/lib/image/store/file_system.rb +119 -0
- data/lib/image/store/hdfs.rb +149 -0
- data/lib/image/store/http.rb +78 -0
- data/lib/image/store/lunacloud.rb +126 -0
- data/lib/image/store/s3.rb +121 -0
- data/lib/image/store/store.rb +39 -0
- data/lib/image/store/walrus.rb +130 -0
- data/lib/image/version.rb +5 -0
- data/lib/visor-image.rb +30 -0
- data/spec/lib/client_spec.rb +0 -0
- data/spec/lib/meta_spec.rb +230 -0
- data/spec/lib/routes/delete_image_spec.rb +98 -0
- data/spec/lib/routes/get_image_spec.rb +78 -0
- data/spec/lib/routes/get_images_detail_spec.rb +104 -0
- data/spec/lib/routes/get_images_spec.rb +104 -0
- data/spec/lib/routes/head_image_spec.rb +51 -0
- data/spec/lib/routes/post_image_spec.rb +112 -0
- data/spec/lib/routes/put_image_spec.rb +109 -0
- data/spec/lib/server_spec.rb +62 -0
- data/spec/lib/store/cumulus_spec.rb +0 -0
- data/spec/lib/store/file_system_spec.rb +32 -0
- data/spec/lib/store/http_spec.rb +56 -0
- data/spec/lib/store/s3_spec.rb +37 -0
- data/spec/lib/store/store_spec.rb +36 -0
- data/spec/lib/store/walrus_spec.rb +0 -0
- metadata +217 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Visor::Image::Server do
|
4
|
+
include Visor::Common::Util
|
5
|
+
|
6
|
+
let(:test_api) { Visor::Image::Server }
|
7
|
+
let(:err) { Proc.new { fail "API request failed" } }
|
8
|
+
|
9
|
+
let(:accept_json) { {'Accept' => 'application/json'} }
|
10
|
+
let(:accept_xml) { {'Accept' => 'application/xml'} }
|
11
|
+
|
12
|
+
let(:parse_opts) { {symbolize_names: true} }
|
13
|
+
let(:valid_post) { {name: 'server_spec', architecture: 'i386', access: 'public'} }
|
14
|
+
let(:api_options) { {config: File.expand_path(File.join(File.dirname(__FILE__), '../../../', 'config/server.rb'))} }
|
15
|
+
|
16
|
+
inserted = []
|
17
|
+
|
18
|
+
before(:each) do
|
19
|
+
EM.synchrony do
|
20
|
+
inserted << DB.post_image(valid_post)[:_id]
|
21
|
+
EM.stop
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
after(:all) do
|
26
|
+
EM.synchrony do
|
27
|
+
inserted.each { |id| DB.delete_image(id) }
|
28
|
+
EM.stop
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# GET /images/<id>
|
34
|
+
#
|
35
|
+
describe "GET /images/:id" do
|
36
|
+
it "should return an image metadata in headers" do
|
37
|
+
id = inserted.sample
|
38
|
+
with_api(test_api, api_options) do
|
39
|
+
get_request({:path => "/images/#{id}"}, err) do |c|
|
40
|
+
assert_200 c
|
41
|
+
pull_meta_from_headers(c.response_header).should_not be_empty
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should return a JSON error if accepted" do
|
47
|
+
with_api(test_api, api_options) do
|
48
|
+
get_request({:path => "/images/fakeid", head: accept_json}, err) do |c|
|
49
|
+
assert_404 c
|
50
|
+
c.response.should match /\{/
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return a XML error if accepted" do
|
56
|
+
with_api(test_api, api_options) do
|
57
|
+
get_request({:path => "/images/fakeid", head: accept_xml}, err) do |c|
|
58
|
+
assert_404 c
|
59
|
+
c.response.should match /\<?xml/
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should raise a HTTPNotFound 404 error if no images found" do
|
65
|
+
with_api(test_api, api_options) do
|
66
|
+
get_request({:path => "/images/fakeid"}, err) do |c|
|
67
|
+
assert_404 c
|
68
|
+
c.response.should match /fakeid/
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should raise a HTTPInternalServer 500 error if no server error" do
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Visor::Image::Server do
|
4
|
+
|
5
|
+
let(:test_api) { Visor::Image::Server }
|
6
|
+
let(:err) { Proc.new { fail "API request failed" } }
|
7
|
+
let(:accept_json) { {'Accept' => 'application/json'} }
|
8
|
+
let(:accept_xml) { {'Accept' => 'application/xml'} }
|
9
|
+
let(:parse_opts) { {symbolize_names: true} }
|
10
|
+
let(:valid_post) { {name: 'server_spec', architecture: 'i386', access: 'public'} }
|
11
|
+
let(:api_options) { {config: File.expand_path(File.join(File.dirname(__FILE__), '../../../', 'config/server.rb'))} }
|
12
|
+
|
13
|
+
inserted = []
|
14
|
+
|
15
|
+
before(:all) do
|
16
|
+
EM.synchrony do
|
17
|
+
inserted << DB.post_image(valid_post)[:_id]
|
18
|
+
inserted << DB.post_image(valid_post.merge(architecture: 'x86_64'))[:_id]
|
19
|
+
EM.stop
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
after(:all) do
|
24
|
+
EM.synchrony do
|
25
|
+
inserted.each { |id| DB.delete_image(id) }
|
26
|
+
EM.stop
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# GET /images/detail
|
32
|
+
#
|
33
|
+
describe "GET /images/detail" do
|
34
|
+
|
35
|
+
it "should return a JSON string if no accept header provided" do
|
36
|
+
with_api(test_api, api_options) do
|
37
|
+
get_request({:path => '/images'}, err) do |c|
|
38
|
+
assert_200 c
|
39
|
+
c.response.should be_a String
|
40
|
+
c.response.should match /\{/
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return all images meta hashes inside a JSON array" do
|
46
|
+
with_api(test_api, api_options) do
|
47
|
+
get_request({:path => '/images'}, err) do |c|
|
48
|
+
res = parse_body c
|
49
|
+
res.should be_a Array
|
50
|
+
res.first.should be_a Hash
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return a JSON string if accepted" do
|
56
|
+
with_api(test_api, api_options) do
|
57
|
+
get_request({:path => '/images', head: accept_json}, err) do |c|
|
58
|
+
assert_200 c
|
59
|
+
c.response.should be_a String
|
60
|
+
c.response.should match /\{/
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should return a XML document if accepted" do
|
66
|
+
with_api(test_api, api_options) do
|
67
|
+
get_request({:path => '/images', head: accept_xml}, err) do |c|
|
68
|
+
assert_200 c
|
69
|
+
c.response.should be_a String
|
70
|
+
c.response.should match /\<?xml/
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should accept filter query parameters" do
|
76
|
+
with_api(test_api, api_options) do
|
77
|
+
get_request({path: '/images/detail', head: accept_json, query: {architecture: 'i386'}}, err) do |c|
|
78
|
+
body = parse_body c
|
79
|
+
body.should be_a Array
|
80
|
+
body.each { |meta| meta[:architecture].should == 'i386' }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should accept sorting query parameters" do
|
86
|
+
with_api(test_api, api_options) do
|
87
|
+
get_request({path: '/images/detail', head: accept_json, query: {sort: 'architecture', dir: 'desc'}}, err) do |c|
|
88
|
+
body = parse_body c
|
89
|
+
body.should be_a Array
|
90
|
+
body.first[:architecture].should == 'x86_64'
|
91
|
+
body.last[:architecture].should == 'i386'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should raise a HTTPNotFound 404 error if no images found" do
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should raise a HTTPInternalServer 500 error if no server error" do
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Visor::Image::Server do
|
4
|
+
|
5
|
+
let(:test_api) { Visor::Image::Server }
|
6
|
+
let(:err) { Proc.new { fail "API request failed" } }
|
7
|
+
let(:accept_json) { {'Accept' => 'application/json'} }
|
8
|
+
let(:accept_xml) { {'Accept' => 'application/xml'} }
|
9
|
+
let(:parse_opts) { {symbolize_names: true} }
|
10
|
+
let(:valid_post) { {name: 'server_spec', architecture: 'i386', access: 'public'} }
|
11
|
+
let(:api_options) { {config: File.expand_path(File.join(File.dirname(__FILE__), '../../../', 'config/server.rb'))} }
|
12
|
+
|
13
|
+
inserted = []
|
14
|
+
|
15
|
+
before(:all) do
|
16
|
+
EM.synchrony do
|
17
|
+
inserted << DB.post_image(valid_post)[:_id]
|
18
|
+
inserted << DB.post_image(valid_post.merge(architecture: 'x86_64'))[:_id]
|
19
|
+
EM.stop
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
after(:all) do
|
24
|
+
EM.synchrony do
|
25
|
+
inserted.each { |id| DB.delete_image(id) }
|
26
|
+
EM.stop
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# GET /images
|
32
|
+
#
|
33
|
+
describe "GET /images" do
|
34
|
+
|
35
|
+
it "should return a JSON string if no accept header provided" do
|
36
|
+
with_api(test_api, api_options) do
|
37
|
+
get_request({:path => '/images'}, err) do |c|
|
38
|
+
assert_200 c
|
39
|
+
c.response.should be_a String
|
40
|
+
c.response.should match /\{/
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return all images meta hashes inside a JSON array" do
|
46
|
+
with_api(test_api, api_options) do
|
47
|
+
get_request({:path => '/images'}, err) do |c|
|
48
|
+
res = parse_body c
|
49
|
+
res.should be_a Array
|
50
|
+
res.first.should be_a Hash
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return a JSON string if accepted" do
|
56
|
+
with_api(test_api, api_options) do
|
57
|
+
get_request({:path => '/images', head: accept_json}, err) do |c|
|
58
|
+
assert_200 c
|
59
|
+
c.response.should be_a String
|
60
|
+
c.response.should match /\{/
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should return a XML document if accepted" do
|
66
|
+
with_api(test_api, api_options) do
|
67
|
+
get_request({:path => '/images', head: accept_xml}, err) do |c|
|
68
|
+
assert_200 c
|
69
|
+
c.response.should be_a String
|
70
|
+
c.response.should match /\<?xml/
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should accept filter query parameters" do
|
76
|
+
with_api(test_api, api_options) do
|
77
|
+
get_request({path: '/images', head: accept_json, query: {architecture: 'i386'}}, err) do |c|
|
78
|
+
body = parse_body c
|
79
|
+
body.should be_a Array
|
80
|
+
body.each { |meta| meta[:architecture].should == 'i386' }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should accept sorting query parameters" do
|
86
|
+
with_api(test_api, api_options) do
|
87
|
+
get_request({path: '/images', head: accept_json, query: {sort: 'architecture', dir: 'desc'}}, err) do |c|
|
88
|
+
body = parse_body c
|
89
|
+
body.should be_a Array
|
90
|
+
body.first[:architecture].should == 'x86_64'
|
91
|
+
body.last[:architecture].should == 'i386'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should raise a HTTPNotFound 404 error if no images found" do
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should raise a HTTPInternalServer 500 error if no server error" do
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Visor::Image::Server do
|
4
|
+
|
5
|
+
let(:test_api) { Visor::Image::Server }
|
6
|
+
let(:err) { Proc.new { fail "API request failed" } }
|
7
|
+
let(:valid_post) { {name: 'server_spec', architecture: 'i386', access: 'public'} }
|
8
|
+
let(:api_options) { {config: File.expand_path(File.join(File.dirname(__FILE__), '../../../', 'config/server.rb'))} }
|
9
|
+
|
10
|
+
inserted = []
|
11
|
+
|
12
|
+
before(:all) do
|
13
|
+
EM.synchrony do
|
14
|
+
inserted << DB.post_image(valid_post)[:_id]
|
15
|
+
EM.stop
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
after(:all) do
|
20
|
+
EM.synchrony do
|
21
|
+
inserted.each { |id| DB.delete_image(id) }
|
22
|
+
EM.stop
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# HEAD /images/<id>
|
28
|
+
#
|
29
|
+
describe "HEAD /images/:id" do
|
30
|
+
before :each do
|
31
|
+
with_api(test_api, api_options) do
|
32
|
+
head_request({:path => "/images/#{inserted.sample}"}, err) { |c| assert_200 c; @res = c }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should return an empty body hash" do
|
37
|
+
@res.response.should be_empty
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return image metadata as HTTP headers" do
|
41
|
+
created_at = @res.response_header['X_IMAGE_META_CREATED_AT']
|
42
|
+
Date.parse(created_at).should be_a Date
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should raise a HTTPNotFound 404 error if image not found" do
|
46
|
+
with_api(test_api, api_options) do
|
47
|
+
head_request({:path => "/images/fake"}, err) { |c| assert_404_path_or_op c }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Visor::Image::Server do
|
4
|
+
include Visor::Common::Util
|
5
|
+
|
6
|
+
let(:test_api) { Visor::Image::Server }
|
7
|
+
let(:err) { Proc.new { fail "API request failed" } }
|
8
|
+
|
9
|
+
let(:accept_json) { {'Accept' => 'application/json'} }
|
10
|
+
let(:accept_xml) { {'Accept' => 'application/xml'} }
|
11
|
+
|
12
|
+
let(:parse_opts) { {symbolize_names: true} }
|
13
|
+
let(:valid_post) { {name: 'server_spec', architecture: 'i386', access: 'public'} }
|
14
|
+
let(:post_headers) { push_meta_into_headers(valid_post) }
|
15
|
+
let(:api_options) { {config: File.expand_path(File.join(File.dirname(__FILE__), '../../../', 'config/server.rb'))} }
|
16
|
+
|
17
|
+
inserted = []
|
18
|
+
|
19
|
+
before(:all) do
|
20
|
+
EM.synchrony do
|
21
|
+
inserted << DB.post_image(valid_post)[:_id]
|
22
|
+
EM.stop
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
after(:all) do
|
27
|
+
EM.synchrony do
|
28
|
+
inserted.each { |id| DB.delete_image(id) }
|
29
|
+
EM.stop
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# POST /images
|
35
|
+
#
|
36
|
+
describe "POST /images/" do
|
37
|
+
|
38
|
+
it "should post an image metadata and return it as response's body" do
|
39
|
+
with_api(test_api, api_options) do
|
40
|
+
post_request({:path => "/images/", :head => post_headers}, err) do |c|
|
41
|
+
meta = parse_body(c)
|
42
|
+
inserted << meta[:_id]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return a JSON string if no accept header provided" do
|
48
|
+
with_api(test_api, api_options) do
|
49
|
+
post_request({:path => "/images/", :head => post_headers}, err) do |c|
|
50
|
+
meta = parse_body(c)
|
51
|
+
inserted << meta[:_id]
|
52
|
+
c.response.should match /\{/
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return a JSON string if accepted" do
|
58
|
+
with_api(test_api, api_options) do
|
59
|
+
post_request({:path => "/images/", :head => post_headers.merge(accept_json)}, err) do |c|
|
60
|
+
meta = parse_body(c)
|
61
|
+
inserted << meta[:_id]
|
62
|
+
c.response.should match /\{/
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should return a XML document if accepted" do
|
68
|
+
with_api(test_api, api_options) do
|
69
|
+
post_request({:path => "/images/", :head => post_headers.merge(accept_xml)}, err) do |c|
|
70
|
+
c.response.should match /\<?xml/
|
71
|
+
inserted << c.response.scan(%r{<_id>([^<]+)</_id>}).flatten.first
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should raise a 400 error if meta validation fails" do
|
77
|
+
with_api(test_api, api_options) do
|
78
|
+
headers = post_headers.merge('x-image-meta-store' => 'invalid one')
|
79
|
+
post_request({:path => "/images/#{@id}", :head => headers, :body => 'something'}, err) do |c|
|
80
|
+
assert_400 c
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should raise a 400 error if no headers neither body provided" do
|
86
|
+
with_api(test_api, api_options) do
|
87
|
+
post_request({:path => "/images/#{@id}"}, err) do |c|
|
88
|
+
assert_400 c
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should raise a 400 error if location header and body are both provided" do
|
94
|
+
with_api(test_api, api_options) do
|
95
|
+
headers = post_headers.merge('x-image-meta-location' => 'file:///path/file.iso')
|
96
|
+
post_request({:path => "/images/#{@id}", :head => headers, :body => 'something'}, err) do |c|
|
97
|
+
assert_400 c
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should raise a 400 error if store is HTTP" do
|
103
|
+
with_api(test_api, api_options) do
|
104
|
+
headers = post_headers.merge('x-image-meta-store' => 'http')
|
105
|
+
post_request({:path => "/images/#{@id}", :head => headers, :body => 'something'}, err) do |c|
|
106
|
+
assert_400 c
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|