deltacloud-core 0.1.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. data/DISCLAIMER +8 -0
  2. data/{COPYING → LICENSE} +0 -0
  3. data/NOTICE +13 -0
  4. data/Rakefile +50 -51
  5. data/bin/deltacloudd +8 -1
  6. data/config.ru +0 -2
  7. data/config/drivers.yaml +48 -0
  8. data/deltacloud-core.gemspec +75 -0
  9. data/deltacloud.rb +3 -2
  10. data/lib/deltacloud/backend_capability.rb +15 -3
  11. data/lib/deltacloud/base_driver.rb +0 -2
  12. data/lib/deltacloud/base_driver/base_driver.rb +85 -89
  13. data/lib/deltacloud/base_driver/features.rb +61 -7
  14. data/lib/deltacloud/base_driver/mock_driver.rb +42 -43
  15. data/lib/deltacloud/core_ext.rb +18 -0
  16. data/lib/deltacloud/core_ext/integer.rb +31 -0
  17. data/lib/deltacloud/core_ext/string.rb +50 -0
  18. data/lib/deltacloud/drivers/azure/azure_driver.rb +71 -22
  19. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +641 -584
  20. data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +0 -2
  21. data/lib/deltacloud/drivers/eucalyptus/eucalyptus_driver.rb +167 -0
  22. data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +39 -1
  23. data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +41 -25
  24. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob1.yml +6 -3
  25. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob2.yml +6 -3
  26. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob3.yml +4 -2
  27. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob4.yml +5 -2
  28. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob5.yml +4 -2
  29. data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +1 -0
  30. data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +1 -0
  31. data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +1 -0
  32. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml +1 -0
  33. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml +1 -0
  34. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml +1 -0
  35. data/lib/deltacloud/drivers/mock/mock_driver.rb +138 -30
  36. data/lib/deltacloud/drivers/opennebula/cloud_client.rb +13 -15
  37. data/lib/deltacloud/drivers/opennebula/occi_client.rb +13 -15
  38. data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +13 -15
  39. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +224 -113
  40. data/lib/deltacloud/drivers/rhevm/rhevm_client.rb +332 -0
  41. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +221 -170
  42. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +0 -1
  43. data/lib/deltacloud/drivers/sbc/sbc_client.rb +247 -0
  44. data/lib/deltacloud/drivers/sbc/sbc_driver.rb +297 -0
  45. data/lib/deltacloud/drivers/terremark/terremark_driver.rb +0 -2
  46. data/lib/deltacloud/hardware_profile.rb +1 -3
  47. data/lib/deltacloud/helpers.rb +0 -2
  48. data/lib/deltacloud/helpers/application_helper.rb +86 -12
  49. data/lib/deltacloud/helpers/blob_stream.rb +19 -2
  50. data/lib/deltacloud/helpers/conversion_helper.rb +0 -2
  51. data/lib/deltacloud/helpers/hardware_profiles_helper.rb +0 -2
  52. data/lib/deltacloud/method_serializer.rb +0 -2
  53. data/lib/deltacloud/models/base_model.rb +0 -2
  54. data/lib/deltacloud/models/blob.rb +1 -2
  55. data/lib/deltacloud/models/bucket.rb +0 -2
  56. data/lib/deltacloud/models/image.rb +0 -2
  57. data/lib/deltacloud/models/instance.rb +19 -2
  58. data/lib/deltacloud/models/instance_profile.rb +4 -2
  59. data/lib/deltacloud/models/key.rb +0 -2
  60. data/lib/deltacloud/models/load_balancer.rb +0 -2
  61. data/lib/deltacloud/models/realm.rb +0 -2
  62. data/lib/deltacloud/models/storage_snapshot.rb +0 -2
  63. data/lib/deltacloud/models/storage_volume.rb +4 -2
  64. data/lib/deltacloud/runner.rb +132 -0
  65. data/lib/deltacloud/state_machine.rb +0 -2
  66. data/lib/deltacloud/validation.rb +9 -7
  67. data/lib/drivers.rb +36 -48
  68. data/lib/sinatra/accept_media_types.rb +26 -0
  69. data/lib/sinatra/lazy_auth.rb +16 -0
  70. data/lib/sinatra/rabbit.rb +112 -54
  71. data/lib/sinatra/rack_driver_select.rb +50 -16
  72. data/lib/sinatra/rack_etag.rb +79 -0
  73. data/lib/sinatra/rack_matrix_params.rb +84 -0
  74. data/lib/sinatra/rack_runtime.rb +47 -0
  75. data/lib/sinatra/static_assets.rb +16 -0
  76. data/lib/sinatra/url_for.rb +31 -4
  77. data/public/favicon.ico +0 -0
  78. data/public/images/bread-bg.png +0 -0
  79. data/public/images/error.png +0 -0
  80. data/public/images/pending.png +0 -0
  81. data/public/images/running.png +0 -0
  82. data/public/images/stopped.png +0 -0
  83. data/public/javascripts/application.js +35 -0
  84. data/public/stylesheets/compiled/application.css +59 -5
  85. data/public/stylesheets/compiled/screen.css +1 -1
  86. data/server.rb +293 -29
  87. data/support/fedora/deltacloud-core +78 -0
  88. data/support/fedora/deltacloud-core.spec +143 -0
  89. data/support/fedora/deltacloudd +78 -18
  90. data/support/fedora/rubygem-deltacloud-core.spec +76 -40
  91. data/tests/common.rb +172 -0
  92. data/tests/drivers/mock/api_test.rb +133 -0
  93. data/tests/drivers/mock/hardware_profiles_test.rb +134 -0
  94. data/tests/drivers/mock/images_test.rb +126 -0
  95. data/tests/drivers/mock/instance_states_test.rb +71 -0
  96. data/tests/drivers/mock/instances_test.rb +236 -0
  97. data/tests/drivers/mock/realms_test.rb +93 -0
  98. data/tests/drivers/mock/setup.rb +3 -0
  99. data/tests/drivers/mock/url_for_test.rb +67 -0
  100. data/tests/drivers/rackspace/api_test.rb +41 -0
  101. data/tests/drivers/rackspace/hardware_profiles_test.rb +53 -0
  102. data/tests/drivers/rackspace/images_test.rb +40 -0
  103. data/tests/drivers/rackspace/instances_test.rb +161 -0
  104. data/tests/drivers/rackspace/realms_test.rb +36 -0
  105. data/tests/drivers/rackspace/setup.rb +14 -0
  106. data/tests/drivers/rhevm/api_test.rb +39 -0
  107. data/tests/drivers/rhevm/hardware_profiles_test.rb +53 -0
  108. data/tests/drivers/rhevm/images_test.rb +42 -0
  109. data/tests/drivers/rhevm/instances_test.rb +179 -0
  110. data/tests/drivers/rhevm/realms_test.rb +35 -0
  111. data/tests/drivers/rhevm/setup.rb +14 -0
  112. data/tests/rabbit_test.rb +52 -0
  113. data/views/api/show.html.haml +2 -5
  114. data/views/blobs/new.html.haml +17 -1
  115. data/views/blobs/show.html.haml +6 -0
  116. data/views/blobs/show.xml.haml +5 -1
  117. data/views/buckets/index.html.haml +1 -12
  118. data/views/buckets/index.xml.haml +3 -5
  119. data/views/docs/operation.html.haml +23 -11
  120. data/views/drivers/index.html.haml +15 -0
  121. data/views/drivers/index.xml.haml +7 -0
  122. data/views/drivers/show.html.haml +20 -0
  123. data/views/drivers/show.xml.haml +7 -0
  124. data/views/error.html.haml +31 -0
  125. data/views/errors/auth_exception.xml.haml +2 -1
  126. data/views/errors/backend_capability_failure.xml.haml +2 -1
  127. data/views/errors/backend_error.html.haml +3 -0
  128. data/views/errors/backend_error.xml.haml +2 -2
  129. data/views/errors/validation_failure.xml.haml +3 -2
  130. data/views/images/index.html.haml +1 -6
  131. data/views/images/index.xml.haml +2 -0
  132. data/views/images/new.html.haml +14 -0
  133. data/views/images/show.xml.haml +2 -0
  134. data/views/instances/index.html.haml +8 -6
  135. data/views/instances/index.xml.haml +4 -0
  136. data/views/instances/new.html.haml +40 -11
  137. data/views/instances/run.html.haml +9 -0
  138. data/views/instances/run.xml.haml +7 -0
  139. data/views/instances/run_command.html.haml +16 -0
  140. data/views/instances/show.html.haml +14 -0
  141. data/views/instances/show.xml.haml +12 -4
  142. data/views/layout.html.haml +7 -2
  143. data/views/load_balancers/index.html.haml +1 -1
  144. data/views/load_balancers/new.html.haml +2 -2
  145. data/views/load_balancers/show.html.haml +1 -1
  146. data/views/storage_snapshots/index.html.haml +3 -0
  147. data/views/storage_snapshots/new.html.haml +9 -0
  148. data/views/storage_volumes/attach.html.haml +20 -0
  149. data/views/storage_volumes/index.html.haml +16 -1
  150. data/views/storage_volumes/index.xml.haml +1 -10
  151. data/views/storage_volumes/new.html.haml +17 -0
  152. data/views/storage_volumes/show.html.haml +8 -0
  153. data/views/storage_volumes/show.xml.haml +25 -3
  154. metadata +197 -127
  155. data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +0 -130
  156. data/parse.rb +0 -7
  157. data/test.rb +0 -3
  158. data/views/api/drivers.xml.haml +0 -6
@@ -1,5 +1,3 @@
1
- # Copyright (C) 2010 Red Hat, Inc.
2
- #
3
1
  # Licensed to the Apache Software Foundation (ASF) under one or more
4
2
  # contributor license agreements. See the NOTICE file distributed with
5
3
  # this work for additional information regarding copyright ownership. The
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009,2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -63,7 +61,7 @@ module Deltacloud
63
61
  end
64
62
 
65
63
  def param
66
- "hwp_#{name}"
64
+ :"hwp_#{name}"
67
65
  end
68
66
 
69
67
  def fixed?
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009,2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -1,5 +1,3 @@
1
- # Copyright (C) 2009, 2010 Red Hat, Inc.
2
- #
3
1
  # Licensed to the Apache Software Foundation (ASF) under one or more
4
2
  # contributor license agreements. See the NOTICE file distributed with
5
3
  # this work for additional information regarding copyright ownership. The
@@ -17,8 +15,12 @@
17
15
 
18
16
  # Methods added to this helper will be available to all templates in the application.
19
17
 
18
+ require 'benchmark'
19
+
20
20
  module ApplicationHelper
21
21
 
22
+ include Deltacloud
23
+
22
24
  def bread_crumb
23
25
  s = "<ul class='breadcrumb'><li class='first'><a href='#{url_for('/')}'>&#948</a></li>"
24
26
  url = request.path_info.split('?') #remove extra query string parameters
@@ -34,11 +36,16 @@ module ApplicationHelper
34
36
  end
35
37
  end
36
38
  end
39
+ s+="<li class='docs'>#{link_to_documentation}</li>"
37
40
  s+="</ul>"
38
41
  end
39
42
 
40
43
  def instance_action_method(action)
41
- collections[:instances].operations[action.to_sym].method
44
+ action_method(action, :instances)
45
+ end
46
+
47
+ def action_method(action, collection)
48
+ collections[collection].operations[action.to_sym].method
42
49
  end
43
50
 
44
51
  def driver_has_feature?(feature_name, collection_name = :instances)
@@ -67,9 +74,12 @@ module ApplicationHelper
67
74
  filter.merge!(:architecture => params[:architecture]) if params[:architecture]
68
75
  filter.merge!(:owner_id => params[:owner_id]) if params[:owner_id]
69
76
  filter.merge!(:state => params[:state]) if params[:state]
70
- filter = nil if filter.keys.size.eql?(0)
77
+ filter = {} if filter.keys.size.eql?(0)
71
78
  singular = model.to_s.singularize.to_sym
72
- @elements = driver.send(model.to_sym, credentials, filter)
79
+ @benchmark = Benchmark.measure do
80
+ @elements = driver.send(model.to_sym, credentials, filter)
81
+ end
82
+ headers['X-Backend-Runtime'] = @benchmark.real.to_s
73
83
  instance_variable_set(:"@#{model}", @elements)
74
84
  respond_to do |format|
75
85
  format.html { haml :"#{model}/index" }
@@ -79,7 +89,9 @@ module ApplicationHelper
79
89
  end
80
90
 
81
91
  def show(model)
82
- @element = driver.send(model, credentials, { :id => params[:id]} )
92
+ @benchmark = Benchmark.measure do
93
+ @element = driver.send(model, credentials, { :id => params[:id]} )
94
+ end
83
95
  instance_variable_set("@#{model}", @element)
84
96
  if @element
85
97
  respond_to do |format|
@@ -97,7 +109,7 @@ module ApplicationHelper
97
109
  response.status = status
98
110
  respond_to do |format|
99
111
  format.xml { haml :"errors/#{template}", :layout => false }
100
- format.html { haml :"errors/#{template}" }
112
+ format.html { haml :"errors/#{template}", :layout => :error }
101
113
  end
102
114
  end
103
115
 
@@ -112,7 +124,13 @@ module ApplicationHelper
112
124
 
113
125
  @instance = driver.send(:"#{name}_instance", credentials, params["id"])
114
126
 
115
- return redirect(instances_url) if name.eql?(:destroy) or @instance.class!=Instance
127
+ if name == :destroy or @instance.class!=Instance
128
+ respond_to do |format|
129
+ format.xml { return 204 }
130
+ format.json { return 204 }
131
+ format.html { return redirect(instances_url) }
132
+ end
133
+ end
116
134
 
117
135
  respond_to do |format|
118
136
  format.xml { haml :"instances/show" }
@@ -121,8 +139,8 @@ module ApplicationHelper
121
139
  end
122
140
  end
123
141
 
124
- def cdata(&block)
125
- text = capture_haml(&block)
142
+ def cdata(text = nil, &block)
143
+ text ||= capture_haml(&block)
126
144
  "<![CDATA[#{text.strip}]]>"
127
145
  end
128
146
 
@@ -131,9 +149,8 @@ module ApplicationHelper
131
149
  end
132
150
 
133
151
  def link_to_action(action, url, method)
134
- return link_to(action, url) if method.eql? :get
135
152
  capture_haml do
136
- haml_tag :form, :method => :post, :action => url, :class => :link do
153
+ haml_tag :form, :method => :post, :action => url, :class => [:link, method] do
137
154
  haml_tag :input, :type => :hidden, :name => '_method', :value => method
138
155
  haml_tag :button, :type => :submit do
139
156
  haml_concat action
@@ -142,4 +159,61 @@ module ApplicationHelper
142
159
  end
143
160
  end
144
161
 
162
+ def link_to_format(format)
163
+ return '' unless request.env['REQUEST_URI']
164
+ uri = request.env['REQUEST_URI']
165
+ return if uri.include?('format=')
166
+ if uri.include?('?')
167
+ uri+="&format=#{format}"
168
+ else
169
+ uri+="?format=#{format}"
170
+ end
171
+ '<a href="%s">%s</a>' % [uri, "#{format}".upcase]
172
+ end
173
+
174
+ def link_to_documentation
175
+ return '' unless request.env['REQUEST_URI']
176
+ uri = request.env['REQUEST_URI'].dup
177
+ uri.gsub!('/api', '/api/docs/') unless uri.include?("docs") #i.e. if already serving under /api/docs, leave it be
178
+ '<a href="%s">[ Documentation ]</a>' % uri
179
+ end
180
+
181
+ def action_url
182
+ if [:index].include?(@operation.name)
183
+ url_for("/api/#{@collection.name.to_s}")
184
+ elsif [:show, :stop, :start, :reboot, :attach, :detach].include?(@operation.name)
185
+ url_for("/api/#{@collection.name.to_s}/:id/#{@operation.name}")
186
+ elsif [:destroy].include?(@operation.name)
187
+ url_for("/api/#{@collection.name.to_s}/:id")
188
+ else
189
+ url_for("/api/#{@collection.name}/#{@operation.name}")
190
+ end
191
+ end
192
+
193
+ def image_for_state(state)
194
+ state_img = "stopped" if (state!='RUNNING' or state!='PENDING')
195
+ "<img src='/images/#{state.downcase}.png' title='#{state}'/>"
196
+ end
197
+
198
+ def truncate_words(text, length = 10)
199
+ return nil unless text
200
+ return text if text.length<=length
201
+ end_string = "...#{text[(text.length-(length/2))..text.length]}"
202
+ "#{text[0..(length/2)]}#{end_string}"
203
+ end
204
+
205
+ # Reverse the entrypoints hash for a driver from drivers.yaml; note that
206
+ # +d+ is a hash, not an actual driver object
207
+ def driver_provider(d)
208
+ result = {}
209
+ if d[:entrypoints]
210
+ d[:entrypoints].each do |kind, details|
211
+ details.each do |prov, url|
212
+ result[prov] ||= {}
213
+ result[prov][kind] = url
214
+ end
215
+ end
216
+ end
217
+ result
218
+ end
145
219
  end
@@ -1,5 +1,3 @@
1
- # Copyright (C) 2010 Red Hat, Inc.
2
- #
3
1
  # Licensed to the Apache Software Foundation (ASF) under one or more
4
2
  # contributor license agreements. See the NOTICE file distributed with
5
3
  # this work for additional information regarding copyright ownership. The
@@ -15,6 +13,7 @@
15
13
  # License for the specific language governing permissions and limitations
16
14
  # under the License.
17
15
 
16
+ include Deltacloud
18
17
  begin
19
18
  require 'eventmachine'
20
19
  #--
@@ -62,3 +61,21 @@ rescue LoadError => e
62
61
  end
63
62
  end
64
63
  end
64
+
65
+ class Hash
66
+
67
+ def gsub_keys(pattern, replacement)
68
+ rgx_pattern = Regexp.compile(pattern, true)
69
+ remove = []
70
+ self.each_key do |key|
71
+ if key.to_s.match(rgx_pattern)
72
+ new_key = key.to_s.gsub(rgx_pattern, replacement)
73
+ self[new_key] = self[key]
74
+ remove << key
75
+ end #key.match
76
+ end # each_key do
77
+ #remove the original keys
78
+ self.delete_if{|k,v| remove.include?(k)}
79
+ end #def
80
+
81
+ end #class
@@ -1,5 +1,3 @@
1
- # Copyright (C) 2009, 2010 Red Hat, Inc.
2
- #
3
1
  # Licensed to the Apache Software Foundation (ASF) under one or more
4
2
  # contributor license agreements. See the NOTICE file distributed with
5
3
  # this work for additional information regarding copyright ownership. The
@@ -1,5 +1,3 @@
1
- # Copyright (C) 2009, 2010 Red Hat, Inc.
2
- #
3
1
  # Licensed to the Apache Software Foundation (ASF) under one or more
4
2
  # contributor license agreements. See the NOTICE file distributed with
5
3
  # this work for additional information regarding copyright ownership. The
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009,2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -24,5 +22,6 @@ class Blob < BaseModel
24
22
  attr_accessor :content_type
25
23
  attr_accessor :last_modified
26
24
  attr_accessor :content
25
+ attr_accessor :user_metadata
27
26
 
28
27
  end
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -30,6 +28,25 @@ class Instance < BaseModel
30
28
  attr_accessor :launch_time
31
29
  attr_accessor :keyname
32
30
  attr_accessor :authn_error
31
+ attr_accessor :username
32
+ attr_accessor :password
33
+ attr_accessor :create_image
34
+
35
+ def can_create_image?
36
+ self.create_image
37
+ end
38
+
39
+ def to_s
40
+ name
41
+ end
42
+
43
+ def hardware_profile
44
+ instance_profile
45
+ end
46
+
47
+ def hardware_profile=(profile)
48
+ instance_profile = profile
49
+ end
33
50
 
34
51
  def initialize(init=nil)
35
52
  super(init)
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -38,6 +36,10 @@ class InstanceProfile < BaseModel
38
36
  id
39
37
  end
40
38
 
39
+ def to_s
40
+ name
41
+ end
42
+
41
43
  def overrides
42
44
  [:memory, :storage, :architecture, :cpu].inject({}) do |h, p|
43
45
  if v = instance_variable_get("@#{p}")
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -1,6 +1,4 @@
1
1
  #
2
- # Copyright (C) 2009, 2010 Red Hat, Inc.
3
- #
4
2
  # Licensed to the Apache Software Foundation (ASF) under one or more
5
3
  # contributor license agreements. See the NOTICE file distributed with
6
4
  # this work for additional information regarding copyright ownership. The
@@ -24,5 +22,9 @@ class StorageVolume < BaseModel
24
22
  attr_accessor :capacity
25
23
  attr_accessor :instance_id
26
24
  attr_accessor :device
25
+ attr_accessor :realm_id
26
+ attr_accessor :actions
27
+ attr_accessor :name
28
+ attr_accessor :kind
27
29
 
28
30
  end
@@ -0,0 +1,132 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ require 'net/ssh'
17
+ require 'socket'
18
+ require 'tempfile'
19
+
20
+ module Deltacloud
21
+
22
+ module Runner
23
+
24
+ class RunnerError < StandardError
25
+ attr_reader :message
26
+ def initialize(message)
27
+ @message = message
28
+ super
29
+ end
30
+ end
31
+
32
+ class InstanceSSHError < RunnerError; end
33
+
34
+ def self.execute(command, opts={})
35
+
36
+ if opts[:credentials] and (not opts[:credentials][:password] and not opts[:private_key])
37
+ raise RunnerError::new("Either password or key must be specified")
38
+ end
39
+
40
+ # First check networking and firewalling
41
+ network = Network::new(opts[:ip], opts[:port])
42
+
43
+ # Then check SSH availability
44
+ ssh = SSH::new(network, opts[:credentials], opts[:private_key])
45
+
46
+ # Finaly execute SSH command on instance
47
+ ssh.execute(command)
48
+ end
49
+
50
+ class Network
51
+ attr_accessor :ip, :port
52
+
53
+ def initialize(ip, port)
54
+ @ip, @port = ip, port
55
+ end
56
+ end
57
+
58
+ class SSH
59
+
60
+ attr_reader :network
61
+ attr_accessor :credentials, :key
62
+ attr_reader :command
63
+
64
+ def initialize(network, credentials, key=nil)
65
+ @network, @credentials, @key = network, credentials, key
66
+ @result = ""
67
+ end
68
+
69
+ def execute(command)
70
+ @command = command
71
+ config = ssh_config(@network, @credentials, @key)
72
+ begin
73
+ session = nil
74
+ # Default timeout for connecting to an instance.
75
+ # 20 seconds should be OK for most of connections, if you are
76
+ # experiencing some Exceptions with Timeouts increase this value.
77
+ # Please keep in mind that the HTTP request timeout is set to 60
78
+ # seconds, so you need to fit into this time
79
+ Timeout::timeout(20) do
80
+ session = Net::SSH.start(@network.ip, 'root', config)
81
+ end
82
+ session.open_channel do |channel|
83
+ channel.on_data do |ch, data|
84
+ @result += data
85
+ end
86
+ channel.exec(command)
87
+ session.loop
88
+ end
89
+ session.close
90
+ rescue Exception => e
91
+ raise InstanceSSHError.new("#{e.class.name}: #{e.message}")
92
+ ensure
93
+ # FileUtils.rm(config[:keys].first) rescue nil
94
+ end
95
+ Deltacloud::Runner::Response.new(self, @result)
96
+ end
97
+
98
+ private
99
+
100
+ def ssh_config(network, credentials, key)
101
+ config = { :port => network.port }
102
+ config.merge!({ :password => credentials[:password ]}) if credentials[:password]
103
+ config.merge!({ :keys => [ keyfile(key) ] }) unless key.nil?
104
+ config
105
+ end
106
+
107
+ # Right now there is no way howto pass private_key using String
108
+ # eg. without saving key to temporary file.
109
+ def keyfile(key)
110
+ keyfile = Tempfile.new("ec2_private.key")
111
+ key_material = ""
112
+ key.split("\n").each { |line| key_material+="#{line.strip}\n" if line.strip.size>0 }
113
+ keyfile.write(key_material) && keyfile.close
114
+ puts "[*] Using #{keyfile.path} as private key"
115
+ keyfile.path
116
+ end
117
+
118
+ end
119
+
120
+ class Response
121
+
122
+ attr_reader :body
123
+ attr_reader :ssh
124
+
125
+ def initialize(ssh, response_body)
126
+ @body, @ssh = response_body, ssh
127
+ end
128
+
129
+ end
130
+
131
+ end
132
+ end