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