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.
Files changed (43) hide show
  1. data/bin/visor +423 -0
  2. data/bin/visor-image +10 -0
  3. data/config/server.rb +14 -0
  4. data/lib/image/auth.rb +147 -0
  5. data/lib/image/cli.rb +397 -0
  6. data/lib/image/client.rb +490 -0
  7. data/lib/image/meta.rb +219 -0
  8. data/lib/image/routes/delete_all_images.rb +40 -0
  9. data/lib/image/routes/delete_image.rb +62 -0
  10. data/lib/image/routes/get_image.rb +78 -0
  11. data/lib/image/routes/get_images.rb +54 -0
  12. data/lib/image/routes/get_images_detail.rb +54 -0
  13. data/lib/image/routes/head_image.rb +51 -0
  14. data/lib/image/routes/post_image.rb +189 -0
  15. data/lib/image/routes/put_image.rb +205 -0
  16. data/lib/image/server.rb +307 -0
  17. data/lib/image/store/cumulus.rb +126 -0
  18. data/lib/image/store/file_system.rb +119 -0
  19. data/lib/image/store/hdfs.rb +149 -0
  20. data/lib/image/store/http.rb +78 -0
  21. data/lib/image/store/lunacloud.rb +126 -0
  22. data/lib/image/store/s3.rb +121 -0
  23. data/lib/image/store/store.rb +39 -0
  24. data/lib/image/store/walrus.rb +130 -0
  25. data/lib/image/version.rb +5 -0
  26. data/lib/visor-image.rb +30 -0
  27. data/spec/lib/client_spec.rb +0 -0
  28. data/spec/lib/meta_spec.rb +230 -0
  29. data/spec/lib/routes/delete_image_spec.rb +98 -0
  30. data/spec/lib/routes/get_image_spec.rb +78 -0
  31. data/spec/lib/routes/get_images_detail_spec.rb +104 -0
  32. data/spec/lib/routes/get_images_spec.rb +104 -0
  33. data/spec/lib/routes/head_image_spec.rb +51 -0
  34. data/spec/lib/routes/post_image_spec.rb +112 -0
  35. data/spec/lib/routes/put_image_spec.rb +109 -0
  36. data/spec/lib/server_spec.rb +62 -0
  37. data/spec/lib/store/cumulus_spec.rb +0 -0
  38. data/spec/lib/store/file_system_spec.rb +32 -0
  39. data/spec/lib/store/http_spec.rb +56 -0
  40. data/spec/lib/store/s3_spec.rb +37 -0
  41. data/spec/lib/store/store_spec.rb +36 -0
  42. data/spec/lib/store/walrus_spec.rb +0 -0
  43. 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