image-resize.patch
opennebula-3.8.1.resize/include/ImageManager.h 2013-01-14 14:04:13.000000000 -0500 | ||
---|---|---|
168 | 168 |
* occurred describing the error. |
169 | 169 |
* @result 0 on success |
170 | 170 |
*/ |
171 |
int stat_image(Template* img_tmpl, const string& ds_tmpl, string& res); |
|
171 |
int stat_image(Template* img_tmpl, const string& ds_tmpl, string& res); |
|
172 |
|
|
173 |
/** |
|
174 |
* Resizes the image |
|
175 |
* @param iid id of image |
|
176 |
* @param new_size new size of the image in MB |
|
177 |
* @return 0 on success |
|
178 |
*/ |
|
179 |
int resize_image(int iid, int new_size, const string& ds_data, string& error); |
|
172 | 180 |
|
173 | 181 |
private: |
174 | 182 |
/** |
opennebula-3.8.1.resize/include/ImageManagerDriver.h 2013-01-14 12:18:25.000000000 -0500 | ||
---|---|---|
99 | 99 |
* @param drv_msg xml data for the mad operation. |
100 | 100 |
*/ |
101 | 101 |
void rm(int oid, const string& drv_msg) const; |
102 |
|
|
103 |
/** |
|
104 |
* Sends a resize request to the MAD: "RESIZE IMAGE_ID PATH" |
|
105 |
* @param oid the image id. |
|
106 |
* @param drv_msg xml data for the mad operation. |
|
107 |
*/ |
|
108 |
void resize(int oid, const string& drv_msg) const; |
|
102 | 109 |
}; |
103 | 110 |
|
104 | 111 |
/* -------------------------------------------------------------------------- */ |
opennebula-3.8.1.resize/include/RequestManagerImage.h 2013-01-14 12:17:40.000000000 -0500 | ||
---|---|---|
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 |
opennebula-3.8.1.resize/src/datastore_mad/one_datastore.rb 2013-01-14 15:15:05.000000000 -0500 | ||
---|---|---|
44 | 44 |
|
45 | 45 |
# Image Driver Protocol constants |
46 | 46 |
ACTION = { |
47 |
:cp => "CP", |
|
48 |
:rm => "RM", |
|
49 |
:mkfs => "MKFS", |
|
50 |
:log => "LOG", |
|
51 |
:stat => "STAT", |
|
52 |
:clone => "CLONE" |
|
47 |
:cp => "CP", |
|
48 |
:rm => "RM", |
|
49 |
:mkfs => "MKFS", |
|
50 |
:log => "LOG", |
|
51 |
:stat => "STAT", |
|
52 |
:clone => "CLONE", |
|
53 |
:resize => "RESIZE" |
|
53 | 54 |
} |
54 | 55 |
|
55 | 56 |
# Register default actions for the protocol |
... | ... | |
59 | 60 |
:threaded => true, |
60 | 61 |
:retries => 0, |
61 | 62 |
:local_actions => { |
62 |
ACTION[:stat] => nil, |
|
63 |
ACTION[:cp] => nil, |
|
64 |
ACTION[:rm] => nil, |
|
65 |
ACTION[:mkfs] => nil, |
|
66 |
ACTION[:clone]=> nil |
|
63 |
ACTION[:stat] => nil, |
|
64 |
ACTION[:cp] => nil, |
|
65 |
ACTION[:rm] => nil, |
|
66 |
ACTION[:mkfs] => nil, |
|
67 |
ACTION[:clone] => nil, |
|
68 |
ACTION[:resize]=> nil |
|
67 | 69 |
} |
68 | 70 |
}.merge!(options) |
69 | 71 |
|
... | ... | |
84 | 86 |
register_action(ACTION[:mkfs].to_sym, method("mkfs")) |
85 | 87 |
register_action(ACTION[:stat].to_sym, method("stat")) |
86 | 88 |
register_action(ACTION[:clone].to_sym,method("clone")) |
89 |
register_action(ACTION[:resize].to_sym,method("resize")) |
|
87 | 90 |
end |
88 | 91 |
|
89 | 92 |
############################################################################ |
... | ... | |
115 | 118 |
do_image_action(id, ds, :clone, "#{drv_message} #{id}") |
116 | 119 |
end |
117 | 120 |
|
121 |
def resize(id, drv_message) |
|
122 |
ds = get_ds_type(drv_message) |
|
123 |
do_image_action(id, ds, :resize, "#{drv_message} #{id}") |
|
124 |
end |
|
125 |
|
|
118 | 126 |
private |
119 | 127 |
|
120 | 128 |
def is_available?(ds, id, action) |
opennebula-3.8.1.resize/src/image/ImageManagerActions.cc 2013-01-14 15:00:41.000000000 -0500 | ||
---|---|---|
737 | 737 |
|
738 | 738 |
return rc; |
739 | 739 |
} |
740 |
/* -------------------------------------------------------------------------- */ |
|
741 |
/* -------------------------------------------------------------------------- */ |
|
742 |
|
|
743 |
int ImageManager::resize_image(int iid, |
|
744 |
int new_size, |
|
745 |
const string& ds_data, |
|
746 |
string& error) |
|
747 |
{ |
|
748 |
const ImageManagerDriver* imd = get(); |
|
749 |
|
|
750 |
ostringstream oss; |
|
751 |
Image * img; |
|
752 |
|
|
753 |
string img_tmpl; |
|
754 |
string * drv_msg; |
|
755 |
|
|
756 |
if ( imd == 0 ) |
|
757 |
{ |
|
758 |
error = "Could not get datastore driver"; |
|
759 |
|
|
760 |
NebulaLog::log("ImM",Log::ERROR, error); |
|
761 |
return -1; |
|
762 |
} |
|
763 |
|
|
764 |
img = ipool->get(iid, true); |
|
765 |
|
|
766 |
if (img == 0) |
|
767 |
{ |
|
768 |
error = "Cannot resize image, it does not exist"; |
|
769 |
return -1; |
|
770 |
} |
|
771 |
|
|
772 |
if (img->get_state() != Image::READY ) |
|
773 |
{ |
|
774 |
oss << "Cannot resize image in state: " |
|
775 |
<< Image::state_to_str(img->get_state()); |
|
776 |
|
|
777 |
error = oss.str(); |
|
778 |
img->unlock(); |
|
779 |
return -1; |
|
780 |
} |
|
781 |
|
|
782 |
img->set_state(Image::LOCKED); |
|
783 |
img->set_size(new_size); |
|
784 |
|
|
785 |
ipool->update(img); |
|
786 |
|
|
787 |
drv_msg = format_message(img->to_xml(img_tmpl), ds_data); |
|
788 |
|
|
789 |
imd->resize(img->get_oid(), *drv_msg); |
|
790 |
|
|
791 |
oss << "Resizing image " << img->get_path() |
|
792 |
<<" to " << img->get_size() |
|
793 |
<< "Mb (type: " << img->get_fstype() << ")"; |
|
794 |
|
|
795 |
NebulaLog::log("ImM", Log::INFO, oss); |
|
796 |
|
|
797 |
img->unlock(); |
|
798 |
|
|
799 |
delete drv_msg; |
|
800 |
|
|
801 |
return 0; |
|
802 |
} |
|
740 | 803 |
|
741 | 804 |
/* -------------------------------------------------------------------------- */ |
742 | 805 |
/* -------------------------------------------------------------------------- */ |
opennebula-3.8.1.resize/src/image/ImageManagerDriver.cc 2013-01-14 12:52:25.000000000 -0500 | ||
---|---|---|
83 | 83 |
} |
84 | 84 |
|
85 | 85 |
/* -------------------------------------------------------------------------- */ |
86 |
|
|
87 |
void ImageManagerDriver::resize(int oid, const string& drv_msg) const |
|
88 |
{ |
|
89 |
ostringstream os; |
|
90 |
|
|
91 |
os << "RESIZE " << oid << " " << drv_msg << endl; |
|
92 |
|
|
93 |
write(os); |
|
94 |
} |
|
95 |
|
|
96 |
/* -------------------------------------------------------------------------- */ |
|
86 | 97 |
/* -------------------------------------------------------------------------- */ |
87 | 98 |
|
88 | 99 |
/* ************************************************************************** */ |
... | ... | |
522 | 533 |
} |
523 | 534 |
|
524 | 535 |
/* -------------------------------------------------------------------------- */ |
536 |
|
|
537 |
static void resize_action(istringstream& is, |
|
538 |
ImagePool* ipool, |
|
539 |
int id, |
|
540 |
const string& result) |
|
541 |
{ |
|
542 |
string info; |
|
543 |
Image * image; |
|
544 |
|
|
545 |
ostringstream oss; |
|
546 |
|
|
547 |
image = ipool->get(id, true); |
|
548 |
|
|
549 |
if ( image == 0 ) |
|
550 |
{ |
|
551 |
return; |
|
552 |
} |
|
553 |
|
|
554 |
if ( result == "FAILURE" ) |
|
555 |
{ |
|
556 |
goto error; |
|
557 |
} |
|
558 |
|
|
559 |
image->set_state(Image::READY); |
|
560 |
|
|
561 |
ipool->update(image); |
|
562 |
|
|
563 |
image->unlock(); |
|
564 |
|
|
565 |
NebulaLog::log("ImM", Log::INFO, "Image successfully resized."); |
|
566 |
|
|
567 |
return; |
|
568 |
|
|
569 |
error: |
|
570 |
oss << "Error resizing image"; |
|
571 |
|
|
572 |
getline(is, info); |
|
573 |
|
|
574 |
if (!info.empty() && (info[0] != '-')) |
|
575 |
{ |
|
576 |
oss << ": " << info; |
|
577 |
} |
|
578 |
|
|
579 |
NebulaLog::log("ImM", Log::ERROR, oss); |
|
580 |
|
|
581 |
image->set_template_error_message(oss.str()); |
|
582 |
image->set_state(Image::ERROR); |
|
583 |
|
|
584 |
ipool->update(image); |
|
585 |
|
|
586 |
image->unlock(); |
|
587 |
|
|
588 |
return; |
|
589 |
} |
|
590 |
|
|
591 |
/* -------------------------------------------------------------------------- */ |
|
525 | 592 |
/* -------------------------------------------------------------------------- */ |
526 | 593 |
|
527 | 594 |
void ImageManagerDriver::protocol( |
... | ... | |
591 | 658 |
{ |
592 | 659 |
rm_action(is, ipool, id, result); |
593 | 660 |
} |
661 |
else if ( action == "RESIZE" ) |
|
662 |
{ |
|
663 |
resize_action(is, ipool, id, result); |
|
664 |
} |
|
594 | 665 |
else if (action == "LOG") |
595 | 666 |
{ |
596 | 667 |
getline(is,info); |
opennebula-3.8.1.resize/src/rm/RequestManager.cc 2013-01-14 12:17:40.000000000 -0500 | ||
---|---|---|
333 | 333 |
xmlrpc_c::methodPtr image_enable(new ImageEnable()); |
334 | 334 |
xmlrpc_c::methodPtr image_chtype(new ImageChangeType()); |
335 | 335 |
xmlrpc_c::methodPtr image_clone(new ImageClone()); |
336 |
xmlrpc_c::methodPtr image_resize(new ImageResize()); |
|
336 | 337 |
|
337 | 338 |
// Chown Methods |
338 | 339 |
xmlrpc_c::methodPtr vm_chown(new VirtualMachineChown()); |
... | ... | |
444 | 445 |
/* Image related methods*/ |
445 | 446 |
RequestManagerRegistry.addMethod("one.image.persistent", image_persistent); |
446 | 447 |
RequestManagerRegistry.addMethod("one.image.enable", image_enable); |
447 |
RequestManagerRegistry.addMethod("one.image.update", image_update);
|
|
448 |
RequestManagerRegistry.addMethod("one.image.update", image_update); |
|
448 | 449 |
RequestManagerRegistry.addMethod("one.image.allocate", image_allocate); |
449 | 450 |
RequestManagerRegistry.addMethod("one.image.delete", image_delete); |
450 | 451 |
RequestManagerRegistry.addMethod("one.image.info", image_info); |
... | ... | |
452 | 453 |
RequestManagerRegistry.addMethod("one.image.chmod", image_chmod); |
453 | 454 |
RequestManagerRegistry.addMethod("one.image.chtype", image_chtype); |
454 | 455 |
RequestManagerRegistry.addMethod("one.image.clone", image_clone); |
456 |
RequestManagerRegistry.addMethod("one.image.resize", image_resize); |
|
455 | 457 |
|
456 | 458 |
RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info); |
457 | 459 |
|
opennebula-3.8.1.resize/src/rm/RequestManagerImage.cc 2013-01-14 18:05:33.000000000 -0500 | ||
---|---|---|
303 | 303 |
success_response(new_id, att); |
304 | 304 |
} |
305 | 305 |
|
306 |
/* ------------------------------------------------------------------------- */ |
|
307 |
/* ------------------------------------------------------------------------- */ |
|
308 |
|
|
309 |
void ImageResize::request_execute(xmlrpc_c::paramList const& paramList, |
|
310 |
RequestAttributes& att) |
|
311 |
{ |
|
312 |
int id = xmlrpc_c::value_int(paramList.getInt(1)); |
|
313 |
int new_size = xmlrpc_c::value_int(paramList.getInt(2)); |
|
314 |
|
|
315 |
int rc, ds_id, size, uid, gid; |
|
316 |
string error_str, ds_data; |
|
317 |
|
|
318 |
Template img_usage; |
|
319 |
Image * img; |
|
320 |
Datastore * ds; |
|
321 |
|
|
322 |
Nebula& nd = Nebula::instance(); |
|
323 |
ImageManager * imagem = nd.get_imagem(); |
|
324 |
DatastorePool * dspool = nd.get_dspool(); |
|
325 |
|
|
326 |
if ( basic_authorization(id, att) == false ) |
|
327 |
{ |
|
328 |
return; |
|
329 |
} |
|
330 |
|
|
331 |
// ------------------------- Get Image info ------------------------- |
|
332 |
|
|
333 |
img = static_cast<Image *>(pool->get(id,true)); |
|
334 |
|
|
335 |
if ( img == 0 ) |
|
336 |
{ |
|
337 |
failure_response(NO_EXISTS, |
|
338 |
get_error(object_name(auth_object),id), |
|
339 |
att); |
|
340 |
|
|
341 |
return; |
|
342 |
} |
|
343 |
|
|
344 |
ds_id = img->get_ds_id(); |
|
345 |
size = img->get_size(); |
|
346 |
uid = img->get_uid(); |
|
347 |
gid = img->get_gid(); |
|
348 |
|
|
349 |
img->unlock(); |
|
350 |
|
|
351 |
// ------------------------- Get Datastore info ---------------------------- |
|
352 |
|
|
353 |
ds = dspool->get(ds_id, true); |
|
354 |
|
|
355 |
if ( ds == 0 ) |
|
356 |
{ |
|
357 |
failure_response(NO_EXISTS, |
|
358 |
get_error(object_name(PoolObjectSQL::DATASTORE), ds_id), |
|
359 |
att); |
|
360 |
|
|
361 |
return; |
|
362 |
} |
|
363 |
|
|
364 |
ds->to_xml(ds_data); |
|
365 |
|
|
366 |
ds->unlock(); |
|
367 |
|
|
368 |
// -------------------------- Check and Update Quotas ---------------------------- |
|
369 |
|
|
370 |
// Check quota for owner of the image, not the request caller |
|
371 |
RequestAttributes quota_att(uid, gid, att); |
|
372 |
|
|
373 |
img_usage.add("DATASTORE", ds_id); |
|
374 |
img_usage.add("IMAGES", 0); // Don't update images count |
|
375 |
|
|
376 |
if ( new_size > size ) |
|
377 |
{ |
|
378 |
// Update quota usage to extended size |
|
379 |
img_usage.add("SIZE", new_size - size); |
|
380 |
|
|
381 |
if ( quota_authorization(&img_usage, Quotas::DATASTORE, quota_att) == false ) |
|
382 |
{ |
|
383 |
// Over quota |
|
384 |
return; |
|
385 |
} |
|
386 |
} |
|
387 |
|
|
388 |
rc = imagem->resize_image(id, new_size, ds_data, error_str); |
|
389 |
|
|
390 |
if( rc < 0 ) |
|
391 |
{ |
|
392 |
if ( new_size > size ) { |
|
393 |
// Rollback quota update |
|
394 |
quota_rollback(&img_usage, Quotas::DATASTORE, quota_att); |
|
395 |
} |
|
396 |
|
|
397 |
failure_response(INTERNAL, request_error(error_str,""), att); |
|
398 |
return; |
|
399 |
} |
|
400 |
|
|
401 |
// If disk is being shrinked, reduce quota usage |
|
402 |
if ( new_size < size ) |
|
403 |
{ |
|
404 |
img_usage.add("SIZE", size - new_size); |
|
405 |
|
|
406 |
quota_rollback(&img_usage, Quotas::DATASTORE, quota_att); |
|
407 |
} |
|
408 |
|
|
409 |
success_response(id, att); |
|
410 |
} |
|
306 | 411 |
|
opennebula-3.8.1.resize/src/um/QuotaDatastore.cc 2013-01-14 18:04:07.000000000 -0500 | ||
---|---|---|
31 | 31 |
map<string, float> ds_request; |
32 | 32 |
|
33 | 33 |
string ds_id; |
34 |
int size; |
|
34 |
int size, images;
|
|
35 | 35 |
|
36 | 36 |
tmpl->get("DATASTORE", ds_id); |
37 | 37 |
|
... | ... | |
47 | 47 |
return false; |
48 | 48 |
} |
49 | 49 |
|
50 |
ds_request.insert(make_pair("IMAGES",1)); |
|
51 |
ds_request.insert(make_pair("SIZE", size)); |
|
50 |
if ( tmpl->get("IMAGES", images) == false ) |
|
51 |
{ |
|
52 |
// Increment image count by default |
|
53 |
images = 1; |
|
54 |
} |
|
55 |
|
|
56 |
ds_request.insert(make_pair("IMAGES", images)); |
|
57 |
ds_request.insert(make_pair("SIZE", size)); |
|
52 | 58 |
|
53 | 59 |
return check_quota(ds_id, ds_request, error); |
54 | 60 |
} |
... | ... | |
61 | 67 |
map<string, float> ds_request; |
62 | 68 |
|
63 | 69 |
string ds_id; |
64 |
int size; |
|
70 |
int size, images;
|
|
65 | 71 |
|
66 | 72 |
tmpl->get("DATASTORE", ds_id); |
67 | 73 |
|
... | ... | |
75 | 81 |
return; |
76 | 82 |
} |
77 | 83 |
|
78 |
ds_request.insert(make_pair("IMAGES",1)); |
|
79 |
ds_request.insert(make_pair("SIZE", size)); |
|
84 |
if ( tmpl->get("IMAGES", images) == false ) |
|
85 |
{ |
|
86 |
// Decrement image count by default |
|
87 |
images = 1; |
|
88 |
} |
|
89 |
|
|
90 |
ds_request.insert(make_pair("IMAGES", images)); |
|
91 |
ds_request.insert(make_pair("SIZE", size)); |
|
80 | 92 |
|
81 | 93 |
del_quota(ds_id, ds_request); |
82 | 94 |
} |