Sorry, this one. You need to apply first this patch:
https://fedorahosted.org/pipermail/deltacloud-devel/2010-February/000460.htm...
(...which is my 'first' version based on Nokogiri gem. Version above use 'deltacloud-client' gem)
On 18/02/10 15:57 +0100, mfojtik@redhat.com wrote:
client/bin/deltacloudc | 177 +++++++++++++++++++++++------------------------- 1 files changed, 84 insertions(+), 93 deletions(-)
diff --git a/client/bin/deltacloudc b/client/bin/deltacloudc index 53df7bb..6450055 100755 --- a/client/bin/deltacloudc +++ b/client/bin/deltacloudc @@ -17,16 +17,14 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
require 'rubygems' -require 'rest_client' require 'optparse' -require 'nokogiri' +require 'rest_client' require 'uri' +require 'deltacloud'
-options = {
- :format => :plain
-} +options = {}
-@optparse = OptionParser.new do|opts| +@optparse = OptionParser.new do |opts|
opts.banner = <<BANNER Usage: @@ -41,9 +39,9 @@ BANNER opts.on( nil, '--image-id ID', 'Image ID') { |id| options[:image_id] = id } opts.on( nil, '--arch ARCH', 'Architecture (x86, x86_64)') { |id| options[:architecture] = id } opts.on( nil, '--flavor_id FLAVOR', 'Flavor') { |id| options[:flavor_id] = id }
- opts.on( nil, '--name NAME', 'Name (for instance eg.)') { |name| options[:name] = name } opts.on( '-l', '--list', 'List collections/operations') { |id| options[:list] = true } opts.on( '-u', '--url', 'API url ($API_URL variable)') { |url| options[:api_url] = url }
- opts.on( nil, '--xml', 'XML output') { |format| options[:format] = :xml } opts.on( '-h', '--help', 'Display this screen' ) { puts opts ; exit } opts.on( '-v', '--version', 'Display API version' ) { options[:version]=true }
end @@ -53,105 +51,98 @@ def invalid_usage(error_msg='') exit(1) end
-def convert_to_plain(xml)
- doc = Nokogiri::XML(xml)
- doc.root.traverse do |elem|
- yield "-----------------------" if elem.children.size>1
- next unless elem.children.size.eql?(1)
- if not elem.eql?(doc.root) and not elem.name.eql?('text')
yield "#{string_to_width(elem.name, 15)}: #{elem.content.strip}"
- end
- end
- return nil
-end
-def string_to_width(string, width, options = {})
- options.merge!(
- :pad => ' ', :align => :left
- )
- new_string = ""
- i = 0
- string.each_byte do |c|
- break if i == width
- new_string += c.chr
- i += 1
- end
- # add padding
- if new_string.length < width
- padding = (options[:pad] * (width - new_string.length))
- new_string = options[:align] == :left ?
new_string + padding : padding + new_string
- end
- new_string
-end
@optparse.parse!
# First try to get API_URL from environment options[:api_url] = ENV['API_URL'] if options[:api_url].nil? -options[:collection] = ARGV[0] -options[:operation] = ARGV[1]
-invalid_usage("API_URL is not set") if options[:api_url].nil? +url = URI.parse(options[:api_url]) +api_url = "http://#%7Burl.host%7D#%7Burl.port ? ":#{url.port}" : ''}#{url.path}"
-options[:list]=true if options[:collection].nil? and options[:operation].nil? +options[:collection] = ARGV[0] +options[:operation] = ARGV[1]
-# Default response to XML -params = { :accept => "application/xml" } +# Connect to Deltacloud API and fetch all entry points +client = DeltaCloud.new(url.user, url.password, api_url) +collections = client.entry_points.keys
-operations = {} -operations[:get] = [ 'index', 'show', 'new'] -operations[:post] = [ 'save', 'create' ] -operations[:put] = [ 'update' ] -operations[:delete] = [ 'delete' ] +# Exclude collection which don't have methods in client library yet +collections.delete(:hardware_profiles) +collections.delete(:instance_states)
-rest = RestClient::Resource.new( options[:api_url] , :accept => 'application/xml' ) +# If list parameter passed print out available collection +# with API documentation +if options[:list] and options[:collection].nil?
- collections.each do |c|
- doc = client.fetch_documentation(c.to_s)
- puts sprintf("%-22s: %s", c.to_s[0, 22], doc[:description])
- end
- exit(0)
+end
-doc = Nokogiri::XML(rest.get(:accept => "application/xml")) -version, driver = doc.xpath('/api/@version'), doc.xpath('/api/@driver') -collections = doc.xpath('/api/link/@rel').collect { |rel| rel.to_s } +# If collection parameter is present and user requested list +# print all operation defined for collection with API documentation +if options[:list] and options[:collection]
- doc = client.fetch_documentation(options[:collection])
- doc[:operations].each do |c|
- puts sprintf("%-20s: %s", c[:name][0, 20], c[:description])
- end
- exit(0)
+end
if options[:version]
- puts "API [#{version}] Driver: [#{driver}]"
- exit
- puts "Deltacloud API(#{client.driver_name}) 0.1"
- exit(0)
end
-# List available collection for driver
-if options[:list] and not options[:collection]
- puts "Available collections for driver #{driver} [#{version}]:\n\n"
- collections.collect { |c| puts c }
-elsif options[:list] and options[:collection]
- # TODO: Place here all available collection operations (through /api/docs)
-else
- options[:params] = {}
- options[:params]['image_id'] = options[:image_id] unless options[:image_id].nil?
- options[:params]['architecture'] = options[:architecture] unless options[:architecture].nil?
- options[:params]['flavor_id'] = options[:flavor_id] unless options[:flavor_id].nil?
- options[:operation] = 'index' if options[:operation].nil?
- # First guess HTTP method to use
- method = operations.keys.select { |k| operations[k].include?(options[:operation]) }.first
- invalid_usage("Unknown operation: #{options[:operation]} ") if method.nil?
- invalid_usage("Unknown collection: #{options[:collection]}") unless collections.include?(options[:collection])
- # 'show' and 'index' is not needed in URI
- options[:operation] = nil if ['show', 'index'].include?(options[:operation])
- # Resource means Rest URI ['/flavors', '/images/:id']
- resource = [options[:collection], options[:operation], options[:id]].compact.join('/')
- if method.eql?(:post)
- puts rest[resource].send(method, params, options[:params])
- else
- resource += '?'+URI.escape(options[:params].collect{|k,v| "#{k}=#{v}"}.join('&')) if options[:params]
- case options[:format]
when :xml
puts rest[resource].send(method, params)
when :plain
convert_to_plain(rest[resource].send(method, params)) do |line|
puts line
end
- end
+# List items from collection (typically /flavors) +# Do same if 'index' operation is set +if options[:collection] and ( options[:operation].nil? or options[:operation].eql?('index') )
- invalid_usage("Unknown collection: #{options[:collection]}") unless collections.include?(options[:collection].to_sym)
- params = {}
- params.merge!(:architecture => options[:architecture]) if options[:architecture]
- params.merge!(:id => options[:id]) if options[:id]
- client.send(options[:collection].to_s, params).each do |model|
- puts model.to_plain end
- exit(0)
end
+if options[:collection] and options[:operation]
- invalid_usage("Unknown collection: #{options[:collection]}") unless collections.include?(options[:collection].to_sym)
- params = {}
- params.merge!(:id => options[:id]) if options[:id]
- # If collection is set and requested operation is 'show' just 'singularize'
- # collection name and print item with specified id (-i parameter)
- if options[:operation].eql?('show')
- puts client.send(options[:collection].gsub(/s$/, ''), options[:id] ).to_plain
- exit(0)
- end
- # If collection is set and requested operation is create new instance,
- # --image-id, --flavor-id and --name parameters are used
- # Returns created instance in plain form
- if options[:collection].eql?('instances') and options[:operation].eql?('create')
- params.merge!(:name => options[:name]) if options[:name]
- params.merge!(:image_id => options[:image_id]) if options[:image_id]
- params.merge!(:flavor_id => options[:flavor_id]) if options[:flavor_id]
- instance = client.create_instance(options[:image_id], params)
- puts instance.to_plain
- exit(0)
- end
- # All other operations above collections is done there:
- if options[:collection].eql?('instances')
- instance = client.instance(options[:id])
- instance.send("#{options[:operation]}!".to_s)
- instance = client.instance(options[:id])
- puts instance.to_plain
- exit(0)
- end
+end
+# If all above passed (eg. no parameters)
+puts @optparse
1.6.4.4