diff --git a/include/Image.h b/include/Image.h index 64f249e701..538721b443 100644 --- a/include/Image.h +++ b/include/Image.h @@ -322,9 +322,20 @@ public: return cloning_ops; } - int dec_cloning(int img_id) + int dec_cloning(PoolObjectSQL::ObjectType ot, int oid) { - if ( img_clone_collection.del(img_id) == 0 ) + int rc = -1; + + if (ot == PoolObjectSQL::IMAGE) + { + rc = img_clone_collection.del(oid); + } + else //if (ot == PoolObjectSQL::MARKETPLACEAPP) + { + rc = app_clone_collection.del(oid); + } + + if ( rc == 0 ) { cloning_ops--; } @@ -332,9 +343,20 @@ public: return cloning_ops; } - int inc_cloning(int img_id) + int inc_cloning(PoolObjectSQL::ObjectType ot, int oid) { - if ( img_clone_collection.add(img_id) == 0 ) + int rc = -1; + + if (ot == PoolObjectSQL::IMAGE) + { + rc = img_clone_collection.add(oid); + } + else //if (ot == PoolObjectSQL::MARKETPLACEAPP) + { + rc = app_clone_collection.add(oid); + } + + if ( rc == 0 ) { cloning_ops++; } @@ -581,7 +603,7 @@ private: int running_vms; /** - * Number of pending cloning operations + * Number of pending cloning operations, for both images and apps */ int cloning_ops; @@ -611,6 +633,11 @@ private: */ ObjectCollection img_clone_collection; + /** + * Stores a collection with the Marketplace apps cloning this image + */ + ObjectCollection app_clone_collection; + /** * Snapshot list for this image */ diff --git a/include/ImageManager.h b/include/ImageManager.h index 0ac1f9c746..f0c7c1d3c9 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -116,9 +116,30 @@ public: /** * Closes any cloning operation on the image, updating the state if needed * @param iid image id of the image to that was being cloned - * @param clone_img_id the cloned image (id > 0) or market app (id =< 0) + * @param ot Object type, image or market app + * @param clone_oid the cloned resource id */ - void release_cloning_image(int iid, int clone_img_id); + void release_cloning_resource(int iid, PoolObjectSQL::ObjectType ot, int clone_oid); + + /** + * Closes any cloning operation on the image, updating the state if needed + * @param iid image id of the image to that was being cloned + * @param clone_img_id the cloned image id + */ + void release_cloning_image(int iid, int clone_img_id) + { + release_cloning_resource(iid, PoolObjectSQL::IMAGE, clone_img_id); + }; + + /** + * Closes any cloning operation on the image, updating the state if needed + * @param iid image id of the image to that was being cloned + * @param clone_oid the cloned marketplace app id + */ + void release_cloning_app(int iid, int clone_oid) + { + release_cloning_resource(iid, PoolObjectSQL::MARKETPLACEAPP, clone_oid); + }; /** * Enables the image @@ -155,12 +176,38 @@ public: /** * Sets the state to CLONE for the given image - * @param new_id for the target image (new_id>0) or market app (new_id =<0) + * @param ot Object type, image or market app + * @param new_id for the target image or market app * @param clonning_id the ID of the image to be cloned * @param error if any - * @return 0 if siccess + * @return 0 on success */ - int set_clone_state(int new_id, int cloning_id, std::string& error); + int set_clone_state(PoolObjectSQL::ObjectType ot, int new_id, + int cloning_id, std::string& error); + + /** + * Sets the state to CLONE for the given image + * @param new_id for the target image + * @param clonning_id the ID of the image to be cloned + * @param error if any + * @return 0 on success + */ + int set_img_clone_state(int new_id, int cloning_id, std::string& error) + { + return set_clone_state(PoolObjectSQL::IMAGE, new_id, cloning_id, error); + }; + + /** + * Sets the state to CLONE for the given image + * @param new_id for the target market app + * @param clonning_id the ID of the image to be cloned + * @param error if any + * @return 0 on success + */ + int set_app_clone_state(int new_id, int cloning_id, std::string& error) + { + return set_clone_state(PoolObjectSQL::MARKETPLACEAPP, new_id, cloning_id, error); + }; /** * Clone an existing image to the repository diff --git a/share/doc/xsd/image.xsd b/share/doc/xsd/image.xsd index a1696c031c..dcd46ecf7e 100644 --- a/share/doc/xsd/image.xsd +++ b/share/doc/xsd/image.xsd @@ -65,6 +65,13 @@ + + + + + + + diff --git a/src/image/Image.cc b/src/image/Image.cc index 47c3eff1d3..30f167d3d3 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -57,6 +57,7 @@ Image::Image(int _uid, ds_name(""), vm_collection("VMS"), img_clone_collection("CLONES"), + app_clone_collection("APP_CLONES"), snapshots(-1), target_snapshot(-1) { @@ -337,6 +338,7 @@ string& Image::to_xml(string& xml) const ostringstream oss; string vm_collection_xml; string clone_collection_xml; + string app_clone_collection_xml; string snapshots_xml; oss << @@ -365,6 +367,7 @@ string& Image::to_xml(string& xml) const "" << ds_name << "" << vm_collection.to_xml(vm_collection_xml) << img_clone_collection.to_xml(clone_collection_xml) << + app_clone_collection.to_xml(app_clone_collection_xml) << obj_template->to_xml(template_xml) << snapshots.to_xml(snapshots_xml) << ""; @@ -468,6 +471,19 @@ int Image::from_xml(const string& xml) content.clear(); + ObjectXML::get_nodes("/IMAGE/APP_CLONES", content); + + if (content.empty()) + { + return -1; + } + + rc += app_clone_collection.from_xml_node(content[0]); + + ObjectXML::free_nodes(content); + + content.clear(); + ObjectXML::get_nodes("/IMAGE/SNAPSHOTS", content); if (!content.empty()) diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 25bf7d2c30..bab51b0eda 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -243,7 +243,8 @@ void ImageManager::release_image(int vm_id, int iid, bool failed) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void ImageManager::release_cloning_image(int iid, int clone_img_id) +void ImageManager::release_cloning_resource( + int iid, PoolObjectSQL::ObjectType ot, int clone_oid) { Image * img = ipool->get(iid,true); @@ -272,7 +273,7 @@ void ImageManager::release_cloning_image(int iid, int clone_img_id) { case Image::USED: case Image::CLONE: - if (img->dec_cloning(clone_img_id) == 0 && img->get_running() == 0) + if (img->dec_cloning(ot, clone_oid) == 0 && img->get_running() == 0) { img->set_state(Image::READY); } @@ -602,7 +603,8 @@ int ImageManager::can_clone_image(int cloning_id, ostringstream& oss_error) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int ImageManager::set_clone_state(int new_id, int cloning_id, std::string& error) +int ImageManager::set_clone_state( + PoolObjectSQL::ObjectType ot, int new_id, int cloning_id, string& error) { int rc = 0; Image * img = ipool->get(cloning_id, true); @@ -616,7 +618,7 @@ int ImageManager::set_clone_state(int new_id, int cloning_id, std::string& error switch(img->get_state()) { case Image::READY: - img->inc_cloning(new_id); + img->inc_cloning(ot, new_id); if (img->is_persistent()) { @@ -632,7 +634,7 @@ int ImageManager::set_clone_state(int new_id, int cloning_id, std::string& error case Image::USED: case Image::CLONE: - img->inc_cloning(new_id); + img->inc_cloning(ot, new_id); ipool->update(img); break; @@ -678,7 +680,7 @@ int ImageManager::clone_image(int new_id, return -1; } - if ( set_clone_state(new_id, cloning_id, error) == -1 ) + if ( set_img_clone_state(new_id, cloning_id, error) == -1 ) { return -1; } diff --git a/src/market/MarketPlaceManagerActions.cc b/src/market/MarketPlaceManagerActions.cc index 25e6714803..5bc6a3b048 100644 --- a/src/market/MarketPlaceManagerActions.cc +++ b/src/market/MarketPlaceManagerActions.cc @@ -97,7 +97,7 @@ int MarketPlaceManager::import_app( ds->unlock(); - if (imagem->set_clone_state(-app_id, origin_id, err) != 0) + if (imagem->set_app_clone_state(app_id, origin_id, err) != 0) { return -1; } @@ -140,7 +140,7 @@ void MarketPlaceManager::release_app_resources(int appid) switch (type) { case MarketPlaceApp::IMAGE: - imagem->release_cloning_image(iid, -appid); + imagem->release_cloning_app(iid, appid); return; case MarketPlaceApp::VMTEMPLATE: diff --git a/src/onedb/local/4.13.85_to_4.90.0.rb b/src/onedb/local/4.13.85_to_4.90.0.rb index a41a6cab0a..b3bfe27aae 100644 --- a/src/onedb/local/4.13.85_to_4.90.0.rb +++ b/src/onedb/local/4.13.85_to_4.90.0.rb @@ -161,6 +161,32 @@ module Migrator log_time() + @db.run "ALTER TABLE image_pool RENAME TO old_image_pool;" + @db.run "CREATE TABLE image_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name,uid) );" + + @db.transaction do + @db.fetch("SELECT * FROM old_image_pool") do |row| + doc = Nokogiri::XML(row[:body],nil,NOKOGIRI_ENCODING){|c| c.default_xml.noblanks} + + doc.at_xpath("/IMAGE/TEMPLATE").add_child(doc.create_element("APP_CLONES")) + + @db[:image_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + end + + + @db.run "DROP TABLE old_image_pool;" + + log_time() + return true end