(no subject)
by Martyn Taylor
Updated to handle deleted users correctly, and redirect to controller index (fixes pool redirect issue)
12 years, 8 months
[PATCH conductor] Warehouse sync update (rev. 2)
by Jan Provazník
From: Jan Provaznik <jprovazn(a)redhat.com>
sync code moved to models. Image, ProviderImage, Icicle and Template now has
warehouse_sync method. When you call this method attributes are updated from
warehouse, note that save call is not part of this method - you need to save
explicitly (this is because of after_save hooks for image and provider_iamge
call warehouse_sync so there could be recursion)
---
src/app/models/icicle.rb | 15 +++
src/app/models/image.rb | 36 ++++++--
src/app/models/image_warehouse_object.rb | 49 ++++++++---
src/app/models/provider_image.rb | 31 +++++--
src/app/models/template.rb | 15 ++--
src/app/util/image_descriptor_xml.rb | 12 +--
src/lib/warehouse_client.rb | 4 +
src/warehouse_sync/warehouse_sync-server | 2 +-
src/warehouse_sync/warehouse_sync.rb | 145 ++++-------------------------
9 files changed, 144 insertions(+), 165 deletions(-)
diff --git a/src/app/models/icicle.rb b/src/app/models/icicle.rb
index 2bad5d9..a086285 100644
--- a/src/app/models/icicle.rb
+++ b/src/app/models/icicle.rb
@@ -12,7 +12,22 @@
#
class Icicle < ActiveRecord::Base
+ include ImageWarehouseObject
+
validates_presence_of :uuid
validates_uniqueness_of :uuid
belongs_to :provider_image
+
+ def self.create_or_update(uuid)
+ icicle = Icicle.find_by_uuid(uuid) || Icicle.new(:uuid => uuid)
+ icicle.warehouse_sync
+ icicle.log_changes
+ icicle.save! if icicle.changed?
+ icicle
+ end
+
+ def warehouse_sync
+ obj = warehouse.bucket('icicles').object(self.uuid)
+ self.xml = obj.body
+ end
end
diff --git a/src/app/models/image.rb b/src/app/models/image.rb
index 7a8aae4..f15f2da 100644
--- a/src/app/models/image.rb
+++ b/src/app/models/image.rb
@@ -79,15 +79,8 @@ class Image < ActiveRecord::Base
# TODO: for now when build is finished we call upload automatically for all providers
def after_update
if self.status_changed? and self.status == STATE_COMPLETED
- # TODO: use after_commit callback in rails 3 - it's better to have it outside
- # update transaction
- begin
- invoke_sync
- upload_to_all_providers_with_account
- rescue => e
- logger.error e.message
- logger.error e.backtrace.join("\n ")
- end
+ safe_warehouse_sync
+ upload_to_all_providers_with_account
end
end
@@ -176,6 +169,31 @@ class Image < ActiveRecord::Base
image
end
+ def warehouse_bucket
+ 'images'
+ end
+
+ def warehouse_sync
+ bucket = warehouse.bucket(warehouse_bucket)
+ raise WarehouseObjectNotFoundError unless bucket.include?(self.uuid)
+ obj = bucket.object(self.uuid)
+ attrs = obj.attrs([:uuid, :target, :template])
+ unless attrs[:target]
+ raise "target uuid is not set"
+ end
+ unless ptype = ProviderType.find_by_codename(attrs[:target])
+ raise "provider type #{attrs[:target]} not found"
+ end
+ unless attrs[:template]
+ raise "template uuid is not set"
+ end
+ unless tpl = Template.find_by_uuid(attrs[:template])
+ raise "Template with uuid #{attrs[:template]} not found"
+ end
+ self.provider_type_id = ptype.id
+ self.template_id = tpl.id
+ end
+
private
def upload_to_all_providers_with_account
diff --git a/src/app/models/image_warehouse_object.rb b/src/app/models/image_warehouse_object.rb
index 40a7c3b..43f3b76 100644
--- a/src/app/models/image_warehouse_object.rb
+++ b/src/app/models/image_warehouse_object.rb
@@ -19,6 +19,8 @@
require 'warehouse_client'
+class WarehouseObjectNotFoundError < Exception;end
+
module ImageWarehouseObject
WAREHOUSE_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/image_warehouse.yml")
@@ -40,32 +42,57 @@ module ImageWarehouseObject
# TODO: it would be nice not call upload, when save was invoked by warehouse
# sync script
def upload
- whouse = Warehouse::Client.new(WAREHOUSE_CONFIG['baseurl'])
# TODO: for now there is no way how it check if bucket exists in warehouse
# so we try to create bucket everytime, if bucket exists, warehouse returns
# 500 Internal server error
- whouse.create_bucket(warehouse_bucket) rescue true
+ warehouse.create_bucket(warehouse_bucket) rescue true
# TODO: we delete existing object if it exists
- whouse.bucket(warehouse_bucket).object(self.uuid).delete! rescue true
- whouse.bucket(warehouse_bucket).create_object(self.uuid, warehouse_body, warehouse_attrs)
+ warehouse.bucket(warehouse_bucket).object(self.uuid).delete! rescue true
+ warehouse.bucket(warehouse_bucket).create_object(self.uuid, warehouse_body, warehouse_attrs)
end
def delete_in_warehouse
- whouse = Warehouse::Client.new(WAREHOUSE_CONFIG['baseurl'])
begin
- whouse.bucket(warehouse_bucket).object(self.uuid).delete!
+ warehouse.bucket(warehouse_bucket).object(self.uuid).delete!
rescue
logger.error "failed to delete #{self.uuid} in warehouse: #{$!}"
end
end
+ def warehouse
+ @warehouse ||= Warehouse::Client.new(WAREHOUSE_CONFIG['baseurl'])
+ end
+
+ def warehouse_url
+ "#{WAREHOUSE_CONFIG['baseurl']}/#{warehouse_bucket}/#{self.uuid}"
+ end
+
+ def safe_warehouse_sync
+ warehouse_sync
+ log_changes
+ rescue RestClient::ResourceNotFound, WarehouseObjectNotFoundError
+ logger.error "Failed to fetch #{self.class.class_name} with uuid #{self.uuid} - not found in warehouse"
+ rescue => e
+ logger.error "Failed to sync #{self.class.class_name} with uuid #{self.uuid}: #{e.message}"
+ logger.error e.backtrace.join("\n ")
+ end
+
+ def log_changes
+ if self.new_record?
+ logger.info "#{self.class.class_name} #{self.uuid} is not in DB yet"
+ elsif self.changed?
+ logger.info "#{self.class.class_name} #{self.uuid} has been changed:"
+ self.changed.each do |attr|
+ logger.info "old #{attr}: #{self.send(attr + '_was')}"
+ logger.info "new #{attr}: #{self[attr]}"
+ end
+ else
+ logger.info "#{self.class.class_name} #{self.uuid} is without changes"
+ end
+ end
+
def generate_uuid
# TODO: generate real uuid here, e.g. with some ruby uuid generator
self.uuid ||= UUIDTools::UUID.timestamp_create.to_s
end
-
- def invoke_sync
- # TODO: invoke warehouse_sync here (after switching to eventmachine)
- # pass self.uuid to sync only changed object
- end
end
diff --git a/src/app/models/provider_image.rb b/src/app/models/provider_image.rb
index 67390dd..aee69a9 100644
--- a/src/app/models/provider_image.rb
+++ b/src/app/models/provider_image.rb
@@ -33,12 +33,31 @@ class ProviderImage < ActiveRecord::Base
def after_update
if self.status_changed? and self.status == STATE_COMPLETED
- begin
- invoke_sync
- rescue => e
- logger.error e.message
- logger.error e.backtrace.join("\n ")
- end
+ safe_warehouse_sync
end
end
+
+ def warehouse_bucket
+ 'provider_images'
+ end
+
+ def warehouse_sync
+ bucket = warehouse.bucket(warehouse_bucket)
+ raise WarehouseObjectNotFoundError unless bucket.include?(self.uuid)
+ obj = bucket.object(self.uuid)
+ attrs = obj.attrs([:uuid, :image, :icicle, :target_identifier])
+ unless attrs[:image]
+ raise "image uuid is not set"
+ end
+ unless img = Image.find_by_uuid(attrs[:image])
+ raise "image with uuid #{attrs[:image]} not found"
+ end
+ begin
+ self.icicle = Icicle.create_or_update(attrs[:icicle])
+ rescue
+ logger.error "Failed to fetch icicle '#{attrs[:icicle]}', setting icicle to nil: #{$!.message}"
+ end
+ self.image_id = img.id
+ self.provider_image_key = attrs[:target_identifier]
+ end
end
diff --git a/src/app/models/template.rb b/src/app/models/template.rb
index 3147e16..1b09dae 100644
--- a/src/app/models/template.rb
+++ b/src/app/models/template.rb
@@ -78,9 +78,11 @@ class Template < ActiveRecord::Base
def update_from_xml
self.name = xml.name
self.summary = xml.description
- self.platform = xml.platform
- self.platform_version = xml.platform_version
- self.architecture = xml.architecture
+ self.platform_hash = {
+ :platform => xml.platform,
+ :version => xml.platform_version,
+ :architecture => xml.architecture,
+ }
end
def providers
@@ -157,8 +159,9 @@ class Template < ActiveRecord::Base
'templates'
end
- def warehouse_url
- baseurl = YAML.load_file("#{RAILS_ROOT}/config/image_warehouse.yml")['baseurl'] + "/templates/"
- self.uuid ? baseurl + self.uuid : baseurl
+ def warehouse_sync
+ obj = warehouse.bucket(warehouse_bucket).object(self.uuid)
+ xml = obj.body
+ update_from_xml
end
end
diff --git a/src/app/util/image_descriptor_xml.rb b/src/app/util/image_descriptor_xml.rb
index 8476770..02634b2 100644
--- a/src/app/util/image_descriptor_xml.rb
+++ b/src/app/util/image_descriptor_xml.rb
@@ -52,8 +52,7 @@ class ImageDescriptorXML
end
def platform
- node = @root.at_xpath('/template/os')
- return node ? node['name'] : nil
+ return get_node_text('os/name')
end
def platform=(platform_hash)
@@ -80,17 +79,16 @@ class ImageDescriptorXML
end
def platform_version
- node = @root.at_xpath('/image/os/version')
- return node ? node.content : nil
+ return get_node_text('os/version')
end
def architecture
- node = @root.at_xpath('/template/os/arch')
- return node ? node.content : nil
+ return get_node_text('os/arch')
end
def architecture=(str)
- get_or_create_node('os')['architecture'] = str
+ node = get_or_create_node('arch', get_or_create_node('os'))
+ node.content = str
end
def services=(services)
diff --git a/src/lib/warehouse_client.rb b/src/lib/warehouse_client.rb
index 9431e47..12b8d9d 100644
--- a/src/lib/warehouse_client.rb
+++ b/src/lib/warehouse_client.rb
@@ -99,6 +99,10 @@ module Warehouse
def create_object(key, body, attrs)
BucketObject.create(@connection, key, self, body, attrs)
end
+
+ def include?(key)
+ object_names.include?(key)
+ end
end
class Connection
diff --git a/src/warehouse_sync/warehouse_sync-server b/src/warehouse_sync/warehouse_sync-server
index 7fc15f5..603a520 100755
--- a/src/warehouse_sync/warehouse_sync-server
+++ b/src/warehouse_sync/warehouse_sync-server
@@ -61,7 +61,7 @@ else
end
logger = Logger.new(LOG_FILE)
-logger.level = Logger::DEBUG
+logger.level = Logger::INFO
logger.datetime_format = "%Y-%m-%d %H:%M:%S"
logger.info "Warehouse_sync starting up"
diff --git a/src/warehouse_sync/warehouse_sync.rb b/src/warehouse_sync/warehouse_sync.rb
index f18c1e9..5868db9 100644
--- a/src/warehouse_sync/warehouse_sync.rb
+++ b/src/warehouse_sync/warehouse_sync.rb
@@ -11,143 +11,38 @@ class WarehouseSync
@uri = opts[:uri]
@delay = opts[:delay] || 10*60
@logger = opts[:logger]
+ ActiveRecord::Base.logger = @logger
@whouse = Warehouse::Client.new(@uri)
end
def run
while true
begin
- @logger.debug "---------------------------------------"
- pull_templates
- pull_images
- pull_provider_images
+ @logger.info "***** Runnning warehouse sync"
+ # TODO: I disabled template sync - templates should never
+ # be changed by anything else than conductor
+ #(a)logger.info "*** syncing templates"
+ #Template.all.each do |i|
+ # i.safe_warehouse_sync
+ # i.save! if i.changed?
+ #end
+ @logger.info "*** syncing images"
+ Image.all.each do |i|
+ i.safe_warehouse_sync
+ i.save! if i.changed?
+ end
+ @logger.info "*** syncing provider images"
+ ProviderImage.all.each do |i|
+ i.safe_warehouse_sync
+ i.save! if i.changed?
+ end
rescue => e
@logger.error e.message
@logger.error "backtrace:\n" + e.backtrace.join("\n ")
ensure
- @logger.debug "sleep #{@delay}"
+ @logger.info "sleep #{@delay}"
sleep @delay
end
end
end
-
- def pull_templates
- @logger.debug "*** Getting templates"
- @whouse.bucket('templates').objects.each do |bucket_obj|
- safely_process(bucket_obj) do |obj|
- attrs = obj.attrs([:uuid])
- #tpl = Template.find_by_uuid(attrs[:uuid]) || Template.new(:uuid => attrs[:uuid])
- unless tpl = Template.find_by_uuid(attrs[:uuid])
- raise NotFoundError, "Template with uuid #{attrs[:uuid]} not found"
- end
- tpl.xml = obj.body
- tpl.update_from_xml
- update_changes(tpl)
- end
- end
- end
-
- def pull_images
- @logger.debug "*** Getting images"
- @whouse.bucket('images').objects.each do |bucket_obj|
- safely_process(bucket_obj) do |obj|
- attrs = obj.attrs([:uuid, :target, :template])
- #img = Image.find_by_uuid(attrs[:uuid]) || Image.new(:uuid => attrs[:uuid])
- unless img = Image.find_by_uuid(attrs[:uuid])
- raise NotFoundError, "image with uuid #{attrs[:uuid]} not found"
- end
- unless attrs[:target]
- raise "target uuid is not set"
- end
- unless ptype = ProviderType.find_by_codename(attrs[:target])
- raise "provider type #{attrs[:target]} not found"
- end
- unless attrs[:template]
- raise "template uuid is not set"
- end
- unless tpl = Template.find_by_uuid(attrs[:template])
- raise "Template with uuid #{attrs[:template]} not found"
- end
- img.provider_type_id = ptype.id
- img.template_id = tpl.id
- update_changes(img)
- end
- end
- end
-
- def pull_provider_images
- @logger.debug "*** Getting provider images"
- @whouse.bucket('provider_images').objects.each do |bucket_obj|
- safely_process(bucket_obj) do |obj|
- attrs = obj.attrs([:uuid, :image, :icicle, :target_identifier])
- # we don't allow create non-existing ProviderImage in conductor because
- # we don't know provider_id (provider attribute contains only url or
- # string which is not unique in conductor)
- unless pimg = ProviderImage.find_by_uuid(attrs[:uuid])
- raise NotFoundError, "provider image with uuid #{attrs[:uuid]} not found"
- end
- unless attrs[:image]
- raise "image uuid is not set"
- end
- unless img = Image.find_by_uuid(attrs[:image])
- raise "image with uuid #{attrs[:image]} not found"
- end
- unless attrs[:icicle]
- raise "icicle uuid is not set"
- end
- pimg.image_id = img.id
- pimg.icicle = pull_provider_image_icicle(attrs[:icicle])
- pimg.provider_image_key = attrs[:target_identifier]
- update_changes(pimg)
- end
- end
- end
-
- private
-
- def pull_provider_image_icicle(uuid)
- @logger.debug " getting provider image icicle with uuid #{uuid}"
- begin
- whouse_icicle = @whouse.bucket('icicles').object(uuid)
- icicle = Icicle.find_by_uuid(uuid) || Icicle.new(:uuid => uuid)
- icicle.xml = whouse_icicle.body
- icicle.uuid = uuid
- update_changes(icicle)
- icicle
- rescue
- @logger.debug " skipping image icicle with uuid #{uuid}: #{$!.message}"
- nil
- end
- end
-
- def safely_process(obj)
- begin
- yield obj
- rescue NotFoundError => e
- @logger.error "Skipping #{obj.key} - not found in DB"
- rescue => e
- @logger.error "Error while processing #{obj.key} (skipping): #{e.message}"
- @logger.error e.backtrace.join("\n ")
- end
- end
-
- def update_changes(obj)
- if obj.new_record?
- @logger.debug "#{obj.class.class_name} #{obj.uuid} is not in DB, saving"
- obj.save!
- elsif obj.changed?
- @logger.debug "#{obj.class.class_name} #{obj.uuid} has been changed:"
- log_changes(obj)
- obj.save!
- else
- @logger.debug "#{obj.class.class_name} #{obj.uuid} is without changes"
- end
- end
-
- def log_changes(obj)
- obj.changed.each do |attr|
- @logger.debug "old #{attr}: #{obj.send(attr + '_was')}"
- @logger.debug "new #{attr}: #{obj[attr]}"
- end
- end
end
--
1.7.4
12 years, 8 months
[PATCH conductor] Warehouse sync update (rev. 2)
by Jan Provazník
From: Jan Provaznik <jprovazn(a)redhat.com>
sync code moved to models. Image, ProviderImage, Icicle and Template now has
warehouse_sync method. When you call this method attributes are updated from
warehouse, note that save call is not part of this method - you need to save
explicitly (this is because of after_save hooks for image and provider_iamge
call warehouse_sync so there could be recursion)
---
src/app/models/icicle.rb | 15 +++
src/app/models/image.rb | 36 ++++++--
src/app/models/image_warehouse_object.rb | 49 ++++++++---
src/app/models/provider_image.rb | 31 +++++--
src/app/models/template.rb | 15 ++--
src/app/util/image_descriptor_xml.rb | 12 +--
src/lib/warehouse_client.rb | 4 +
src/warehouse_sync/warehouse_sync-server | 2 +-
src/warehouse_sync/warehouse_sync.rb | 145 ++++-------------------------
9 files changed, 144 insertions(+), 165 deletions(-)
diff --git a/src/app/models/icicle.rb b/src/app/models/icicle.rb
index 2bad5d9..a086285 100644
--- a/src/app/models/icicle.rb
+++ b/src/app/models/icicle.rb
@@ -12,7 +12,22 @@
#
class Icicle < ActiveRecord::Base
+ include ImageWarehouseObject
+
validates_presence_of :uuid
validates_uniqueness_of :uuid
belongs_to :provider_image
+
+ def self.create_or_update(uuid)
+ icicle = Icicle.find_by_uuid(uuid) || Icicle.new(:uuid => uuid)
+ icicle.warehouse_sync
+ icicle.log_changes
+ icicle.save! if icicle.changed?
+ icicle
+ end
+
+ def warehouse_sync
+ obj = warehouse.bucket('icicles').object(self.uuid)
+ self.xml = obj.body
+ end
end
diff --git a/src/app/models/image.rb b/src/app/models/image.rb
index 7a8aae4..f15f2da 100644
--- a/src/app/models/image.rb
+++ b/src/app/models/image.rb
@@ -79,15 +79,8 @@ class Image < ActiveRecord::Base
# TODO: for now when build is finished we call upload automatically for all providers
def after_update
if self.status_changed? and self.status == STATE_COMPLETED
- # TODO: use after_commit callback in rails 3 - it's better to have it outside
- # update transaction
- begin
- invoke_sync
- upload_to_all_providers_with_account
- rescue => e
- logger.error e.message
- logger.error e.backtrace.join("\n ")
- end
+ safe_warehouse_sync
+ upload_to_all_providers_with_account
end
end
@@ -176,6 +169,31 @@ class Image < ActiveRecord::Base
image
end
+ def warehouse_bucket
+ 'images'
+ end
+
+ def warehouse_sync
+ bucket = warehouse.bucket(warehouse_bucket)
+ raise WarehouseObjectNotFoundError unless bucket.include?(self.uuid)
+ obj = bucket.object(self.uuid)
+ attrs = obj.attrs([:uuid, :target, :template])
+ unless attrs[:target]
+ raise "target uuid is not set"
+ end
+ unless ptype = ProviderType.find_by_codename(attrs[:target])
+ raise "provider type #{attrs[:target]} not found"
+ end
+ unless attrs[:template]
+ raise "template uuid is not set"
+ end
+ unless tpl = Template.find_by_uuid(attrs[:template])
+ raise "Template with uuid #{attrs[:template]} not found"
+ end
+ self.provider_type_id = ptype.id
+ self.template_id = tpl.id
+ end
+
private
def upload_to_all_providers_with_account
diff --git a/src/app/models/image_warehouse_object.rb b/src/app/models/image_warehouse_object.rb
index 40a7c3b..43f3b76 100644
--- a/src/app/models/image_warehouse_object.rb
+++ b/src/app/models/image_warehouse_object.rb
@@ -19,6 +19,8 @@
require 'warehouse_client'
+class WarehouseObjectNotFoundError < Exception;end
+
module ImageWarehouseObject
WAREHOUSE_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/image_warehouse.yml")
@@ -40,32 +42,57 @@ module ImageWarehouseObject
# TODO: it would be nice not call upload, when save was invoked by warehouse
# sync script
def upload
- whouse = Warehouse::Client.new(WAREHOUSE_CONFIG['baseurl'])
# TODO: for now there is no way how it check if bucket exists in warehouse
# so we try to create bucket everytime, if bucket exists, warehouse returns
# 500 Internal server error
- whouse.create_bucket(warehouse_bucket) rescue true
+ warehouse.create_bucket(warehouse_bucket) rescue true
# TODO: we delete existing object if it exists
- whouse.bucket(warehouse_bucket).object(self.uuid).delete! rescue true
- whouse.bucket(warehouse_bucket).create_object(self.uuid, warehouse_body, warehouse_attrs)
+ warehouse.bucket(warehouse_bucket).object(self.uuid).delete! rescue true
+ warehouse.bucket(warehouse_bucket).create_object(self.uuid, warehouse_body, warehouse_attrs)
end
def delete_in_warehouse
- whouse = Warehouse::Client.new(WAREHOUSE_CONFIG['baseurl'])
begin
- whouse.bucket(warehouse_bucket).object(self.uuid).delete!
+ warehouse.bucket(warehouse_bucket).object(self.uuid).delete!
rescue
logger.error "failed to delete #{self.uuid} in warehouse: #{$!}"
end
end
+ def warehouse
+ @warehouse ||= Warehouse::Client.new(WAREHOUSE_CONFIG['baseurl'])
+ end
+
+ def warehouse_url
+ "#{WAREHOUSE_CONFIG['baseurl']}/#{warehouse_bucket}/#{self.uuid}"
+ end
+
+ def safe_warehouse_sync
+ warehouse_sync
+ log_changes
+ rescue RestClient::ResourceNotFound, WarehouseObjectNotFoundError
+ logger.error "Failed to fetch #{self.class.class_name} with uuid #{self.uuid} - not found in warehouse"
+ rescue => e
+ logger.error "Failed to sync #{self.class.class_name} with uuid #{self.uuid}: #{e.message}"
+ logger.error e.backtrace.join("\n ")
+ end
+
+ def log_changes
+ if self.new_record?
+ logger.info "#{self.class.class_name} #{self.uuid} is not in DB yet"
+ elsif self.changed?
+ logger.info "#{self.class.class_name} #{self.uuid} has been changed:"
+ self.changed.each do |attr|
+ logger.info "old #{attr}: #{self.send(attr + '_was')}"
+ logger.info "new #{attr}: #{self[attr]}"
+ end
+ else
+ logger.info "#{self.class.class_name} #{self.uuid} is without changes"
+ end
+ end
+
def generate_uuid
# TODO: generate real uuid here, e.g. with some ruby uuid generator
self.uuid ||= UUIDTools::UUID.timestamp_create.to_s
end
-
- def invoke_sync
- # TODO: invoke warehouse_sync here (after switching to eventmachine)
- # pass self.uuid to sync only changed object
- end
end
diff --git a/src/app/models/provider_image.rb b/src/app/models/provider_image.rb
index 67390dd..aee69a9 100644
--- a/src/app/models/provider_image.rb
+++ b/src/app/models/provider_image.rb
@@ -33,12 +33,31 @@ class ProviderImage < ActiveRecord::Base
def after_update
if self.status_changed? and self.status == STATE_COMPLETED
- begin
- invoke_sync
- rescue => e
- logger.error e.message
- logger.error e.backtrace.join("\n ")
- end
+ safe_warehouse_sync
end
end
+
+ def warehouse_bucket
+ 'provider_images'
+ end
+
+ def warehouse_sync
+ bucket = warehouse.bucket(warehouse_bucket)
+ raise WarehouseObjectNotFoundError unless bucket.include?(self.uuid)
+ obj = bucket.object(self.uuid)
+ attrs = obj.attrs([:uuid, :image, :icicle, :target_identifier])
+ unless attrs[:image]
+ raise "image uuid is not set"
+ end
+ unless img = Image.find_by_uuid(attrs[:image])
+ raise "image with uuid #{attrs[:image]} not found"
+ end
+ begin
+ self.icicle = Icicle.create_or_update(attrs[:icicle])
+ rescue
+ logger.error "Failed to fetch icicle '#{attrs[:icicle]}', setting icicle to nil: #{$!.message}"
+ end
+ self.image_id = img.id
+ self.provider_image_key = attrs[:target_identifier]
+ end
end
diff --git a/src/app/models/template.rb b/src/app/models/template.rb
index 3147e16..1b09dae 100644
--- a/src/app/models/template.rb
+++ b/src/app/models/template.rb
@@ -78,9 +78,11 @@ class Template < ActiveRecord::Base
def update_from_xml
self.name = xml.name
self.summary = xml.description
- self.platform = xml.platform
- self.platform_version = xml.platform_version
- self.architecture = xml.architecture
+ self.platform_hash = {
+ :platform => xml.platform,
+ :version => xml.platform_version,
+ :architecture => xml.architecture,
+ }
end
def providers
@@ -157,8 +159,9 @@ class Template < ActiveRecord::Base
'templates'
end
- def warehouse_url
- baseurl = YAML.load_file("#{RAILS_ROOT}/config/image_warehouse.yml")['baseurl'] + "/templates/"
- self.uuid ? baseurl + self.uuid : baseurl
+ def warehouse_sync
+ obj = warehouse.bucket(warehouse_bucket).object(self.uuid)
+ xml = obj.body
+ update_from_xml
end
end
diff --git a/src/app/util/image_descriptor_xml.rb b/src/app/util/image_descriptor_xml.rb
index 8476770..02634b2 100644
--- a/src/app/util/image_descriptor_xml.rb
+++ b/src/app/util/image_descriptor_xml.rb
@@ -52,8 +52,7 @@ class ImageDescriptorXML
end
def platform
- node = @root.at_xpath('/template/os')
- return node ? node['name'] : nil
+ return get_node_text('os/name')
end
def platform=(platform_hash)
@@ -80,17 +79,16 @@ class ImageDescriptorXML
end
def platform_version
- node = @root.at_xpath('/image/os/version')
- return node ? node.content : nil
+ return get_node_text('os/version')
end
def architecture
- node = @root.at_xpath('/template/os/arch')
- return node ? node.content : nil
+ return get_node_text('os/arch')
end
def architecture=(str)
- get_or_create_node('os')['architecture'] = str
+ node = get_or_create_node('arch', get_or_create_node('os'))
+ node.content = str
end
def services=(services)
diff --git a/src/lib/warehouse_client.rb b/src/lib/warehouse_client.rb
index 9431e47..12b8d9d 100644
--- a/src/lib/warehouse_client.rb
+++ b/src/lib/warehouse_client.rb
@@ -99,6 +99,10 @@ module Warehouse
def create_object(key, body, attrs)
BucketObject.create(@connection, key, self, body, attrs)
end
+
+ def include?(key)
+ object_names.include?(key)
+ end
end
class Connection
diff --git a/src/warehouse_sync/warehouse_sync-server b/src/warehouse_sync/warehouse_sync-server
index 7fc15f5..603a520 100755
--- a/src/warehouse_sync/warehouse_sync-server
+++ b/src/warehouse_sync/warehouse_sync-server
@@ -61,7 +61,7 @@ else
end
logger = Logger.new(LOG_FILE)
-logger.level = Logger::DEBUG
+logger.level = Logger::INFO
logger.datetime_format = "%Y-%m-%d %H:%M:%S"
logger.info "Warehouse_sync starting up"
diff --git a/src/warehouse_sync/warehouse_sync.rb b/src/warehouse_sync/warehouse_sync.rb
index f18c1e9..5868db9 100644
--- a/src/warehouse_sync/warehouse_sync.rb
+++ b/src/warehouse_sync/warehouse_sync.rb
@@ -11,143 +11,38 @@ class WarehouseSync
@uri = opts[:uri]
@delay = opts[:delay] || 10*60
@logger = opts[:logger]
+ ActiveRecord::Base.logger = @logger
@whouse = Warehouse::Client.new(@uri)
end
def run
while true
begin
- @logger.debug "---------------------------------------"
- pull_templates
- pull_images
- pull_provider_images
+ @logger.info "***** Runnning warehouse sync"
+ # TODO: I disabled template sync - templates should never
+ # be changed by anything else than conductor
+ #(a)logger.info "*** syncing templates"
+ #Template.all.each do |i|
+ # i.safe_warehouse_sync
+ # i.save! if i.changed?
+ #end
+ @logger.info "*** syncing images"
+ Image.all.each do |i|
+ i.safe_warehouse_sync
+ i.save! if i.changed?
+ end
+ @logger.info "*** syncing provider images"
+ ProviderImage.all.each do |i|
+ i.safe_warehouse_sync
+ i.save! if i.changed?
+ end
rescue => e
@logger.error e.message
@logger.error "backtrace:\n" + e.backtrace.join("\n ")
ensure
- @logger.debug "sleep #{@delay}"
+ @logger.info "sleep #{@delay}"
sleep @delay
end
end
end
-
- def pull_templates
- @logger.debug "*** Getting templates"
- @whouse.bucket('templates').objects.each do |bucket_obj|
- safely_process(bucket_obj) do |obj|
- attrs = obj.attrs([:uuid])
- #tpl = Template.find_by_uuid(attrs[:uuid]) || Template.new(:uuid => attrs[:uuid])
- unless tpl = Template.find_by_uuid(attrs[:uuid])
- raise NotFoundError, "Template with uuid #{attrs[:uuid]} not found"
- end
- tpl.xml = obj.body
- tpl.update_from_xml
- update_changes(tpl)
- end
- end
- end
-
- def pull_images
- @logger.debug "*** Getting images"
- @whouse.bucket('images').objects.each do |bucket_obj|
- safely_process(bucket_obj) do |obj|
- attrs = obj.attrs([:uuid, :target, :template])
- #img = Image.find_by_uuid(attrs[:uuid]) || Image.new(:uuid => attrs[:uuid])
- unless img = Image.find_by_uuid(attrs[:uuid])
- raise NotFoundError, "image with uuid #{attrs[:uuid]} not found"
- end
- unless attrs[:target]
- raise "target uuid is not set"
- end
- unless ptype = ProviderType.find_by_codename(attrs[:target])
- raise "provider type #{attrs[:target]} not found"
- end
- unless attrs[:template]
- raise "template uuid is not set"
- end
- unless tpl = Template.find_by_uuid(attrs[:template])
- raise "Template with uuid #{attrs[:template]} not found"
- end
- img.provider_type_id = ptype.id
- img.template_id = tpl.id
- update_changes(img)
- end
- end
- end
-
- def pull_provider_images
- @logger.debug "*** Getting provider images"
- @whouse.bucket('provider_images').objects.each do |bucket_obj|
- safely_process(bucket_obj) do |obj|
- attrs = obj.attrs([:uuid, :image, :icicle, :target_identifier])
- # we don't allow create non-existing ProviderImage in conductor because
- # we don't know provider_id (provider attribute contains only url or
- # string which is not unique in conductor)
- unless pimg = ProviderImage.find_by_uuid(attrs[:uuid])
- raise NotFoundError, "provider image with uuid #{attrs[:uuid]} not found"
- end
- unless attrs[:image]
- raise "image uuid is not set"
- end
- unless img = Image.find_by_uuid(attrs[:image])
- raise "image with uuid #{attrs[:image]} not found"
- end
- unless attrs[:icicle]
- raise "icicle uuid is not set"
- end
- pimg.image_id = img.id
- pimg.icicle = pull_provider_image_icicle(attrs[:icicle])
- pimg.provider_image_key = attrs[:target_identifier]
- update_changes(pimg)
- end
- end
- end
-
- private
-
- def pull_provider_image_icicle(uuid)
- @logger.debug " getting provider image icicle with uuid #{uuid}"
- begin
- whouse_icicle = @whouse.bucket('icicles').object(uuid)
- icicle = Icicle.find_by_uuid(uuid) || Icicle.new(:uuid => uuid)
- icicle.xml = whouse_icicle.body
- icicle.uuid = uuid
- update_changes(icicle)
- icicle
- rescue
- @logger.debug " skipping image icicle with uuid #{uuid}: #{$!.message}"
- nil
- end
- end
-
- def safely_process(obj)
- begin
- yield obj
- rescue NotFoundError => e
- @logger.error "Skipping #{obj.key} - not found in DB"
- rescue => e
- @logger.error "Error while processing #{obj.key} (skipping): #{e.message}"
- @logger.error e.backtrace.join("\n ")
- end
- end
-
- def update_changes(obj)
- if obj.new_record?
- @logger.debug "#{obj.class.class_name} #{obj.uuid} is not in DB, saving"
- obj.save!
- elsif obj.changed?
- @logger.debug "#{obj.class.class_name} #{obj.uuid} has been changed:"
- log_changes(obj)
- obj.save!
- else
- @logger.debug "#{obj.class.class_name} #{obj.uuid} is without changes"
- end
- end
-
- def log_changes(obj)
- obj.changed.each do |attr|
- @logger.debug "old #{attr}: #{obj.send(attr + '_was')}"
- @logger.debug "new #{attr}: #{obj[attr]}"
- end
- end
end
--
1.7.4
12 years, 8 months
[PATCH conductor] Warehouse sync update
by Jan Provazník
From: Jan Provaznik <jprovazn(a)redhat.com>
sync code moved to models. Image, ProviderImage, Icicle and Template now has
warehouse_sync method. When you call this method attributes are updated from
warehouse, note that save call is not part of this method - you need to save
explicitly (this is because of after_save hooks for image and provider_iamge
call warehouse_sync so there could be recursion)
---
src/app/models/icicle.rb | 15 +++
src/app/models/image.rb | 36 ++++++--
src/app/models/image_warehouse_object.rb | 49 ++++++++---
src/app/models/provider_image.rb | 31 +++++--
src/app/models/template.rb | 15 ++--
src/app/util/image_descriptor_xml.rb | 12 +--
src/lib/warehouse_client.rb | 4 +
src/warehouse_sync/warehouse_sync-server | 2 +-
src/warehouse_sync/warehouse_sync.rb | 145 ++++-------------------------
9 files changed, 144 insertions(+), 165 deletions(-)
diff --git a/src/app/models/icicle.rb b/src/app/models/icicle.rb
index 2bad5d9..a086285 100644
--- a/src/app/models/icicle.rb
+++ b/src/app/models/icicle.rb
@@ -12,7 +12,22 @@
#
class Icicle < ActiveRecord::Base
+ include ImageWarehouseObject
+
validates_presence_of :uuid
validates_uniqueness_of :uuid
belongs_to :provider_image
+
+ def self.create_or_update(uuid)
+ icicle = Icicle.find_by_uuid(uuid) || Icicle.new(:uuid => uuid)
+ icicle.warehouse_sync
+ icicle.log_changes
+ icicle.save! if icicle.changed?
+ icicle
+ end
+
+ def warehouse_sync
+ obj = warehouse.bucket('icicles').object(self.uuid)
+ self.xml = obj.body
+ end
end
diff --git a/src/app/models/image.rb b/src/app/models/image.rb
index 7a8aae4..f15f2da 100644
--- a/src/app/models/image.rb
+++ b/src/app/models/image.rb
@@ -79,15 +79,8 @@ class Image < ActiveRecord::Base
# TODO: for now when build is finished we call upload automatically for all providers
def after_update
if self.status_changed? and self.status == STATE_COMPLETED
- # TODO: use after_commit callback in rails 3 - it's better to have it outside
- # update transaction
- begin
- invoke_sync
- upload_to_all_providers_with_account
- rescue => e
- logger.error e.message
- logger.error e.backtrace.join("\n ")
- end
+ safe_warehouse_sync
+ upload_to_all_providers_with_account
end
end
@@ -176,6 +169,31 @@ class Image < ActiveRecord::Base
image
end
+ def warehouse_bucket
+ 'images'
+ end
+
+ def warehouse_sync
+ bucket = warehouse.bucket(warehouse_bucket)
+ raise WarehouseObjectNotFoundError unless bucket.include?(self.uuid)
+ obj = bucket.object(self.uuid)
+ attrs = obj.attrs([:uuid, :target, :template])
+ unless attrs[:target]
+ raise "target uuid is not set"
+ end
+ unless ptype = ProviderType.find_by_codename(attrs[:target])
+ raise "provider type #{attrs[:target]} not found"
+ end
+ unless attrs[:template]
+ raise "template uuid is not set"
+ end
+ unless tpl = Template.find_by_uuid(attrs[:template])
+ raise "Template with uuid #{attrs[:template]} not found"
+ end
+ self.provider_type_id = ptype.id
+ self.template_id = tpl.id
+ end
+
private
def upload_to_all_providers_with_account
diff --git a/src/app/models/image_warehouse_object.rb b/src/app/models/image_warehouse_object.rb
index 40a7c3b..43f3b76 100644
--- a/src/app/models/image_warehouse_object.rb
+++ b/src/app/models/image_warehouse_object.rb
@@ -19,6 +19,8 @@
require 'warehouse_client'
+class WarehouseObjectNotFoundError < Exception;end
+
module ImageWarehouseObject
WAREHOUSE_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/image_warehouse.yml")
@@ -40,32 +42,57 @@ module ImageWarehouseObject
# TODO: it would be nice not call upload, when save was invoked by warehouse
# sync script
def upload
- whouse = Warehouse::Client.new(WAREHOUSE_CONFIG['baseurl'])
# TODO: for now there is no way how it check if bucket exists in warehouse
# so we try to create bucket everytime, if bucket exists, warehouse returns
# 500 Internal server error
- whouse.create_bucket(warehouse_bucket) rescue true
+ warehouse.create_bucket(warehouse_bucket) rescue true
# TODO: we delete existing object if it exists
- whouse.bucket(warehouse_bucket).object(self.uuid).delete! rescue true
- whouse.bucket(warehouse_bucket).create_object(self.uuid, warehouse_body, warehouse_attrs)
+ warehouse.bucket(warehouse_bucket).object(self.uuid).delete! rescue true
+ warehouse.bucket(warehouse_bucket).create_object(self.uuid, warehouse_body, warehouse_attrs)
end
def delete_in_warehouse
- whouse = Warehouse::Client.new(WAREHOUSE_CONFIG['baseurl'])
begin
- whouse.bucket(warehouse_bucket).object(self.uuid).delete!
+ warehouse.bucket(warehouse_bucket).object(self.uuid).delete!
rescue
logger.error "failed to delete #{self.uuid} in warehouse: #{$!}"
end
end
+ def warehouse
+ @warehouse ||= Warehouse::Client.new(WAREHOUSE_CONFIG['baseurl'])
+ end
+
+ def warehouse_url
+ "#{WAREHOUSE_CONFIG['baseurl']}/#{warehouse_bucket}/#{self.uuid}"
+ end
+
+ def safe_warehouse_sync
+ warehouse_sync
+ log_changes
+ rescue RestClient::ResourceNotFound, WarehouseObjectNotFoundError
+ logger.error "Failed to fetch #{self.class.class_name} with uuid #{self.uuid} - not found in warehouse"
+ rescue => e
+ logger.error "Failed to sync #{self.class.class_name} with uuid #{self.uuid}: #{e.message}"
+ logger.error e.backtrace.join("\n ")
+ end
+
+ def log_changes
+ if self.new_record?
+ logger.info "#{self.class.class_name} #{self.uuid} is not in DB yet"
+ elsif self.changed?
+ logger.info "#{self.class.class_name} #{self.uuid} has been changed:"
+ self.changed.each do |attr|
+ logger.info "old #{attr}: #{self.send(attr + '_was')}"
+ logger.info "new #{attr}: #{self[attr]}"
+ end
+ else
+ logger.info "#{self.class.class_name} #{self.uuid} is without changes"
+ end
+ end
+
def generate_uuid
# TODO: generate real uuid here, e.g. with some ruby uuid generator
self.uuid ||= UUIDTools::UUID.timestamp_create.to_s
end
-
- def invoke_sync
- # TODO: invoke warehouse_sync here (after switching to eventmachine)
- # pass self.uuid to sync only changed object
- end
end
diff --git a/src/app/models/provider_image.rb b/src/app/models/provider_image.rb
index 67390dd..aee69a9 100644
--- a/src/app/models/provider_image.rb
+++ b/src/app/models/provider_image.rb
@@ -33,12 +33,31 @@ class ProviderImage < ActiveRecord::Base
def after_update
if self.status_changed? and self.status == STATE_COMPLETED
- begin
- invoke_sync
- rescue => e
- logger.error e.message
- logger.error e.backtrace.join("\n ")
- end
+ safe_warehouse_sync
end
end
+
+ def warehouse_bucket
+ 'provider_images'
+ end
+
+ def warehouse_sync
+ bucket = warehouse.bucket(warehouse_bucket)
+ raise WarehouseObjectNotFoundError unless bucket.include?(self.uuid)
+ obj = bucket.object(self.uuid)
+ attrs = obj.attrs([:uuid, :image, :icicle, :target_identifier])
+ unless attrs[:image]
+ raise "image uuid is not set"
+ end
+ unless img = Image.find_by_uuid(attrs[:image])
+ raise "image with uuid #{attrs[:image]} not found"
+ end
+ begin
+ self.icicle = Icicle.create_or_update(attrs[:icicle])
+ rescue
+ logger.error "Failed to fetch icicle '#{attrs[:icicle]}', setting icicle to nil: #{$!.message}"
+ end
+ self.image_id = img.id
+ self.provider_image_key = attrs[:target_identifier]
+ end
end
diff --git a/src/app/models/template.rb b/src/app/models/template.rb
index 3147e16..1b09dae 100644
--- a/src/app/models/template.rb
+++ b/src/app/models/template.rb
@@ -78,9 +78,11 @@ class Template < ActiveRecord::Base
def update_from_xml
self.name = xml.name
self.summary = xml.description
- self.platform = xml.platform
- self.platform_version = xml.platform_version
- self.architecture = xml.architecture
+ self.platform_hash = {
+ :platform => xml.platform,
+ :version => xml.platform_version,
+ :architecture => xml.architecture,
+ }
end
def providers
@@ -157,8 +159,9 @@ class Template < ActiveRecord::Base
'templates'
end
- def warehouse_url
- baseurl = YAML.load_file("#{RAILS_ROOT}/config/image_warehouse.yml")['baseurl'] + "/templates/"
- self.uuid ? baseurl + self.uuid : baseurl
+ def warehouse_sync
+ obj = warehouse.bucket(warehouse_bucket).object(self.uuid)
+ xml = obj.body
+ update_from_xml
end
end
diff --git a/src/app/util/image_descriptor_xml.rb b/src/app/util/image_descriptor_xml.rb
index 8476770..02634b2 100644
--- a/src/app/util/image_descriptor_xml.rb
+++ b/src/app/util/image_descriptor_xml.rb
@@ -52,8 +52,7 @@ class ImageDescriptorXML
end
def platform
- node = @root.at_xpath('/template/os')
- return node ? node['name'] : nil
+ return get_node_text('os/name')
end
def platform=(platform_hash)
@@ -80,17 +79,16 @@ class ImageDescriptorXML
end
def platform_version
- node = @root.at_xpath('/image/os/version')
- return node ? node.content : nil
+ return get_node_text('os/version')
end
def architecture
- node = @root.at_xpath('/template/os/arch')
- return node ? node.content : nil
+ return get_node_text('os/arch')
end
def architecture=(str)
- get_or_create_node('os')['architecture'] = str
+ node = get_or_create_node('arch', get_or_create_node('os'))
+ node.content = str
end
def services=(services)
diff --git a/src/lib/warehouse_client.rb b/src/lib/warehouse_client.rb
index 9431e47..12b8d9d 100644
--- a/src/lib/warehouse_client.rb
+++ b/src/lib/warehouse_client.rb
@@ -99,6 +99,10 @@ module Warehouse
def create_object(key, body, attrs)
BucketObject.create(@connection, key, self, body, attrs)
end
+
+ def include?(key)
+ object_names.include?(key)
+ end
end
class Connection
diff --git a/src/warehouse_sync/warehouse_sync-server b/src/warehouse_sync/warehouse_sync-server
index 7fc15f5..603a520 100755
--- a/src/warehouse_sync/warehouse_sync-server
+++ b/src/warehouse_sync/warehouse_sync-server
@@ -61,7 +61,7 @@ else
end
logger = Logger.new(LOG_FILE)
-logger.level = Logger::DEBUG
+logger.level = Logger::INFO
logger.datetime_format = "%Y-%m-%d %H:%M:%S"
logger.info "Warehouse_sync starting up"
diff --git a/src/warehouse_sync/warehouse_sync.rb b/src/warehouse_sync/warehouse_sync.rb
index f18c1e9..5868db9 100644
--- a/src/warehouse_sync/warehouse_sync.rb
+++ b/src/warehouse_sync/warehouse_sync.rb
@@ -11,143 +11,38 @@ class WarehouseSync
@uri = opts[:uri]
@delay = opts[:delay] || 10*60
@logger = opts[:logger]
+ ActiveRecord::Base.logger = @logger
@whouse = Warehouse::Client.new(@uri)
end
def run
while true
begin
- @logger.debug "---------------------------------------"
- pull_templates
- pull_images
- pull_provider_images
+ @logger.info "***** Runnning warehouse sync"
+ # TODO: I disabled template sync - templates should never
+ # be changed by anything else than conductor
+ #(a)logger.info "*** syncing templates"
+ #Template.all.each do |i|
+ # i.safe_warehouse_sync
+ # i.save! if i.changed?
+ #end
+ @logger.info "*** syncing images"
+ Image.all.each do |i|
+ i.safe_warehouse_sync
+ i.save! if i.changed?
+ end
+ @logger.info "*** syncing provider images"
+ ProviderImage.all.each do |i|
+ i.safe_warehouse_sync
+ i.save! if i.changed?
+ end
rescue => e
@logger.error e.message
@logger.error "backtrace:\n" + e.backtrace.join("\n ")
ensure
- @logger.debug "sleep #{@delay}"
+ @logger.info "sleep #{@delay}"
sleep @delay
end
end
end
-
- def pull_templates
- @logger.debug "*** Getting templates"
- @whouse.bucket('templates').objects.each do |bucket_obj|
- safely_process(bucket_obj) do |obj|
- attrs = obj.attrs([:uuid])
- #tpl = Template.find_by_uuid(attrs[:uuid]) || Template.new(:uuid => attrs[:uuid])
- unless tpl = Template.find_by_uuid(attrs[:uuid])
- raise NotFoundError, "Template with uuid #{attrs[:uuid]} not found"
- end
- tpl.xml = obj.body
- tpl.update_from_xml
- update_changes(tpl)
- end
- end
- end
-
- def pull_images
- @logger.debug "*** Getting images"
- @whouse.bucket('images').objects.each do |bucket_obj|
- safely_process(bucket_obj) do |obj|
- attrs = obj.attrs([:uuid, :target, :template])
- #img = Image.find_by_uuid(attrs[:uuid]) || Image.new(:uuid => attrs[:uuid])
- unless img = Image.find_by_uuid(attrs[:uuid])
- raise NotFoundError, "image with uuid #{attrs[:uuid]} not found"
- end
- unless attrs[:target]
- raise "target uuid is not set"
- end
- unless ptype = ProviderType.find_by_codename(attrs[:target])
- raise "provider type #{attrs[:target]} not found"
- end
- unless attrs[:template]
- raise "template uuid is not set"
- end
- unless tpl = Template.find_by_uuid(attrs[:template])
- raise "Template with uuid #{attrs[:template]} not found"
- end
- img.provider_type_id = ptype.id
- img.template_id = tpl.id
- update_changes(img)
- end
- end
- end
-
- def pull_provider_images
- @logger.debug "*** Getting provider images"
- @whouse.bucket('provider_images').objects.each do |bucket_obj|
- safely_process(bucket_obj) do |obj|
- attrs = obj.attrs([:uuid, :image, :icicle, :target_identifier])
- # we don't allow create non-existing ProviderImage in conductor because
- # we don't know provider_id (provider attribute contains only url or
- # string which is not unique in conductor)
- unless pimg = ProviderImage.find_by_uuid(attrs[:uuid])
- raise NotFoundError, "provider image with uuid #{attrs[:uuid]} not found"
- end
- unless attrs[:image]
- raise "image uuid is not set"
- end
- unless img = Image.find_by_uuid(attrs[:image])
- raise "image with uuid #{attrs[:image]} not found"
- end
- unless attrs[:icicle]
- raise "icicle uuid is not set"
- end
- pimg.image_id = img.id
- pimg.icicle = pull_provider_image_icicle(attrs[:icicle])
- pimg.provider_image_key = attrs[:target_identifier]
- update_changes(pimg)
- end
- end
- end
-
- private
-
- def pull_provider_image_icicle(uuid)
- @logger.debug " getting provider image icicle with uuid #{uuid}"
- begin
- whouse_icicle = @whouse.bucket('icicles').object(uuid)
- icicle = Icicle.find_by_uuid(uuid) || Icicle.new(:uuid => uuid)
- icicle.xml = whouse_icicle.body
- icicle.uuid = uuid
- update_changes(icicle)
- icicle
- rescue
- @logger.debug " skipping image icicle with uuid #{uuid}: #{$!.message}"
- nil
- end
- end
-
- def safely_process(obj)
- begin
- yield obj
- rescue NotFoundError => e
- @logger.error "Skipping #{obj.key} - not found in DB"
- rescue => e
- @logger.error "Error while processing #{obj.key} (skipping): #{e.message}"
- @logger.error e.backtrace.join("\n ")
- end
- end
-
- def update_changes(obj)
- if obj.new_record?
- @logger.debug "#{obj.class.class_name} #{obj.uuid} is not in DB, saving"
- obj.save!
- elsif obj.changed?
- @logger.debug "#{obj.class.class_name} #{obj.uuid} has been changed:"
- log_changes(obj)
- obj.save!
- else
- @logger.debug "#{obj.class.class_name} #{obj.uuid} is without changes"
- end
- end
-
- def log_changes(obj)
- obj.changed.each do |attr|
- @logger.debug "old #{attr}: #{obj.send(attr + '_was')}"
- @logger.debug "new #{attr}: #{obj[attr]}"
- end
- end
end
--
1.7.4
12 years, 8 months
[PATCH] Trivial fix in Template test step
by Matt Wagner
---
src/features/step_definitions/template_steps.rb | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/features/step_definitions/template_steps.rb b/src/features/step_definitions/template_steps.rb
index 3136425..0e78a47 100644
--- a/src/features/step_definitions/template_steps.rb
+++ b/src/features/step_definitions/template_steps.rb
@@ -115,7 +115,7 @@ Given /^there is an imported template$/ do
end
Given /^has package "([^"]*)"$/ do |arg1|
- @template.add_packages [:arg1]
+ @template.add_packages [arg1]
end
When /^I edit the template$/ do
--
1.7.4
12 years, 8 months
[PATCH conductor] BZ 684088 - Prevent default pool from being deleted by renaming v2
by Richard Su
https://bugzilla.redhat.com/show_bug.cgi?id=684088
---
src/app/controllers/resources/pools_controller.rb | 2 +-
src/features/pool.feature | 14 +++++++++++---
src/features/step_definitions/pool_steps.rb | 10 ++++++----
3 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/src/app/controllers/resources/pools_controller.rb b/src/app/controllers/resources/pools_controller.rb
index 3a927f1..337a1b8 100644
--- a/src/app/controllers/resources/pools_controller.rb
+++ b/src/app/controllers/resources/pools_controller.rb
@@ -77,7 +77,7 @@ class Resources::PoolsController < ApplicationController
# FIXME: remove this check when pools can be assigned to new users
# default_pool cannot be deleted because metadata object has it tied
# to id of 1 and deleting it prevents new users from being created
- if pool.name == "default_pool"
+ if pool.id == MetadataObject.lookup("self_service_default_pool").id
flash[:notice] = "The default pool cannot be deleted"
else
pool.destroy if check_privilege(Privilege::MODIFY, pool)
diff --git a/src/features/pool.feature b/src/features/pool.feature
index 864357b..75cb1c3 100644
--- a/src/features/pool.feature
+++ b/src/features/pool.feature
@@ -42,15 +42,15 @@ Feature: Manage Pools
Then I should see "Name must only contain: numbers, letters, spaces, '_' and '-'"
Scenario: Delete pools
- Given there are no pools
+ Given I am on the pools page
And a pool "Amazon Startrek Pool" exists
And a pool "Redhat Voyager Pool" exists
And I am on the resources pools page
- And there are 2 pools
+ And there are 3 pools
When I check "Redhat Voyager Pool" pool
And I check "Amazon Startrek Pool" pool
And I press "Destroy"
- Then there should only be 0 pools
+ Then there should only be 1 pools
And I should be on the resources pools page
And I should not see "Redhat Voyager Pool"
And I should not see "Amazon Startrek Pool"
@@ -86,3 +86,11 @@ Feature: Manage Pools
And I press "Destroy"
Then I should see "The default pool cannot be deleted"
And I should see "default_pool"
+
+ Scenario: Cannot delete default_pool by renaming it
+ Given I renamed default_pool to pool_default
+ Given I am on the pools page
+ When I check "pool_default" pool
+ And I press "Destroy"
+ Then I should see "The default pool cannot be deleted"
+ And I should see "pool_default"
diff --git a/src/features/step_definitions/pool_steps.rb b/src/features/step_definitions/pool_steps.rb
index 689bd47..5fd48c1 100644
--- a/src/features/step_definitions/pool_steps.rb
+++ b/src/features/step_definitions/pool_steps.rb
@@ -8,10 +8,6 @@ Given /^I have Pool Creator permissions on a pool named "([^\"]*)"$/ do |name|
Factory(:pool_creator_permission, :user => @user, :permission_object => @pool)
end
-Given /^there are no pools$/ do
- Pool.delete_all
-end
-
Given /^there are (\d+) pools$/ do |number|
Pool.count.should == number.to_i
end
@@ -59,3 +55,9 @@ Given /^the "([^\"]*)" Pool has a quota with following capacities:$/ do |name,ta
@pool.quota_id = @quota.id
@pool.save
end
+
+Given /^I renamed default_pool to pool_default$/ do
+ p = Pool.find_by_name("default_pool")
+ p.name = "pool_default"
+ p.save
+end
--
1.7.4
12 years, 8 months
#690 Credentials model for provider account (rev.2)
by jzigmund@redhat.com
This patchset contains subtasks:
#691 - Build credential model to support any provider,
#693 - Update the generate_credentials method,
#692 - Surface new creds model in 'add account form
12 years, 8 months
[PATCH] Fix Template XML generation
by Matt Wagner
Modifies the XML generated for packages in a template to conform
to what ImageFactory 2 expects.
---
src/app/util/image_descriptor_xml.rb | 14 ++++++--------
1 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/src/app/util/image_descriptor_xml.rb b/src/app/util/image_descriptor_xml.rb
index 3a4bbae..8476770 100644
--- a/src/app/util/image_descriptor_xml.rb
+++ b/src/app/util/image_descriptor_xml.rb
@@ -130,13 +130,13 @@ class ImageDescriptorXML
def packages
@root.xpath('/template/packages/package').map do |s|
- s.at_xpath('.//name').text
+ s.attr('name').to_s
end
end
def groups
@root.xpath('/template/groups/group').map do |s|
- s.at_xpath('.//name').text
+ s.attr('name').to_s
end
end
@@ -177,9 +177,8 @@ class ImageDescriptorXML
def add_group_node(parent, group)
pnode = get_or_create_node('group', parent)
- n = Nokogiri::XML::Node.new('name', @doc)
- n.content = name
- pnode << n
+ pnode['name'] = group
+ pnode
end
def recreate_repo_nodes
@@ -206,9 +205,8 @@ class ImageDescriptorXML
def add_package_node(parent, name)
pnode = get_or_create_node('package', parent)
- n = Nokogiri::XML::Node.new('name', @doc)
- n.content = name
- pnode << n
+ pnode['name'] = name
+ pnode
end
def repository_manager
--
1.7.4
12 years, 8 months
[PATCH aeolus] BZ#676654 Add error handling for record not found exceptions
by Martyn Taylor
From: Martyn Taylor <mtaylor(a)redhat.com>
---
src/app/controllers/application_controller.rb | 6 +++++
src/features/error_handling.feature | 21 ++++++++++++++++++++
.../step_definitions/error_handling_steps.rb | 4 +++
3 files changed, 31 insertions(+), 0 deletions(-)
create mode 100644 src/features/error_handling.feature
create mode 100644 src/features/step_definitions/error_handling_steps.rb
diff --git a/src/app/controllers/application_controller.rb b/src/app/controllers/application_controller.rb
index a720939..380cfac 100644
--- a/src/app/controllers/application_controller.rb
+++ b/src/app/controllers/application_controller.rb
@@ -35,6 +35,7 @@ class ApplicationController < ActionController::Base
rescue_from PermissionError, :with => :handle_perm_error
rescue_from ActionError, :with => :handle_action_error
rescue_from PartialSuccessError, :with => :handle_partial_success_error
+ rescue_from ActiveRecord::RecordNotFound, :with => :handle_active_record_not_found_error
helper_method :check_privilege
@@ -136,6 +137,11 @@ class ApplicationController < ActionController::Base
end
end
+ def handle_active_record_not_found_error(error)
+ redirect_to :back
+ flash[:notice] = "The record you tried to access does not exist, it may have been deleted"
+ end
+
private
def json_error_hash(msg, status)
json = {}
diff --git a/src/features/error_handling.feature b/src/features/error_handling.feature
new file mode 100644
index 0000000..bc5d171
--- /dev/null
+++ b/src/features/error_handling.feature
@@ -0,0 +1,21 @@
+Feature: Error Handling
+ In order to order to perform operations upon site objects
+ As a user
+ I must be able to correctly view any object errors
+
+ Background:
+ Given I am an authorised user
+ And I am logged in
+
+ @allow-rescue
+ Scenario: Display Record Not Found error for a deleted object
+ Given there are the following conductor hardware profiles:
+ | name | memory | cpu |storage | architecture |
+ | m1-small | 1740 | 2 | 160 | i386 |
+ | m1-large | 4096 | 4 | 850 | x86_64 |
+ | m1-xlarge | 8192 | 8 | 1690 | x86_64 |
+ And I am on the hardware profiles page
+ When another user deletes hardware profile "m1-small"
+ And I follow "m1-small"
+ Then I should be on the hardware profiles page
+ And I should see "The record you tried to access does not exist, it may have been deleted"
\ No newline at end of file
diff --git a/src/features/step_definitions/error_handling_steps.rb b/src/features/step_definitions/error_handling_steps.rb
new file mode 100644
index 0000000..6889de0
--- /dev/null
+++ b/src/features/step_definitions/error_handling_steps.rb
@@ -0,0 +1,4 @@
+When /^another user deletes hardware profile "([^"]*)"$/ do |name|
+ hwp = HardwareProfile.find_by_name(name)
+ hwp.delete
+end
\ No newline at end of file
--
1.7.4
12 years, 8 months