diff --git a/include/Image.h b/include/Image.h index d700cb0c8f..60ba8cdb82 100644 --- a/include/Image.h +++ b/include/Image.h @@ -39,6 +39,22 @@ public: DATABLOCK = 2 /** < User persistent data device */ }; + /** + * Return the string representation of an ImageType + * @param ob the type + * @return the string + */ + static string type_to_str(ImageType ob) + { + switch (ob) + { + case OS: return "OS" ; break; + case CDROM: return "CDROM" ; break; + case DATABLOCK: return "DATABLOCK" ; break; + default: return ""; + } + }; + /** * Image State */ @@ -199,6 +215,17 @@ public: 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() + { + ImageTemplate * it = static_cast(obj_template); + + return it->is_saving(); + } + /** * Set permissions for the Image. Extends the PoolSQLObject method * by checking the persistent state of the image. @@ -291,7 +318,7 @@ public: /** * Factory method for image templates */ - Template * get_new_template() + Template * get_new_template() const { return new ImageTemplate; } @@ -299,11 +326,19 @@ public: /** * Returns the Datastore ID */ - int get_ds_id() + int get_ds_id() const { return ds_id; }; + /** + * Returns the Datastore ID + */ + const string& get_ds_name() const + { + return ds_name; + }; + private: // ------------------------------------------------------------------------- diff --git a/include/ImageManager.h b/include/ImageManager.h index 98b30be801..3d75dfd4a9 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -99,14 +99,8 @@ public: /** * Releases an image and triggers any needed operations in the repo * @param iid image id of the image to be released - * @param disk_path base path for disk location - * @param disk number for this image in the VM - * @param saveid id of image to save the current image */ - void release_image(const string& iid, - const string& disk_path, - int disk_num, - const string& saveid) + void release_image(const string& iid) { int image_id; istringstream iss; @@ -114,30 +108,14 @@ public: iss.str(iid); iss >> image_id; - release_image(image_id, disk_path, disk_num, saveid); + release_image(image_id); }; /** * Releases an image and triggers any needed operations in the repo * @param iid image id of the image to be released - * @param disk_path base path for disk location - * @param disk number for this image in the VM - * @param saveid id of image to save the current image */ - void release_image(int iid, - const string& disk_path, - int disk_num, - const string& saveid); - - /** - * Moves a VM disk to the Image Repository - * @param disk_path base path for disk location - * @param disk number for this image in the VM - * @param saveid id of image to save the current image - */ - void disk_to_image(const string& disk_path, - int disk_num, - const string& save_id); + void release_image(int iid); /** * Enables the image @@ -205,9 +183,7 @@ private: * @param action the name of the action * @param arg arguments for the action function */ - void do_action( - const string & action, - void * arg); + void do_action(const string& action, void * arg); /** * Acquires an image updating its state. @@ -230,9 +206,7 @@ private: * @param ds_data Datastore XML representation * @return the XML message */ - string * format_message( - const string& img_data, - const string& ds_data); + string * format_message(const string& img_data, const string& ds_data); }; #endif /*IMAGE_MANAGER_H*/ diff --git a/include/ImageTemplate.h b/include/ImageTemplate.h index 21dd0eec64..36c2727bb6 100644 --- a/include/ImageTemplate.h +++ b/include/ImageTemplate.h @@ -41,11 +41,36 @@ public: return Template::check(rs_attr, restricted_attributes); }; + bool is_saving() + { + string saving; + + get(saving_attribute, saving); + + return (saving.empty() == false); + } + + void set_saving() + { + SingleAttribute * attr= new SingleAttribute(saving_attribute, "YES"); + + erase(saving_attribute); + + set(attr); + } + + void unset_saving() + { + erase(saving_attribute); + } + private: friend class ImagePool; static vector restricted_attributes; + static string saving_attribute; + /** * Stores the attributes as restricted, these attributes will be used in * ImageTemplate::check diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 89355b1999..6b5472807e 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -48,8 +48,11 @@ protected: virtual void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att) = 0; - bool vm_authorization(int id, ImageTemplate *tmpl, - RequestAttributes& att, PoolObjectAuth* host_perms); + bool vm_authorization(int id, + ImageTemplate * tmpl, + RequestAttributes& att, + PoolObjectAuth * host_perms, + PoolObjectAuth * ds_perm); int get_host_information(int hid, string& name, string& vmm, string& vnm, RequestAttributes& att, PoolObjectAuth& host_perms); diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 8a7fa03708..f9dbc1b147 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -653,15 +653,27 @@ public: int generate_context(string &files); // ------------------------------------------------------------------------ - // Image repository related functions + // Datastore related functions // ------------------------------------------------------------------------ /** * Set the SAVE_AS attribute for the "disk_id"th disk. * @param disk_id Index of the disk to save - * @param img_id ID of the image this disk will be saved to. + * @param source to save the disk (SAVE_AS_SOURCE) + * @param img_id ID of the image this disk will be saved to (SAVE_AS). * @return 0 if success */ - int save_disk(int disk_id, int img_id, string& error_str); + int save_disk(const string& 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 + * @return -1 if failure + */ + int get_image_from_disk(int disk_id, string& error_str); // ------------------------------------------------------------------------ // Authorization related functions diff --git a/src/image/Image.cc b/src/image/Image.cc index 6772927672..058d8551a0 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -96,6 +96,7 @@ int Image::insert(SqlDB *db, string& error_str) string dev_prefix; string source_attr; string aname; + string saved_id; ostringstream oss; @@ -159,34 +160,36 @@ int Image::insert(SqlDB *db, string& error_str) erase_template_attribute("PATH", path); erase_template_attribute("SOURCE", source); - // The template should contain PATH or SOURCE - if ( source.empty() && path.empty() ) + if (!isSaving()) //Not a saving image { - string size_attr; - istringstream iss; - - erase_template_attribute("SIZE", size_attr); - erase_template_attribute("FSTYPE", fs_type); - - // DATABLOCK image needs SIZE and FSTYPE - if (type != DATABLOCK || size_attr.empty() || fs_type.empty()) + if ( source.empty() && path.empty() ) { - goto error_no_path; + string size_attr; + istringstream iss; + + erase_template_attribute("SIZE", size_attr); + erase_template_attribute("FSTYPE", fs_type); + + // DATABLOCK image needs SIZE and FSTYPE + if (type != DATABLOCK || size_attr.empty() || fs_type.empty()) + { + goto error_no_path; + } + + iss.str(size_attr); + + iss >> size_mb; + + if (iss.fail() == true) + { + goto error_size_format; + } } - - iss.str(size_attr); - - iss >> size_mb; - - if (iss.fail() == true) + else if ( !source.empty() && !path.empty() ) { - goto error_size_format; + goto error_path_and_source; } } - else if ( !source.empty() && !path.empty() ) - { - goto error_path_and_source; - } state = LOCKED; //LOCKED till the ImageManager copies it to the Repository diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 2c499730d5..eb8056b4cc 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -128,84 +128,14 @@ int ImageManager::acquire_image(Image *img, string& error) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void ImageManager::move_image(Image *img, const string& source) -{ - const ImageManagerDriver* imd = get(); - ostringstream oss; - - if ( imd == 0 ) - { - NebulaLog::log("ImM",Log::ERROR, - "Could not get driver to update repository"); - return; - } - - oss << "Moving disk " << source << " to repository image " - << img->get_oid(); - - imd->mv(img->get_oid(),source,img->get_source()); - - NebulaLog::log("ImM",Log::INFO,oss); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void ImageManager::disk_to_image(const string& disk_path, - int disk_num, - const string& save_id) -{ - int sid; - - istringstream iss; - Image * img; - - ostringstream disk_file; - - iss.str(save_id); - - iss >> sid; - - img = ipool->get(sid,true); - - if ( img == 0 ) - { - NebulaLog::log("ImM",Log::ERROR,"Could not get image to saveas disk."); - } - else - { - disk_file << disk_path << "/disk." << disk_num; - - move_image(img,disk_file.str()); - } - - img->unlock(); -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -void ImageManager::release_image(int iid, - const string& disk_path, - int disk_num, - const string& save_id) +void ImageManager::release_image(int iid) { int rvms; - int sid = -1; - - istringstream iss; - Image * img; + Image * img; ostringstream disk_file; - if ( save_id.empty() == false ) - { - iss.str(save_id); - - iss >> sid; - } - img = ipool->get(iid,true); if ( img == 0 ) @@ -218,48 +148,14 @@ void ImageManager::release_image(int iid, case Image::USED: rvms = img->dec_running(); - if ( img->isPersistent() && !disk_path.empty() ) + if ( img->isPersistent() || rvms == 0 ) { - disk_file << disk_path << "/disk." << disk_num; - - img->set_state(Image::LOCKED); - - move_image(img,disk_file.str()); + img->set_state(Image::READY); ipool->update(img); img->unlock(); } - else - { - if ( rvms == 0) - { - img->set_state(Image::READY); - } - - ipool->update(img); - - img->unlock(); - - if ( sid != -1 ) - { - img = ipool->get(sid,true); - - if ( img == 0 ) - { - NebulaLog::log("ImM",Log::ERROR, - "Could not get image to saveas disk."); - } - else - { - disk_file << disk_path << "/disk." << disk_num; - - move_image(img,disk_file.str()); - } - - img->unlock(); - } - } break; case Image::DISABLED: @@ -372,8 +268,7 @@ int ImageManager::delete_image(int iid, const string& ds_data) } drv_msg = format_message(img->to_xml(img_tmpl), ds_data); - - source = img->get_source(); + source = img->get_source(); if (source.empty()) { @@ -431,30 +326,25 @@ int ImageManager::register_image(int iid, const string& ds_data) drv_msg = format_message(img->to_xml(img_tmpl), ds_data); path = img->get_path(); - if ( path.empty() == true ) //NO PATH -> USE SOURCE OR MKFS FOR DATABLOCK + if ( path.empty() == true ) //NO PATH { - if ( img->get_type() == Image::DATABLOCK) - { - string fs = img->get_fstype(); - int size = img->get_size(); + string source = img->get_source(); + if ( img->isSaving() || img->get_type() == Image::DATABLOCK ) + { imd->mkfs(img->get_oid(), *drv_msg); - oss << "Creating disk at " << img->get_source() << " of " - << size << "Mb with format " << fs; + oss << "Creating disk at " << source + << " of "<< img->get_size() + << "Mb (type: " << img->get_fstype() << ")"; } - else + else if ( !source.empty() ) //Source in Template { - string source = img->get_source(); + img->set_state(Image::READY); + ipool->update(img); - if (source != "-") //SAVE_AS IMAGE DO NOT ENABLE THE IMAGE - { - img->set_state(Image::READY); - ipool->update(img); - - oss << "Using source " << img->get_source() - << " from template for image " << img->get_name(); - } + oss << "Using source " << source + << " from template for image " << img->get_name(); } } else //PATH -> COPY TO REPOSITORY AS SOURCE diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index c04f5ff565..64ad5e128e 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -179,40 +179,69 @@ void ImageManagerDriver::protocol( goto error_cp; } } - else if ( action == "MV" ) - { - if ( result == "SUCCESS" ) - { - if (image->get_source() == "-") - { - image->set_source(source); - } - - image->set_size(size_mb); - - image->set_state(Image::READY); - - ipool->update(image); - - NebulaLog::log("ImM", Log::INFO, "Image saved and ready to use."); - } - else - { - goto error_mv; - } - } else if ( action == "MKFS" ) { if ( result == "SUCCESS" ) { - image->set_source(source); - image->set_size(size_mb); + bool is_saving = image->isSaving(); - image->set_state(Image::READY); + string disk_id; + string vm_id; + int rc; + + image->set_source(source); + + if (is_saving) + { + image->get_template_attribute("SAVED_DISK_ID",disk_id); + image->get_template_attribute("SAVED_VM_ID", vm_id); + } + else + { + image->set_size(size_mb); + + image->set_state(Image::READY); + + NebulaLog::log("ImM", Log::INFO, + "Image created and ready to use"); + } ipool->update(image); - NebulaLog::log("ImM", Log::INFO, "Image created and ready to use"); + image->unlock(); + + if (is_saving) + { + Nebula& nd = Nebula::instance(); + + VirtualMachinePool * vmpool = nd.get_vmpool(); + + VirtualMachine * vm; + istringstream iss(vm_id); + + int vm_id_i; + + iss >> vm_id_i; + + vm = vmpool->get(vm_id_i, true); + + if ( vm == 0 ) + { + goto error_save_no_vm; + } + + rc = vm->save_disk(disk_id, source, id); + + if ( rc == -1 ) + { + vm->unlock(); + goto error_save_state_vm; + } + + vm->unlock(); + } + + return; } else { @@ -255,11 +284,6 @@ error_cp: os << "Error copying image in the repository"; goto error_common; -error_mv: - os.str(""); - os << "Error saving image to the repository"; - goto error_common; - error_mkfs: os.str(""); os << "Error creating datablock"; @@ -280,9 +304,28 @@ error_rm: } NebulaLog::log("ImM", Log::ERROR, os); - return; +error_save_no_vm: + os.str(""); + os << "Image created for SAVE_AS, but the associated VM does not exist."; + + goto error_save_common; + +error_save_state_vm: + os.str(""); + os << "Image created for SAVE_AS, but VM is no longer running"; + + goto error_save_common; + +error_save_common: + image = ipool->get(id, true); + + if (image == 0 ) + { + return; + } + error_common: getline(is,info); diff --git a/src/image/ImageTemplate.cc b/src/image/ImageTemplate.cc index 60c1fb623a..3ef5145020 100644 --- a/src/image/ImageTemplate.cc +++ b/src/image/ImageTemplate.cc @@ -21,5 +21,7 @@ vector ImageTemplate::restricted_attributes; +string ImageTemplate::saving_attribute = "SAVE_AS"; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index cca7b559cf..24e3cd17aa 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -24,7 +24,8 @@ bool RequestManagerVirtualMachine::vm_authorization(int oid, ImageTemplate * tmpl, RequestAttributes& att, - PoolObjectAuth * host_perm) + PoolObjectAuth * host_perm, + PoolObjectAuth * ds_perm) { PoolObjectSQL * object; PoolObjectAuth vm_perms; @@ -57,13 +58,19 @@ bool RequestManagerVirtualMachine::vm_authorization(int oid, { ar.add_auth(AuthRequest::MANAGE, *host_perm); } - else if (tmpl != 0) + + if (tmpl != 0) { string t_xml; ar.add_create_auth(PoolObjectSQL::IMAGE, tmpl->to_xml(t_xml)); } + if ( ds_perm != 0 ) + { + ar.add_auth(AuthRequest::USE, *ds_perm); + } + if (UserPool::authorize(ar) == -1) { failure_response(AUTHORIZATION, @@ -177,7 +184,7 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, Nebula& nd = Nebula::instance(); DispatchManager * dm = nd.get_dm(); - if ( vm_authorization(id,0,att,0) == false ) + if ( vm_authorization(id, 0, att, 0, 0) == false ) { return; } @@ -282,7 +289,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, return; } - auth = vm_authorization(id,0,att,&host_perms); + auth = vm_authorization(id, 0, att, &host_perms, 0); if ( auth == false ) { @@ -344,7 +351,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList return; } - auth = vm_authorization(id,0,att,&host_perms); + auth = vm_authorization(id, 0, att, &host_perms, 0); if ( auth == false ) { @@ -394,8 +401,10 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) { - Nebula& nd = Nebula::instance(); - ImagePool * ipool = nd.get_ipool(); + 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)); @@ -403,24 +412,100 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis string img_type = xmlrpc_c::value_string(paramList.getString(4)); VirtualMachine * vm; - string vm_owner; - int iid; - ImageTemplate * itemplate; + int iid_orig; + + Image * img; + Datastore * ds; int rc; - ostringstream oss; string error_str; - // ------------------ Template for the new image ------------------ + // ------------------------------------------------------------------------- + // Prepare and check the VM/DISK to be saved_as + // ------------------------------------------------------------------------- + + if ( (vm = get_vm(id, att)) == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::VM), id), + att); + return; + } - oss << "NAME= \"" << img_name << "\"" << endl; - oss << "PUBLIC = NO " << endl; - oss << "SOURCE = - " << endl; - oss << "SAVED_DISK_ID = " << disk_id << endl; - oss << "SAVED_VM_ID = " << id << endl; + iid_orig = vm->get_image_from_disk(disk_id, error_str); - if ( img_type != "" ) + pool->update(vm); + + vm->unlock(); + + if ( iid_orig == -1 ) + { + failure_response(INTERNAL, + request_error("Can not used selected DISK", error_str), + att); + return; + } + + // ------------------------------------------------------------------------- + // Get the data of the Image to be saved + // ------------------------------------------------------------------------- + + if ( (img = ipool->get(iid_orig, true)) != 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::IMAGE), iid_orig), + att); + return; + } + + int ds_id = img->get_ds_id(); + string ds_name = img->get_ds_name(); + int size = img->get_size(); + + Image::ImageType type = img->get_type(); + + img->unlock(); + + if ((ds = dspool->get(ds_id, true)) == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::DATASTORE), ds_id), + att); + return; + } + + // ------------------------------------------------------------------------- + // Get the data of the DataStore for the new image + // ------------------------------------------------------------------------- + string ds_data; + PoolObjectAuth ds_perms; + + ds->get_permissions(ds_perms); + ds->to_xml(ds_data); + + ds->unlock(); + + // ------------------------------------------------------------------------- + // Create a template for the new Image + // ------------------------------------------------------------------------- + ImageTemplate * itemplate; + ostringstream oss; + + oss << "NAME = \"" << img_name << "\"" << endl; + oss << "PUBLIC = NO" << endl; + oss << "SIZE = " << size << endl; + oss << "FS_TYPE = save_as" << endl; + + oss << "SAVED_IMAGE_ID = " << iid_orig << endl; + oss << "SAVED_DISK_ID = " << disk_id << endl; + oss << "SAVED_VM_ID = " << id << endl; + + if ( img_type.empty() ) + { + oss << "TYPE = " << Image::type_to_str(type) << endl; + } + else { oss << "TYPE = " << img_type << endl; } @@ -429,24 +514,32 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis itemplate->parse_str_or_xml(oss.str(), error_str); - // ------------------ Authorize the operation ------------------ + itemplate->set_saving(); - if ( vm_authorization(id,itemplate,att,0) == false ) + // ------------------------------------------------------------------------- + // Authorize the operation + // ------------------------------------------------------------------------- + + if ( vm_authorization(id, itemplate, att, 0, &ds_perms) == false ) { delete itemplate; return; } - // ------------------ Create the image ------------------ - - // TODO: get values from source image DS - int ds_id = 0; - string ds_name = ""; - string ds_data = ""; - - rc = ipool->allocate(att.uid, att.gid, att.uname, att.gname, itemplate, - ds_id, ds_name, ds_data, &iid, error_str); + // ------------------------------------------------------------------------- + // Create the image + // ------------------------------------------------------------------------- + rc = ipool->allocate(att.uid, + att.gid, + att.uname, + att.gname, + itemplate, + ds_id, + ds_name, + ds_data, + &iid, + error_str); if (rc < 0) { failure_response(INTERNAL, @@ -454,50 +547,6 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis return; } - // ------------------ Store image id to save the disk ------------------ - - if ( (vm = get_vm(id, att)) == 0 ) - { - Image * img; - - if ( (img = ipool->get(iid,true)) != 0 ) - { - string tmp_error; - - ipool->drop(img, tmp_error); - img->unlock(); - } - - return; - } - - rc = vm->save_disk(disk_id, iid, error_str); - - if ( rc == 0 ) - { - pool->update(vm); - } - - vm->unlock(); - - if ( rc == -1 ) - { - Image * img; - - if ( (img = ipool->get(iid,true)) != 0 ) - { - string tmp_error; - - ipool->drop(img, tmp_error); - img->unlock(); - } - - failure_response(INTERNAL, - request_error("Can not save_as disk",error_str), - att); - return; - } - // Return the new allocated Image ID success_response(iid, att); } diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 20cfe4e821..d3d1212d84 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -790,26 +790,23 @@ void TransferManager::epilog_action(int vid) tm_mad = disk->vector_value("TM_MAD"); - if ( save == "YES" ) + if ( save == "YES" ) //TODO SAVE_SOURCE { - ostringstream tsource; string source; + string save_source; - source = disk->vector_value("SOURCE"); + source = disk->vector_value("SOURCE"); + save_source = disk->vector_value("SAVE_AS_SOURCE"); - if ( source.empty() ) + if ( source.empty() && save_source.empty() ) { vm->log("TM", Log::ERROR, "No SOURCE to save disk image"); continue; } - if ( source.find(":") == string::npos ) //Regular file + if (!save_source.empty()) //Use the save as source instead { - tsource << nd.get_nebula_hostname() << ":" << source << " "; - } - else //TM Plugin specific protocol - { - tsource << source << " "; + source = save_source; } //MVDS tm_mad hostname:remote_system_dir/disk.0 @@ -817,7 +814,7 @@ void TransferManager::epilog_action(int vid) << tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << i << " " - << tsource.str() << endl; + << source << endl; } else if ( !tm_mad.empty() ) //No saving disk and no system_ds disk { diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 759c4b89ce..c3f8fb05fa 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -824,9 +824,7 @@ error_common: for ( it=acquired_images.begin() ; it < acquired_images.end(); it++ ) { - // Set disk_path and save_id to empty string, this way the image manager - // won't try to move any files - imagem->release_image(*it,"",-1,""); + imagem->release_image(*it); } return -1; @@ -849,14 +847,7 @@ void VirtualMachine::release_disk_images() Nebula& nd = Nebula::instance(); imagem = nd.get_imagem(); - num_disks = get_template_attribute("DISK",disks); - - if (hasHistory() != 0) - { - /* - disk_base_path = get_local_dir(); - */ - } + num_disks = get_template_attribute("DISK",disks); for(int i=0; ivector_value("IMAGE_ID"); - saveas = disk->vector_value("SAVE_AS"); + iid = disk->vector_value("IMAGE_ID"); - if ( iid.empty() ) + if ( !iid.empty() ) { - if (!saveas.empty()) - { - imagem->disk_to_image(disk_base_path,i,saveas); - } - } - else - { - imagem->release_image(iid,disk_base_path,i,saveas); + imagem->release_image(iid); } } } @@ -1037,26 +1020,45 @@ int VirtualMachine::generate_context(string &files) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualMachine::save_disk(int disk_id, int img_id, string& error_str) +static int id_from_attr (VectorAttribute * attr, const char *name) { - int num_disks; + int id; + string id_str; + + id_str = attr->vector_value(name); + + if (id_str.empty()) + { + return -1; + } + + istringstream iss(id_str); + iss >> id; + + return id; +} + +/* -------------------------------------------------------------------------- */ + +int VirtualMachine::get_image_from_disk(int disk_id, string& error_str) +{ + int num_disks; + int tid; + int iid = -1; + vector disks; VectorAttribute * disk; - string disk_id_str; - int tmp_disk_id; - ostringstream oss; - istringstream iss; + + num_disks = obj_template->get("DISK",disks); if ( state == DONE || state == FAILED ) { goto error_state; } - num_disks = obj_template->get("DISK",disks); - - for(int i=0; i(disks[i]); @@ -1065,12 +1067,9 @@ int VirtualMachine::save_disk(int disk_id, int img_id, string& error_str) continue; } - disk_id_str = disk->vector_value("DISK_ID"); + tid = id_from_attr(disk,"DISK_ID"); - iss.str(disk_id_str); - iss >> tmp_disk_id; - - if ( tmp_disk_id == disk_id ) + if ( disk_id == tid ) { if(!((disk->vector_value("SAVE_AS")).empty())) { @@ -1082,12 +1081,16 @@ int VirtualMachine::save_disk(int disk_id, int img_id, string& error_str) goto error_persistent; } + iid = id_from_attr(disk, "IMAGE_ID"); + + if (iid == -1) + { + goto error_image_id; + } + disk->replace("SAVE", "YES"); - oss << (img_id); - disk->replace("SAVE_AS", oss.str()); - - return 0; + return iid; } } @@ -1105,6 +1108,10 @@ 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 << "."; @@ -1117,6 +1124,53 @@ error_common: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int VirtualMachine::save_disk(const string& disk_id, + const string& source, + int img_id) +{ + vector disks; + VectorAttribute * disk; + + int num_disks; + string tdisk_id; + + ostringstream oss; + + if ( state == DONE || state == FAILED ) + { + return -1; + } + + num_disks = obj_template->get("DISK",disks); + + for(int i=0; i(disks[i]); + + if ( disk == 0 ) + { + continue; + } + + tdisk_id = disk->vector_value("DISK_ID"); + + if ( tdisk_id == disk_id ) + { + disk->replace("SAVE_AS_SOURCE", source); + + oss << (img_id); + disk->replace("SAVE_AS", oss.str()); + + break; + } + } + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void VirtualMachine::set_auth_request(int uid, AuthRequest& ar, VirtualMachineTemplate *tmpl)