From d8d951f328e241586d3531a8a02dde2388046a47 Mon Sep 17 00:00:00 2001 From: Chris Hoge Date: Tue, 29 Apr 2014 11:47:16 -0700 Subject: [PATCH] Fixed the Glance add_image parser for new client The python-glanceclient (glance) was updated to not report back on the id of an uploaded image with the v2 API [1]. This broke the parser for the glance_image provider. This change first checks for the previous behavior (for performance and backwards compatability), and failing that parses the results table and pulls the id (if it exits) out of the results. The new parse_table method was made to be generic so that any result from the glance client could be parsed into an array of maps. [1] https://github.com/openstack/python-glanceclient/search?q=Added+new+image+with+ID&ref=cmdform Change-Id: If7b5445c6f51d886427248827a73cc16b5a2e488 --- lib/puppet/provider/glance.rb | 32 ++++++++++++++++++++-- lib/puppet/provider/glance_image/glance.rb | 19 +++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/lib/puppet/provider/glance.rb b/lib/puppet/provider/glance.rb index a31967f3..06c1c60a 100644 --- a/lib/puppet/provider/glance.rb +++ b/lib/puppet/provider/glance.rb @@ -106,7 +106,6 @@ class Puppet::Provider::Glance < Puppet::Provider self.class.auth_glance_stdin(args) end - private def self.list_glance_images ids = [] @@ -132,6 +131,35 @@ class Puppet::Provider::Glance < Puppet::Provider return attrs end + def parse_table(table) + # parse the table into an array of maps with a simplistic state machine + found_header = false + parsed_header = false + keys = nil + results = [] + table.split("\n").collect do |line| + # look for the header + if not found_header + if line =~ /^\+[-|+]+\+$/ + found_header = true + nil + end + # look for the key names in the table header + elsif not parsed_header + if line =~ /^(\|\s*[:alpha:]\s*)|$/ + keys = line.split('|').map(&:strip) + parsed_header = true + end + # parse the values in the rest of the table + elsif line =~ /^|.*|$/ + values = line.split('|').map(&:strip) + result = Hash[keys.zip values] + results << result + end + end + results + end + # Remove warning from the output. This is a temporary hack until # things will be refactored to use the REST API def self.remove_warnings(results) @@ -139,7 +167,7 @@ class Puppet::Provider::Glance < Puppet::Provider in_warning = false results.split("\n").collect do |line| unless found_header - if line =~ /^\+[-\+]+\+$/ + if line =~ /^\+[-\+]+\+$/ # Matches upper and lower box borders in_warning = false found_header = true line diff --git a/lib/puppet/provider/glance_image/glance.rb b/lib/puppet/provider/glance_image/glance.rb index d863daab..53ebd61b 100644 --- a/lib/puppet/provider/glance_image/glance.rb +++ b/lib/puppet/provider/glance_image/glance.rb @@ -64,17 +64,32 @@ Puppet::Type.type(:glance_image).provide( else results = auth_glance('image-create', "--name=#{resource[:name]}", "--is-public=#{resource[:is_public]}", "--container-format=#{resource[:container_format]}", "--disk-format=#{resource[:disk_format]}", location) end + + id = nil + + # Check the old behavior of the python-glanceclient if results =~ /Added new image with ID: (\S+)/ + id = $1 + else # the new behavior doesn't print the status, so parse the table + results_array = parse_table(results) + results_array.each do |result| + if result["Property"] == "id" + id = result["Value"] + end + end + end + + if id @property_hash = { :ensure => :present, :name => resource[:name], :is_public => resource[:is_public], :container_format => resource[:container_format], :disk_format => resource[:disk_format], - :id => $1 + :id => id } else - fail("did not get expected message from image creation, got #{results}") + fail("did not get expected message from image creation, got #{results}") end end