Hi David, When I run this patch on mock, system templates display fine, even with machineTemplates inline volumeTemplates and networkTemplates. However, when I run on fgcp, I get the following error:
E, [2013-03-16T00:36:11.714489 #13212] ERROR -- 500: [NoMethodError] undefined method `[]' for nil:NilClass d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:273:in `to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in `block in to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in `each' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in `to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:150:in `convert_to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:127:in `to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in `block in to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in `each' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in `to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:150:in `convert_to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in `block in to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in `map' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in `to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in `block in to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in `each' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in `to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:150:in `convert_to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in `block in to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in `map' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:242:in `to_xml' d:/sources/OSS/cloud/deltacloud/server/lib/cimi/models/schema.rb:381:in `block in to_xml' I've printed module and name in schema.rb:273: model: #<CIMI::Model::SystemTemplate:0x40d8de8> name: property model: {:name=>"Secure1", :description=>"Network tier 1", :type=>"http://schemas.dmtf.org/cimi/1/Network", :network_template=>#<CIMI::Model::NetworkTemplate:0x4 0da540 @select_attrs=[], @base_id=nil, @attribute_values={:id=>nil, :name=>"Private network", :description=>"", :created=>nil, :updated=>nil, :property=>nil, :n etwork_config=>#<CIMI::Model::NetworkConfigurationRef:0x40da138 @select_attrs=[], @base_id=nil, @attribute_values={:id=>nil, :name=>nil, :description=>nil, :cre ated=>nil, :updated=>nil, :property=>nil, :network_type=>"PRIVATE", :mtu=>nil, :class_of_service=>"BRONZE", :operations=>nil, :href=>nil}>, :forwarding_group=># <CIMI::Model::ForwardingGroupRef:0x40d9880 @select_attrs=[], @base_id=nil, @attribute_values={:id=>nil, :name=>nil, :description=>nil, :created=>nil, :updated=> nil, :property=>nil, :networks=>nil, :operations=>nil, :href=>nil}>, :operations=>nil}>} name: properties model: name: property Do you understand what's wrong? Regards, Dies Koper > -----Original Message----- > From: di...@fast.au.fujitsu.com [mailto:di...@fast.au.fujitsu.com] > Sent: Saturday, 16 March 2013 12:42 AM > To: dev@deltacloud.apache.org > Subject: [PATCH] added Template subcollections to SystemTemplate > > From: Dies Koper <di...@fast.au.fujitsu.com> > > --- > server/lib/cimi/models.rb | 4 +- > server/lib/cimi/models/machine_template.rb | 6 +- > server/lib/cimi/models/network_template.rb | 4 +- > server/lib/cimi/models/system.rb | 4 +- > server/lib/cimi/models/system_template.rb | 20 +++-- > server/lib/cimi/models/volume_template.rb | 4 +- > server/lib/deltacloud/drivers/fgcp/fgcp_client.rb | 4 + > .../drivers/fgcp/fgcp_driver_cimi_methods.rb | 94 > +++++++++++++++++----- > .../mock/data/cimi/system_template/template1.json | 31 ++++++- > .../drivers/mock/mock_driver_cimi_methods.rb | 32 ++++++++ > .../cimi/collections/system_templates_test.rb | 47 +++++++++++ > 11 files changed, 207 insertions(+), 43 deletions(-) > > diff --git a/server/lib/cimi/models.rb b/server/lib/cimi/models.rb > index 8eeb96c..e605b42 100644 > --- a/server/lib/cimi/models.rb > +++ b/server/lib/cimi/models.rb > @@ -79,7 +79,7 @@ require_relative './models/address_template_create' > require_relative './models/address_create' > require_relative './models/forwarding_group' > require_relative './models/forwarding_group_template' > -require_relative './models/system_template' > -require_relative './models/system' > require_relative './models/network_template' > require_relative './models/network_create' > +require_relative './models/system_template' > +require_relative './models/system' > diff --git a/server/lib/cimi/models/machine_template.rb > b/server/lib/cimi/models/machine_template.rb > index 68e865b..c167555 100644 > --- a/server/lib/cimi/models/machine_template.rb > +++ b/server/lib/cimi/models/machine_template.rb > @@ -28,10 +28,12 @@ class CIMI::Model::MachineTemplate < > CIMI::Model::Base > scalar :href, :initial_location > end > > - array :volume_templates do > - scalar :href, :initial_location > + class CIMI::Model::VolumeTemplateWithLocation < > CIMI::Model::VolumeTemplate > + text :initial_location > end > > + array :volume_templates, :ref => > CIMI::Model::VolumeTemplateWithLocation > + > array :network_interfaces do > href :vsp > text :hostname, :mac_address, :state, :protocol, :allocation > diff --git a/server/lib/cimi/models/network_template.rb > b/server/lib/cimi/models/network_template.rb > index 4f69f52..301d56a 100644 > --- a/server/lib/cimi/models/network_template.rb > +++ b/server/lib/cimi/models/network_template.rb > @@ -17,8 +17,8 @@ class CIMI::Model::NetworkTemplate < CIMI::Model::Base > > acts_as_root_entity > > - ref :network_config, :required => true > - ref :forwarding_group, :required => true > + ref :network_config, :class => CIMI::Model::NetworkConfiguration > + ref :forwarding_group > > array :operations do > scalar :rel, :href > diff --git a/server/lib/cimi/models/system.rb > b/server/lib/cimi/models/system.rb > index 118f9f5..e8a9ad8 100644 > --- a/server/lib/cimi/models/system.rb > +++ b/server/lib/cimi/models/system.rb > @@ -17,7 +17,9 @@ class CIMI::Model::System < CIMI::Model::Base > > acts_as_root_entity > > - text :state > + href :system_template, :required => false > + > + text :state, :required => true > > # FIXME: Any reason for these comments? > > diff --git a/server/lib/cimi/models/system_template.rb > b/server/lib/cimi/models/system_template.rb > index 82e418b..c60f759 100644 > --- a/server/lib/cimi/models/system_template.rb > +++ b/server/lib/cimi/models/system_template.rb > @@ -20,19 +20,17 @@ class CIMI::Model::SystemTemplate < > CIMI::Model::Base > array :component_descriptors do > text :name, :description > hash_map :properties > - text :type > - > - # FIXME: Any reasons for these comments? > + text :type, :required => true > > #component_template, comprises: > - # struct :machine_template, :class => > CIMI::Model::MachineTemplate > - # struct :system_template, :class => > CIMI::Model::SystemTemplate > - # struct :credential_template, :class => > CIMI::Model::CredentialTemplate > - # struct :volume_template, :class => > CIMI::Model::VolumeTemplate > - # struct :network_template, :class => > CIMI::Model::NetworkTemplate > - # struct :network_port_template, :class => > CIMI::Model::NetworkPortTemplate > - # struct :forwarding_group_template, :class => > CIMI::Model::ForwardingGroupTemplate > - # struct :address_template, :class => > CIMI::Model::AddressTemplate > + ref :machine_template, :class => CIMI::Model::MachineTemplate > + ref :system_template, :class => CIMI::Model::SystemTemplate > + ref :credential_template, :class => > CIMI::Model::CredentialTemplate > + ref :volume_template, :class => CIMI::Model::VolumeTemplate > + ref :network_template, :class => CIMI::Model::NetworkTemplate > + ref :network_port_template, :class => > CIMI::Model::NetworkPortTemplate > + ref :forwarding_group_template, :class => > CIMI::Model::ForwardingGroupTemplate > + ref :address_template, :class => CIMI::Model::AddressTemplate > text :quantity > end > > diff --git a/server/lib/cimi/models/volume_template.rb > b/server/lib/cimi/models/volume_template.rb > index bda4657..43e9c86 100644 > --- a/server/lib/cimi/models/volume_template.rb > +++ b/server/lib/cimi/models/volume_template.rb > @@ -17,8 +17,8 @@ class CIMI::Model::VolumeTemplate < CIMI::Model::Base > > acts_as_root_entity > > - ref :volume_config, :required => true > - ref :volume_image, :required => true > + ref :volume_config, :required => true, :class => > CIMI::Model::VolumeConfiguration > + ref :volume_image > > array :meter_templates do > end > diff --git a/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb > b/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb > index fed3b70..9597c13 100644 > --- a/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb > +++ b/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb > @@ -94,6 +94,10 @@ class FgcpClient > request('ListVSYSDescriptor') > end > > + def get_vsys_descriptor_configuration(vsys_descriptor_id) > + request('GetVSYSDescriptorConfiguration', {'vsysDescriptorId' => > vsys_descriptor_id}) > + end > + > def list_vservers(vsys_id) > request('ListVServer', {'vsysId' => vsys_id}) > end > diff --git > a/server/lib/deltacloud/drivers/fgcp/fgcp_driver_cimi_methods.rb > b/server/lib/deltacloud/drivers/fgcp/fgcp_driver_cimi_methods.rb > index b4d31f6..60f5e84 100644 > --- a/server/lib/deltacloud/drivers/fgcp/fgcp_driver_cimi_methods.rb > +++ b/server/lib/deltacloud/drivers/fgcp/fgcp_driver_cimi_methods.rb > @@ -29,39 +29,95 @@ module Deltacloud::Drivers::Fgcp > def systems(credentials, opts={}) > safely do > client = new_client(credentials) > + xml = client.list_vsys['vsyss'] > + return [] if xml.nil? > + context = opts[:env] > > - if opts and opts[:id] > - vsys_ids = [opts[:id]] > - else > - xml = client.list_vsys['vsyss'] > - return [] if xml.nil? > - vsys_ids = xml[0]['vsys'].collect { |vsys| > vsys['vsysId'][0] } > - end > - > - vsys_ids.collect do |vsys_id| > - vsys = client.get_vsys_configuration(vsys_id)['vsys'][0] > + systems = xml[0]['vsys'].collect do |vsys| > + vsys_id = vsys['vsysId'][0] > vsys_description_el = vsys['description'] > CIMI::Model::System.new( > - :id => vsys['vsysId'][0], > + :id => vsys_id, > :name => vsys['vsysName'][0], > -# :machines => > "http://cimi.example.org/systems/#{vsys['vsysId'][0]}/machines?realm > _id=#{vsys['vsysId'][0]}", > -# :volumes => > "http://cimi.example.org/systems/#{vsys['vsysId'][0]}/volumes?realm_ > id=#{vsys['vsysId'][0]}", > -# :networks => > "http://cimi.example.org/systems/#{vsys['vsysId'][0]}/networks?realm > _id=#{vsys['vsysId'][0]}", > -# :addresses => > "http://cimi.example.org/systems/#{vsys['vsysId'][0]}/addresses?real > m_id=#{vsys['vsysId'][0]}", > - :description => vsys_description_el ? > vsys_description_el[0] : nil > + :description => vsys_description_el ? > vsys_description_el[0] : nil, > + :machines => { :href => > context.system_url("#{vsys_id}/machines") }, > + :volumes => { :href => > context.system_url("#{vsys_id}/volumes") }, > + :networks => { :href => > context.system_url("#{vsys_id}/networks") }, > + :addresses => { :href => > context.system_url("#{vsys_id}/addresses") } > ) > end > + systems = systems.select { |s| opts[:id] == s[:id] } if opts[:id] > + # now add system state > + systems.each do |system| > + xml = client.list_vservers(system[:id])['vservers'] > + if xml.nil? > + system[:state] = 'MIXED' > + else > + xml[0]['vserver'].each do |vserver| > + state = > @@INSTANCE_STATE_MAP[client.get_vserver_status(vserver['vserverId'][ > 0])['vserverStatus'][0]] > + state = 'STARTED' if state == 'RUNNING' > + system[:state] ||= state > + if system[:state] != state > + system[:state] = 'MIXED' > + break > + end > + end > + end > + end > + systems > end > end > > def system_templates(credentials, opts={}) > safely do > client = new_client(credentials) > + context = opts[:env] > templates = > client.list_vsys_descriptor['vsysdescriptors'][0]['vsysdescriptor']. > collect do |desc| > + conf = > client.get_vsys_descriptor_configuration(desc['vsysdescriptorId'][0] > )['vsysdescriptor'][0] > + components = conf['vservers'][0]['vserver'].collect do > |vserver| > + next if vserver['vserverType'][0] == 'firewall' > + volume_templates = vserver['vdisks'][0]['vdisk'].collect > do |vdisk| > + CIMI::Model::VolumeTemplateWithLocation.new( > +# :volume_config => {:capacity => > "#{vdisk['size'][0].to_i * 1024 * 1024}"} > + :volume_config => > CIMI::Model::VolumeConfiguration.new(:capacity => > vdisk['size'][0].to_i * 1024 * 1024) > + ) > + end if vserver['vdisks'] > + { > + :name => desc['vsysdescriptorName'][0], > + :description => '', > + :type => > "http://schemas.dmtf.org/cimi/1/Machine", > + :machine_template => CIMI::Model::MachineTemplate.new( > + :name => vserver['vserverName'][0], > + :description => '', > + :machine_config => > CIMI::Service::MachineConfiguration.find(vserver['vserverType'][0], > context), > + :machine_image => { :href => > context.machine_image_url(vserver['diskimageId'][0]) }, > + :volume_templates => volume_templates > + ) > + } > + end > + if conf['vsysdescriptorId'][0] =~ /(1|2|3)-tier Skeleton/ > + tiers = ['DMZ', 'Secure1', 'Secure2'] > + components += 1.upto($1.to_i).collect do |n| > + { > + :name => tiers[n], > + :description => "Network tier #{n}", > + :type => > "http://schemas.dmtf.org/cimi/1/Network", > + :network_template => > CIMI::Model::NetworkTemplate.new( > + :name => 'Private network', > + :description => '', > + :network_config => > CIMI::Model::NetworkConfiguration.new( > + :network_type => 'PRIVATE', > + :class_of_service => 'BRONZE' > + ) > + ) > + } > + end > + end > CIMI::Model::SystemTemplate.new( > - :id => desc['vsysdescriptorId'][0], > - :name => desc['vsysdescriptorName'][0], > - :description => desc['description'][0] > + :id => desc['vsysdescriptorId'][0], > + :name => desc['vsysdescriptorName'][0], > + :description => desc['description'][0], > + :component_descriptors => components.compact > ) > end > templates = templates.select { |t| opts[:id] == t[:id] } if > opts[:id] > diff --git > a/server/lib/deltacloud/drivers/mock/data/cimi/system_template/templ > ate1.json > b/server/lib/deltacloud/drivers/mock/data/cimi/system_template/templ > ate1.json > index 495fc24..913252b 100644 > --- > a/server/lib/deltacloud/drivers/mock/data/cimi/system_template/templ > ate1.json > +++ > b/server/lib/deltacloud/drivers/mock/data/cimi/system_template/templ > ate1.json > @@ -4,20 +4,43 @@ > "created": "Fri Feb 08 12:15:15 EET 2013", > "componentDescriptors": [ > { "name": "my machine", > - "type": "http://schemas.dmtf.org/cimi/1/Machine", > "description": "an inline mock machine template", > + "type": "http://schemas.dmtf.org/cimi/1/Machine", > "machineTemplate": { > "name": "machine in mock system", > "description": "machine in system", > "machineConfig": { "href": > "http://example.com/configs/m1-small" }, > - "machineImage": { "href": "http://example.com/images/img1" } > + "machineImage": { "href": "http://example.com/images/img1" }, > + "volumeTemplates": [ > + { "href": "http://example.com/volumes/sysvol1" } > + ] > } > }, > + { "name": "my second machine", > + "description": "another inline mock machine template", > + "type": "http://schemas.dmtf.org/cimi/1/Machine", > + "machineTemplate": { > + "name": "machine in mock system", > + "description": "machine in system", > + "machineConfig": { "href": > "http://example.com/configs/m1-small" }, > + "machineImage": { "href": "http://example.com/images/img1" }, > + "volumeTemplates": [ > + { "volumeConfig": {"capacity": 10485760} } > + ] > + } > + }, > + { "name": "my third machine", > + "description": "a reference to a mock machine template", > + "type": "http://schemas.dmtf.org/cimi/1/Machine", > + "machineTemplate": { "href" : > "http://example.com/machine_templates/template1" } > + }, > { "name": "my network", > + "description": "an inline network template", > "type": "http://schemas.dmtf.org/cimi/1/Network", > - "description": "a reference to an existing mock network template", > "networkTemplate": { > - "href": > "http://cimi.example.org/network_templates/template1" > + "name": "network in mock system", > + "description": "network in system", > + "networkConfig": { "networkType": "PRIVATE", > "classOfService": "GOLD" } > } > } > ], > diff --git > a/server/lib/deltacloud/drivers/mock/mock_driver_cimi_methods.rb > b/server/lib/deltacloud/drivers/mock/mock_driver_cimi_methods.rb > index b1c57c8..13987f2 100644 > --- a/server/lib/deltacloud/drivers/mock/mock_driver_cimi_methods.rb > +++ b/server/lib/deltacloud/drivers/mock/mock_driver_cimi_methods.rb > @@ -35,6 +35,38 @@ module Deltacloud::Drivers::Mock > systems.map{|sys|convert_cimi_mock_urls(:system, > sys ,opts[:env])}.flatten > end > > + def create_system(credentials, opts={}) > + check_credentials(credentials) > + id = "#{opts[:env].send("systems_url")}/#{opts[:name]}" > + sys_hsh = { "id"=> id, > + "name" => opts[:name], > + "description" => opts[:description], > + "created" => Time.now, > + "state" => "STOPPED", > + "systemTemplate"=> { "href" => > opts[:system_template].id }, > + "operations" => [{"rel"=>"edit", "href"=> id}, > + {"rel"=>"delete", "href"=> > id}] } > + system = CIMI::Model::System.from_json(JSON.generate(sys_hsh)) > + > + @client.store_cimi(:system, system) > + system > + end > + > + def delete_system(credentials, id) > + check_credentials(credentials) > + @client.destroy_cimi(:system, id) > + end > + > + def start_system(credentials, id) > + check_credentials(credentials) > + update_object_state(id, "System", "STARTED") > + end > + > + def stop_system(credentials, id) > + check_credentials(credentials) > + update_object_state(id, "System", "STOPPED") > + end > + > def system_templates(credentials, opts={}) > check_credentials(credentials) > if opts[:id].nil? > diff --git a/server/tests/cimi/collections/system_templates_test.rb > b/server/tests/cimi/collections/system_templates_test.rb > index 8c4f1a7..87488b4 100644 > --- a/server/tests/cimi/collections/system_templates_test.rb > +++ b/server/tests/cimi/collections/system_templates_test.rb > @@ -38,4 +38,51 @@ describe CIMI::Collections::SystemTemplates do > status.must_equal 404 > end > > + it 'should allow to retrieve system template\'s machine template\'s > ref details' do > + get root_url '/system_templates/template1' > + (xml/'SystemTemplate/componentDescriptor').each do |c| > + if (c/'name').inner_text == 'my third machine' > + (c/'machineTemplate').wont_be_empty > + (c/'machineTemplate').to_s.must_equal '<machineTemplate > href="http://example.com/machine_templates/template1"/>' > + end > + end > + end > + > + it 'should allow to retrieve system template\'s machine template\'s > inline details' do > + get root_url '/system_templates/template1' > + (xml/'SystemTemplate/componentDescriptor').each do |c| > + if (c/'name').inner_text == 'my machine' > + (c/'machineTemplate').wont_be_empty > + (c/'machineTemplate/name').inner_text.must_equal 'machine in > mock system' > + (c/'machineTemplate/description').inner_text.must_equal > 'machine in system' > + (c/'machineTemplate/machineConfig').to_s.must_equal > '<machineConfig href="http://example.com/configs/m1-small"/>' > + (c/'machineTemplate/machineImage').to_s.must_equal > '<machineImage href="http://example.com/images/img1"/>' > + (c/'machineTemplate/volumeTemplate').to_s.must_equal > '<volumeTemplate href="http://example.com/volumes/sysvol1"/>' > + end > + end > + end > + > + it 'should allow to retrieve system template\'s machine template\'s > inline volume template' do > + get root_url '/system_templates/template1' > + (xml/'SystemTemplate/componentDescriptor').each do |c| > + if (c/'name').inner_text == 'my second machine' > + (c/'machineTemplate').wont_be_empty > + (c/'machineTemplate/description').inner_text.must_equal > 'another inline mock machine template' > + (c/'machineTemplate/volumeTemplate').wont_be_empty > + > (c/'machineTemplate/volumeTemplate/volumeConfig').wont_be_empty > + > (c/'machineTemplate/volumeTemplate/volumeConfig/capacity').inner_tex > t.must_equal '10485760' > + end > + end > + end > + > + it 'should allow to retrieve system template\'s network' do > + get root_url '/system_templates/template1' > + (xml/'SystemTemplate/componentDescriptor').each do |c| > + if (c/'name').inner_text == 'network in mock system' > + (c/'networkTemplate').inner_text.must_equal 'my network' > + > (c/'networkTemplate/networkConfig/networkType').inner_text.must_equa > l 'GOLD' > + end > + end > + end > + > end > -- > 1.8.0.msysgit.0 > >