image-resize-4.2.patch
| include/ImageManager.h | ||
|---|---|---|
| 180 | 180 |
* occurred describing the error. |
| 181 | 181 |
* @result 0 on success |
| 182 | 182 |
*/ |
| 183 |
int stat_image(Template* img_tmpl, const string& ds_tmpl, string& res); |
|
| 183 |
int stat_image(Template* img_tmpl, const string& ds_tmpl, string& res); |
|
| 184 |
|
|
| 185 |
/** |
|
| 186 |
* Resizes the image |
|
| 187 |
* @param iid id of image |
|
| 188 |
* @param new_size new size of the image in MB |
|
| 189 |
* @return 0 on success |
|
| 190 |
*/ |
|
| 191 |
int resize_image(int iid, int new_size, const string& ds_data, string& error); |
|
| 184 | 192 |
|
| 185 | 193 |
/** |
| 186 | 194 |
* Trigger a monitor action for the datastore. |
| include/ImageManagerDriver.h | ||
|---|---|---|
| 114 | 114 |
* @param drv_msg xml data for the mad operation. |
| 115 | 115 |
*/ |
| 116 | 116 |
void monitor(int oid, const string& drv_msg) const; |
| 117 |
|
|
| 118 |
/** |
|
| 119 |
* Sends a resize request to the MAD: "RESIZE IMAGE_ID PATH" |
|
| 120 |
* @param oid the image id. |
|
| 121 |
* @param drv_msg xml data for the mad operation. |
|
| 122 |
*/ |
|
| 123 |
void resize(int oid, const string& drv_msg) const; |
|
| 117 | 124 |
}; |
| 118 | 125 |
|
| 119 | 126 |
/* -------------------------------------------------------------------------- */ |
| include/RequestManagerImage.h | ||
|---|---|---|
| 121 | 121 |
|
| 122 | 122 |
/* -------------------------------------------------------------------------- */ |
| 123 | 123 |
/* -------------------------------------------------------------------------- */ |
| 124 |
|
|
| 125 |
class ImageResize : public RequestManagerImage |
|
| 126 |
{
|
|
| 127 |
public: |
|
| 128 |
ImageResize(): |
|
| 129 |
RequestManagerImage("ImageResize",
|
|
| 130 |
"Changes the size of an image", |
|
| 131 |
"A:sii"){};
|
|
| 132 |
|
|
| 133 |
~ImageResize(){};
|
|
| 134 |
|
|
| 135 |
void request_execute(xmlrpc_c::paramList const& _paramList, |
|
| 136 |
RequestAttributes& att); |
|
| 137 |
}; |
|
| 138 |
|
|
| 139 |
/* -------------------------------------------------------------------------- */ |
|
| 140 |
/* -------------------------------------------------------------------------- */ |
|
| 124 | 141 |
/* -------------------------------------------------------------------------- */ |
| 125 | 142 |
|
| 126 | 143 |
#endif |
| src/datastore_mad/one_datastore.rb | ||
|---|---|---|
| 50 | 50 |
:log => "LOG", |
| 51 | 51 |
:stat => "STAT", |
| 52 | 52 |
:clone => "CLONE", |
| 53 |
:monitor => "MONITOR" |
|
| 53 |
:monitor => "MONITOR", |
|
| 54 |
:resize => "RESIZE" |
|
| 54 | 55 |
} |
| 55 | 56 |
|
| 56 | 57 |
# Register default actions for the protocol |
| ... | ... | |
| 65 | 66 |
ACTION[:rm] => nil, |
| 66 | 67 |
ACTION[:mkfs] => nil, |
| 67 | 68 |
ACTION[:clone] => nil, |
| 68 |
ACTION[:monitor] => nil |
|
| 69 |
ACTION[:monitor] => nil, |
|
| 70 |
ACTION[:resize] => nil |
|
| 69 | 71 |
} |
| 70 | 72 |
}.merge!(options) |
| 71 | 73 |
|
| ... | ... | |
| 87 | 89 |
register_action(ACTION[:stat].to_sym, method("stat"))
|
| 88 | 90 |
register_action(ACTION[:clone].to_sym, method("clone"))
|
| 89 | 91 |
register_action(ACTION[:monitor].to_sym, method("monitor"))
|
| 92 |
register_action(ACTION[:resize].to_sym,method("resize"))
|
|
| 90 | 93 |
end |
| 91 | 94 |
|
| 92 | 95 |
############################################################################ |
| ... | ... | |
| 123 | 126 |
do_image_action(id, ds, :monitor, "#{drv_message} #{id}", true)
|
| 124 | 127 |
end |
| 125 | 128 |
|
| 129 |
def resize(id, drv_message) |
|
| 130 |
ds = get_ds_type(drv_message) |
|
| 131 |
do_image_action(id, ds, :resize, "#{drv_message} #{id}")
|
|
| 132 |
end |
|
| 133 |
|
|
| 126 | 134 |
private |
| 127 | 135 |
|
| 128 | 136 |
def is_available?(ds, id, action) |
| src/image/ImageManagerActions.cc | ||
|---|---|---|
| 826 | 826 |
|
| 827 | 827 |
return rc; |
| 828 | 828 |
} |
| 829 |
/* -------------------------------------------------------------------------- */ |
|
| 830 |
/* -------------------------------------------------------------------------- */ |
|
| 831 |
|
|
| 832 |
int ImageManager::resize_image(int iid, |
|
| 833 |
int new_size, |
|
| 834 |
const string& ds_data, |
|
| 835 |
string& error) |
|
| 836 |
{
|
|
| 837 |
const ImageManagerDriver* imd = get(); |
|
| 838 |
|
|
| 839 |
ostringstream oss; |
|
| 840 |
Image * img; |
|
| 841 |
|
|
| 842 |
string img_tmpl; |
|
| 843 |
string * drv_msg; |
|
| 844 |
|
|
| 845 |
if ( imd == 0 ) |
|
| 846 |
{
|
|
| 847 |
error = "Could not get datastore driver"; |
|
| 848 |
|
|
| 849 |
NebulaLog::log("ImM",Log::ERROR, error);
|
|
| 850 |
return -1; |
|
| 851 |
} |
|
| 852 |
|
|
| 853 |
img = ipool->get(iid, true); |
|
| 854 |
|
|
| 855 |
if (img == 0) |
|
| 856 |
{
|
|
| 857 |
error = "Cannot resize image, it does not exist"; |
|
| 858 |
return -1; |
|
| 859 |
} |
|
| 860 |
|
|
| 861 |
if ( img->get_state() != Image::READY && |
|
| 862 |
img->get_state() != Image::USED && |
|
| 863 |
img->get_state() != Image::USED_PERS ) |
|
| 864 |
{
|
|
| 865 |
oss << "Cannot resize image in state: " |
|
| 866 |
<< Image::state_to_str(img->get_state()); |
|
| 867 |
|
|
| 868 |
error = oss.str(); |
|
| 869 |
img->unlock(); |
|
| 870 |
return -1; |
|
| 871 |
} |
|
| 872 |
|
|
| 873 |
img->set_state(Image::LOCKED); |
|
| 874 |
img->set_size(new_size); |
|
| 875 |
|
|
| 876 |
ipool->update(img); |
|
| 877 |
|
|
| 878 |
drv_msg = format_message(img->to_xml(img_tmpl), ds_data); |
|
| 879 |
|
|
| 880 |
imd->resize(img->get_oid(), *drv_msg); |
|
| 881 |
|
|
| 882 |
oss << "Resizing image " << img->get_path() |
|
| 883 |
<<" to " << img->get_size() |
|
| 884 |
<< "Mb (type: " << img->get_fstype() << ")"; |
|
| 885 |
|
|
| 886 |
NebulaLog::log("ImM", Log::INFO, oss);
|
|
| 887 |
|
|
| 888 |
img->unlock(); |
|
| 889 |
|
|
| 890 |
delete drv_msg; |
|
| 891 |
|
|
| 892 |
return 0; |
|
| 893 |
} |
|
| 829 | 894 |
|
| 830 | 895 |
/* -------------------------------------------------------------------------- */ |
| 831 | 896 |
/* -------------------------------------------------------------------------- */ |
| src/image/ImageManagerDriver.cc | ||
|---|---|---|
| 94 | 94 |
} |
| 95 | 95 |
|
| 96 | 96 |
/* -------------------------------------------------------------------------- */ |
| 97 |
|
|
| 98 |
void ImageManagerDriver::resize(int oid, const string& drv_msg) const |
|
| 99 |
{
|
|
| 100 |
ostringstream os; |
|
| 101 |
|
|
| 102 |
os << "RESIZE " << oid << " " << drv_msg << endl; |
|
| 103 |
|
|
| 104 |
write(os); |
|
| 105 |
} |
|
| 106 |
|
|
| 107 |
/* -------------------------------------------------------------------------- */ |
|
| 97 | 108 |
/* -------------------------------------------------------------------------- */ |
| 98 | 109 |
|
| 99 | 110 |
/* ************************************************************************** */ |
| ... | ... | |
| 666 | 677 |
} |
| 667 | 678 |
|
| 668 | 679 |
/* -------------------------------------------------------------------------- */ |
| 680 |
|
|
| 681 |
static void resize_action(istringstream& is, |
|
| 682 |
ImagePool* ipool, |
|
| 683 |
int id, |
|
| 684 |
const string& result) |
|
| 685 |
{
|
|
| 686 |
string info; |
|
| 687 |
Image * image; |
|
| 688 |
|
|
| 689 |
ostringstream oss; |
|
| 690 |
|
|
| 691 |
image = ipool->get(id, true); |
|
| 692 |
|
|
| 693 |
if ( image == 0 ) |
|
| 694 |
{
|
|
| 695 |
return; |
|
| 696 |
} |
|
| 697 |
|
|
| 698 |
if ( result == "FAILURE" ) |
|
| 699 |
{
|
|
| 700 |
goto error; |
|
| 701 |
} |
|
| 702 |
|
|
| 703 |
if ( image->get_running() == 0 ) {
|
|
| 704 |
image->set_state(Image::READY); |
|
| 705 |
} else if ( image->isPersistent() ) {
|
|
| 706 |
image->set_state(Image::USED_PERS); |
|
| 707 |
} else {
|
|
| 708 |
image->set_state(Image::USED); |
|
| 709 |
} |
|
| 710 |
|
|
| 711 |
ipool->update(image); |
|
| 712 |
|
|
| 713 |
image->unlock(); |
|
| 714 |
|
|
| 715 |
NebulaLog::log("ImM", Log::INFO, "Image successfully resized.");
|
|
| 716 |
|
|
| 717 |
return; |
|
| 718 |
|
|
| 719 |
error: |
|
| 720 |
oss << "Error resizing image"; |
|
| 721 |
|
|
| 722 |
getline(is, info); |
|
| 723 |
|
|
| 724 |
if (!info.empty() && (info[0] != '-')) |
|
| 725 |
{
|
|
| 726 |
oss << ": " << info; |
|
| 727 |
} |
|
| 728 |
|
|
| 729 |
NebulaLog::log("ImM", Log::ERROR, oss);
|
|
| 730 |
|
|
| 731 |
image->set_template_error_message(oss.str()); |
|
| 732 |
image->set_state(Image::ERROR); |
|
| 733 |
|
|
| 734 |
ipool->update(image); |
|
| 735 |
|
|
| 736 |
image->unlock(); |
|
| 737 |
|
|
| 738 |
return; |
|
| 739 |
} |
|
| 740 |
|
|
| 741 |
/* -------------------------------------------------------------------------- */ |
|
| 669 | 742 |
/* -------------------------------------------------------------------------- */ |
| 670 | 743 |
|
| 671 | 744 |
void ImageManagerDriver::protocol(const string& message) const |
| ... | ... | |
| 740 | 813 |
{
|
| 741 | 814 |
monitor_action(is, dspool, id, result); |
| 742 | 815 |
} |
| 816 |
else if ( action == "RESIZE" ) |
|
| 817 |
{
|
|
| 818 |
resize_action(is, ipool, id, result); |
|
| 819 |
} |
|
| 743 | 820 |
else if (action == "LOG") |
| 744 | 821 |
{
|
| 745 | 822 |
getline(is,info); |
| src/rm/RequestManager.cc | ||
|---|---|---|
| 343 | 343 |
xmlrpc_c::methodPtr image_enable(new ImageEnable()); |
| 344 | 344 |
xmlrpc_c::methodPtr image_chtype(new ImageChangeType()); |
| 345 | 345 |
xmlrpc_c::methodPtr image_clone(new ImageClone()); |
| 346 |
xmlrpc_c::methodPtr image_resize(new ImageResize()); |
|
| 346 | 347 |
|
| 347 | 348 |
// Chown Methods |
| 348 | 349 |
xmlrpc_c::methodPtr vm_chown(new VirtualMachineChown()); |
| ... | ... | |
| 494 | 495 |
RequestManagerRegistry.addMethod("one.image.chtype", image_chtype);
|
| 495 | 496 |
RequestManagerRegistry.addMethod("one.image.clone", image_clone);
|
| 496 | 497 |
RequestManagerRegistry.addMethod("one.image.rename", image_rename);
|
| 498 |
RequestManagerRegistry.addMethod("one.image.resize", image_resize);
|
|
| 497 | 499 |
|
| 498 | 500 |
RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info);
|
| 499 | 501 |
|
| src/rm/RequestManagerImage.cc | ||
|---|---|---|
| 423 | 423 |
success_response(new_id, att); |
| 424 | 424 |
} |
| 425 | 425 |
|
| 426 |
/* ------------------------------------------------------------------------- */ |
|
| 427 |
/* ------------------------------------------------------------------------- */ |
|
| 428 |
|
|
| 429 |
void ImageResize::request_execute(xmlrpc_c::paramList const& paramList, |
|
| 430 |
RequestAttributes& att) |
|
| 431 |
{
|
|
| 432 |
int id = xmlrpc_c::value_int(paramList.getInt(1)); |
|
| 433 |
int new_size = xmlrpc_c::value_int(paramList.getInt(2)); |
|
| 434 |
|
|
| 435 |
int rc, ds_id, size, uid, gid; |
|
| 436 |
string error_str, ds_data; |
|
| 437 |
|
|
| 438 |
Template img_usage; |
|
| 439 |
Image * img; |
|
| 440 |
Datastore * ds; |
|
| 441 |
|
|
| 442 |
Nebula& nd = Nebula::instance(); |
|
| 443 |
ImageManager * imagem = nd.get_imagem(); |
|
| 444 |
DatastorePool * dspool = nd.get_dspool(); |
|
| 445 |
|
|
| 446 |
if ( basic_authorization(id, att) == false ) |
|
| 447 |
{
|
|
| 448 |
return; |
|
| 449 |
} |
|
| 450 |
|
|
| 451 |
// ------------------------- Get Image info ------------------------- |
|
| 452 |
|
|
| 453 |
img = static_cast<Image *>(pool->get(id,true)); |
|
| 454 |
|
|
| 455 |
if ( img == 0 ) |
|
| 456 |
{
|
|
| 457 |
failure_response(NO_EXISTS, |
|
| 458 |
get_error(object_name(auth_object),id), |
|
| 459 |
att); |
|
| 460 |
|
|
| 461 |
return; |
|
| 462 |
} |
|
| 463 |
|
|
| 464 |
ds_id = img->get_ds_id(); |
|
| 465 |
size = img->get_size(); |
|
| 466 |
uid = img->get_uid(); |
|
| 467 |
gid = img->get_gid(); |
|
| 468 |
|
|
| 469 |
img->unlock(); |
|
| 470 |
|
|
| 471 |
// ------------------------- Get Datastore info ---------------------------- |
|
| 472 |
|
|
| 473 |
ds = dspool->get(ds_id, true); |
|
| 474 |
|
|
| 475 |
if ( ds == 0 ) |
|
| 476 |
{
|
|
| 477 |
failure_response(NO_EXISTS, |
|
| 478 |
get_error(object_name(PoolObjectSQL::DATASTORE), ds_id), |
|
| 479 |
att); |
|
| 480 |
|
|
| 481 |
return; |
|
| 482 |
} |
|
| 483 |
|
|
| 484 |
ds->to_xml(ds_data); |
|
| 485 |
|
|
| 486 |
ds->unlock(); |
|
| 487 |
|
|
| 488 |
// -------------------------- Check and Update Quotas ---------------------------- |
|
| 489 |
|
|
| 490 |
// Check quota for owner of the image, not the request caller |
|
| 491 |
RequestAttributes quota_att(uid, gid, att); |
|
| 492 |
|
|
| 493 |
img_usage.add("DATASTORE", ds_id);
|
|
| 494 |
img_usage.add("IMAGES", 0); // Don't update images count
|
|
| 495 |
|
|
| 496 |
if ( new_size > size ) |
|
| 497 |
{
|
|
| 498 |
// Update quota usage to extended size |
|
| 499 |
img_usage.add("SIZE", new_size - size);
|
|
| 500 |
|
|
| 501 |
if ( quota_authorization(&img_usage, Quotas::DATASTORE, quota_att) == false ) |
|
| 502 |
{
|
|
| 503 |
// Over quota |
|
| 504 |
return; |
|
| 505 |
} |
|
| 506 |
} |
|
| 507 |
|
|
| 508 |
rc = imagem->resize_image(id, new_size, ds_data, error_str); |
|
| 509 |
|
|
| 510 |
if( rc < 0 ) |
|
| 511 |
{
|
|
| 512 |
if ( new_size > size ) {
|
|
| 513 |
// Rollback quota update |
|
| 514 |
quota_rollback(&img_usage, Quotas::DATASTORE, quota_att); |
|
| 515 |
} |
|
| 516 |
|
|
| 517 |
failure_response(INTERNAL, request_error(error_str,""), att); |
|
| 518 |
return; |
|
| 519 |
} |
|
| 520 |
|
|
| 521 |
// If disk is being shrinked, reduce quota usage |
|
| 522 |
if ( new_size < size ) |
|
| 523 |
{
|
|
| 524 |
img_usage.add("SIZE", size - new_size);
|
|
| 525 |
|
|
| 526 |
quota_rollback(&img_usage, Quotas::DATASTORE, quota_att); |
|
| 527 |
} |
|
| 528 |
|
|
| 529 |
success_response(id, att); |
|
| 530 |
} |
|
| 426 | 531 |
|
| src/um/QuotaDatastore.cc | ||
|---|---|---|
| 32 | 32 |
map<string, float> ds_request; |
| 33 | 33 |
|
| 34 | 34 |
string ds_id; |
| 35 |
int size; |
|
| 35 |
int size, images;
|
|
| 36 | 36 |
|
| 37 | 37 |
tmpl->get("DATASTORE", ds_id);
|
| 38 | 38 |
|
| ... | ... | |
| 48 | 48 |
return false; |
| 49 | 49 |
} |
| 50 | 50 |
|
| 51 |
ds_request.insert(make_pair("IMAGES",1));
|
|
| 52 |
ds_request.insert(make_pair("SIZE", size));
|
|
| 51 |
if ( tmpl->get("IMAGES", images) == false )
|
|
| 52 |
{
|
|
| 53 |
// Increment image count by default |
|
| 54 |
images = 1; |
|
| 55 |
} |
|
| 56 |
|
|
| 57 |
ds_request.insert(make_pair("IMAGES", images));
|
|
| 58 |
ds_request.insert(make_pair("SIZE", size));
|
|
| 53 | 59 |
|
| 54 | 60 |
return check_quota(ds_id, ds_request, default_quotas, error); |
| 55 | 61 |
} |
| ... | ... | |
| 62 | 68 |
map<string, float> ds_request; |
| 63 | 69 |
|
| 64 | 70 |
string ds_id; |
| 65 |
int size; |
|
| 71 |
int size, images;
|
|
| 66 | 72 |
|
| 67 | 73 |
tmpl->get("DATASTORE", ds_id);
|
| 68 | 74 |
|
| ... | ... | |
| 76 | 82 |
return; |
| 77 | 83 |
} |
| 78 | 84 |
|
| 79 |
ds_request.insert(make_pair("IMAGES",1));
|
|
| 80 |
ds_request.insert(make_pair("SIZE", size));
|
|
| 85 |
if ( tmpl->get("IMAGES", images) == false )
|
|
| 86 |
{
|
|
| 87 |
// Decrement image count by default |
|
| 88 |
images = 1; |
|
| 89 |
} |
|
| 90 |
|
|
| 91 |
ds_request.insert(make_pair("IMAGES", images));
|
|
| 92 |
ds_request.insert(make_pair("SIZE", size));
|
|
| 81 | 93 |
|
| 82 | 94 |
del_quota(ds_id, ds_request); |
| 83 | 95 |
} |
| 84 |
- |
|