mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-20 10:50:08 +03:00
Merge branch 'feature-3782'
This commit is contained in:
commit
6cb6eea178
@ -97,16 +97,16 @@ public:
|
||||
{
|
||||
switch (ob)
|
||||
{
|
||||
case FILE: return "FILE" ; break;
|
||||
case CD_ROM: return "CDROM" ; break;
|
||||
case BLOCK: return "BLOCK" ; break;
|
||||
case RBD: return "RBD" ; break;
|
||||
case RBD_CDROM: return "RBD_CDROM" ; break;
|
||||
case GLUSTER: return "GLUSTER" ; break;
|
||||
case GLUSTER_CDROM: return "GLUSTER_CDROM" ; break;
|
||||
case SHEEPDOG: return "SHEEPDOG" ; break;
|
||||
case SHEEPDOG_CDROM: return "SHEEPDOG_CDROM" ; break;
|
||||
default: return "";
|
||||
case FILE: return "FILE" ; break;
|
||||
case CD_ROM: return "CDROM" ; break;
|
||||
case BLOCK: return "BLOCK" ; break;
|
||||
case RBD: return "RBD" ; break;
|
||||
case RBD_CDROM: return "RBD_CDROM" ; break;
|
||||
case GLUSTER: return "GLUSTER" ; break;
|
||||
case GLUSTER_CDROM: return "GLUSTER_CDROM" ; break;
|
||||
case SHEEPDOG: return "SHEEPDOG" ; break;
|
||||
case SHEEPDOG_CDROM: return "SHEEPDOG_CDROM" ; break;
|
||||
default: return "";
|
||||
}
|
||||
};
|
||||
|
||||
@ -178,7 +178,7 @@ public:
|
||||
* Returns true if the image is persistent
|
||||
* @return true if the image is persistent
|
||||
*/
|
||||
bool isPersistent() const
|
||||
bool is_persistent() const
|
||||
{
|
||||
return (persistent_img == 1);
|
||||
};
|
||||
@ -348,35 +348,13 @@ public:
|
||||
*/
|
||||
int set_type(string& _type, string& error);
|
||||
|
||||
/**
|
||||
* Check if the image can be used by other users
|
||||
* @return true if group or others can access the image
|
||||
*/
|
||||
bool isPublic()
|
||||
{
|
||||
return (group_u == 1 || other_u == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the image is used for saving_as a current one
|
||||
* @return true if the image will be used to save an existing image.
|
||||
*/
|
||||
bool isSaving()
|
||||
bool is_saving()
|
||||
{
|
||||
ImageTemplate * it = static_cast<ImageTemplate *>(obj_template);
|
||||
|
||||
return it->is_saving();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the image is a hot snapshot
|
||||
* @return true if image is a hot snapshot
|
||||
*/
|
||||
bool isHot()
|
||||
{
|
||||
ImageTemplate * it = static_cast<ImageTemplate *>(obj_template);
|
||||
|
||||
return it->is_saving_hot();
|
||||
return (static_cast<ImageTemplate *>(obj_template))->is_saving();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,43 +61,16 @@ public:
|
||||
|
||||
bool is_saving()
|
||||
{
|
||||
string saving;
|
||||
bool save_as_hot;
|
||||
|
||||
get(saving_attribute, saving);
|
||||
get("SAVE_AS_HOT", save_as_hot);
|
||||
|
||||
return (saving.empty() == false);
|
||||
}
|
||||
|
||||
bool is_saving_hot()
|
||||
{
|
||||
string save_as_hot;
|
||||
|
||||
get(saving_hot_attribute, save_as_hot);
|
||||
|
||||
return (save_as_hot.empty() == false);
|
||||
return save_as_hot;
|
||||
}
|
||||
|
||||
void set_saving()
|
||||
{
|
||||
SingleAttribute * attr= new SingleAttribute(saving_attribute, "YES");
|
||||
|
||||
erase(saving_attribute);
|
||||
|
||||
set(attr);
|
||||
}
|
||||
|
||||
void set_saving_hot()
|
||||
{
|
||||
SingleAttribute * attr = new SingleAttribute(saving_hot_attribute,"YES");
|
||||
|
||||
erase(saving_hot_attribute);
|
||||
|
||||
set(attr);
|
||||
}
|
||||
|
||||
void unset_saving()
|
||||
{
|
||||
erase(saving_attribute);
|
||||
replace("SAVE_AS_HOT", "YES");
|
||||
}
|
||||
|
||||
private:
|
||||
@ -105,9 +78,6 @@ private:
|
||||
|
||||
static vector<string> restricted_attributes;
|
||||
|
||||
static string saving_attribute;
|
||||
static string saving_hot_attribute;
|
||||
|
||||
bool has_restricted()
|
||||
{
|
||||
return restricted_attributes.size() > 0;
|
||||
|
@ -75,8 +75,8 @@ public:
|
||||
DETACH_NIC_FAILURE,/**< Sent by the VMM when a detach nic action fails */
|
||||
CLEANUP_SUCCESS, /**< Sent by the VMM when a cleanup action succeeds */
|
||||
CLEANUP_FAILURE, /**< Sent by the VMM when a cleanup action fails */
|
||||
SAVEAS_HOT_SUCCESS,/**< Sent by the VMM when hot saveas succeeds */
|
||||
SAVEAS_HOT_FAILURE,/**< Sent by the VMM when hot saveas fails */
|
||||
SAVEAS_SUCCESS, /**< Sent by the VMM when saveas succeeds */
|
||||
SAVEAS_FAILURE, /**< Sent by the VMM when saveas fails */
|
||||
SNAPSHOT_CREATE_SUCCESS, /**< Sent by the VMM on snap. create success */
|
||||
SNAPSHOT_CREATE_FAILURE, /**< Sent by the VMM on snap. create failure */
|
||||
SNAPSHOT_REVERT_SUCCESS, /**< Sent by the VMM on snap. revert success */
|
||||
@ -252,9 +252,9 @@ private:
|
||||
|
||||
void detach_failure_action(int vid);
|
||||
|
||||
void saveas_hot_success_action(int vid);
|
||||
void saveas_success_action(int vid);
|
||||
|
||||
void saveas_hot_failure_action(int vid);
|
||||
void saveas_failure_action(int vid);
|
||||
|
||||
void attach_nic_success_action(int vid);
|
||||
|
||||
|
@ -170,32 +170,15 @@ public:
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class VirtualMachineSaveDisk : public RequestManagerVirtualMachine
|
||||
class VirtualMachineDiskSaveas : public RequestManagerVirtualMachine
|
||||
{
|
||||
public:
|
||||
VirtualMachineSaveDisk():
|
||||
RequestManagerVirtualMachine("VirtualMachineSaveDisk",
|
||||
"Saves a disk from virtual machine as a new image",
|
||||
"A:siissb"){};
|
||||
VirtualMachineDiskSaveas():
|
||||
RequestManagerVirtualMachine("VirtualMachineDiskSaveas",
|
||||
"Save a disk from virtual machine as a new image",
|
||||
"A:siissi"){};
|
||||
|
||||
~VirtualMachineSaveDisk(){};
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att);
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class VirtualMachineSaveDiskCancel : public RequestManagerVirtualMachine
|
||||
{
|
||||
public:
|
||||
VirtualMachineSaveDiskCancel():
|
||||
RequestManagerVirtualMachine("VirtualMachineSaveDiskCancel",
|
||||
"Cancels a disk snapshot set by VirtualMachineSaveDisk",
|
||||
"A:sii"){};
|
||||
|
||||
~VirtualMachineSaveDiskCancel(){};
|
||||
~VirtualMachineDiskSaveas(){};
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att);
|
||||
|
@ -1270,82 +1270,56 @@ public:
|
||||
int generate_context(string &files, int &disk_id, string& token_password);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Datastore related functions
|
||||
// "Save as" Disk related functions (save_as hot)
|
||||
// -------------------------------------------------------------------------
|
||||
/**
|
||||
* Gest the associated image to the given disk_id
|
||||
* Mark the disk that is going to be "save as"
|
||||
* @param disk_id of the VM
|
||||
* @param hot is this a save_as hot operation
|
||||
* @param snap_id of the disk to save, -1 to select the active snapshot
|
||||
* @param err_str describing the error
|
||||
* @return -1 if the image cannot saveas
|
||||
* @return -1 if the image cannot saveas or image_id of current disk
|
||||
*/
|
||||
int get_image_from_disk(int disk_id, bool hot, string& err_str);
|
||||
int set_saveas_disk(int disk_id, int snap_id, string& err_str);
|
||||
|
||||
/**
|
||||
* Sets the corresponding SAVE_AS state.
|
||||
* Set save attributes for the disk
|
||||
* @param disk_id Index of the disk to save
|
||||
* @param hot is this a save_as hot operation
|
||||
* @return 0 if the VM can be saved as
|
||||
* @param source to save the disk
|
||||
* @param img_id ID of the image this disk will be saved to
|
||||
*/
|
||||
int set_saveas_state(int disk_id, bool hot);
|
||||
int set_saveas_disk(int disk_id, const string& source, int img_id);
|
||||
|
||||
/**
|
||||
* Clears the SAVE_AS state, moving the VM to the original state.
|
||||
* @param disk_id Index of the disk to save
|
||||
* @param hot is this a save_as hot operation
|
||||
* @return 0 if the VM was in a SAVE_AS state
|
||||
* Sets the corresponding state to save the disk.
|
||||
* @return 0 if the VM can be saved
|
||||
*/
|
||||
int clear_saveas_state(int disk_id, bool hot);
|
||||
int set_saveas_state();
|
||||
|
||||
/**
|
||||
* Set the SAVE_AS attribute for the "disk_id"th disk.
|
||||
* @param disk_id Index of the disk to save
|
||||
* @param source to save the disk (SAVE_AS_SOURCE)
|
||||
* @param img_id ID of the image this disk will be saved to (SAVE_AS).
|
||||
* Clears the save state, moving the VM to the original state.
|
||||
* @return 0 if the VM was in an saveas state
|
||||
*/
|
||||
int save_disk(int disk_id,
|
||||
const string& source,
|
||||
int img_id);
|
||||
/**
|
||||
* Clears the SAVE_AS attribute for the "disk_id"th disk.
|
||||
* @param disk_id Index of the disk to save
|
||||
* @return 0 on success, -1 if the disk does not exist
|
||||
*/
|
||||
int clear_save_disk(int disk_id);
|
||||
int clear_saveas_state();
|
||||
|
||||
/**
|
||||
* Returns the image ID to be saved-as.
|
||||
* @param disk_id Index of the disk to save
|
||||
* @return The image ID, or -1 if the disk is not going to be saved-as
|
||||
* Clears the SAVE_AS_* attributes of the disk being saved as
|
||||
* @return the ID of the image this disk will be saved to or -1 if it
|
||||
* is not found.
|
||||
*/
|
||||
int get_save_disk_image(int disk_id);
|
||||
int clear_saveas_disk();
|
||||
|
||||
/**
|
||||
* Set the SAVE_AS attribute for the "disk_id"th disk.
|
||||
* @param disk_id Index of the disk to save
|
||||
* @param source to save the disk (SAVE_AS_SOURCE)
|
||||
* @param img_id ID of the image this disk will be saved to (SAVE_AS).
|
||||
*/
|
||||
int save_disk_hot(int disk_id,
|
||||
const string& source,
|
||||
int img_id);
|
||||
/**
|
||||
* Get the original image id of the disk. It also checks that the disk can
|
||||
* be saved_as.
|
||||
* @param disk_id Index of the disk to save
|
||||
* @param error_str describes the error
|
||||
* @param source of the image to save the disk to
|
||||
* @param image_id of the image to save the disk to
|
||||
* @param tm_mad in use by the disk
|
||||
* @param ds_id of the datastore in use by the disk
|
||||
* @return -1 if failure
|
||||
*/
|
||||
int get_saveas_disk_hot(int& disk_id, string& source, int& image_id);
|
||||
|
||||
/**
|
||||
* Clears the save_as attributes of the disk being (hot) saved as
|
||||
*
|
||||
* @param img_id ID of the image this disk will be saved to. Can be
|
||||
* -1 if it is not found
|
||||
* @return 0 if a disk with (HOTPLUG_)SAVE_AS was cleaned
|
||||
*/
|
||||
int cancel_saveas_disk(int& image_id);
|
||||
int get_saveas_disk(int& disk_id, string& source, int& image_id,
|
||||
string& snap_id, string& tm_mad, string& ds_id);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Authorization related functions
|
||||
|
@ -344,10 +344,8 @@ public:
|
||||
* Images and updates usage quotas
|
||||
*
|
||||
* @param vid VM id
|
||||
* @param release_save_as true to release non-persistent images
|
||||
* in the detach event
|
||||
*/
|
||||
void delete_attach_disk(int vid, bool release_save_as);
|
||||
void delete_attach_disk(int vid);
|
||||
|
||||
/**
|
||||
* Deletes the NIC that was in the process of being attached
|
||||
|
@ -601,13 +601,8 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
d["CLONE"]
|
||||
end
|
||||
|
||||
column :"SAVE_AS", "", :size=>7 do |d|
|
||||
d["SAVE_AS"] || "-"
|
||||
end
|
||||
|
||||
|
||||
default :ID, :TARGET, :IMAGE, :TYPE,
|
||||
:SAVE, :SAVE_AS
|
||||
:SAVE
|
||||
end.show(vm_disks, {})
|
||||
|
||||
while vm.has_elements?("/VM/TEMPLATE/DISK")
|
||||
|
@ -104,6 +104,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
" the --retry option."
|
||||
}
|
||||
|
||||
SNAP={
|
||||
:name => "snapshot",
|
||||
:short => "-s snapshot",
|
||||
:large => "--snapshot snapshot",
|
||||
:format => String,
|
||||
:description => "ID of the Snapshot to save."
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# Global Options
|
||||
########################################################################
|
||||
@ -298,29 +306,36 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
end
|
||||
end
|
||||
|
||||
disk_snapshot_desc = <<-EOT.unindent
|
||||
Sets the specified VM disk to be saved in a new Image. The Image is
|
||||
created immediately, but the contents are saved only after the VM is
|
||||
shut down gracefully (i.e., using 'onevm shutdown' and not
|
||||
'onevm delete')
|
||||
|
||||
If '--live' is specified, the Image will be saved immediately.
|
||||
disk_saveas_desc = <<-EOT.unindent
|
||||
Saves the specified VM disk as a new Image. The Image is
|
||||
created immediately, and the contents of the VM disk will be saved to
|
||||
it.
|
||||
|
||||
States: ANY
|
||||
EOT
|
||||
|
||||
command :"disk-snapshot", disk_snapshot_desc, :vmid, :diskid, :img_name,
|
||||
:options=>[TYPE, OneVMHelper::LIVE] do
|
||||
disk_id = args[1].to_i
|
||||
image_name = args[2]
|
||||
image_type = options[:type] || ""
|
||||
command :"disk-saveas", disk_saveas_desc, :vmid, :diskid, :img_name,
|
||||
:options=>[TYPE, SNAP] do
|
||||
|
||||
verbose = "disk #{disk_id} prepared to be saved in " <<
|
||||
"the image #{image_name}"
|
||||
disk_id = args[1].to_i
|
||||
image_name = args[2]
|
||||
image_type = options[:type] || ""
|
||||
snapshot_id = options[:snapshot]
|
||||
|
||||
if snapshot_id.nil? || snapshot_id.empty?
|
||||
snapshot_id = -1
|
||||
|
||||
verbose = "disk #{disk_id} prepared to be saved in " <<
|
||||
"the image #{image_name}"
|
||||
else
|
||||
snapshot_id = snapshot_id.to_i
|
||||
|
||||
verbose = "disk #{disk_id} snapshot #{snapshot_id} prepared to " <<
|
||||
"be saved in the image #{image_name}"
|
||||
end
|
||||
|
||||
helper.perform_action(args[0],options,verbose) do |vm|
|
||||
res = vm.disk_snapshot(disk_id, image_name, image_type,
|
||||
options[:live]==true)
|
||||
res = vm.disk_saveas(disk_id, image_name, image_type, snapshot_id)
|
||||
|
||||
if !OpenNebula.is_error?(res)
|
||||
puts "Image ID: #{res}"
|
||||
@ -330,19 +345,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
end
|
||||
end
|
||||
|
||||
disk_snapshot_cancel_desc = <<-EOT.unindent
|
||||
Cancels a deferred disk snapshot that has been set by disk-snapshot.
|
||||
The target image is also deleted.
|
||||
|
||||
States: ANY
|
||||
EOT
|
||||
|
||||
command :"disk-snapshot-cancel", disk_snapshot_cancel_desc, :vmid, :diskid do
|
||||
helper.perform_action(args[0],options,"disk snapshot canceled") do |vm|
|
||||
vm.disk_snapshot_cancel(args[1].to_i)
|
||||
end
|
||||
end
|
||||
|
||||
shutdown_desc = <<-EOT.unindent
|
||||
Shuts down the given VM. The VM life cycle will end.
|
||||
|
||||
|
@ -218,10 +218,9 @@ class EC2QueryServer < CloudServer
|
||||
return rc
|
||||
end
|
||||
|
||||
image_id = vm.disk_snapshot(1,
|
||||
params["Name"],
|
||||
OpenNebula::Image::IMAGE_TYPES[0],
|
||||
true)
|
||||
image_id = vm.disk_saveas(1,
|
||||
params["Name"],
|
||||
OpenNebula::Image::IMAGE_TYPES[0])
|
||||
|
||||
# TODO Add AMI Tags
|
||||
# TODO A new persistent image should be created for each instance
|
||||
|
@ -302,10 +302,9 @@ module EBS
|
||||
|
||||
disk_id = vm["TEMPLATE/DISK[IMAGE_ID=#{image_id}]/DISK_ID"]
|
||||
if !disk_id.nil?
|
||||
snapshot_id = vm.disk_snapshot(disk_id.to_i,
|
||||
snapshot_id = vm.disk_saveas(disk_id.to_i,
|
||||
params["Description"]||ImageEC2.generate_uuid,
|
||||
OpenNebula::Image::IMAGE_TYPES[image["TYPE"].to_i],
|
||||
true)
|
||||
OpenNebula::Image::IMAGE_TYPES[image["TYPE"].to_i])
|
||||
|
||||
if OpenNebula::is_error?(snapshot_id)
|
||||
return snapshot_id
|
||||
|
@ -183,7 +183,7 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
erase_template_attribute("PATH", path);
|
||||
erase_template_attribute("SOURCE", source);
|
||||
|
||||
if (!isSaving()) //Not a saving image
|
||||
if (!is_saving()) //Not a saving image
|
||||
{
|
||||
if ( source.empty() && path.empty() )
|
||||
{
|
||||
@ -624,9 +624,9 @@ int Image::disk_attribute( VectorAttribute * disk,
|
||||
new_disk_type = RBD_CDROM;
|
||||
break;
|
||||
|
||||
case SHEEPDOG:
|
||||
new_disk_type = SHEEPDOG_CDROM;
|
||||
break;
|
||||
case SHEEPDOG:
|
||||
new_disk_type = SHEEPDOG_CDROM;
|
||||
break;
|
||||
|
||||
case GLUSTER:
|
||||
new_disk_type = GLUSTER_CDROM;
|
||||
@ -730,7 +730,7 @@ ImageTemplate * Image::clone_template(const string& new_name) const
|
||||
tmpl->replace("FSTYPE", fs_type);
|
||||
tmpl->replace("SIZE", size_mb);
|
||||
|
||||
if ( isPersistent() )
|
||||
if ( is_persistent() )
|
||||
{
|
||||
tmpl->replace("PERSISTENT", "YES");
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ int ImageManager::acquire_image(int vm_id, Image *img, string& error)
|
||||
case Image::READY:
|
||||
img->inc_running(vm_id);
|
||||
|
||||
if ( img->isPersistent() )
|
||||
if ( img->is_persistent() )
|
||||
{
|
||||
img->set_state(Image::USED_PERS);
|
||||
}
|
||||
@ -160,11 +160,9 @@ int ImageManager::acquire_image(int vm_id, Image *img, string& error)
|
||||
|
||||
void ImageManager::release_image(int vm_id, int iid, bool failed)
|
||||
{
|
||||
Image * img;
|
||||
ostringstream oss;
|
||||
|
||||
ostringstream disk_file;
|
||||
|
||||
img = ipool->get(iid,true);
|
||||
Image * img = ipool->get(iid,true);
|
||||
|
||||
if ( img == 0 )
|
||||
{
|
||||
@ -218,27 +216,10 @@ void ImageManager::release_image(int vm_id, int iid, bool failed)
|
||||
break;
|
||||
|
||||
case Image::LOCKED:
|
||||
if ( img->isSaving() ) //SAVE_AS images are LOCKED till released
|
||||
{
|
||||
if (failed == true)
|
||||
{
|
||||
img->set_state(Image::ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
img->set_state(Image::READY);
|
||||
}
|
||||
oss << "Releasing image in wrong state: "
|
||||
<< Image::state_to_str(img->get_state());
|
||||
|
||||
ipool->update(img);
|
||||
}
|
||||
else
|
||||
{
|
||||
stringstream oss;
|
||||
oss << "Releasing image in wrong state: "
|
||||
<< Image::state_to_str(img->get_state());
|
||||
|
||||
NebulaLog::log("ImM", Log::ERROR, oss.str());
|
||||
}
|
||||
NebulaLog::log("ImM", Log::ERROR, oss.str());
|
||||
|
||||
img->unlock();
|
||||
break;
|
||||
@ -249,7 +230,6 @@ void ImageManager::release_image(int vm_id, int iid, bool failed)
|
||||
case Image::DISABLED:
|
||||
case Image::READY:
|
||||
case Image::ERROR:
|
||||
ostringstream oss;
|
||||
oss << "Releasing image in wrong state: "
|
||||
<< Image::state_to_str(img->get_state());
|
||||
|
||||
@ -265,11 +245,7 @@ void ImageManager::release_image(int vm_id, int iid, bool failed)
|
||||
|
||||
void ImageManager::release_cloning_image(int iid, int clone_img_id)
|
||||
{
|
||||
Image * img;
|
||||
|
||||
ostringstream disk_file;
|
||||
|
||||
img = ipool->get(iid,true);
|
||||
Image * img = ipool->get(iid,true);
|
||||
|
||||
if ( img == 0 )
|
||||
{
|
||||
@ -296,15 +272,13 @@ 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)
|
||||
{
|
||||
img->set_state(Image::READY);
|
||||
}
|
||||
|
||||
ipool->update(img);
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case Image::DELETE:
|
||||
case Image::INIT:
|
||||
@ -313,14 +287,13 @@ void ImageManager::release_cloning_image(int iid, int clone_img_id)
|
||||
case Image::ERROR:
|
||||
case Image::USED_PERS:
|
||||
case Image::LOCKED:
|
||||
ostringstream oss;
|
||||
|
||||
ostringstream oss;
|
||||
oss << "Releasing image in wrong state: "
|
||||
<< Image::state_to_str(img->get_state());
|
||||
oss << "Releasing image in wrong state: "
|
||||
<< Image::state_to_str(img->get_state());
|
||||
|
||||
NebulaLog::log("ImM", Log::ERROR, oss.str());
|
||||
|
||||
break;
|
||||
NebulaLog::log("ImM", Log::ERROR, oss.str());
|
||||
break;
|
||||
}
|
||||
|
||||
img->unlock();
|
||||
@ -639,7 +612,7 @@ int ImageManager::clone_image(int new_id,
|
||||
case Image::READY:
|
||||
img->inc_cloning(new_id);
|
||||
|
||||
if (img->isPersistent())
|
||||
if (img->is_persistent())
|
||||
{
|
||||
img->set_state(Image::CLONE);
|
||||
}
|
||||
@ -738,12 +711,11 @@ int ImageManager::register_image(int iid, const string& ds_data, string& error)
|
||||
{
|
||||
string source = img->get_source();
|
||||
|
||||
if ( img->isSaving() || img->get_type() == Image::DATABLOCK )
|
||||
if ( img->is_saving() || img->get_type() == Image::DATABLOCK )
|
||||
{
|
||||
imd->mkfs(img->get_oid(), *drv_msg);
|
||||
|
||||
oss << "Creating disk at " << source
|
||||
<< " of "<< img->get_size()
|
||||
oss << "Creating disk at " << source << " of "<< img->get_size()
|
||||
<< "Mb (type: " << img->get_fstype() << ")";
|
||||
}
|
||||
else if ( !source.empty() ) //Source in Template
|
||||
|
@ -369,15 +369,12 @@ static int mkfs_action(istringstream& is,
|
||||
string source;
|
||||
Image * image;
|
||||
bool is_saving = false;
|
||||
bool is_hot = false;
|
||||
|
||||
string info;
|
||||
int rc;
|
||||
|
||||
int vm_id = -1;
|
||||
int ds_id = -1;
|
||||
|
||||
int disk_id;
|
||||
int vm_id = -1;
|
||||
int ds_id = -1;
|
||||
int disk_id = -1;
|
||||
|
||||
VirtualMachine * vm;
|
||||
ostringstream oss;
|
||||
@ -411,14 +408,13 @@ static int mkfs_action(istringstream& is,
|
||||
return ds_id;
|
||||
}
|
||||
|
||||
is_saving = image->isSaving();
|
||||
is_hot = image->isHot();
|
||||
is_saving = image->is_saving();
|
||||
ds_id = image->get_ds_id();
|
||||
|
||||
if ( is_saving )
|
||||
{
|
||||
image->get_template_attribute("SAVED_VM_ID", vm_id);
|
||||
image->get_template_attribute("SAVED_DISK_ID", disk_id);
|
||||
image->get_template_attribute("SAVED_VM_ID", vm_id);
|
||||
}
|
||||
|
||||
if ( result == "FAILURE" )
|
||||
@ -459,28 +455,12 @@ static int mkfs_action(istringstream& is,
|
||||
goto error_save_get;
|
||||
}
|
||||
|
||||
if ( is_hot ) //Saveas hot, trigger disk copy
|
||||
if ( vm->set_saveas_disk(disk_id, source, id) == -1 )
|
||||
{
|
||||
rc = vm->save_disk_hot(disk_id, source, id);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_save_state;
|
||||
}
|
||||
|
||||
tm->trigger(TransferManager::SAVEAS_HOT, vm_id);
|
||||
goto error_save_state;
|
||||
}
|
||||
else //setup disk information
|
||||
{
|
||||
rc = vm->save_disk(disk_id, source, id);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_save_state;
|
||||
}
|
||||
|
||||
vm->clear_saveas_state(disk_id, is_hot);
|
||||
}
|
||||
tm->trigger(TransferManager::SAVEAS_HOT, vm_id);
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
@ -493,12 +473,12 @@ error_img:
|
||||
goto error;
|
||||
|
||||
error_save_get:
|
||||
oss << "Image created for SAVE_AS, but the associated VM does not exist.";
|
||||
oss << "Image created to save as a disk but VM does not exist.";
|
||||
goto error_save;
|
||||
|
||||
error_save_state:
|
||||
vm->unlock();
|
||||
oss << "Image created for SAVE_AS, but VM is no longer running";
|
||||
oss << "Image created to save as disk but VM is no longer running";
|
||||
|
||||
error_save:
|
||||
image = ipool->get(id, true);
|
||||
@ -530,7 +510,10 @@ error:
|
||||
{
|
||||
if ((vm = vmpool->get(vm_id, true)) != 0)
|
||||
{
|
||||
vm->clear_saveas_state(disk_id, is_hot);
|
||||
vm->clear_saveas_state();
|
||||
|
||||
vm->clear_saveas_disk();
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->unlock();
|
||||
|
@ -21,8 +21,5 @@
|
||||
|
||||
vector<string> ImageTemplate::restricted_attributes;
|
||||
|
||||
string ImageTemplate::saving_attribute = "SAVE_AS";
|
||||
string ImageTemplate::saving_hot_attribute = "SAVE_AS_HOT";
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -938,7 +938,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag
|
||||
break;
|
||||
|
||||
case VirtualMachine::HOTPLUG_SAVEAS:
|
||||
vm->cancel_saveas_disk(image_id);
|
||||
image_id = vm->clear_saveas_disk();
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->set_running_etime(the_time);
|
||||
@ -952,7 +952,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag
|
||||
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
|
||||
tm->trigger(TransferManager::DRIVER_CANCEL, vid);
|
||||
|
||||
vm->cancel_saveas_disk(image_id);
|
||||
image_id = vm->clear_saveas_disk();
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->set_running_etime(the_time);
|
||||
@ -1129,11 +1129,11 @@ void LifeCycleManager::recover(VirtualMachine * vm, bool success)
|
||||
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
|
||||
if (success)
|
||||
{
|
||||
lcm_action = LifeCycleManager::SAVEAS_HOT_SUCCESS;
|
||||
lcm_action = LifeCycleManager::SAVEAS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
lcm_action = LifeCycleManager::SAVEAS_HOT_FAILURE;
|
||||
lcm_action = LifeCycleManager::SAVEAS_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -166,12 +166,12 @@ void LifeCycleManager::trigger(Actions action, int _vid)
|
||||
aname = "DETACH_FAILURE";
|
||||
break;
|
||||
|
||||
case SAVEAS_HOT_SUCCESS:
|
||||
aname = "SAVEAS_HOT_SUCCESS";
|
||||
case SAVEAS_SUCCESS:
|
||||
aname = "SAVEAS_SUCCESS";
|
||||
break;
|
||||
|
||||
case SAVEAS_HOT_FAILURE:
|
||||
aname = "SAVEAS_HOT_FAILURE";
|
||||
case SAVEAS_FAILURE:
|
||||
aname = "SAVEAS_FAILURE";
|
||||
break;
|
||||
|
||||
case ATTACH_NIC_SUCCESS:
|
||||
@ -399,13 +399,13 @@ void LifeCycleManager::do_action(const string &action, void * arg)
|
||||
{
|
||||
detach_failure_action(vid);
|
||||
}
|
||||
else if (action == "SAVEAS_HOT_SUCCESS")
|
||||
else if (action == "SAVEAS_SUCCESS")
|
||||
{
|
||||
saveas_hot_success_action(vid);
|
||||
saveas_success_action(vid);
|
||||
}
|
||||
else if (action == "SAVEAS_HOT_FAILURE")
|
||||
else if (action == "SAVEAS_FAILURE")
|
||||
{
|
||||
saveas_hot_failure_action(vid);
|
||||
saveas_failure_action(vid);
|
||||
}
|
||||
else if (action == "ATTACH_NIC_SUCCESS")
|
||||
{
|
||||
|
@ -1232,7 +1232,7 @@ void LifeCycleManager::attach_failure_action(int vid)
|
||||
{
|
||||
vm->unlock();
|
||||
|
||||
vmpool->delete_attach_disk(vid, false);
|
||||
vmpool->delete_attach_disk(vid);
|
||||
|
||||
vm = vmpool->get(vid,true);
|
||||
|
||||
@ -1282,7 +1282,7 @@ void LifeCycleManager::detach_success_action(int vid)
|
||||
{
|
||||
vm->unlock();
|
||||
|
||||
vmpool->delete_attach_disk(vid, true);
|
||||
vmpool->delete_attach_disk(vid);
|
||||
|
||||
vm = vmpool->get(vid,true);
|
||||
|
||||
@ -1604,27 +1604,32 @@ void LifeCycleManager::detach_nic_failure_action(int vid)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void LifeCycleManager::saveas_hot_success_action(int vid)
|
||||
void LifeCycleManager::saveas_success_action(int vid)
|
||||
{
|
||||
VirtualMachine * vm;
|
||||
Image * image;
|
||||
|
||||
int image_id;
|
||||
int disk_id;
|
||||
string source;
|
||||
string tm_mad;
|
||||
string snap;
|
||||
string ds_id;
|
||||
string src;
|
||||
|
||||
vm = vmpool->get(vid,true);
|
||||
VirtualMachine * vm = vmpool->get(vid,true);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int rc = vm->get_saveas_disk_hot(disk_id, source, image_id);
|
||||
int rc = vm->get_saveas_disk(disk_id, src, image_id, snap, tm_mad, ds_id);
|
||||
|
||||
if (vm->clear_saveas_state(disk_id, true) == -1)
|
||||
vm->clear_saveas_disk();
|
||||
|
||||
if (vm->clear_saveas_state() == -1)
|
||||
{
|
||||
vm->log("LCM", Log::ERROR, "saveas_hot_success_action, VM in a wrong state");
|
||||
vm->log("LCM",Log::ERROR, "saveas_success_action, VM in a wrong state");
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
return;
|
||||
@ -1634,14 +1639,14 @@ void LifeCycleManager::saveas_hot_success_action(int vid)
|
||||
|
||||
vm->unlock();
|
||||
|
||||
if ( rc != 0 )
|
||||
if (rc != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
image = ipool->get(image_id, true);
|
||||
Image * image = ipool->get(image_id, true);
|
||||
|
||||
if ( image == 0 )
|
||||
if (image == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -1656,27 +1661,32 @@ void LifeCycleManager::saveas_hot_success_action(int vid)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void LifeCycleManager::saveas_hot_failure_action(int vid)
|
||||
void LifeCycleManager::saveas_failure_action(int vid)
|
||||
{
|
||||
VirtualMachine * vm;
|
||||
Image * image;
|
||||
|
||||
int image_id;
|
||||
int disk_id;
|
||||
string source;
|
||||
string tm_mad;
|
||||
string snap;
|
||||
string ds_id;
|
||||
string src;
|
||||
|
||||
vm = vmpool->get(vid,true);
|
||||
VirtualMachine * vm = vmpool->get(vid,true);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int rc = vm->get_saveas_disk_hot(disk_id, source, image_id);
|
||||
int rc = vm->get_saveas_disk(disk_id, src, image_id, snap, tm_mad, ds_id);
|
||||
|
||||
if (vm->clear_saveas_state(disk_id, true) == -1)
|
||||
vm->clear_saveas_disk();
|
||||
|
||||
if (vm->clear_saveas_state() == -1)
|
||||
{
|
||||
vm->log("LCM", Log::ERROR, "saveas_hot_success_action, VM in a wrong state");
|
||||
vm->log("LCM",Log::ERROR, "saveas_failure_action, VM in a wrong state");
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
return;
|
||||
@ -1686,14 +1696,14 @@ void LifeCycleManager::saveas_hot_failure_action(int vid)
|
||||
|
||||
vm->unlock();
|
||||
|
||||
if ( rc != 0 )
|
||||
if (rc != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
image = ipool->get(image_id, true);
|
||||
Image * image = ipool->get(image_id, true);
|
||||
|
||||
if ( image == 0 )
|
||||
if (image == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -29,8 +29,6 @@ module OpenNebula
|
||||
:action => "vm.action",
|
||||
:migrate => "vm.migrate",
|
||||
:deploy => "vm.deploy",
|
||||
:savedisk => "vm.savedisk",
|
||||
:savediskcancel => "vm.savediskcancel",
|
||||
:chown => "vm.chown",
|
||||
:chmod => "vm.chmod",
|
||||
:monitoring => "vm.monitoring",
|
||||
@ -45,6 +43,7 @@ module OpenNebula
|
||||
:attachnic => "vm.attachnic",
|
||||
:detachnic => "vm.detachnic",
|
||||
:recover => "vm.recover",
|
||||
:disksaveas => "vm.disksaveas",
|
||||
:disksnapshotcreate => "vm.disksnapshotcreate",
|
||||
:disksnapshotrevert => "vm.disksnapshotrevert",
|
||||
:disksnapshotdelete => "vm.disksnapshotdelete"
|
||||
@ -460,7 +459,7 @@ module OpenNebula
|
||||
migrate(host_id, true, enforce)
|
||||
end
|
||||
|
||||
# Set the specified vm's disk to be saved in a new image
|
||||
# Set the specified vm's disk to be saved as a new image
|
||||
# when the VirtualMachine shutdowns
|
||||
#
|
||||
# @param disk_id [Integer] ID of the disk to be saved
|
||||
@ -468,36 +467,23 @@ module OpenNebula
|
||||
# disk will be saved
|
||||
# @param image_type [String] Type of the new image. Set to empty string
|
||||
# to use the default type
|
||||
# @param hot [true|false] True to save the disk immediately, false will
|
||||
# perform the operation when the VM shuts down
|
||||
# @param snap_id [Integer] ID of the snapshot to save, -1 to use the
|
||||
# current disk image state
|
||||
#
|
||||
# @return [Integer, OpenNebula::Error] the new Image ID in case of
|
||||
# success, error otherwise
|
||||
def disk_snapshot(disk_id, image_name, image_type="", hot=false)
|
||||
def disk_saveas(disk_id, image_name, image_type="", snap_id=-1)
|
||||
return Error.new('ID not defined') if !@pe_id
|
||||
|
||||
rc = @client.call(VM_METHODS[:savedisk],
|
||||
rc = @client.call(VM_METHODS[:disksaveas],
|
||||
@pe_id,
|
||||
disk_id,
|
||||
image_name,
|
||||
image_type,
|
||||
hot)
|
||||
snap_id)
|
||||
return rc
|
||||
end
|
||||
|
||||
# @deprecated use {#disk_snapshot}
|
||||
def save_as(disk_id, image_name, image_type="", hot=false)
|
||||
return disk_snapshot(disk_id, image_name, image_type, hot)
|
||||
end
|
||||
|
||||
# Cancels a deferred snapshot that has been set by disk_snapshot.
|
||||
# The target image is also deleted.
|
||||
def disk_snapshot_cancel(disk_id)
|
||||
return call(VM_METHODS[:savediskcancel],
|
||||
@pe_id,
|
||||
disk_id)
|
||||
end
|
||||
|
||||
# Resize the VM
|
||||
#
|
||||
# @param capacity_template [String] Template containing the new capacity
|
||||
@ -784,8 +770,7 @@ module OpenNebula
|
||||
image_id = disk["IMAGE_ID"]
|
||||
|
||||
if !image_id.nil? && !image_id.empty?
|
||||
rc = disk_snapshot(disk_id.to_i, "#{name}-disk-#{disk_id}",
|
||||
"", true)
|
||||
rc = disk_saveas(disk_id.to_i,"#{name}-disk-#{disk_id}","",-1)
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
|
@ -293,8 +293,6 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr vm_deploy(new VirtualMachineDeploy());
|
||||
xmlrpc_c::methodPtr vm_migrate(new VirtualMachineMigrate());
|
||||
xmlrpc_c::methodPtr vm_action(new VirtualMachineAction());
|
||||
xmlrpc_c::methodPtr vm_savedisk(new VirtualMachineSaveDisk());
|
||||
xmlrpc_c::methodPtr vm_savedisk_cancel(new VirtualMachineSaveDiskCancel());
|
||||
xmlrpc_c::methodPtr vm_monitoring(new VirtualMachineMonitoring());
|
||||
xmlrpc_c::methodPtr vm_attach(new VirtualMachineAttach());
|
||||
xmlrpc_c::methodPtr vm_detach(new VirtualMachineDetach());
|
||||
@ -304,6 +302,7 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::methodPtr vm_snap_create(new VirtualMachineSnapshotCreate());
|
||||
xmlrpc_c::methodPtr vm_snap_revert(new VirtualMachineSnapshotRevert());
|
||||
xmlrpc_c::methodPtr vm_snap_delete(new VirtualMachineSnapshotDelete());
|
||||
xmlrpc_c::methodPtr vm_dsaveas(new VirtualMachineDiskSaveas());
|
||||
xmlrpc_c::methodPtr vm_dsnap_create(new VirtualMachineDiskSnapshotCreate());
|
||||
xmlrpc_c::methodPtr vm_dsnap_revert(new VirtualMachineDiskSnapshotRevert());
|
||||
xmlrpc_c::methodPtr vm_dsnap_delete(new VirtualMachineDiskSnapshotDelete());
|
||||
@ -449,8 +448,6 @@ void RequestManager::register_xml_methods()
|
||||
RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy);
|
||||
RequestManagerRegistry.addMethod("one.vm.action", vm_action);
|
||||
RequestManagerRegistry.addMethod("one.vm.migrate", vm_migrate);
|
||||
RequestManagerRegistry.addMethod("one.vm.savedisk", vm_savedisk);
|
||||
RequestManagerRegistry.addMethod("one.vm.savediskcancel", vm_savedisk_cancel);
|
||||
RequestManagerRegistry.addMethod("one.vm.allocate", vm_allocate);
|
||||
RequestManagerRegistry.addMethod("one.vm.info", vm_info);
|
||||
RequestManagerRegistry.addMethod("one.vm.chown", vm_chown);
|
||||
@ -466,6 +463,7 @@ void RequestManager::register_xml_methods()
|
||||
RequestManagerRegistry.addMethod("one.vm.snapshotcreate", vm_snap_create);
|
||||
RequestManagerRegistry.addMethod("one.vm.snapshotrevert", vm_snap_revert);
|
||||
RequestManagerRegistry.addMethod("one.vm.snapshotdelete", vm_snap_delete);
|
||||
RequestManagerRegistry.addMethod("one.vm.disksaveas", vm_dsaveas);
|
||||
RequestManagerRegistry.addMethod("one.vm.disksnapshotcreate", vm_dsnap_create);
|
||||
RequestManagerRegistry.addMethod("one.vm.disksnapshotrevert", vm_dsnap_revert);
|
||||
RequestManagerRegistry.addMethod("one.vm.disksnapshotdelete", vm_dsnap_delete);
|
||||
|
@ -179,55 +179,12 @@ int HostDelete::drop(int oid, PoolObjectSQL * object, string& error_msg)
|
||||
|
||||
int ImageDelete::drop(int oid, PoolObjectSQL * object, string& error_msg)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImageManager * imagem = nd.get_imagem();
|
||||
VirtualMachinePool * vmpool = nd.get_vmpool();
|
||||
|
||||
VirtualMachine * vm;
|
||||
|
||||
bool save_as;
|
||||
int rc, img_id, vm_id, disk_id;
|
||||
|
||||
object->get_template_attribute("SAVE_AS", save_as);
|
||||
|
||||
save_as &= object->get_template_attribute("SAVED_VM_ID", vm_id) &
|
||||
object->get_template_attribute("SAVED_DISK_ID", disk_id);
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImageManager * imagem = nd.get_imagem();
|
||||
|
||||
object->unlock();
|
||||
|
||||
rc = imagem->delete_image(oid, error_msg);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Cancel the disk snapshot
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
if (rc == 0 && save_as)
|
||||
{
|
||||
vm = vmpool->get(vm_id, true);
|
||||
|
||||
if (vm == 0)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (vm->get_state() == VirtualMachine::DONE)
|
||||
{
|
||||
vm->unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
img_id = vm->get_save_disk_image(disk_id);
|
||||
|
||||
if ( img_id == oid )
|
||||
{
|
||||
vm->clear_save_disk(disk_id);
|
||||
vmpool->update(vm);
|
||||
}
|
||||
|
||||
vm->unlock();
|
||||
}
|
||||
|
||||
return rc;
|
||||
return imagem->delete_image(oid, error_msg);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
@ -495,7 +495,7 @@ void ImageSnapshotDelete::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
return;
|
||||
}
|
||||
|
||||
success_response(id, att);
|
||||
success_response(snap_id, att);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -524,7 +524,7 @@ void ImageSnapshotRevert::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
return;
|
||||
}
|
||||
|
||||
success_response(id, att);
|
||||
success_response(snap_id, att);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -553,6 +553,6 @@ void ImageSnapshotFlatten::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
return;
|
||||
}
|
||||
|
||||
success_response(id, att);
|
||||
success_response(snap_id, att);
|
||||
}
|
||||
|
||||
|
@ -1176,66 +1176,72 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
void VirtualMachineDiskSaveas::request_execute(
|
||||
xmlrpc_c::paramList const& paramList, RequestAttributes& att)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
Nebula& nd = Nebula::instance();
|
||||
|
||||
ImagePool * ipool = nd.get_ipool();
|
||||
DatastorePool * dspool = nd.get_dspool();
|
||||
|
||||
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
int disk_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
string img_name = xmlrpc_c::value_string(paramList.getString(3));
|
||||
string img_type = xmlrpc_c::value_string(paramList.getString(4));
|
||||
bool is_hot = false; //Optional XML-RPC argument
|
||||
|
||||
if ( paramList.size() > 5 )
|
||||
{
|
||||
is_hot = xmlrpc_c::value_boolean(paramList.getBoolean(5));
|
||||
}
|
||||
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
int disk_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
string img_name = xmlrpc_c::value_string(paramList.getString(3));
|
||||
string img_type = xmlrpc_c::value_string(paramList.getString(4));
|
||||
int snap_id = xmlrpc_c::value_int(paramList.getInt(5));
|
||||
|
||||
VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
|
||||
|
||||
VirtualMachine * vm;
|
||||
Datastore * ds;
|
||||
int iid;
|
||||
Image * img;
|
||||
int iid;
|
||||
int iid_orig;
|
||||
|
||||
string error_str;
|
||||
string ds_data;
|
||||
PoolObjectAuth ds_perms;
|
||||
long long avail;
|
||||
bool ds_check;
|
||||
|
||||
string driver;
|
||||
string target;
|
||||
string dev_prefix;
|
||||
|
||||
int ds_id;
|
||||
string ds_name;
|
||||
long long size;
|
||||
|
||||
string iname_orig;
|
||||
string iuname_orig;
|
||||
|
||||
Image::ImageType type;
|
||||
Image::DiskType ds_disk_type;
|
||||
|
||||
ImageTemplate * itemplate;
|
||||
Template img_usage;
|
||||
|
||||
int rc;
|
||||
bool rc_auth;
|
||||
string error;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Prepare and check the VM/DISK to be saved_as
|
||||
// Prepare and check the VM/DISK to be saved as
|
||||
// -------------------------------------------------------------------------
|
||||
if ((vm = get_vm(id, att)) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( vm->set_saveas_state(disk_id, is_hot) != 0 )
|
||||
if (vm->set_saveas_state() != 0)
|
||||
{
|
||||
vm->unlock();
|
||||
|
||||
failure_response(INTERNAL,
|
||||
request_error("VM has to be RUNNING, POWEROFF or"
|
||||
" SUSPENDED to snapshot disks.",""), att);
|
||||
return;
|
||||
goto error_state;
|
||||
}
|
||||
|
||||
int iid_orig = vm->get_image_from_disk(disk_id, is_hot, error_str);
|
||||
iid_orig = vm->set_saveas_disk(disk_id, snap_id, error);
|
||||
|
||||
if ( iid_orig == -1 )
|
||||
if (iid_orig == -1)
|
||||
{
|
||||
vm->clear_saveas_state(disk_id, is_hot);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
failure_response(INTERNAL,
|
||||
request_error("Cannot use selected DISK", error_str),
|
||||
att);
|
||||
return;
|
||||
goto error_disk;
|
||||
}
|
||||
|
||||
vmpool->update(vm);
|
||||
@ -1245,32 +1251,21 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
|
||||
// -------------------------------------------------------------------------
|
||||
// Get the data of the Image to be saved
|
||||
// -------------------------------------------------------------------------
|
||||
Image * img = ipool->get(iid_orig, true);
|
||||
img = ipool->get(iid_orig, true);
|
||||
|
||||
if ( img == 0 )
|
||||
{
|
||||
failure_response(NO_EXISTS,
|
||||
get_error(object_name(PoolObjectSQL::IMAGE), iid_orig),
|
||||
att);
|
||||
|
||||
if ((vm = vmpool->get(id, true)) != 0)
|
||||
{
|
||||
vm->clear_saveas_state(disk_id, is_hot);
|
||||
|
||||
vmpool->update(vm);
|
||||
vm->unlock();
|
||||
}
|
||||
|
||||
return;
|
||||
goto error_image;
|
||||
}
|
||||
|
||||
int ds_id = img->get_ds_id();
|
||||
string ds_name = img->get_ds_name();
|
||||
long long size = img->get_size();
|
||||
ds_id = img->get_ds_id();
|
||||
ds_name = img->get_ds_name();
|
||||
|
||||
string iname_orig = img->get_name();
|
||||
string iuname_orig = img->get_uname();
|
||||
Image::ImageType type = img->get_type();
|
||||
size = img->get_size();
|
||||
type = img->get_type();
|
||||
|
||||
iname_orig = img->get_name();
|
||||
iuname_orig = img->get_uname();
|
||||
|
||||
img->get_template_attribute("DRIVER", driver);
|
||||
img->get_template_attribute("TARGET", target);
|
||||
@ -1283,74 +1278,39 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
|
||||
case Image::OS:
|
||||
case Image::DATABLOCK:
|
||||
case Image::CDROM:
|
||||
break;
|
||||
break;
|
||||
|
||||
case Image::KERNEL:
|
||||
case Image::RAMDISK:
|
||||
case Image::CONTEXT:
|
||||
failure_response(INTERNAL,
|
||||
request_error("Cannot save_as image of type " +
|
||||
Image::type_to_str(type), ""), att);
|
||||
return;
|
||||
goto error_image_type;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Get the data of the DataStore for the new image
|
||||
// Get the data of the DataStore for the new image & size
|
||||
// -------------------------------------------------------------------------
|
||||
if ((ds = dspool->get(ds_id, true)) == 0 )
|
||||
{
|
||||
failure_response(NO_EXISTS,
|
||||
get_error(object_name(PoolObjectSQL::DATASTORE), ds_id),
|
||||
att);
|
||||
|
||||
if ((vm = vmpool->get(id, true)) != 0)
|
||||
{
|
||||
vm->clear_saveas_state(disk_id, is_hot);
|
||||
|
||||
vmpool->update(vm);
|
||||
vm->unlock();
|
||||
}
|
||||
|
||||
return;
|
||||
goto error_ds;
|
||||
}
|
||||
|
||||
string ds_data;
|
||||
PoolObjectAuth ds_perms;
|
||||
long long avail;
|
||||
bool ds_check;
|
||||
|
||||
ds->get_permissions(ds_perms);
|
||||
ds->to_xml(ds_data);
|
||||
|
||||
ds_check = ds->get_avail_mb(avail);
|
||||
|
||||
Image::DiskType ds_disk_type = ds->get_disk_type();
|
||||
ds_check = ds->get_avail_mb(avail);
|
||||
ds_disk_type = ds->get_disk_type();
|
||||
|
||||
ds->unlock();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Check Datastore Capacity
|
||||
// -------------------------------------------------------------------------
|
||||
if (ds_check && (size > avail))
|
||||
{
|
||||
failure_response(ACTION, "Not enough space in datastore", att);
|
||||
|
||||
if ((vm = vmpool->get(id, true)) != 0)
|
||||
{
|
||||
vm->clear_saveas_state(disk_id, is_hot);
|
||||
|
||||
vmpool->update(vm);
|
||||
vm->unlock();
|
||||
}
|
||||
|
||||
return;
|
||||
goto error_size;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Create a template for the new Image
|
||||
// -------------------------------------------------------------------------
|
||||
ImageTemplate * itemplate = new ImageTemplate;
|
||||
Template img_usage;
|
||||
itemplate = new ImageTemplate;
|
||||
|
||||
itemplate->add("NAME", img_name);
|
||||
itemplate->add("SIZE", size);
|
||||
@ -1358,15 +1318,9 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
|
||||
itemplate->add("SAVED_IMAGE_ID",iid_orig);
|
||||
itemplate->add("SAVED_DISK_ID",disk_id);
|
||||
itemplate->add("SAVED_VM_ID", id);
|
||||
|
||||
itemplate->set_saving();
|
||||
|
||||
if ( is_hot )
|
||||
{
|
||||
itemplate->set_saving_hot();
|
||||
}
|
||||
|
||||
if ( img_type.empty() )
|
||||
if (img_type.empty())
|
||||
{
|
||||
itemplate->add("TYPE", Image::type_to_str(type));
|
||||
}
|
||||
@ -1375,17 +1329,17 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
|
||||
itemplate->add("TYPE", img_type);
|
||||
}
|
||||
|
||||
if ( driver.empty() == false )
|
||||
if (!driver.empty())
|
||||
{
|
||||
itemplate->add("DRIVER", driver);
|
||||
}
|
||||
|
||||
if ( target.empty() == false )
|
||||
if (!target.empty())
|
||||
{
|
||||
itemplate->add("TARGET", target);
|
||||
}
|
||||
|
||||
if ( dev_prefix.empty() == false )
|
||||
if (!dev_prefix.empty())
|
||||
{
|
||||
itemplate->add("DEV_PREFIX", dev_prefix);
|
||||
}
|
||||
@ -1396,7 +1350,7 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
|
||||
// -------------------------------------------------------------------------
|
||||
// Authorize the operation & check quotas
|
||||
// -------------------------------------------------------------------------
|
||||
bool rc_auth = vm_authorization(id, itemplate, 0, att, 0,&ds_perms,auth_op);
|
||||
rc_auth = vm_authorization(id, itemplate, 0, att, 0,&ds_perms,auth_op);
|
||||
|
||||
if ( rc_auth == true )
|
||||
{
|
||||
@ -1405,216 +1359,111 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
|
||||
|
||||
if ( rc_auth == false)
|
||||
{
|
||||
delete itemplate;
|
||||
|
||||
if ((vm = vmpool->get(id, true)) != 0)
|
||||
{
|
||||
vm->clear_saveas_state(disk_id, is_hot);
|
||||
|
||||
vmpool->update(vm);
|
||||
vm->unlock();
|
||||
}
|
||||
|
||||
return;
|
||||
goto error_auth;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Create the image
|
||||
// -------------------------------------------------------------------------
|
||||
int rc = ipool->allocate(att.uid,
|
||||
att.gid,
|
||||
att.uname,
|
||||
att.gname,
|
||||
att.umask,
|
||||
itemplate,
|
||||
ds_id,
|
||||
ds_name,
|
||||
ds_disk_type,
|
||||
ds_data,
|
||||
Datastore::IMAGE_DS,
|
||||
-1,
|
||||
&iid,
|
||||
error_str);
|
||||
rc = ipool->allocate(att.uid,
|
||||
att.gid,
|
||||
att.uname,
|
||||
att.gname,
|
||||
att.umask,
|
||||
itemplate,
|
||||
ds_id,
|
||||
ds_name,
|
||||
ds_disk_type,
|
||||
ds_data,
|
||||
Datastore::IMAGE_DS,
|
||||
-1,
|
||||
&iid,
|
||||
error);
|
||||
if (rc < 0)
|
||||
{
|
||||
quota_rollback(&img_usage, Quotas::DATASTORE, att);
|
||||
|
||||
if ((vm = vmpool->get(id, true)) != 0)
|
||||
{
|
||||
vm->clear_saveas_state(disk_id, is_hot);
|
||||
|
||||
vmpool->update(vm);
|
||||
vm->unlock();
|
||||
}
|
||||
|
||||
failure_response(INTERNAL,
|
||||
allocate_error(PoolObjectSQL::IMAGE, error_str), att);
|
||||
return;
|
||||
goto error_allocate;
|
||||
}
|
||||
|
||||
ds = dspool->get(ds_id, true);
|
||||
|
||||
if ( ds != 0 ) // TODO: error otherwise or leave image in ERROR?
|
||||
if (ds == 0)
|
||||
{
|
||||
ds->add_image(iid);
|
||||
|
||||
dspool->update(ds);
|
||||
|
||||
ds->unlock();
|
||||
goto error_ds_removed;
|
||||
}
|
||||
|
||||
ds->add_image(iid);
|
||||
|
||||
dspool->update(ds);
|
||||
|
||||
ds->unlock();
|
||||
|
||||
success_response(iid, att);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
return;
|
||||
|
||||
void VirtualMachineSaveDiskCancel::request_execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
error_state:
|
||||
vm->unlock();
|
||||
|
||||
AclManager * aclm = nd.get_aclm();
|
||||
ImageManager * imagem = nd.get_imagem();
|
||||
ImagePool * ipool = nd.get_ipool();
|
||||
Image * img;
|
||||
int img_id;
|
||||
failure_response(INTERNAL,request_error("VM has to be RUNNING, POWEROFF or "
|
||||
"SUSPENDED to save disks.",""), att);
|
||||
return;
|
||||
|
||||
VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
|
||||
VirtualMachine * vm;
|
||||
error_disk:
|
||||
vm->clear_saveas_state();
|
||||
|
||||
string error_str;
|
||||
|
||||
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
int disk_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Authorize the VM operation
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
if (att.uid != UserPool::ONEADMIN_ID)
|
||||
{
|
||||
PoolObjectAuth vm_perms;
|
||||
PoolObjectAuth img_perms;
|
||||
|
||||
if ((vm = get_vm(id, att)) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vm->get_permissions(vm_perms);
|
||||
|
||||
img_id = vm->get_save_disk_image(disk_id);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
AuthRequest ar(att.uid, att.group_ids);
|
||||
|
||||
ar.add_auth(auth_op, vm_perms); // MANAGE VM
|
||||
|
||||
img = ipool->get(img_id, true);
|
||||
|
||||
if ( img != 0 )
|
||||
{
|
||||
img->get_permissions(img_perms);
|
||||
|
||||
img->unlock();
|
||||
|
||||
ar.add_auth(AuthRequest::MANAGE, img_perms); // MANAGE IMAGE
|
||||
}
|
||||
|
||||
if (UserPool::authorize(ar) == -1)
|
||||
{
|
||||
failure_response(AUTHORIZATION,
|
||||
authorization_error(ar.message, att),
|
||||
att);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Check the VM state
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
if ((vm = get_vm(id, att)) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((vm->get_state() != VirtualMachine::ACTIVE ||
|
||||
(vm->get_lcm_state() != VirtualMachine::RUNNING &&
|
||||
vm->get_lcm_state() != VirtualMachine::UNKNOWN) ) &&
|
||||
vm->get_state() != VirtualMachine::POWEROFF &&
|
||||
vm->get_state() != VirtualMachine::SUSPENDED)
|
||||
{
|
||||
failure_response(ACTION,
|
||||
request_error("Wrong state to perform action",""),
|
||||
att);
|
||||
|
||||
vm->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Cancel the disk snapshot
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
img_id = vm->get_save_disk_image(disk_id);
|
||||
|
||||
if ( img_id == -1 )
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << "Disk with ID [" << disk_id << "] is not going to be saved";
|
||||
|
||||
failure_response(ACTION,
|
||||
request_error(oss.str(), ""),
|
||||
att);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
vm->clear_save_disk(disk_id);
|
||||
|
||||
vmpool->update(vm);
|
||||
vm->clear_saveas_disk();
|
||||
|
||||
vm->unlock();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Delete the target Image
|
||||
// -------------------------------------------------------------------------
|
||||
failure_response(INTERNAL,request_error("Cannot use DISK", error), att);
|
||||
return;
|
||||
|
||||
img = ipool->get(img_id, true);
|
||||
error_image:
|
||||
failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::IMAGE),
|
||||
iid_orig), att);
|
||||
goto error_common;
|
||||
|
||||
if ( img != 0 )
|
||||
error_image_type:
|
||||
failure_response(INTERNAL, request_error("Cannot save_as image of type " +
|
||||
Image::type_to_str(type), ""), att);
|
||||
goto error_common;
|
||||
|
||||
error_ds:
|
||||
failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::DATASTORE),
|
||||
ds_id), att);
|
||||
goto error_common;
|
||||
|
||||
error_size:
|
||||
failure_response(ACTION, "Not enough space in datastore", att);
|
||||
goto error_common;
|
||||
|
||||
error_auth:
|
||||
delete itemplate;
|
||||
goto error_common;
|
||||
|
||||
error_allocate:
|
||||
quota_rollback(&img_usage, Quotas::DATASTORE, att);
|
||||
failure_response(INTERNAL, allocate_error(PoolObjectSQL::IMAGE, error),att);
|
||||
goto error_common;
|
||||
|
||||
error_ds_removed:
|
||||
failure_response(NO_EXISTS,get_error(object_name(PoolObjectSQL::DATASTORE),
|
||||
ds_id), att);
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
if ((vm = vmpool->get(id, true)) != 0)
|
||||
{
|
||||
img->unlock();
|
||||
vm->clear_saveas_state();
|
||||
|
||||
int rc = imagem->delete_image(img_id, error_str);
|
||||
vm->clear_saveas_disk();
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << "The snapshot was canceled, but "
|
||||
<< object_name(PoolObjectSQL::IMAGE) << " [" << img_id
|
||||
<< "] could not be deleted: " << error_str;
|
||||
vmpool->update(vm);
|
||||
|
||||
failure_response(INTERNAL,
|
||||
request_error(oss.str(), ""),
|
||||
att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
aclm->del_resource_rules(img_id, PoolObjectSQL::IMAGE);
|
||||
vm->unlock();
|
||||
}
|
||||
|
||||
// TODO: Delete the cloned template
|
||||
|
||||
success_response(id, att);
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -2555,7 +2404,7 @@ void VirtualMachineDiskSnapshotRevert::request_execute(
|
||||
}
|
||||
else
|
||||
{
|
||||
success_response(id, att);
|
||||
success_response(snap_id, att);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -2594,7 +2443,7 @@ void VirtualMachineDiskSnapshotDelete::request_execute(
|
||||
}
|
||||
else
|
||||
{
|
||||
success_response(id, att);
|
||||
success_response(snap_id, att);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -55,7 +55,6 @@ module OpenNebulaJSON
|
||||
when "suspend" then self.suspend
|
||||
when "reset" then self.reset
|
||||
when "saveas" then self.save_as(action_hash['params'])
|
||||
when "disk_snapshot_cancel" then self.disk_snapshot_cancel(action_hash['params'])
|
||||
when "snapshot_create" then self.snapshot_create(action_hash['params'])
|
||||
when "snapshot_revert" then self.snapshot_revert(action_hash['params'])
|
||||
when "snapshot_delete" then self.snapshot_delete(action_hash['params'])
|
||||
@ -105,14 +104,7 @@ module OpenNebulaJSON
|
||||
end
|
||||
|
||||
def save_as(params=Hash.new)
|
||||
clone = params['clonetemplate']
|
||||
clone = false if clone.nil?
|
||||
|
||||
disk_snapshot(params['disk_id'].to_i, params['image_name'], params['type'], params['hot'], clone)
|
||||
end
|
||||
|
||||
def disk_snapshot_cancel(params=Hash.new)
|
||||
super(params['disk_id'].to_i)
|
||||
disk_saveas(params['disk_id'].to_i, params['image_name'], params['type'])
|
||||
end
|
||||
|
||||
def snapshot_create(params=Hash.new)
|
||||
|
@ -1233,27 +1233,20 @@ void TransferManager::epilog_transfer_command(
|
||||
const VectorAttribute * disk,
|
||||
ostream& xfr)
|
||||
{
|
||||
string save;
|
||||
string tm_mad;
|
||||
int disk_id;
|
||||
|
||||
disk->vector_value("DISK_ID", disk_id);
|
||||
|
||||
save = disk->vector_value("SAVE");
|
||||
string save = disk->vector_value("SAVE");
|
||||
|
||||
disk->vector_value("DISK_ID", disk_id);
|
||||
|
||||
transform(save.begin(),save.end(),save.begin(),(int(*)(int))toupper);
|
||||
|
||||
if ( save == "YES" )
|
||||
{
|
||||
string source;
|
||||
string save_source;
|
||||
string ds_id;
|
||||
|
||||
source = disk->vector_value("SOURCE");
|
||||
save_source = disk->vector_value("SAVE_AS_SOURCE");
|
||||
|
||||
tm_mad = disk->vector_value("TM_MAD");
|
||||
ds_id = disk->vector_value("DATASTORE_ID");
|
||||
string source = disk->vector_value("SOURCE");
|
||||
string tm_mad = disk->vector_value("TM_MAD");
|
||||
string ds_id = disk->vector_value("DATASTORE_ID");
|
||||
|
||||
if ( ds_id.empty() || tm_mad.empty() )
|
||||
{
|
||||
@ -1261,17 +1254,12 @@ void TransferManager::epilog_transfer_command(
|
||||
return;
|
||||
}
|
||||
|
||||
if (source.empty() && save_source.empty())
|
||||
if (source.empty())
|
||||
{
|
||||
vm->log("TM", Log::ERROR, "No SOURCE to save disk image");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!save_source.empty())//Use the save_as_source instead
|
||||
{
|
||||
source = save_source;
|
||||
}
|
||||
|
||||
//MVDS tm_mad hostname:remote_system_dir/disk.0 <fe:SOURCE|SOURCE> vmid dsid
|
||||
xfr << "MVDS "
|
||||
<< tm_mad << " "
|
||||
@ -1284,6 +1272,8 @@ void TransferManager::epilog_transfer_command(
|
||||
}
|
||||
else //No saving disk
|
||||
{
|
||||
string tm_mad;
|
||||
|
||||
int ds_id_i;
|
||||
int vv_rc = 0;
|
||||
|
||||
@ -2063,30 +2053,21 @@ void TransferManager::saveas_hot_action(int vid)
|
||||
{
|
||||
int disk_id;
|
||||
int image_id;
|
||||
string save_source;
|
||||
|
||||
string save;
|
||||
string src;
|
||||
string snap_id;
|
||||
string tm_mad;
|
||||
string ds_id;
|
||||
|
||||
int num;
|
||||
int disk_id_iter;
|
||||
|
||||
ostringstream os;
|
||||
|
||||
ofstream xfr;
|
||||
string xfr_name;
|
||||
|
||||
string source;
|
||||
|
||||
const VectorAttribute * disk;
|
||||
vector<const Attribute *> attrs;
|
||||
|
||||
VirtualMachine * vm;
|
||||
Nebula& nd = Nebula::instance();
|
||||
|
||||
const TransferManagerDriver * tm_md;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Setup & Transfer script
|
||||
// ------------------------------------------------------------------------
|
||||
@ -2104,9 +2085,9 @@ void TransferManager::saveas_hot_action(int vid)
|
||||
goto error_common;
|
||||
}
|
||||
|
||||
if (vm->get_saveas_disk_hot(disk_id, save_source, image_id) == -1)
|
||||
if (vm->get_saveas_disk(disk_id, src, image_id, snap_id, tm_mad, ds_id)!= 0)
|
||||
{
|
||||
vm->log("TM", Log::ERROR,"Could not get disk information to saveas it");
|
||||
vm->log("TM", Log::ERROR,"Could not get disk information to export it");
|
||||
goto error_common;
|
||||
}
|
||||
|
||||
@ -2117,41 +2098,7 @@ void TransferManager::saveas_hot_action(int vid)
|
||||
goto error_driver;
|
||||
}
|
||||
|
||||
num = vm->get_template_attribute("DISK",attrs);
|
||||
|
||||
for (int i=0 ; i < num ; i++)
|
||||
{
|
||||
disk = dynamic_cast<const VectorAttribute *>(attrs[i]);
|
||||
|
||||
if ( disk == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
disk->vector_value("DISK_ID", disk_id_iter);
|
||||
|
||||
if (disk_id == disk_id_iter)
|
||||
{
|
||||
tm_mad = disk->vector_value("TM_MAD");
|
||||
ds_id = disk->vector_value("DATASTORE_ID");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ds_id.empty() || tm_mad.empty() )
|
||||
{
|
||||
vm->log("TM", Log::ERROR, "No DS_ID or TM_MAD to save disk image");
|
||||
goto error_common;
|
||||
}
|
||||
|
||||
if (save_source.empty())
|
||||
{
|
||||
vm->log("TM", Log::ERROR, "No SOURCE to save disk image");
|
||||
goto error_common;
|
||||
}
|
||||
|
||||
xfr_name = vm->get_transfer_file() + ".saveas_hot";
|
||||
xfr_name = vm->get_transfer_file() + ".disk_saveas";
|
||||
xfr.open(xfr_name.c_str(),ios::out | ios::trunc);
|
||||
|
||||
if (xfr.fail() == true)
|
||||
@ -2159,12 +2106,13 @@ void TransferManager::saveas_hot_action(int vid)
|
||||
goto error_file;
|
||||
}
|
||||
|
||||
//MVDS tm_mad hostname:remote_system_dir/disk.0 <fe:SOURCE|SOURCE> vmid dsid
|
||||
//CPDS tm_mad hostname:remote_system_dir/disk.0 source snapid vmid dsid
|
||||
xfr << "CPDS "
|
||||
<< tm_mad << " "
|
||||
<< vm->get_hostname() << ":"
|
||||
<< vm->get_remote_system_dir() << "/disk." << disk_id << " "
|
||||
<< save_source << " "
|
||||
<< src << " "
|
||||
<< snap_id << " "
|
||||
<< vm->get_oid() << " "
|
||||
<< ds_id
|
||||
<< endl;
|
||||
@ -2189,7 +2137,7 @@ error_file:
|
||||
error_common:
|
||||
vm->log("TM", Log::ERROR, os);
|
||||
|
||||
(nd.get_lcm())->trigger(LifeCycleManager::SAVEAS_HOT_FAILURE, vid);
|
||||
(nd.get_lcm())->trigger(LifeCycleManager::SAVEAS_FAILURE, vid);
|
||||
|
||||
vm->unlock();
|
||||
return;
|
||||
|
@ -136,7 +136,7 @@ void TransferManagerDriver::protocol(const string& message) const
|
||||
case VirtualMachine::HOTPLUG_SAVEAS:
|
||||
case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF:
|
||||
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
|
||||
lcm_action = LifeCycleManager::SAVEAS_HOT_SUCCESS;
|
||||
lcm_action = LifeCycleManager::SAVEAS_SUCCESS;
|
||||
break;
|
||||
|
||||
case VirtualMachine::HOTPLUG_PROLOG_POWEROFF:
|
||||
@ -197,7 +197,7 @@ void TransferManagerDriver::protocol(const string& message) const
|
||||
case VirtualMachine::HOTPLUG_SAVEAS:
|
||||
case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF:
|
||||
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
|
||||
lcm_action = LifeCycleManager::SAVEAS_HOT_FAILURE;
|
||||
lcm_action = LifeCycleManager::SAVEAS_FAILURE;
|
||||
break;
|
||||
|
||||
case VirtualMachine::HOTPLUG_PROLOG_POWEROFF:
|
||||
|
@ -16,16 +16,18 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# mvds host:remote_system_ds/disk.i fe:SOURCE
|
||||
# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid
|
||||
# - fe is the front-end hostname
|
||||
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
|
||||
# - host is the target host to deploy the VM
|
||||
# - remote_system_ds is the path for the system datastore in the host
|
||||
# - snapid is the snapshot id. "-1" for none
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
VM_ID=$3
|
||||
DS_ID=$4
|
||||
SNAP_ID=$3
|
||||
VM_ID=$4
|
||||
DS_ID=$5
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
@ -43,13 +45,13 @@ source ${DRIVER_PATH}/../../datastore/ceph/ceph.conf
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
SRC_HOST=`arg_host $SRC`
|
||||
SRC_PATH=`arg_path $SRC`
|
||||
RBD_SRC=`arg_path $SRC`
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Get Image information
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
DISK_ID=$(echo "$SRC_PATH" | $AWK -F. '{print $NF}')
|
||||
DISK_ID=$(echo "$RBD_SRC" | $AWK -F. '{print $NF}')
|
||||
|
||||
XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin"
|
||||
|
||||
@ -76,7 +78,7 @@ else
|
||||
RBD_DST="${RBD_SRC}-${VM_ID}-${DISK_ID}"
|
||||
fi
|
||||
|
||||
if [ -n "$SNAP_ID" ]; then
|
||||
if [ "$SNAP_ID" != "-1" ]; then
|
||||
RBD_DST="${RBD_DST}-${SNAP_ID}@${SNAP_ID}"
|
||||
fi
|
||||
|
||||
|
@ -16,91 +16,4 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# mvds host:remote_system_ds/disk.i fe:SOURCE
|
||||
# - fe is the front-end hostname
|
||||
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
|
||||
# - host is the target host to deploy the VM
|
||||
# - remote_system_ds is the path for the system datastore in the host
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
VM_ID=$3
|
||||
DS_ID=$4
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
|
||||
fi
|
||||
|
||||
DRIVER_PATH=$(dirname $0)
|
||||
|
||||
source $TMCOMMON
|
||||
source ${DRIVER_PATH}/../../datastore/ceph/ceph.conf
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Set dst path and dir
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
SRC_HOST=`arg_host $SRC`
|
||||
SRC_PATH=`arg_path $SRC`
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Get Image information
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
DISK_ID=$(echo "$SRC_PATH" | $AWK -F. '{print $NF}')
|
||||
|
||||
XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin"
|
||||
|
||||
unset i j XPATH_ELEMENTS
|
||||
|
||||
while IFS= read -r -d '' element; do
|
||||
XPATH_ELEMENTS[i++]="$element"
|
||||
done < <(onevm show -x $VM_ID| $XPATH \
|
||||
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SOURCE \
|
||||
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \
|
||||
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER)
|
||||
|
||||
RBD_SRC="${XPATH_ELEMENTS[j++]}"
|
||||
CLONE="${XPATH_ELEMENTS[j++]}"
|
||||
CEPH_USER="${XPATH_ELEMENTS[j++]}"
|
||||
|
||||
# No need to copy back to datastore no cloned images
|
||||
if [ "$CLONE" = "NO" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -n "$CEPH_USER" ]; then
|
||||
RBD="$RBD --id ${CEPH_USER}"
|
||||
fi
|
||||
|
||||
# cloned, so the name will be "<pool>/one-<imageid>-<vmid>-<diskid>"
|
||||
RBD_DST="${RBD_SRC}-${VM_ID}-${DISK_ID}"
|
||||
RBD_SNAP="${VM_ID}-${DISK_ID}"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Move the image back to the datastore
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
log "Dumping $RBD_DST to $DST"
|
||||
|
||||
DUMP_CMD=$(cat <<EOF
|
||||
set -e
|
||||
|
||||
RBD_FORMAT=\$($RBD info $RBD_DST | sed -n 's/.*format: // p')
|
||||
|
||||
if [ "\${RBD_FORMAT}" = "2" ]; then
|
||||
$RBD flatten $RBD_DST
|
||||
$RBD snap unprotect $RBD_SRC@$RBD_SNAP
|
||||
$RBD snap rm $RBD_SRC@$RBD_SNAP
|
||||
fi
|
||||
|
||||
$RBD rename $RBD_DST $DST
|
||||
EOF
|
||||
)
|
||||
|
||||
ssh_exec_and_log "$SRC_HOST" "$DUMP_CMD" \
|
||||
"Error saving $RBD_DST as $DST in $SRC_HOST"
|
||||
|
||||
exit 0
|
||||
|
@ -16,16 +16,18 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# mvds host:remote_system_ds/disk.i fe:SOURCE
|
||||
# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid
|
||||
# - fe is the front-end hostname
|
||||
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
|
||||
# - host is the target host to deploy the VM
|
||||
# - remote_system_ds is the path for the system datastore in the host
|
||||
# - snapid is the snapshot id. "-1" for none
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
VM_ID=$3
|
||||
DS_ID=$4
|
||||
SNAP_ID=$3
|
||||
VM_ID=$4
|
||||
DS_ID=$5
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
|
@ -16,16 +16,18 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# mvds host:remote_system_ds/disk.i fe:SOURCE
|
||||
# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid
|
||||
# - fe is the front-end hostname
|
||||
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
|
||||
# - host is the target host to deploy the VM
|
||||
# - remote_system_ds is the path for the system datastore in the host
|
||||
# - snapid is the snapshot id. "-1" for none
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
VM_ID=$3
|
||||
DS_ID=$4
|
||||
SNAP_ID=$3
|
||||
VM_ID=$4
|
||||
DS_ID=$5
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
|
@ -22,52 +22,4 @@
|
||||
# - host is the target host to deploy the VM
|
||||
# - remote_system_ds is the path for the system datastore in the host
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
VM_ID=$3
|
||||
DS_ID=$4
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
|
||||
fi
|
||||
|
||||
DRIVER_PATH=$(dirname $0)
|
||||
|
||||
source $TMCOMMON
|
||||
source ${DRIVER_PATH}/../../datastore/lvm/lvm.conf
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Set dst path and dir
|
||||
#-------------------------------------------------------------------------------
|
||||
SRC_PATH=`arg_path $SRC`
|
||||
SRC_HOST=`arg_host $SRC`
|
||||
|
||||
DST_PATH=`arg_path $DST`
|
||||
DST_HOST=`arg_host $DST`
|
||||
|
||||
VG_NAME=$(echo $DST_PATH|cut -d. -f1)
|
||||
LV_NAME=$(echo $DST_PATH|cut -d. -f2)
|
||||
|
||||
TARGET_DEV=/dev/$VG_NAME/$LV_NAME
|
||||
|
||||
DUMP_CMD=$(cat <<EOF
|
||||
DEV=\$(readlink $SRC_PATH)
|
||||
LV=\$(basename \$DEV)
|
||||
VM=\$(echo \$LV|cut -d- -f4)
|
||||
DISK_ID=\$(echo \$LV|cut -d- -f5)
|
||||
|
||||
if [ -n "\$VM" -a -n "\$DISK_ID" ]; then
|
||||
$SUDO $LVRENAME ${VG_NAME} \${LV} ${LV_NAME}
|
||||
fi
|
||||
EOF
|
||||
)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Move the image back to the datastore
|
||||
#-------------------------------------------------------------------------------
|
||||
log "Dumping $SRC to $DST"
|
||||
ssh_exec_and_log "$SRC_HOST" "$DUMP_CMD" "Error dumping $SRC to $DST"
|
||||
|
||||
exit 0
|
||||
|
@ -16,60 +16,4 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# mvds host:remote_system_ds/disk.i fe:SOURCE vmid dsid
|
||||
# - fe is the front-end hostname
|
||||
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
|
||||
# - host is the target host to deploy the VM
|
||||
# - remote_system_ds is the path for the system datastore in the host
|
||||
# - vmid is the id of the VM
|
||||
# - dsid is the target datastore (0 is the system datastore)
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
|
||||
VMID=$3
|
||||
DSID=$4
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
|
||||
fi
|
||||
|
||||
. $TMCOMMON
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Set dst path and dir
|
||||
#-------------------------------------------------------------------------------
|
||||
SRC_PATH=`arg_path $SRC`
|
||||
SRC_HOST=`arg_host $SRC`
|
||||
SRC_DIR=`dirname $SRC_PATH`
|
||||
|
||||
DST_ARG_PATH=`arg_path $DST`
|
||||
|
||||
SRC_DS_PATH="$(dirname $(dirname $(dirname $SRC_PATH)))"
|
||||
DST_DS_PATH="$(dirname $(dirname $DST_ARG_PATH))"
|
||||
|
||||
DST_PATH="${SRC_DS_PATH}${DST_ARG_PATH##$DST_DS_PATH}"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Move the image back to the datastore
|
||||
#-------------------------------------------------------------------------------
|
||||
MVSCRIPT=$(cat <<EOF
|
||||
SRC_READLN=\$($READLINK -f $SRC_PATH)
|
||||
DST_READLN=\$($READLINK -f $DST_PATH)
|
||||
|
||||
if [ \( -L $SRC_PATH \) -a \( "\$SRC_READLN" = "\$DST_READLN" \) ] ; then
|
||||
echo "Not moving files to image repo, they are the same"
|
||||
else
|
||||
$QEMU_IMG convert $SRC_PATH -O qcow2 $DST_PATH
|
||||
rm $SRC_PATH
|
||||
fi
|
||||
EOF
|
||||
)
|
||||
|
||||
log "Moving $SRC_PATH to datastore as $DST_PATH"
|
||||
|
||||
ssh_exec_and_log $SRC_HOST "$MVSCRIPT" "Could not move image $DST_PATH"
|
||||
|
||||
exit 0
|
||||
|
@ -1 +0,0 @@
|
||||
../common/not_supported.sh
|
74
src/tm_mad/qcow2/snap_create
Executable file
74
src/tm_mad/qcow2/snap_create
Executable file
@ -0,0 +1,74 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2015, OpenNebula Project (OpenNebula.org), C12G Labs #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||
# not use this file except in compliance with the License. You may obtain #
|
||||
# a copy of the License at #
|
||||
# #
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# snap_create host:parent_image snap_id vmid ds_id
|
||||
|
||||
SRC=$1
|
||||
SNAP_ID=$2
|
||||
VMID=$3
|
||||
DSID=$4
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
DATASTORES=/var/lib/one/datastores
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
|
||||
DATASTORES=$ONE_LOCATION/var/datastores
|
||||
fi
|
||||
|
||||
. $TMCOMMON
|
||||
|
||||
SRC_PATH=`arg_path $SRC`
|
||||
|
||||
SYSTEM_DS_PATH=$(dirname ${SRC_PATH})
|
||||
|
||||
DISK_ID=$(basename ${SRC} | cut -d. -f2)
|
||||
DISK_PATH="${SYSTEM_DS_PATH}/disk.${DISK_ID}"
|
||||
SNAP_DIR="${DISK_PATH}.snap"
|
||||
SNAP_PATH="${SNAP_DIR}/${SNAP_ID}"
|
||||
SNAP_PATH_RELATIVE=$(basename ${SNAP_PATH})
|
||||
CURRENT_PATH=${DISK_PATH}
|
||||
|
||||
if [ ! -d ${SNAP_PATH} ]; then
|
||||
mkdir ${SNAP_DIR}
|
||||
fi
|
||||
|
||||
# Move save current snapshot and create a new one. The snapshot uses
|
||||
# absolute path name as the qemu-img has problems with relative backing
|
||||
# file paths and symlinks
|
||||
mv ${CURRENT_PATH} ${SNAP_PATH}
|
||||
qemu-img create -f qcow2 -b ${SNAP_PATH} ${CURRENT_PATH}
|
||||
|
||||
# TODO: Check that the new snapshot can be created. Roll back in case
|
||||
# of error
|
||||
|
||||
# Convert backing file absolute path to relative path so it works outside
|
||||
# the system directory. Do not do this for snapshot one as:
|
||||
# * It could be a non backed file (persistent)
|
||||
# * The backing file is in images directory, is not relative
|
||||
if [ "$SNAP_ID" != "0" ]; then
|
||||
BACKING_FILE=$(qemu-img info ${SNAP_PATH} | grep '^backing file:' | \
|
||||
cut -d: -f2 | sed 's/^ //')
|
||||
|
||||
if [ -n "$BACKING_FILE" ]; then
|
||||
RELATIVE_BACKING_FILE=$(basename ${BACKING_FILE})
|
||||
|
||||
qemu-img rebase -u -b ${RELATIVE_BACKING_FILE} ${SNAP_PATH}
|
||||
fi
|
||||
fi
|
||||
|
@ -1 +0,0 @@
|
||||
../common/not_supported.sh
|
48
src/tm_mad/qcow2/snap_delete
Executable file
48
src/tm_mad/qcow2/snap_delete
Executable file
@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2015, OpenNebula Project (OpenNebula.org), C12G Labs #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||
# not use this file except in compliance with the License. You may obtain #
|
||||
# a copy of the License at #
|
||||
# #
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# snap_delete host:parent_image snap_id vmid ds_id
|
||||
|
||||
SRC=$1
|
||||
SNAP_ID=$2
|
||||
VMID=$3
|
||||
DSID=$4
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
DATASTORES=/var/lib/one/datastores
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
|
||||
DATASTORES=$ONE_LOCATION/var/datastores
|
||||
fi
|
||||
|
||||
. $TMCOMMON
|
||||
|
||||
SRC_PATH=`arg_path $SRC`
|
||||
|
||||
SYSTEM_DS_PATH=$(dirname ${SRC_PATH})
|
||||
|
||||
DISK_ID=$(basename ${SRC} | cut -d. -f2)
|
||||
DISK_PATH="${SYSTEM_DS_PATH}/disk.${DISK_ID}"
|
||||
SNAP_DIR="${DISK_PATH}.snap"
|
||||
SNAP_PATH="${SNAP_DIR}/${SNAP_ID}"
|
||||
SNAP_PATH_RELATIVE=$(basename ${SNAP_PATH})
|
||||
CURRENT_PATH=${DISK_PATH}
|
||||
|
||||
rm ${SNAP_PATH}
|
||||
|
@ -1 +0,0 @@
|
||||
../common/not_supported.sh
|
49
src/tm_mad/qcow2/snap_revert
Executable file
49
src/tm_mad/qcow2/snap_revert
Executable file
@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2015, OpenNebula Project (OpenNebula.org), C12G Labs #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
|
||||
# not use this file except in compliance with the License. You may obtain #
|
||||
# a copy of the License at #
|
||||
# #
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# snap_create host:parent_image snap_id vmid ds_id
|
||||
|
||||
SRC=$1
|
||||
SNAP_ID=$2
|
||||
VMID=$3
|
||||
DSID=$4
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
DATASTORES=/var/lib/one/datastores
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
|
||||
DATASTORES=$ONE_LOCATION/var/datastores
|
||||
fi
|
||||
|
||||
. $TMCOMMON
|
||||
|
||||
SRC_PATH=`arg_path $SRC`
|
||||
|
||||
SYSTEM_DS_PATH=$(dirname ${SRC_PATH})
|
||||
|
||||
DISK_ID=$(basename ${SRC} | cut -d. -f2)
|
||||
DISK_PATH="${SYSTEM_DS_PATH}/disk.${DISK_ID}"
|
||||
SNAP_DIR="${DISK_PATH}.snap"
|
||||
SNAP_PATH="${SNAP_DIR}/${SNAP_ID}"
|
||||
SNAP_PATH_RELATIVE=$(basename ${SNAP_PATH})
|
||||
CURRENT_PATH=${DISK_PATH}
|
||||
|
||||
rm ${CURRENT_PATH}
|
||||
qemu-img create -f qcow2 -b ${SNAP_PATH} ${CURRENT_PATH}
|
||||
|
@ -16,19 +16,18 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# mvds host:remote_system_ds/disk.i fe:SOURCE vmid dsid
|
||||
# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid
|
||||
# - fe is the front-end hostname
|
||||
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
|
||||
# - host is the target host to deploy the VM
|
||||
# - remote_system_ds is the path for the system datastore in the host
|
||||
# - vmid is the id of the VM
|
||||
# - dsid is the target datastore (0 is the system datastore)
|
||||
# - snapid is the snapshot id. "-1" for none
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
|
||||
VMID=$3
|
||||
DSID=$4
|
||||
SNAP_ID=$3
|
||||
VMID=$4
|
||||
DSID=$5
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
|
@ -16,60 +16,4 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# mvds host:remote_system_ds/disk.i fe:SOURCE vmid dsid
|
||||
# - fe is the front-end hostname
|
||||
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
|
||||
# - host is the target host to deploy the VM
|
||||
# - remote_system_ds is the path for the system datastore in the host
|
||||
# - vmid is the id of the VM
|
||||
# - dsid is the target datastore (0 is the system datastore)
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
|
||||
VMID=$3
|
||||
DSID=$4
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
|
||||
fi
|
||||
|
||||
. $TMCOMMON
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Set dst path and dir
|
||||
#-------------------------------------------------------------------------------
|
||||
SRC_PATH=`arg_path $SRC`
|
||||
SRC_HOST=`arg_host $SRC`
|
||||
SRC_DIR=`dirname $SRC_PATH`
|
||||
|
||||
DST_ARG_PATH=`arg_path $DST`
|
||||
|
||||
SRC_DS_PATH="$(dirname $(dirname $(dirname $SRC_PATH)))"
|
||||
DST_DS_PATH="$(dirname $(dirname $DST_ARG_PATH))"
|
||||
|
||||
DST_PATH="${SRC_DS_PATH}${DST_ARG_PATH##$DST_DS_PATH}"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Move the image back to the datastore
|
||||
#-------------------------------------------------------------------------------
|
||||
MVSCRIPT=$(cat <<EOF
|
||||
SRC_READLN=\$($READLINK -f $SRC_PATH)
|
||||
DST_READLN=\$($READLINK -f $DST_PATH)
|
||||
|
||||
if [ \( -L $SRC_PATH \) -a \( "\$SRC_READLN" = "\$DST_READLN" \) ] ; then
|
||||
echo "Not moving files to image repo, they are the same"
|
||||
rm $SRC_PATH
|
||||
else
|
||||
mv -f $SRC_PATH $DST_PATH
|
||||
fi
|
||||
EOF
|
||||
)
|
||||
|
||||
log "Moving $SRC_PATH to datastore as $DST_PATH"
|
||||
|
||||
ssh_exec_and_log $SRC_HOST "$MVSCRIPT" "Could not move image $DST_PATH"
|
||||
|
||||
exit 0
|
||||
|
@ -16,19 +16,18 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# cpds host:remote_system_ds/disk.i fe:SOURCE vmid dsid
|
||||
# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid
|
||||
# - fe is the front-end hostname
|
||||
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
|
||||
# - host is the target host to deploy the VM
|
||||
# - remote_system_ds is the path for the system datastore in the host
|
||||
# - vmid is the id of the VM
|
||||
# - dsid is the target datastore (0 is the system datastore)
|
||||
# - snapid is the snapshot id. "-1" for none
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
|
||||
VMID=$3
|
||||
DSID=$4
|
||||
SNAP_ID=$3
|
||||
VMID=$4
|
||||
DSID=$5
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
|
@ -16,77 +16,4 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# mvds host:remote_system_ds/disk.i fe:SOURCE vmid dsid
|
||||
# - fe is the front-end hostname
|
||||
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
|
||||
# - host is the target host to deploy the VM
|
||||
# - remote_system_ds is the path for the system datastore in the host
|
||||
# - vmid is the id of the VM
|
||||
# - dsid is the target datastore (0 is the system datastore)
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
|
||||
VMID=$3
|
||||
DSID=$4
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
|
||||
VMWARERC=/etc/one/vmwarerc
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
|
||||
VMWARERC=$ONE_LOCATION/etc/vmwarerc
|
||||
fi
|
||||
|
||||
. $TMCOMMON
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Retrieve needed information, Example (same for SRC)
|
||||
# SRC : esx1:/vmfs/volumes/105/90/disk.0
|
||||
# DST : one:/vmfs/volumes/104/84045f4a
|
||||
# SRC_PATH : /vmfs/volumes/105/90/disk.0
|
||||
# SRC_DISK : /vmfs/volumes/105/90/disk.0/disk.vmdk
|
||||
# SRC_HOST : esx1
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
SRC_PATH=`arg_path $SRC`
|
||||
DST_PATH=`arg_path $DST`
|
||||
|
||||
SRC_DISK="$SRC_PATH/disk.vmdk"
|
||||
DST_DISK="$DST_PATH/disk.vmdk"
|
||||
|
||||
SRC_HOST=`arg_host $SRC`
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Move the image back to the datastore
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
log "Moving $SRC to $DST"
|
||||
|
||||
MVSCRIPT=$(cat <<EOF
|
||||
|
||||
SRC_DISK_LN=\$($READLINK -f $SRC_DISK)
|
||||
DST_DISK_LN=\$($READLINK -f $DST_DISK)
|
||||
|
||||
if [ \( -L $SRC_DISK \) -a \( "\$SRC_DISK_LN" = "\$DST_DISK_LN" \) ]; then
|
||||
echo "Not moving files to image repo, they are the same"
|
||||
elif [ -L "$SRC_PATH.iso" ]; then
|
||||
echo "Not moving the file it is a CDROM"
|
||||
else
|
||||
mkdir -p $DST_PATH
|
||||
$VMKFSTOOLS -U $DST_DISK
|
||||
$VMKFSTOOLS -i $SRC_DISK -d thin $DST_DISK
|
||||
|
||||
if [ -d $DST_PATH ]; then
|
||||
chmod 0770 $DST_PATH
|
||||
else
|
||||
chmod 0660 $DST_PATH
|
||||
fi
|
||||
fi
|
||||
|
||||
EOF
|
||||
)
|
||||
|
||||
ssh_exec_and_log $SRC_HOST "$MVSCRIPT" "Could not move image $SRC to $DST"
|
||||
|
||||
exit 0
|
||||
|
@ -2530,7 +2530,6 @@ int VirtualMachine::set_attach_nic(int nic_id)
|
||||
void VirtualMachine::release_disk_images()
|
||||
{
|
||||
int iid;
|
||||
int save_as_id;
|
||||
int num_disks;
|
||||
int did = -1;
|
||||
|
||||
@ -2572,12 +2571,6 @@ void VirtualMachine::release_disk_images()
|
||||
|
||||
imagem->release_image(oid, iid, img_error);
|
||||
}
|
||||
|
||||
if ( disk->vector_value("SAVE_AS", save_as_id) == 0 )
|
||||
{
|
||||
imagem->release_image(oid, save_as_id, img_error);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -3180,162 +3173,6 @@ int VirtualMachine::generate_context(string &files, int &disk_id,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::get_image_from_disk(int disk_id, bool hot, string& err_str)
|
||||
{
|
||||
int iid = -1;
|
||||
int rc;
|
||||
|
||||
VectorAttribute * disk;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
disk = get_disk(disk_id);
|
||||
|
||||
if ( disk == 0 )
|
||||
{
|
||||
goto error_not_found;
|
||||
}
|
||||
|
||||
if(!((disk->vector_value("SAVE_AS")).empty()))
|
||||
{
|
||||
goto error_saved;
|
||||
}
|
||||
|
||||
if(!(disk->vector_value("PERSISTENT").empty()) && !hot)
|
||||
{
|
||||
goto error_persistent;
|
||||
}
|
||||
|
||||
rc = disk->vector_value("IMAGE_ID", iid);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
goto error_image_id;
|
||||
}
|
||||
|
||||
return iid;
|
||||
|
||||
error_persistent:
|
||||
oss << "Source image for DISK " << disk_id << " is persistent.";
|
||||
goto error_common;
|
||||
|
||||
error_saved:
|
||||
oss << "The DISK " << disk_id << " is already going to be saved.";
|
||||
goto error_common;
|
||||
|
||||
error_image_id:
|
||||
oss << "The DISK " << disk_id << " does not have a valid IMAGE_ID.";
|
||||
goto error_common;
|
||||
|
||||
error_not_found:
|
||||
oss << "The DISK " << disk_id << " does not exist for VM " << oid << ".";
|
||||
|
||||
error_common:
|
||||
err_str = oss.str();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::set_saveas_state(int disk_id, bool hot)
|
||||
{
|
||||
VectorAttribute* disk;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ACTIVE:
|
||||
switch (lcm_state)
|
||||
{
|
||||
case RUNNING:
|
||||
lcm_state = HOTPLUG_SAVEAS;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case POWEROFF:
|
||||
state = ACTIVE;
|
||||
lcm_state = HOTPLUG_SAVEAS_POWEROFF;
|
||||
break;
|
||||
|
||||
case SUSPENDED:
|
||||
state = ACTIVE;
|
||||
lcm_state = HOTPLUG_SAVEAS_SUSPENDED;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
disk = get_disk(disk_id);
|
||||
|
||||
if ( disk != 0 )
|
||||
{
|
||||
if (hot)
|
||||
{
|
||||
disk->replace("HOTPLUG_SAVE_AS_ACTIVE", "YES");
|
||||
}
|
||||
else
|
||||
{
|
||||
disk->replace("SAVE_AS_ACTIVE", "YES");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::clear_saveas_state(int disk_id, bool hot)
|
||||
{
|
||||
VectorAttribute * disk;
|
||||
|
||||
disk = get_disk(disk_id);
|
||||
|
||||
if (disk != 0)
|
||||
{
|
||||
if (hot)
|
||||
{
|
||||
disk->remove("HOTPLUG_SAVE_AS_ACTIVE");
|
||||
disk->remove("HOTPLUG_SAVE_AS");
|
||||
disk->remove("HOTPLUG_SAVE_AS_SOURCE");
|
||||
}
|
||||
else
|
||||
{
|
||||
disk->remove("SAVE_AS_ACTIVE");
|
||||
}
|
||||
}
|
||||
|
||||
switch (lcm_state)
|
||||
{
|
||||
case HOTPLUG_SAVEAS:
|
||||
lcm_state = RUNNING;
|
||||
break;
|
||||
|
||||
case HOTPLUG_SAVEAS_POWEROFF:
|
||||
state = POWEROFF;
|
||||
lcm_state = LCM_INIT;
|
||||
break;
|
||||
|
||||
case HOTPLUG_SAVEAS_SUSPENDED:
|
||||
state = SUSPENDED;
|
||||
lcm_state = LCM_INIT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -3372,27 +3209,130 @@ const VectorAttribute* VirtualMachine::get_disk(int disk_id) const
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::save_disk(int disk_id,
|
||||
const string& source,
|
||||
int img_id)
|
||||
int VirtualMachine::set_saveas_disk(int disk_id, int snap_id, string& err_str)
|
||||
{
|
||||
VectorAttribute * disk;
|
||||
int iid = -1;
|
||||
|
||||
VectorAttribute * disk = get_disk(disk_id);
|
||||
|
||||
if (disk == 0)
|
||||
{
|
||||
err_str = "DISK does not exist.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (disk->vector_value("IMAGE_ID", iid) != 0)
|
||||
{
|
||||
err_str = "DISK does not have a valid IMAGE_ID.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
const Snapshots * snaps = get_disk_snapshots(disk_id, err_str);
|
||||
|
||||
if (snap_id != -1)
|
||||
{
|
||||
if (snaps == 0 || !snaps->exists(snap_id))
|
||||
{
|
||||
err_str = "Snapshot does not exist.";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
disk->replace("HOTPLUG_SAVE_AS_ACTIVE", "YES");
|
||||
disk->replace("HOTPLUG_SAVE_AS_SNAPSHOT_ID", snap_id);
|
||||
|
||||
return iid;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::set_saveas_disk(int disk_id, const string& source, int iid)
|
||||
{
|
||||
if (lcm_state != HOTPLUG_SAVEAS && lcm_state != HOTPLUG_SAVEAS_SUSPENDED
|
||||
&& lcm_state != HOTPLUG_SAVEAS_POWEROFF )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
disk = get_disk(disk_id);
|
||||
VectorAttribute * disk = get_disk(disk_id);
|
||||
|
||||
if ( disk != 0 )
|
||||
if ( disk == 0 )
|
||||
{
|
||||
disk->replace("SAVE_AS_SOURCE", source);
|
||||
return -1;
|
||||
}
|
||||
|
||||
disk->replace("SAVE_AS", img_id);
|
||||
disk->replace("HOTPLUG_SAVE_AS", iid);
|
||||
disk->replace("HOTPLUG_SAVE_AS_SOURCE", source);
|
||||
|
||||
disk->replace("SAVE", "YES");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::set_saveas_state()
|
||||
{
|
||||
string s;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ACTIVE:
|
||||
if (lcm_state != RUNNING)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
lcm_state = HOTPLUG_SAVEAS;
|
||||
break;
|
||||
|
||||
case POWEROFF:
|
||||
state = ACTIVE;
|
||||
lcm_state = HOTPLUG_SAVEAS_POWEROFF;
|
||||
break;
|
||||
|
||||
case SUSPENDED:
|
||||
state = ACTIVE;
|
||||
lcm_state = HOTPLUG_SAVEAS_SUSPENDED;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
log("VM", Log::INFO, "New state is " + lcm_state_to_str(s,lcm_state));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::clear_saveas_state()
|
||||
{
|
||||
string s;
|
||||
|
||||
switch (lcm_state)
|
||||
{
|
||||
case HOTPLUG_SAVEAS:
|
||||
lcm_state = RUNNING;
|
||||
log("VM", Log::INFO, "New state is "+lcm_state_to_str(s,lcm_state));
|
||||
break;
|
||||
|
||||
case HOTPLUG_SAVEAS_POWEROFF:
|
||||
state = POWEROFF;
|
||||
lcm_state = LCM_INIT;
|
||||
log("VM", Log::INFO, "New state is " + vm_state_to_str(s,state));
|
||||
break;
|
||||
|
||||
case HOTPLUG_SAVEAS_SUSPENDED:
|
||||
state = SUSPENDED;
|
||||
lcm_state = LCM_INIT;
|
||||
log("VM", Log::INFO, "New state is " + vm_state_to_str(s,state));
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -3401,79 +3341,49 @@ int VirtualMachine::save_disk(int disk_id,
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::clear_save_disk(int disk_id)
|
||||
int VirtualMachine::clear_saveas_disk()
|
||||
{
|
||||
VectorAttribute * disk;
|
||||
vector<Attribute *> disks;
|
||||
VectorAttribute * disk;
|
||||
|
||||
disk = get_disk(disk_id);
|
||||
int num_disks, image_id;
|
||||
bool active;
|
||||
|
||||
if ( disk != 0 )
|
||||
num_disks = obj_template->get("DISK", disks);
|
||||
|
||||
for(int i=0; i<num_disks; i++)
|
||||
{
|
||||
disk->remove("SAVE_AS_SOURCE");
|
||||
disk->remove("SAVE_AS");
|
||||
disk->replace("SAVE", "NO");
|
||||
disk = dynamic_cast<VectorAttribute * >(disks[i]);
|
||||
|
||||
return 0;
|
||||
if ( disk == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
disk->vector_value("HOTPLUG_SAVE_AS_ACTIVE", active);
|
||||
|
||||
if (active)
|
||||
{
|
||||
disk->vector_value("HOTPLUG_SAVE_AS", image_id);
|
||||
|
||||
disk->remove("HOTPLUG_SAVE_AS_ACTIVE");
|
||||
disk->remove("HOTPLUG_SAVE_AS");
|
||||
disk->remove("HOTPLUG_SAVE_AS_SOURCE");
|
||||
disk->remove("HOTPLUG_SAVE_AS_SNAPSHOT_ID");
|
||||
|
||||
return image_id;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::get_save_disk_image(int disk_id)
|
||||
{
|
||||
VectorAttribute * disk;
|
||||
bool save;
|
||||
int img_id = -1;
|
||||
|
||||
disk = get_disk(disk_id);
|
||||
|
||||
if ( disk != 0 )
|
||||
{
|
||||
disk->vector_value("SAVE", save);
|
||||
|
||||
if (save)
|
||||
{
|
||||
disk->vector_value("SAVE_AS", img_id);
|
||||
}
|
||||
}
|
||||
|
||||
return img_id;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::save_disk_hot(int disk_id,
|
||||
const string& source,
|
||||
int img_id)
|
||||
{
|
||||
VectorAttribute * disk;
|
||||
|
||||
if (lcm_state != HOTPLUG_SAVEAS && lcm_state != HOTPLUG_SAVEAS_SUSPENDED
|
||||
&& lcm_state != HOTPLUG_SAVEAS_POWEROFF )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
disk = get_disk(disk_id);
|
||||
|
||||
if ( disk != 0 )
|
||||
{
|
||||
disk->replace("HOTPLUG_SAVE_AS", img_id);
|
||||
disk->replace("HOTPLUG_SAVE_AS_SOURCE", source);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::get_saveas_disk_hot(int& disk_id, string& source,
|
||||
int& image_id)
|
||||
int VirtualMachine::get_saveas_disk(int& disk_id, string& source,
|
||||
int& image_id, string& snap_id, string& tm_mad, string& ds_id)
|
||||
{
|
||||
vector<Attribute *> disks;
|
||||
VectorAttribute * disk;
|
||||
@ -3494,78 +3404,20 @@ int VirtualMachine::get_saveas_disk_hot(int& disk_id, string& source,
|
||||
|
||||
if ( disk->vector_value("HOTPLUG_SAVE_AS_ACTIVE") == "YES" )
|
||||
{
|
||||
source = disk->vector_value("HOTPLUG_SAVE_AS_SOURCE");
|
||||
|
||||
rc = disk->vector_value("HOTPLUG_SAVE_AS", image_id);
|
||||
rc = disk->vector_value("HOTPLUG_SAVE_AS_SOURCE", source);
|
||||
rc += disk->vector_value("HOTPLUG_SAVE_AS", image_id);
|
||||
rc += disk->vector_value("HOTPLUG_SAVE_AS_SNAPSHOT_ID", snap_id);
|
||||
rc += disk->vector_value("DISK_ID", disk_id);
|
||||
rc += disk->vector_value("DATASTORE_ID", ds_id);
|
||||
rc += disk->vector_value("TM_MAD", tm_mad);
|
||||
|
||||
if ( rc != 0 || source.empty() )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::cancel_saveas_disk(int& image_id)
|
||||
{
|
||||
vector<Attribute *> disks;
|
||||
VectorAttribute * disk;
|
||||
|
||||
int num_disks;
|
||||
|
||||
num_disks = obj_template->get("DISK", disks);
|
||||
|
||||
bool active, hot_active;
|
||||
|
||||
image_id = -1;
|
||||
|
||||
for(int i=0; i<num_disks; i++)
|
||||
{
|
||||
disk = dynamic_cast<VectorAttribute * >(disks[i]);
|
||||
|
||||
if ( disk == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
disk->vector_value("SAVE_AS_ACTIVE", active);
|
||||
disk->vector_value("HOTPLUG_SAVE_AS_ACTIVE", hot_active);
|
||||
|
||||
if (active)
|
||||
{
|
||||
disk->vector_value("SAVE_AS", image_id);
|
||||
|
||||
disk->remove("SAVE_AS_ACTIVE");
|
||||
disk->remove("SAVE_AS_SOURCE");
|
||||
disk->remove("SAVE_AS");
|
||||
|
||||
disk->replace("SAVE", "NO");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hot_active)
|
||||
{
|
||||
disk->vector_value("HOTPLUG_SAVE_AS", image_id);
|
||||
|
||||
disk->remove("HOTPLUG_SAVE_AS_ACTIVE");
|
||||
disk->remove("HOTPLUG_SAVE_AS");
|
||||
disk->remove("HOTPLUG_SAVE_AS_SOURCE");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -4434,5 +4286,14 @@ void VirtualMachine::delete_disk_snapshot(int did, int snap_id)
|
||||
}
|
||||
|
||||
it->second->delete_snapshot(snap_id);
|
||||
|
||||
if (it->second->size() == 0)
|
||||
{
|
||||
Snapshots * tmp = it->second;
|
||||
|
||||
snapshots.erase(it);
|
||||
|
||||
delete tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1028,7 @@ int VirtualMachinePool::calculate_showback(
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachinePool::delete_attach_disk(int vid, bool release_save_as)
|
||||
void VirtualMachinePool::delete_attach_disk(int vid)
|
||||
{
|
||||
VirtualMachine * vm;
|
||||
VectorAttribute * disk;
|
||||
@ -1076,17 +1076,6 @@ void VirtualMachinePool::delete_attach_disk(int vid, bool release_save_as)
|
||||
}
|
||||
|
||||
imagem->release_image(oid, image_id, false);
|
||||
|
||||
// Release non-persistent images in the detach event
|
||||
if (release_save_as)
|
||||
{
|
||||
int save_as_id;
|
||||
|
||||
if ( disk->vector_value("SAVE_AS", save_as_id) == 0 )
|
||||
{
|
||||
imagem->release_image(oid, save_as_id, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // Volatile disk
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user