bbrowning-deltacloud-core 0.0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/COPYING +502 -0
  2. data/Rakefile +85 -0
  3. data/bin/deltacloudd +88 -0
  4. data/config.ru +5 -0
  5. data/deltacloud.rb +14 -0
  6. data/lib/deltacloud/base_driver.rb +19 -0
  7. data/lib/deltacloud/base_driver/base_driver.rb +189 -0
  8. data/lib/deltacloud/base_driver/features.rb +159 -0
  9. data/lib/deltacloud/base_driver/mock_driver.rb +37 -0
  10. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +340 -0
  11. data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +170 -0
  12. data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +45 -0
  13. data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +322 -0
  14. data/lib/deltacloud/drivers/mock/mock_driver.rb +275 -0
  15. data/lib/deltacloud/drivers/opennebula/cloud_client.rb +116 -0
  16. data/lib/deltacloud/drivers/opennebula/occi_client.rb +204 -0
  17. data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +241 -0
  18. data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +129 -0
  19. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +150 -0
  20. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +254 -0
  21. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_client.rb +84 -0
  22. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +144 -0
  23. data/lib/deltacloud/drivers/terremark/terremark_driver.rb +261 -0
  24. data/lib/deltacloud/hardware_profile.rb +153 -0
  25. data/lib/deltacloud/helpers.rb +5 -0
  26. data/lib/deltacloud/helpers/application_helper.rb +56 -0
  27. data/lib/deltacloud/helpers/conversion_helper.rb +38 -0
  28. data/lib/deltacloud/helpers/hardware_profiles_helper.rb +35 -0
  29. data/lib/deltacloud/method_serializer.rb +84 -0
  30. data/lib/deltacloud/models/base_model.rb +58 -0
  31. data/lib/deltacloud/models/image.rb +26 -0
  32. data/lib/deltacloud/models/instance.rb +37 -0
  33. data/lib/deltacloud/models/instance_profile.rb +47 -0
  34. data/lib/deltacloud/models/realm.rb +25 -0
  35. data/lib/deltacloud/models/storage_snapshot.rb +26 -0
  36. data/lib/deltacloud/models/storage_volume.rb +27 -0
  37. data/lib/deltacloud/state_machine.rb +84 -0
  38. data/lib/deltacloud/validation.rb +70 -0
  39. data/lib/drivers.rb +38 -0
  40. data/lib/sinatra/accept_media_types.rb +128 -0
  41. data/lib/sinatra/lazy_auth.rb +56 -0
  42. data/lib/sinatra/rabbit.rb +272 -0
  43. data/lib/sinatra/respond_to.rb +269 -0
  44. data/lib/sinatra/static_assets.rb +83 -0
  45. data/lib/sinatra/url_for.rb +51 -0
  46. data/public/favicon.ico +0 -0
  47. data/public/images/grid.png +0 -0
  48. data/public/images/logo-wide.png +0 -0
  49. data/public/images/rails.png +0 -0
  50. data/public/images/topbar-bg.png +0 -0
  51. data/public/javascripts/application.js +32 -0
  52. data/public/javascripts/jquery-1.4.2.min.js +154 -0
  53. data/public/stylesheets/compiled/application.css +613 -0
  54. data/public/stylesheets/compiled/ie.css +31 -0
  55. data/public/stylesheets/compiled/print.css +27 -0
  56. data/public/stylesheets/compiled/screen.css +456 -0
  57. data/server.rb +342 -0
  58. data/support/fedora/deltacloudd +68 -0
  59. data/support/fedora/rubygem-deltacloud-core.spec +91 -0
  60. data/tests/deltacloud_test.rb +60 -0
  61. data/tests/images_test.rb +94 -0
  62. data/tests/instances_test.rb +136 -0
  63. data/tests/realms_test.rb +56 -0
  64. data/tests/storage_snapshots_test.rb +48 -0
  65. data/tests/storage_volumes_test.rb +48 -0
  66. data/torquebox-ec2-config.ru +8 -0
  67. data/views/accounts/index.html.haml +11 -0
  68. data/views/accounts/show.html.haml +30 -0
  69. data/views/api/show.html.haml +15 -0
  70. data/views/api/show.xml.haml +5 -0
  71. data/views/docs/collection.html.haml +37 -0
  72. data/views/docs/collection.xml.haml +14 -0
  73. data/views/docs/index.html.haml +15 -0
  74. data/views/docs/index.xml.haml +5 -0
  75. data/views/docs/operation.html.haml +31 -0
  76. data/views/docs/operation.xml.haml +10 -0
  77. data/views/errors/auth_exception.html.haml +8 -0
  78. data/views/errors/auth_exception.xml.haml +2 -0
  79. data/views/errors/backend_error.html.haml +17 -0
  80. data/views/errors/backend_error.xml.haml +8 -0
  81. data/views/errors/validation_failure.html.haml +11 -0
  82. data/views/errors/validation_failure.xml.haml +7 -0
  83. data/views/hardware_profiles/index.html.haml +25 -0
  84. data/views/hardware_profiles/index.xml.haml +4 -0
  85. data/views/hardware_profiles/show.html.haml +19 -0
  86. data/views/hardware_profiles/show.xml.haml +17 -0
  87. data/views/images/index.html.haml +30 -0
  88. data/views/images/index.xml.haml +7 -0
  89. data/views/images/show.html.haml +21 -0
  90. data/views/images/show.xml.haml +5 -0
  91. data/views/instance_states/show.gv.erb +45 -0
  92. data/views/instance_states/show.html.haml +31 -0
  93. data/views/instance_states/show.xml.haml +8 -0
  94. data/views/instances/index.html.haml +30 -0
  95. data/views/instances/index.xml.haml +23 -0
  96. data/views/instances/new.html.haml +55 -0
  97. data/views/instances/show.html.haml +43 -0
  98. data/views/instances/show.xml.haml +41 -0
  99. data/views/layout.html.haml +26 -0
  100. data/views/realms/index.html.haml +29 -0
  101. data/views/realms/index.xml.haml +12 -0
  102. data/views/realms/show.html.haml +15 -0
  103. data/views/realms/show.xml.haml +10 -0
  104. data/views/root/index.html.haml +4 -0
  105. data/views/storage_snapshots/index.html.haml +20 -0
  106. data/views/storage_snapshots/index.xml.haml +11 -0
  107. data/views/storage_snapshots/show.html.haml +14 -0
  108. data/views/storage_snapshots/show.xml.haml +9 -0
  109. data/views/storage_volumes/index.html.haml +21 -0
  110. data/views/storage_volumes/index.xml.haml +13 -0
  111. data/views/storage_volumes/show.html.haml +20 -0
  112. data/views/storage_volumes/show.xml.haml +13 -0
  113. metadata +361 -0
data/server.rb ADDED
@@ -0,0 +1,342 @@
1
+ require 'rubygems'
2
+ require 'deltacloud'
3
+ require 'json'
4
+ require 'sinatra'
5
+ require 'sinatra/respond_to'
6
+ require 'erb'
7
+ require 'haml'
8
+ require 'open3'
9
+ require 'builder'
10
+ require 'drivers'
11
+ require 'sinatra/static_assets'
12
+ require 'sinatra/rabbit'
13
+ require 'sinatra/lazy_auth'
14
+ require 'deltacloud/validation'
15
+ require 'deltacloud/helpers'
16
+
17
+ configure do
18
+ set :raise_errors => false
19
+ end
20
+
21
+ configure :development do
22
+ # So we can just use puts for logging
23
+ $stdout.sync = true
24
+ $stderr.sync = true
25
+ end
26
+
27
+ DRIVER=ENV['API_DRIVER'] ? ENV['API_DRIVER'].to_sym : :mock
28
+
29
+ # You could use $API_HOST environment variable to change your hostname to
30
+ # whatever you want (eg. if you running API behind NAT)
31
+ HOSTNAME=ENV['API_HOST'] ? ENV['API_HOST'] : nil
32
+
33
+ Rack::Mime::MIME_TYPES.merge!({ ".gv" => "text/plain" })
34
+
35
+ Sinatra::Application.register Sinatra::RespondTo
36
+
37
+ # Common actions
38
+ #
39
+
40
+ def filter_all(model)
41
+ filter = {}
42
+ filter.merge!(:id => params[:id]) if params[:id]
43
+ filter.merge!(:architecture => params[:architecture]) if params[:architecture]
44
+ filter.merge!(:owner_id => params[:owner_id]) if params[:owner_id]
45
+ filter.merge!(:state => params[:state]) if params[:state]
46
+ filter = nil if filter.keys.size.eql?(0)
47
+ singular = model.to_s.singularize.to_sym
48
+ @elements = driver.send(model.to_sym, credentials, filter)
49
+ instance_variable_set(:"@#{model}", @elements)
50
+ respond_to do |format|
51
+ format.html { haml :"#{model}/index" }
52
+ format.xml { haml :"#{model}/index" }
53
+ format.json { convert_to_json(singular, @elements) }
54
+ end
55
+ end
56
+
57
+ def show(model)
58
+ @element = driver.send(model, credentials, { :id => params[:id]} )
59
+ instance_variable_set("@#{model}", @element)
60
+ respond_to do |format|
61
+ format.html { haml :"#{model.to_s.pluralize}/show" }
62
+ format.xml { haml :"#{model.to_s.pluralize}/show" }
63
+ format.json { convert_to_json(model, @element) }
64
+ end
65
+ end
66
+
67
+
68
+ #
69
+ # Error handlers
70
+ #
71
+ def report_error(status, template)
72
+ @error = request.env['sinatra.error']
73
+ response.status = status
74
+ respond_to do |format|
75
+ format.xml { haml :"errors/#{template}", :layout => false }
76
+ format.html { haml :"errors/#{template}" }
77
+ end
78
+ end
79
+
80
+ error Deltacloud::Validation::Failure do
81
+ report_error(400, "validation_failure")
82
+ end
83
+
84
+ error Deltacloud::AuthException do
85
+ report_error(403, "auth_exception")
86
+ end
87
+
88
+ error Deltacloud::BackendError do
89
+ report_error(500, "backend_error")
90
+ end
91
+
92
+ # Redirect to /api
93
+ get '/' do redirect url_for('/api'); end
94
+
95
+ get '/api\/?' do
96
+ @version = 1.0
97
+ respond_to do |format|
98
+ format.xml { haml :"api/show" }
99
+ format.json do
100
+ { :api => {
101
+ :version => @version,
102
+ :driver => DRIVER,
103
+ :links => entry_points.collect { |l| { :rel => l[0], :href => l[1]} }
104
+ }
105
+ }.to_json
106
+ end
107
+ format.html { haml :"api/show" }
108
+ end
109
+ end
110
+
111
+ # Rabbit DSL
112
+
113
+ collection :realms do
114
+ description "Within a cloud provider a realm represents a boundary containing resources. The exact definition of a realm is left to the cloud provider. In some cases, a realm may represent different datacenters, different continents, or different pools of resources within a single datacenter. A cloud provider may insist that resources must all exist within a single realm in order to cooperate. For instance, storage volumes may only be allowed to be mounted to instances within the same realm."
115
+
116
+ operation :index do
117
+ description 'Operation will list all available realms. For specific architecture use "architecture" parameter.'
118
+ param :id, :string
119
+ param :architecture, :string, :optional, [ 'i386', 'x86_64' ]
120
+ control { filter_all(:realms) }
121
+ end
122
+
123
+ #FIXME: It always shows whole list
124
+ operation :show do
125
+ description 'Show an realm identified by "id" parameter.'
126
+ param :id, :string, :required
127
+ control { show(:realm) }
128
+ end
129
+
130
+ end
131
+
132
+ collection :images do
133
+ description "An image is a platonic form of a machine. Images are not directly executable, but are a template for creating actual instances of machines."
134
+
135
+ operation :index do
136
+ description 'The instances collection will return a set of all images available to the current use. You can filter images using "owner_id" and "architecture" parameter'
137
+ param :id, :string
138
+ param :owner_id, :string
139
+ param :architecture, :string, :optional
140
+ control { filter_all(:images) }
141
+ end
142
+
143
+ operation :show do
144
+ description 'Show an image identified by "id" parameter.'
145
+ param :id, :string, :required
146
+ control { show(:image) }
147
+ end
148
+
149
+ end
150
+
151
+ collection :instance_states do
152
+ description "The possible states of an instance, and how to traverse between them "
153
+
154
+ operation :index do
155
+ control do
156
+ @machine = driver.instance_state_machine
157
+ respond_to do |format|
158
+ format.xml { haml :'instance_states/show', :layout => false }
159
+ format.json do
160
+ out = []
161
+ @machine.states.each do |state|
162
+ transitions = state.transitions.collect do |t|
163
+ t.automatically? ? {:to => t.destination, :auto => 'true'} : {:to => t.destination, :action => t.action}
164
+ end
165
+ out << { :name => state, :transitions => transitions }
166
+ end
167
+ out.to_json
168
+ end
169
+ format.html { haml :'instance_states/show'}
170
+ format.gv { erb :"instance_states/show" }
171
+ format.png do
172
+ # Trick respond_to into looking up the right template for the
173
+ # graphviz file
174
+ format(:gv); gv = erb :"instance_states/show"; format(:png)
175
+ png = ''
176
+ cmd = 'dot -Kdot -Gpad="0.2,0.2" -Gsize="5.0,8.0" -Gdpi="180" -Tpng'
177
+ Open3.popen3( cmd ) do |stdin, stdout, stderr|
178
+ stdin.write( gv )
179
+ stdin.close()
180
+ png = stdout.read
181
+ end
182
+ png
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ get "/api/instances/new" do
190
+ @instance = Instance.new( { :id=>params[:id], :image_id=>params[:image_id] } )
191
+ @image = driver.image( credentials, :id => params[:image_id] )
192
+ @hardware_profiles = driver.hardware_profiles(credentials, :architecture => @image.architecture )
193
+ @realms = driver.realms(credentials)
194
+ respond_to do |format|
195
+ format.html { haml :"instances/new" }
196
+ end
197
+ end
198
+
199
+ def instance_action(name)
200
+ @instance = driver.send(:"#{name}_instance", credentials, params["id"])
201
+
202
+ return redirect(instances_url) if name.eql?(:destroy) or @instance.class!=Instance
203
+
204
+ respond_to do |format|
205
+ format.html { haml :"instances/show" }
206
+ format.xml { haml :"instances/show" }
207
+ format.json {convert_to_json(:instance, @instance) }
208
+ end
209
+ end
210
+
211
+ collection :instances do
212
+ description "An instance is a concrete machine realized from an image. The images collection may be obtained by following the link from the primary entry-point."
213
+
214
+ operation :index do
215
+ description "List all instances"
216
+ param :id, :string, :optional
217
+ param :state, :string, :optional
218
+ control { filter_all(:instances) }
219
+ end
220
+
221
+ operation :show do
222
+ description 'Show an image identified by "id" parameter.'
223
+ param :id, :string, :required
224
+ control { show(:instance) }
225
+ end
226
+
227
+ operation :create do
228
+ description "Create a new instance"
229
+ param :image_id, :string, :required
230
+ param :realm_id, :string, :optional
231
+ param :hwp_id, :string, :optional
232
+ control do
233
+ @image = driver.image(credentials, :id => params[:image_id])
234
+ instance = driver.create_instance(credentials, @image.id, params)
235
+ respond_to do |format|
236
+ format.xml do
237
+ response.status = 201 # Created
238
+ response['Location'] = instance_url(instance.id)
239
+ @instance = instance
240
+ haml :"instances/show"
241
+ end
242
+ format.html do
243
+ redirect instance_url(instance.id) if instance and instance.id
244
+ redirect instances_url
245
+ end
246
+ end
247
+ end
248
+ end
249
+
250
+ operation :reboot, :method => :post, :member => true do
251
+ description "Reboot running instance"
252
+ param :id, :string, :required
253
+ control { instance_action(:reboot) }
254
+ end
255
+
256
+ operation :start, :method => :post, :member => true do
257
+ description "Start an instance"
258
+ param :id, :string, :required
259
+ control { instance_action(:start) }
260
+ end
261
+
262
+ operation :stop, :method => :post, :member => true do
263
+ description "Stop running instance"
264
+ param :id, :string, :required
265
+ control { instance_action(:stop) }
266
+ end
267
+
268
+ operation :destroy do
269
+ description "Destroy instance"
270
+ param :id, :string, :required
271
+ control { instance_action(:destroy) }
272
+ end
273
+ end
274
+
275
+ collection :hardware_profiles do
276
+ description <<END
277
+ A hardware profile represents a configuration of resources upon which a
278
+ machine may be deployed. It defines aspects such as local disk storage,
279
+ available RAM, and architecture. Each provider is free to define as many
280
+ (or as few) hardware profiles as desired.
281
+ END
282
+
283
+ operation :index do
284
+ description "List of available hardware profiles"
285
+ param :id, :string
286
+ param :architecture, :string, :optional, [ 'i386', 'x86_64' ]
287
+ control do
288
+ @profiles = driver.hardware_profiles(credentials, params)
289
+ respond_to do |format|
290
+ format.xml { haml :'hardware_profiles/index' }
291
+ format.html { haml :'hardware_profiles/index' }
292
+ format.json { convert_to_json(:hardware_profile, @profiles) }
293
+ end
294
+ end
295
+ end
296
+
297
+ operation :show do
298
+ description "Show specific hardware profile"
299
+ param :id, :string, :required
300
+ control do
301
+ @profile = driver.hardware_profile(credentials, params[:id])
302
+ respond_to do |format|
303
+ format.xml { haml :'hardware_profiles/show', :layout => false }
304
+ format.html { haml :'hardware_profiles/show' }
305
+ format.json { convert_to_json(:hardware_profile, @profile) }
306
+ end
307
+ end
308
+ end
309
+
310
+ end
311
+
312
+ collection :storage_snapshots do
313
+ description "Storage snapshots description here"
314
+
315
+ operation :index do
316
+ description "Listing of storage snapshots"
317
+ param :id, :string
318
+ control { filter_all(:storage_snapshots) }
319
+ end
320
+
321
+ operation :show do
322
+ description "Show storage snapshot"
323
+ param :id, :string, :required
324
+ control { show(:storage_snapshot) }
325
+ end
326
+ end
327
+
328
+ collection :storage_volumes do
329
+ description "Storage volumes description here"
330
+
331
+ operation :index do
332
+ description "Listing of storage volumes"
333
+ param :id, :string
334
+ control { filter_all(:storage_volumes) }
335
+ end
336
+
337
+ operation :show do
338
+ description "Show storage volume"
339
+ param :id, :string, :required
340
+ control { show(:storage_volume) }
341
+ end
342
+ end
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'optparse'
5
+ require 'thin'
6
+
7
+ options = {
8
+ :env => 'production'
9
+ }
10
+ optparse = OptionParser.new do |opts|
11
+
12
+ opts.banner = <<BANNER
13
+ Usage:
14
+ deltacloudd -i <driver> [options]
15
+
16
+ Options:
17
+ BANNER
18
+ opts.on( '-i', '--driver DRIVER', 'Driver to use') do |driver|
19
+ ENV["API_DRIVER"] = driver
20
+ end
21
+ opts.on( '-r', '--hostname HOSTNAME',
22
+ 'Bind to HOST address (default: localhost)') do |host|
23
+ ENV["API_HOST"] = host
24
+ end
25
+ opts.on( '-p', '--port PORT', 'Use PORT (default: 3001)') do |port|
26
+ ENV["API_PORT"] = port
27
+ end
28
+ opts.on( '-e', '--env ENV', 'Environment (default: "development")') { |env| options[:env] = env }
29
+ opts.on( '-h', '--help', '') { options[:help] = true }
30
+ end
31
+
32
+ optparse.parse!
33
+
34
+ if options[:help]
35
+ puts optparse
36
+ exit(0)
37
+ end
38
+
39
+ unless ENV["API_DRIVER"]
40
+ puts "You need to specify a driver to use (-i <driver>)"
41
+ exit(1)
42
+ end
43
+
44
+ ENV["API_HOST"] = "localhost" unless ENV["API_HOST"]
45
+ ENV["API_PORT"] = "3001" unless ENV["API_PORT"]
46
+
47
+ dirname="#{File.dirname(__FILE__)}/.."
48
+
49
+ argv_opts = ARGV.clone
50
+ argv_opts << ['start'] unless Thin::Runner.commands.include?(options[0])
51
+ argv_opts << ['--address', ENV["API_HOST"] ]
52
+ argv_opts << ['--port', ENV["API_PORT"] ]
53
+ argv_opts << ['--rackup', 'config.ru' ]
54
+ argv_opts << ['--chdir', dirname ]
55
+ argv_opts << ['-e', options[:env] ]
56
+ argv_opts << ['--threaded', '-D', '--stats', '/stats']
57
+
58
+ argv_opts.flatten!
59
+
60
+ puts "Starting Deltacloud API :: #{ENV["API_DRIVER"]} :: http://#{ENV["API_HOST"]}:#{ENV["API_PORT"]}/api"
61
+ puts
62
+
63
+ thin = Thin::Runner.new(argv_opts)
64
+ begin
65
+ thin.run!
66
+ rescue Exception => e
67
+ puts "ERROR: #{e.message}"
68
+ end
@@ -0,0 +1,91 @@
1
+ %global ruby_sitelib %(ruby -rrbconfig -e "puts Config::CONFIG['sitelibdir']")
2
+ %global gemdir %(ruby -rubygems -e 'puts Gem::dir' 2>/dev/null)
3
+ %global gemname deltacloud-core
4
+ %global geminstdir %{gemdir}/gems/%{gemname}-%{version}
5
+
6
+ Summary: Deltacloud REST API
7
+ Name: rubygem-%{gemname}
8
+ Version: 0.0.1
9
+ Release: 2%{?dist}
10
+ Group: Development/Languages
11
+ License: ASL 2.0 and MIT
12
+ URL: http://www.deltacloud.org
13
+ Source0: http://gems.rubyforge.org/gems/%{gemname}-%{version}.gem
14
+ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
15
+ Requires: rubygems
16
+ Requires: ruby(abi) = 1.8
17
+ Requires: rubygem(eventmachine) >= 0.12.10
18
+ Requires: rubygem(haml) >= 2.2.17
19
+ Requires: rubygem(sinatra) >= 0.9.4
20
+ Requires: rubygem(rack) >= 1.0.0
21
+ Requires: rubygem(thin) >= 1.2.5
22
+ Requires: rubygem(builder) >= 2.1.2
23
+ Requires: rubygem(json) >= 1.2.3
24
+ BuildRequires: ruby-json >= 1.1.9
25
+ BuildRequires: rubygem(rake) >= 0.8.7
26
+ BuildRequires: rubygem(rack-test) >= 0.4.0
27
+ BuildRequires: rubygem(cucumber) >= 0.4.0
28
+ BuildRequires: rubygem(rcov) >= 0.9.6
29
+ BuildRequires: rubygems
30
+ BuildRequires: ruby(abi) = 1.8
31
+ BuildArch: noarch
32
+ Provides: rubygem(%{gemname}) = %{version}
33
+
34
+ %description
35
+ The Deltacloud API is built as a service-based REST API.
36
+ You do not directly link a Deltacloud library into your program to use it.
37
+ Instead, a client speaks the Deltacloud API over HTTP to a server
38
+ which implements the REST interface.
39
+
40
+ %prep
41
+
42
+ %build
43
+
44
+ %install
45
+ rm -rf %{buildroot}
46
+ mkdir -p %{buildroot}%{gemdir}
47
+ gem install --local --install-dir %{buildroot}%{gemdir} \
48
+ --force --rdoc %{SOURCE0}
49
+ mkdir -p %{buildroot}/%{_bindir}
50
+ mv %{buildroot}%{geminstdir}/support/fedora/deltacloudd %{buildroot}/%{geminstdir}/bin
51
+ mv %{buildroot}%{gemdir}/bin/* %{buildroot}/%{_bindir}
52
+ rmdir %{buildroot}%{gemdir}/bin
53
+ find %{buildroot}%{geminstdir}/bin -type f | xargs chmod a+x
54
+
55
+ # Needs json_pure gem / not available in Fedora yet
56
+ #%check
57
+ #pushd %{buildroot}%{geminstdir}
58
+ #cucumber features/*.feature
59
+ #popd
60
+
61
+ %clean
62
+ rm -rf %{buildroot}
63
+
64
+ %files
65
+ %defattr(-, root, root, -)
66
+ %{_bindir}/deltacloudd
67
+ %{gemdir}/gems/%{gemname}-%{version}/bin
68
+ %{gemdir}/gems/%{gemname}-%{version}/lib
69
+ %{gemdir}/gems/%{gemname}-%{version}/public/favicon.ico
70
+ %{gemdir}/gems/%{gemname}-%{version}/public/images
71
+ %{gemdir}/gems/%{gemname}-%{version}/public/stylesheets
72
+ %{gemdir}/gems/%{gemname}-%{version}/tests
73
+ %{gemdir}/gems/%{gemname}-%{version}/views
74
+ %{gemdir}/gems/%{gemname}-%{version}/Rakefile
75
+ %{gemdir}/gems/%{gemname}-%{version}/*.rb
76
+ %{gemdir}/gems/%{gemname}-%{version}/config.ru
77
+ %doc %{gemdir}/gems/%{gemname}-%{version}/support/fedora
78
+ %doc %{gemdir}/gems/%{gemname}-%{version}/COPYING
79
+ %doc %{gemdir}/doc/%{gemname}-%{version}
80
+ %{gemdir}/cache/%{gemname}-%{version}.gem
81
+ %{gemdir}/specifications/%{gemname}-%{version}.gemspec
82
+ # MIT
83
+ %{gemdir}/gems/%{gemname}-%{version}/public/javascripts
84
+
85
+ %changelog
86
+ * Mon Apr 26 2010 Michal Fojtik <mfojtik@packager> - 0.0.1-1
87
+ - Initial package
88
+
89
+ * Mon Apr 26 2010 Michal Fojtik <mfojtik@packager> - 0.0.1-2
90
+ - Fixed broken dependencies
91
+ - Added new launcher for Fedora