1
0
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:
Ruben S. Montero 2015-06-16 02:07:37 +02:00
commit 6cb6eea178
40 changed files with 705 additions and 1414 deletions

View File

@ -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();
}
/**

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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");
}

View File

@ -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

View File

@ -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();

View File

@ -21,8 +21,5 @@
vector<string> ImageTemplate::restricted_attributes;
string ImageTemplate::saving_attribute = "SAVE_AS";
string ImageTemplate::saving_hot_attribute = "SAVE_AS_HOT";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -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;

View File

@ -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")
{

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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);
}
/* ------------------------------------------------------------------------- */

View File

@ -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);
}

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1 +0,0 @@
../common/not_supported.sh

74
src/tm_mad/qcow2/snap_create Executable file
View 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

View File

@ -1 +0,0 @@
../common/not_supported.sh

48
src/tm_mad/qcow2/snap_delete Executable file
View 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}

View File

@ -1 +0,0 @@
../common/not_supported.sh

49
src/tm_mad/qcow2/snap_revert Executable file
View 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}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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
{