deltacloud-client 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/Rakefile CHANGED
@@ -15,9 +15,14 @@
15
15
  # License along with this library; if not, write to the Free Software
16
16
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
18
-
18
+ require 'rake/gempackagetask'
19
19
  require 'spec/rake/spectask'
20
20
 
21
+ load 'deltacloud-client.gemspec'
22
+
23
+ Rake::GemPackageTask.new(@spec) do |pkg|
24
+ pkg.need_tar = true
25
+ end
21
26
 
22
27
  desc "Run all examples"
23
28
  Spec::Rake::SpecTask.new('spec') do |t|
data/bin/deltacloudc CHANGED
@@ -1,4 +1,4 @@
1
- #!/bin/env ruby
1
+ #!/usr/bin/env ruby
2
2
  #
3
3
  # Copyright (C) 2009 Red Hat, Inc.
4
4
  #
@@ -39,7 +39,7 @@ BANNER
39
39
  opts.on( '-i', '--id ID', 'ID for operation') { |id| options[:id] = id }
40
40
  opts.on( '-d', '--image-id ID', 'Image ID') { |id| options[:image_id] = id }
41
41
  opts.on( '-a', '--arch ARCH', 'Architecture (x86, x86_64)') { |id| options[:architecture] = id }
42
- opts.on( '-f', '--flavor_id FLAVOR', 'Flavor') { |id| options[:flavor_id] = id }
42
+ opts.on( '-p', '--hardware-profile HARDWARE_PROFILE', 'Hardware Profile') { |id| options[:hwp_id] = id }
43
43
  opts.on( '-n', '--name NAME', 'Name (for instance eg.)') { |name| options[:name] = name }
44
44
  opts.on( '-s', '--state STATE', 'Instance state (RUNNING, STOPPED)') { |state| options[:state] = state }
45
45
  opts.on( '-u', '--url URL', 'API url ($API_URL variable)') { |url| options[:api_url] = url }
@@ -66,11 +66,10 @@ options[:collection] = ARGV[0]
66
66
  options[:operation] = ARGV[1]
67
67
 
68
68
  # Connect to Deltacloud API and fetch all entry points
69
- client = DeltaCloud.new(url.user, url.password, api_url, { :verbose => options[:verbose] })
69
+ client = DeltaCloud.new(url.user || ENV['API_USER'], url.password || ENV['API_PASSWORD'], api_url, { :verbose => options[:verbose] })
70
70
  collections = client.entry_points.keys
71
71
 
72
72
  # Exclude collection which don't have methods in client library yet
73
- collections.delete(:hardware_profiles)
74
73
  collections.delete(:instance_states)
75
74
 
76
75
  # If list parameter passed print out available collection
@@ -98,7 +97,7 @@ if options[:version]
98
97
  exit(0)
99
98
  end
100
99
 
101
- # List items from collection (typically /flavors)
100
+ # List items from collection (typically /instances)
102
101
  # Do same if 'index' operation is set
103
102
  if options[:collection] and ( options[:operation].nil? or options[:operation].eql?('index') )
104
103
  invalid_usage("Unknown collection: #{options[:collection]}") unless collections.include?(options[:collection].to_sym)
@@ -127,12 +126,16 @@ if options[:collection] and options[:operation]
127
126
  end
128
127
 
129
128
  # If collection is set and requested operation is create new instance,
130
- # --image-id, --flavor-id and --name parameters are used
129
+ # --image-id, --hardware-profile and --name parameters are used
131
130
  # Returns created instance in plain form
132
131
  if options[:collection].eql?('instances') and options[:operation].eql?('create')
132
+ invalid_usage("Missing image-id") unless options[:image_id]
133
+ if options[:name] and ! client.feature?(:instances, :user_name)
134
+ invalid_usage("Driver does not support user-supplied name")
135
+ end
133
136
  params.merge!(:name => options[:name]) if options[:name]
134
137
  params.merge!(:image_id => options[:image_id]) if options[:image_id]
135
- params.merge!(:flavor_id => options[:flavor_id]) if options[:flavor_id]
138
+ params.merge!(:hwp_id => options[:hwp_id]) if options[:hwp_id]
136
139
  instance = client.create_instance(options[:image_id], params)
137
140
  puts instance.to_plain
138
141
  exit(0)
@@ -0,0 +1,124 @@
1
+ #
2
+ # Copyright (C) 2009 Red Hat, Inc.
3
+ #
4
+ # This library is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU Lesser General Public
6
+ # License as published by the Free Software Foundation; either
7
+ # version 2.1 of the License, or (at your option) any later version.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+
19
+ require 'dcloud/base_model'
20
+
21
+ module DCloud
22
+ class HardwareProfile < BaseModel
23
+
24
+ class Property
25
+ class Range
26
+ attr_reader :first, :last
27
+ def initialize(element)
28
+ if element
29
+ @first = element.attributes['first']
30
+ @last = element.attributes['last']
31
+ end
32
+ end
33
+ def present?
34
+ ! @first.nil?
35
+ end
36
+ end
37
+ class Enum
38
+ attr_reader :entries
39
+ def initialize(element)
40
+ @entries = []
41
+ if element
42
+ element.get_elements( 'entry' ).each do |entry|
43
+ @entries << entry.attributes['value']
44
+ end
45
+ end
46
+ end
47
+ def present?
48
+ ! @entries.empty?
49
+ end
50
+ end
51
+ attr_reader :name, :kind, :unit, :value, :range, :enum
52
+
53
+ def initialize(xml, name)
54
+ @name = name
55
+ p = REXML::XPath.first(xml, "property[@name = '#{name}']")
56
+ if p
57
+ @value = p.attributes['value']
58
+ @unit = p.attributes['unit']
59
+ @kind = p.attributes['kind']
60
+ @range = Range.new(p.get_elements('range')[0]) if @kind=='range'
61
+ @enum = Enum.new(p.get_elements('enum')[0]) if @kind=='enum'
62
+ end
63
+ end
64
+
65
+ def present?
66
+ ! @value.nil?
67
+ end
68
+
69
+ # FIXME: how to range/enum/kind bits fit into this?
70
+ def to_s
71
+ v = @value || "---"
72
+ u = @unit || ""
73
+ u = "" if ["label", "count"].include?(u)
74
+ "#{v} #{u}"
75
+ end
76
+ end
77
+
78
+ class FloatProperty < Property
79
+ def initialize(xml, name)
80
+ super(xml, name)
81
+ @value = @value.to_f if @value
82
+ end
83
+ end
84
+
85
+ class IntegerProperty < Property
86
+ def initialize(xml, name)
87
+ super(xml, name)
88
+ @value = @value.to_i if @value
89
+ end
90
+ end
91
+
92
+ xml_tag_name :hardware_profile
93
+
94
+ attribute :memory
95
+ attribute :storage
96
+ attribute :cpu
97
+ attribute :architecture
98
+
99
+ def initialize(client, uri, xml=nil)
100
+ super( client, uri, xml )
101
+ end
102
+
103
+ def load_payload(xml=nil)
104
+ super(xml)
105
+ unless xml.nil?
106
+ @memory = FloatProperty.new(xml, 'memory')
107
+ @storage = FloatProperty.new(xml, 'storage')
108
+ @cpu = IntegerProperty.new(xml, 'cpu')
109
+ @architecture = Property.new(xml, 'architecture')
110
+ end
111
+ end
112
+
113
+ def to_plain
114
+ sprintf("%-15s | %-6s | %10s | %10s ", id[0, 15],
115
+ architecture.to_s[0,6], memory.to_s[0,10], storage.to_s[0,10])
116
+ end
117
+
118
+ private
119
+ def property_value(xml, name)
120
+ p = REXML::XPath.first(xml, "property[@name = '#{name}']")
121
+ p ? p.attributes['value'] : ""
122
+ end
123
+ end
124
+ end
@@ -19,6 +19,33 @@
19
19
  require 'dcloud/base_model'
20
20
 
21
21
  module DCloud
22
+
23
+ class InstanceProfile
24
+ attr_reader :hardware_profile, :id
25
+
26
+ def initialize(client, xml)
27
+ @hardware_profile = HardwareProfile.new(client, xml.attributes['href'])
28
+ @properties = {}
29
+ @id = xml.text("id")
30
+ xml.get_elements('property').each do |prop|
31
+ @properties[prop.attributes['name'].to_sym] = {
32
+ :value => prop.attributes['value'],
33
+ :unit => prop.attributes['unit'],
34
+ :kind => prop.attributes['kind'].to_sym
35
+ }
36
+ end
37
+ end
38
+
39
+ def [](prop)
40
+ p = @properties[prop]
41
+ p ? p[:value] : nil
42
+ end
43
+
44
+ def property(prop)
45
+ @properties[prop]
46
+ end
47
+ end
48
+
22
49
  class Instance < BaseModel
23
50
 
24
51
  xml_tag_name :instance
@@ -30,9 +57,9 @@ module DCloud
30
57
  attribute :state
31
58
  attribute :actions
32
59
  attribute :image
33
- attribute :flavor
34
60
  attribute :realm
35
61
  attribute :action_urls
62
+ attribute :instance_profile
36
63
 
37
64
  def initialize(client, uri, xml=nil)
38
65
  @action_urls = {}
@@ -71,6 +98,13 @@ module DCloud
71
98
  unload
72
99
  end
73
100
 
101
+ def destroy!()
102
+ url = action_urls['destroy']
103
+ throw Exception.new( "Unable to destroy" ) unless url
104
+ client.post_instance( url )
105
+ unload
106
+ end
107
+
74
108
  def load_payload(xml=nil)
75
109
  super(xml)
76
110
  unless xml.nil?
@@ -86,13 +120,13 @@ module DCloud
86
120
  end
87
121
  image_uri = xml.get_elements( 'image' )[0].attributes['href']
88
122
  @image = Image.new( @client, image_uri )
89
- flavor_uri = xml.get_elements( 'flavor' )[0].attributes['href']
90
- @flavor = Flavor.new( @client, flavor_uri )
91
123
  # Only use realms if they are there
92
124
  if (!xml.get_elements( 'realm' ).empty?)
93
125
  realm_uri = xml.get_elements( 'realm' )[0].attributes['href']
94
126
  @realm = Realm.new( @client, realm_uri )
95
127
  end
128
+ instance_profile = xml.get_elements( 'hardware-profile' ).first
129
+ @instance_profile = InstanceProfile.new( @client, instance_profile )
96
130
  @state = xml.text( 'state' )
97
131
  @actions = []
98
132
  xml.get_elements( 'actions/link' ).each do |link|
data/lib/deltacloud.rb CHANGED
@@ -18,7 +18,7 @@
18
18
  require 'rest_client'
19
19
  require 'rexml/document'
20
20
  require 'logger'
21
- require 'dcloud/flavor'
21
+ require 'dcloud/hardware_profile'
22
22
  require 'dcloud/realm'
23
23
  require 'dcloud/image'
24
24
  require 'dcloud/instance'
@@ -35,6 +35,7 @@ class DeltaCloud
35
35
  attr_reader :entry_points
36
36
  attr_reader :driver_name
37
37
  attr_reader :last_request_xml
38
+ attr_reader :features
38
39
 
39
40
  def self.driver_name(url)
40
41
  DeltaCloud.new( nil, nil, url) do |client|
@@ -49,6 +50,7 @@ class DeltaCloud
49
50
  @api_uri = URI.parse( api_uri )
50
51
  @entry_points = {}
51
52
  @verbose = opts[:verbose]
53
+ @features = {}
52
54
  discover_entry_points
53
55
  connect( &block )
54
56
  self
@@ -74,31 +76,35 @@ class DeltaCloud
74
76
  @api_uri.path
75
77
  end
76
78
 
77
- def flavors(opts={})
78
- flavors = []
79
- request(entry_points[:flavors], :get, opts) do |response|
79
+ def feature?(collection, name)
80
+ @features.has_key?(collection) && @features[collection].include?(name)
81
+ end
82
+
83
+ def hardware_profiles(opts={})
84
+ hardware_profiles = []
85
+ request(entry_points[:hardware_profiles], :get, opts) do |response|
80
86
  doc = REXML::Document.new( response )
81
- doc.get_elements( 'flavors/flavor' ).each do |flavor|
82
- uri = flavor.attributes['href']
83
- flavors << DCloud::Flavor.new( self, uri, flavor )
87
+ doc.get_elements( 'hardware-profiles/hardware-profile' ).each do |hwp|
88
+ uri = hwp.attributes['href']
89
+ hardware_profiles << DCloud::HardwareProfile.new( self, uri, hwp )
84
90
  end
85
91
  end
86
- flavors
92
+ hardware_profiles
87
93
  end
88
94
 
89
- def flavor(id)
90
- request( entry_points[:flavors], :get, {:id=>id } ) do |response|
95
+ def hardware_profile(id)
96
+ request( entry_points[:hardware_profiles], :get, {:id=>id } ) do |response|
91
97
  doc = REXML::Document.new( response )
92
- doc.get_elements( '/flavor' ).each do |flavor|
93
- uri = flavor.attributes['href']
94
- return DCloud::Flavor.new( self, uri, flavor )
98
+ doc.get_elements( '/hardware-profile' ).each do |hwp|
99
+ uri = hwp.attributes['href']
100
+ return DCloud::HardwareProfile.new( self, uri, hwp )
95
101
  end
96
102
  end
97
103
  end
98
104
 
99
- def fetch_flavor(uri)
100
- xml = fetch_resource( :flavor, uri )
101
- return DCloud::Flavor.new( self, uri, xml ) if xml
105
+ def fetch_hardware_profile(uri)
106
+ xml = fetch_resource( :hardware_profile, uri )
107
+ return DCloud::HardwareProfile.new( self, uri, xml ) if xml
102
108
  nil
103
109
  end
104
110
 
@@ -256,16 +262,32 @@ class DeltaCloud
256
262
  nil
257
263
  end
258
264
 
265
+ # Create a new instance, using image +image_id+. Possible optiosn are
266
+ #
267
+ # name - a user-defined name for the instance
268
+ # realm - a specific realm for placement of the instance
269
+ # hardware_profile - either a string giving the name of the
270
+ # hardware profile or a hash. The hash must have an
271
+ # entry +id+, giving the id of the hardware profile,
272
+ # and may contain additional names of properties,
273
+ # e.g. 'storage', to override entries in the
274
+ # hardware profile
259
275
  def create_instance(image_id, opts={})
260
276
  name = opts[:name]
261
277
  realm_id = opts[:realm]
262
- flavor_id = opts[:flavor]
263
278
 
264
279
  params = {}
265
280
  ( params[:realm_id] = realm_id ) if realm_id
266
- ( params[:flavor_id] = flavor_id ) if flavor_id
267
281
  ( params[:name] = name ) if name
268
282
 
283
+ if opts[:hardware_profile].is_a?(String)
284
+ params[:hwp_id] = opts[:hardware_profile]
285
+ elsif opts[:hardware_profile].is_a?(Hash)
286
+ opts[:hardware_profile].each do |k,v|
287
+ params[:"hwp_#{k}"] = v
288
+ end
289
+ end
290
+
269
291
  params[:image_id] = image_id
270
292
  request( entry_points[:instances], :post, {}, params ) do |response|
271
293
  doc = REXML::Document.new( response )
@@ -344,15 +366,21 @@ class DeltaCloud
344
366
  attr_reader :http
345
367
 
346
368
  def discover_entry_points
369
+ return if @discovered
347
370
  request(api_uri.to_s) do |response|
348
371
  doc = REXML::Document.new( response )
349
372
  @driver_name = doc.root.attributes['driver']
350
373
  doc.get_elements( 'api/link' ).each do |link|
351
- rel = link.attributes['rel']
374
+ rel = link.attributes['rel'].to_sym
352
375
  uri = link.attributes['href']
353
- @entry_points[rel.to_sym] = uri
376
+ @entry_points[rel] = uri
377
+ @features[rel] ||= []
378
+ link.get_elements('feature').each do |feature|
379
+ @features[rel] << feature.attributes['name'].to_sym
380
+ end
354
381
  end
355
382
  end
383
+ @discovered = true
356
384
  end
357
385
 
358
386
  def request(path='', method=:get, query_args={}, form_data={}, &block)
@@ -1,3 +1,4 @@
1
1
  :description: Fedora 10
2
2
  :owner_id: fedoraproject
3
3
  :architecture: x86_64
4
+ :id: img1
@@ -1,3 +1,4 @@
1
1
  :description: Fedora 10
2
2
  :owner_id: fedoraproject
3
3
  :architecture: i386
4
+ :id: img2
@@ -1,3 +1,4 @@
1
1
  :description: JBoss
2
2
  :owner_id: mockuser
3
3
  :architecture: i386
4
+ :id: img3
@@ -0,0 +1,16 @@
1
+ ---
2
+ :realm_id: us
3
+ :public_addresses:
4
+ - img1.inst0.public.com
5
+ :state: RUNNING
6
+ :name: "Mock Instance With Profile Change"
7
+ :private_addresses:
8
+ - img1.inst0.private.com
9
+ :image_id: img1
10
+ :instance_profile: !ruby/object:InstanceProfile
11
+ id: m1-large
12
+ memory: "12288"
13
+ :owner_id: mockuser
14
+ :actions:
15
+ - :reboot
16
+ - :stop
@@ -4,5 +4,6 @@
4
4
  :owner_id: mockuser
5
5
  :public_addresses: [ img3.inst1.public.com ]
6
6
  :private_addresses: [ img3.inst1.private.com ]
7
- :flavor_id: m1-small
8
7
  :realm_id: us
8
+ :instance_profile: !ruby/object:InstanceProfile
9
+ id: m1-small
@@ -4,5 +4,6 @@
4
4
  :owner_id: anotheruser
5
5
  :public_addresses: [ img1.inst2.public.com ]
6
6
  :private_addresses: [ img1.inst2.private.com ]
7
- :flavor_id: m1-small
8
7
  :realm_id: us
8
+ :instance_profile: !ruby/object:InstanceProfile
9
+ id: m1-large
@@ -1,3 +1,4 @@
1
1
  :description: Fedora 10
2
2
  :owner_id: fedoraproject
3
3
  :architecture: x86_64
4
+ :id: img1
@@ -1,3 +1,4 @@
1
1
  :description: Fedora 10
2
2
  :owner_id: fedoraproject
3
3
  :architecture: i386
4
+ :id: img2
@@ -1,3 +1,4 @@
1
1
  :description: JBoss
2
2
  :owner_id: mockuser
3
3
  :architecture: i386
4
+ :id: img3
@@ -0,0 +1,16 @@
1
+ ---
2
+ :realm_id: us
3
+ :public_addresses:
4
+ - img1.inst0.public.com
5
+ :state: RUNNING
6
+ :name: "Mock Instance With Profile Change"
7
+ :private_addresses:
8
+ - img1.inst0.private.com
9
+ :image_id: img1
10
+ :instance_profile: !ruby/object:InstanceProfile
11
+ id: m1-large
12
+ memory: "12288"
13
+ :owner_id: mockuser
14
+ :actions:
15
+ - :reboot
16
+ - :stop
@@ -4,5 +4,6 @@
4
4
  :owner_id: mockuser
5
5
  :public_addresses: [ img3.inst1.public.com ]
6
6
  :private_addresses: [ img3.inst1.private.com ]
7
- :flavor_id: m1-small
8
7
  :realm_id: us
8
+ :instance_profile: !ruby/object:InstanceProfile
9
+ id: m1-small
@@ -4,5 +4,6 @@
4
4
  :owner_id: anotheruser
5
5
  :public_addresses: [ img1.inst2.public.com ]
6
6
  :private_addresses: [ img1.inst2.private.com ]
7
- :flavor_id: m1-small
8
7
  :realm_id: us
8
+ :instance_profile: !ruby/object:InstanceProfile
9
+ id: m1-large
@@ -0,0 +1,71 @@
1
+ #
2
+ # Copyright (C) 2009 Red Hat, Inc.
3
+ #
4
+ # This library is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU Lesser General Public
6
+ # License as published by the Free Software Foundation; either
7
+ # version 2.1 of the License, or (at your option) any later version.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+
19
+ require 'specs/spec_helper'
20
+
21
+ def prop_check(prop, value_class)
22
+ if prop.present?
23
+ prop.value.should_not be_nil
24
+ prop.value.should be_a(value_class)
25
+ end
26
+ end
27
+
28
+ describe "hardware_profiles" do
29
+
30
+ it_should_behave_like "all resources"
31
+
32
+ it "should allow retrieval of all hardware profiles" do
33
+ DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
34
+ hardware_profiles = client.hardware_profiles
35
+ hardware_profiles.should_not be_empty
36
+ hardware_profiles.each do |hwp|
37
+ hwp.uri.should_not be_nil
38
+ hwp.uri.should be_a(String)
39
+ prop_check(hwp.architecture, String)
40
+ prop_check(hwp.storage, Float)
41
+ prop_check(hwp.memory, Float)
42
+ end
43
+ end
44
+ end
45
+
46
+ it "should allow filtering of hardware_profiles by architecture" do
47
+ DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
48
+ hardware_profiles = client.hardware_profiles( :architecture=>'i386' )
49
+ hardware_profiles.should_not be_empty
50
+ hardware_profiles.size.should eql( 2 )
51
+ hardware_profiles.first.architecture.value.should eql( 'i386' )
52
+ end
53
+ end
54
+
55
+ it "should allow fetching a hardware_profile by id" do
56
+ DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
57
+ hwp = client.hardware_profile( 'm1-small' )
58
+ hwp.should_not be_nil
59
+ hwp.id.should eql( 'm1-small' )
60
+ end
61
+ end
62
+
63
+ it "should allow fetching a hardware_profile by URI" do
64
+ DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
65
+ hwp = client.fetch_hardware_profile( API_URL + '/hardware_profiles/m1-small' )
66
+ hwp.should_not be_nil
67
+ hwp.id.should eql( 'm1-small' )
68
+ end
69
+ end
70
+
71
+ end
@@ -28,7 +28,7 @@ describe "initializing the client" do
28
28
 
29
29
  it "should discover entry points upon connection" do
30
30
  DeltaCloud.new( "name", "password", API_URL ) do |client|
31
- client.entry_points[:flavors].should eql( "#{API_URL}/flavors" )
31
+ client.entry_points[:hardware_profiles].should eql( "#{API_URL}/hardware_profiles" )
32
32
  client.entry_points[:images].should eql( "#{API_URL}/images" )
33
33
  client.entry_points[:instances].should eql( "#{API_URL}/instances" )
34
34
  client.entry_points[:storage_volumes].should eql( "#{API_URL}/storage_volumes" )
@@ -33,8 +33,8 @@ describe "instances" do
33
33
  instance.owner_id.should be_a( String )
34
34
  instance.image.should_not be_nil
35
35
  instance.image.should be_a( DCloud::Image )
36
- instance.flavor.should_not be_nil
37
- instance.flavor.should be_a( DCloud::Flavor )
36
+ instance.instance_profile.should_not be_nil
37
+ instance.instance_profile.should be_a( DCloud::InstanceProfile )
38
38
  instance.state.should_not be_nil
39
39
  instance.state.should be_a( String )
40
40
  instance.public_addresses.should_not be_nil
@@ -60,18 +60,21 @@ describe "instances" do
60
60
 
61
61
  it "should allow retrieval of a single instance" do
62
62
  DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
63
- instance = client.instance( "inst1" )
63
+ instance = client.instance( "inst0" )
64
64
  instance.should_not be_nil
65
65
  instance.name.should_not be_nil
66
- instance.name.should eql( 'MockUserInstance' )
66
+ instance.name.should eql( 'Mock Instance With Profile Change' )
67
67
  instance.uri.should_not be_nil
68
68
  instance.uri.should be_a( String )
69
69
  instance.owner_id.should eql( "mockuser" )
70
- instance.public_addresses.first.should eql( "img3.inst1.public.com" )
70
+ instance.public_addresses.first.should eql( "img1.inst0.public.com" )
71
71
  instance.image.should_not be_nil
72
- instance.image.uri.should eql( API_URL + "/images/img3" )
73
- instance.flavor.should_not be_nil
74
- instance.flavor.uri.should eql( API_URL + "/flavors/m1-small" )
72
+ instance.image.uri.should eql( API_URL + "/images/img1" )
73
+ instance.instance_profile.should_not be_nil
74
+ instance.instance_profile.hardware_profile.should_not be_nil
75
+ instance.instance_profile.hardware_profile.uri.should eql( API_URL + "/hardware_profiles/m1-large" )
76
+ instance.instance_profile[:memory].should eql( "12288" )
77
+ instance.instance_profile[:storage].should be_nil
75
78
  instance.state.should eql( "RUNNING" )
76
79
  instance.actions.should_not be_nil
77
80
  end
@@ -85,7 +88,7 @@ describe "instances" do
85
88
  instance.id.should match( /inst[0-9]+/ )
86
89
  instance.name.should eql( 'TestInstance' )
87
90
  instance.image.id.should eql( 'img1' )
88
- instance.flavor.id.should eql( 'm1-large' )
91
+ instance.instance_profile.id.should eql( 'm1-large' )
89
92
  instance.realm.id.should eql( 'us' )
90
93
  end
91
94
  end
@@ -97,31 +100,47 @@ describe "instances" do
97
100
  instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
98
101
  instance.id.should match( /inst[0-9]+/ )
99
102
  instance.image.id.should eql( 'img1' )
100
- instance.flavor.id.should eql( 'm1-large' )
103
+ instance.instance_profile.id.should eql( 'm1-large' )
101
104
  instance.realm.id.should eql( 'eu' )
102
105
  end
103
106
  end
104
107
 
105
- it "should allow creation of new instances with specific flavor" do
108
+ it "should allow creation of new instances with specific hardware profile" do
106
109
  DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
107
- instance = client.create_instance( 'img1', :flavor=>'m1-xlarge' )
110
+ instance = client.create_instance( 'img1',
111
+ :hardware_profile=>'m1-xlarge' )
108
112
  instance.should_not be_nil
109
113
  instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
110
114
  instance.id.should match( /inst[0-9]+/ )
111
115
  instance.image.id.should eql( 'img1' )
112
- instance.flavor.id.should eql( 'm1-xlarge' )
116
+ instance.instance_profile.id.should eql( 'm1-xlarge' )
113
117
  instance.realm.id.should eql( 'us' )
114
118
  end
115
119
  end
116
120
 
117
- it "should allow creation of new instances with specific realm and flavor" do
121
+ it "should allow creation of new instances with specific hardware profile overriding memory" do
118
122
  DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
119
- instance = client.create_instance( 'img1', :realm=>'eu', :flavor=>'m1-xlarge' )
123
+ hwp = { :id => 'm1-xlarge', :memory => 32768 }
124
+ instance = client.create_instance( 'img1', :hardware_profile=> hwp )
120
125
  instance.should_not be_nil
121
126
  instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
122
127
  instance.id.should match( /inst[0-9]+/ )
123
128
  instance.image.id.should eql( 'img1' )
124
- instance.flavor.id.should eql( 'm1-xlarge' )
129
+ instance.instance_profile.id.should eql( 'm1-xlarge' )
130
+ instance.instance_profile[:memory].should eql( "32768" )
131
+ instance.realm.id.should eql( 'us' )
132
+ end
133
+ end
134
+
135
+ it "should allow creation of new instances with specific realm and hardware profile" do
136
+ DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
137
+ instance = client.create_instance( 'img1', :realm=>'eu',
138
+ :hardware_profile=>'m1-xlarge' )
139
+ instance.should_not be_nil
140
+ instance.uri.should match( %r{#{API_URL}/instances/inst[0-9]+} )
141
+ instance.id.should match( /inst[0-9]+/ )
142
+ instance.image.id.should eql( 'img1' )
143
+ instance.instance_profile.id.should eql( 'm1-xlarge' )
125
144
  instance.realm.id.should eql( 'eu' )
126
145
  end
127
146
  end
data/specs/spec_helper.rb CHANGED
@@ -24,8 +24,8 @@ api_host = ENV['API_HOST']
24
24
  ( api_host = 'localhost' ) if api_host == ''
25
25
 
26
26
  api_port = ENV['API_PORT']
27
- ( api_port = 3000 ) if api_port.nil?
28
- ( api_port = 3000 ) if api_port == ''
27
+ ( api_port = 3001 ) if api_port.nil?
28
+ ( api_port = 3001 ) if api_port == ''
29
29
 
30
30
  API_HOST = api_host
31
31
  API_PORT = api_port
@@ -46,7 +46,8 @@ describe "storage volumes" do
46
46
  storage_volume.device.should eql( '/dev/sda1' )
47
47
  storage_volume.instance.should_not be_nil
48
48
  storage_volume.instance.id.should eql( 'inst1' )
49
- storage_volume.instance.flavor.architecture.should eql( 'i386' )
49
+ ip = storage_volume.instance.instance_profile
50
+ ip.hardware_profile.architecture.value.should eql( 'i386' )
50
51
  end
51
52
  end
52
53
 
@@ -62,7 +63,8 @@ describe "storage volumes" do
62
63
  storage_volume.device.should eql( '/dev/sda1' )
63
64
  storage_volume.instance.should_not be_nil
64
65
  storage_volume.instance.id.should eql( 'inst1' )
65
- storage_volume.instance.flavor.architecture.should eql( 'i386' )
66
+ ip = storage_volume.instance.instance_profile
67
+ ip.hardware_profile.architecture.value.should eql( 'i386' )
66
68
  end
67
69
  end
68
70
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deltacloud-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Red Hat, Inc.
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-04 00:00:00 -05:00
12
+ date: 2010-06-17 00:00:00 +02:00
13
13
  default_executable: deltacloudc
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,6 +22,16 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 1.3.1
24
24
  version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.3.0
34
+ version:
25
35
  description: Deltacloud REST Client for API
26
36
  email: deltacloud-users@lists.fedorahosted.org
27
37
  executables:
@@ -33,16 +43,16 @@ extra_rdoc_files:
33
43
  files:
34
44
  - Rakefile
35
45
  - credentials.yml
36
- - lib/dcloud/image.rb
37
- - lib/dcloud/storage_snapshot.rb
38
- - lib/dcloud/realm.rb
46
+ - lib/deltacloud.rb
39
47
  - lib/dcloud/base_model.rb
40
- - lib/dcloud/storage_volume.rb
48
+ - lib/dcloud/hardware_profile.rb
49
+ - lib/dcloud/image.rb
41
50
  - lib/dcloud/instance.rb
51
+ - lib/dcloud/realm.rb
42
52
  - lib/dcloud/state.rb
43
- - lib/dcloud/flavor.rb
53
+ - lib/dcloud/storage_snapshot.rb
54
+ - lib/dcloud/storage_volume.rb
44
55
  - lib/dcloud/transition.rb
45
- - lib/deltacloud.rb
46
56
  - init.rb
47
57
  - bin/deltacloudc
48
58
  - COPYING
@@ -75,35 +85,37 @@ signing_key:
75
85
  specification_version: 3
76
86
  summary: Deltacloud REST Client
77
87
  test_files:
78
- - specs/storage_volume_spec.rb
79
- - specs/realms_spec.rb
80
- - specs/initialization_spec.rb
81
- - specs/spec_helper.rb
82
- - specs/images_spec.rb
83
- - specs/instances_spec.rb
84
- - specs/fixtures/images/img3.yml
85
88
  - specs/fixtures/images/img1.yml
86
89
  - specs/fixtures/images/img2.yml
90
+ - specs/fixtures/images/img3.yml
91
+ - specs/fixtures/instances/inst1.yml
92
+ - specs/fixtures/instances/inst2.yml
93
+ - specs/fixtures/instances/inst0.yml
87
94
  - specs/fixtures/storage_snapshots/snap1.yml
88
- - specs/fixtures/storage_snapshots/snap3.yml
89
95
  - specs/fixtures/storage_snapshots/snap2.yml
96
+ - specs/fixtures/storage_snapshots/snap3.yml
90
97
  - specs/fixtures/storage_volumes/vol1.yml
91
- - specs/fixtures/storage_volumes/vol3.yml
92
98
  - specs/fixtures/storage_volumes/vol2.yml
93
- - specs/fixtures/instances/inst1.yml
94
- - specs/fixtures/instances/inst2.yml
99
+ - specs/fixtures/storage_volumes/vol3.yml
100
+ - specs/spec_helper.rb
101
+ - specs/images_spec.rb
102
+ - specs/initialization_spec.rb
95
103
  - specs/instance_states_spec.rb
96
- - specs/flavors_spec.rb
97
- - specs/data/images/img3.yml
104
+ - specs/instances_spec.rb
105
+ - specs/realms_spec.rb
106
+ - specs/shared/resources.rb
107
+ - specs/storage_snapshot_spec.rb
108
+ - specs/storage_volume_spec.rb
109
+ - specs/hardware_profiles_spec.rb
98
110
  - specs/data/images/img1.yml
99
111
  - specs/data/images/img2.yml
112
+ - specs/data/images/img3.yml
113
+ - specs/data/instances/inst1.yml
114
+ - specs/data/instances/inst2.yml
115
+ - specs/data/instances/inst0.yml
100
116
  - specs/data/storage_snapshots/snap1.yml
101
- - specs/data/storage_snapshots/snap3.yml
102
117
  - specs/data/storage_snapshots/snap2.yml
118
+ - specs/data/storage_snapshots/snap3.yml
103
119
  - specs/data/storage_volumes/vol1.yml
104
- - specs/data/storage_volumes/vol3.yml
105
120
  - specs/data/storage_volumes/vol2.yml
106
- - specs/data/instances/inst1.yml
107
- - specs/data/instances/inst2.yml
108
- - specs/storage_snapshot_spec.rb
109
- - specs/shared/resources.rb
121
+ - specs/data/storage_volumes/vol3.yml
data/lib/dcloud/flavor.rb DELETED
@@ -1,49 +0,0 @@
1
- #
2
- # Copyright (C) 2009 Red Hat, Inc.
3
- #
4
- # This library is free software; you can redistribute it and/or
5
- # modify it under the terms of the GNU Lesser General Public
6
- # License as published by the Free Software Foundation; either
7
- # version 2.1 of the License, or (at your option) any later version.
8
- #
9
- # This library is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- # Lesser General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU Lesser General Public
15
- # License along with this library; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
-
18
-
19
- require 'dcloud/base_model'
20
-
21
- module DCloud
22
- class Flavor < BaseModel
23
-
24
- xml_tag_name :flavor
25
-
26
- attribute :memory
27
- attribute :storage
28
- attribute :architecture
29
-
30
- def initialize(client, uri, xml=nil)
31
- super( client, uri, xml )
32
- end
33
-
34
- def load_payload(xml=nil)
35
- super(xml)
36
- unless xml.nil?
37
- @memory = xml.text( 'memory' ).to_f
38
- @storage = xml.text( 'storage' ).to_f
39
- @architecture = xml.text( 'architecture' )
40
- end
41
- end
42
-
43
- def to_plain
44
- sprintf("%-15s | %-6s | %10s GB | %10s GB", self.id[0, 15], self.architecture[0,6],
45
- self.memory.to_s[0,10], self.storage.to_s[0,10])
46
- end
47
-
48
- end
49
- end
@@ -1,67 +0,0 @@
1
- #
2
- # Copyright (C) 2009 Red Hat, Inc.
3
- #
4
- # This library is free software; you can redistribute it and/or
5
- # modify it under the terms of the GNU Lesser General Public
6
- # License as published by the Free Software Foundation; either
7
- # version 2.1 of the License, or (at your option) any later version.
8
- #
9
- # This library is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
- # Lesser General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU Lesser General Public
15
- # License along with this library; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
-
18
-
19
- require 'specs/spec_helper'
20
-
21
- describe "flavors" do
22
-
23
- it_should_behave_like "all resources"
24
-
25
- it "should allow retrieval of all flavors" do
26
- DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
27
- flavors = client.flavors
28
- flavors.should_not be_empty
29
- flavors.each do |flavor|
30
- flavor.uri.should_not be_nil
31
- flavor.uri.should be_a(String)
32
- flavor.architecture.should_not be_nil
33
- flavor.architecture.should be_a(String)
34
- flavor.storage.should_not be_nil
35
- flavor.storage.should be_a(Float)
36
- flavor.memory.should_not be_nil
37
- flavor.memory.should be_a(Float)
38
- end
39
- end
40
- end
41
-
42
- it "should allow filtering of flavors by architecture" do
43
- DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
44
- flavors = client.flavors( :architecture=>'i386' )
45
- flavors.should_not be_empty
46
- flavors.size.should eql( 1 )
47
- flavors.first.architecture.should eql( 'i386' )
48
- end
49
- end
50
-
51
- it "should allow fetching a flavor by id" do
52
- DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
53
- flavor = client.flavor( 'm1-small' )
54
- flavor.should_not be_nil
55
- flavor.id.should eql( 'm1-small' )
56
- end
57
- end
58
-
59
- it "should allow fetching a flavor by URI" do
60
- DeltaCloud.new( API_NAME, API_PASSWORD, API_URL ) do |client|
61
- flavor = client.fetch_flavor( API_URL + '/flavors/m1-small' )
62
- flavor.should_not be_nil
63
- flavor.id.should eql( 'm1-small' )
64
- end
65
- end
66
-
67
- end