From 34cb7a19be6aa1c4ba8334484ee6dd8d12786b2c Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 12 Nov 2011 03:20:59 +0100 Subject: [PATCH] feature #966: Images can now be referred by name with IMAGE. Conflicts for images with the same name can be resolved with IMAGE_UID and IMAGE_UNAME --- include/ImageManager.h | 8 ++ include/ImagePool.h | 1 - src/image/ImageManagerActions.cc | 25 +++++ src/image/ImagePool.cc | 155 +++++++++++++++++++++++-------- src/image/test/ImagePoolTest.cc | 61 +++++++++++- src/vm/VirtualMachine.cc | 15 --- 6 files changed, 208 insertions(+), 57 deletions(-) diff --git a/include/ImageManager.h b/include/ImageManager.h index 509a25f7d2..59e3f744ef 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -85,6 +85,14 @@ public: * @return pointer to the image or 0 if could not be acquired */ Image * acquire_image(int image_id); + + /** + * Try to acquire an image from the repository for a VM. + * @param name of the image + * @param id of owner + * @return pointer to the image or 0 if could not be acquired + */ + Image * acquire_image(const string& name, int uid); /** * Releases an image and triggers any needed operations in the repo diff --git a/include/ImagePool.h b/include/ImagePool.h index 7eab479ddf..a19337a7a9 100644 --- a/include/ImagePool.h +++ b/include/ImagePool.h @@ -135,7 +135,6 @@ public: * @return 0 on success, * -1 error, * -2 not using the pool, - * -3 deprecated NAME found */ int disk_attribute(VectorAttribute * disk, int disk_id, diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 0b625a2818..39e5ec681b 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -46,6 +46,31 @@ Image * ImageManager::acquire_image(int image_id) /* -------------------------------------------------------------------------- */ +Image * ImageManager::acquire_image(const string& name, int uid) +{ + Image * img; + int rc; + + img = ipool->get(name,uid,true); + + if ( img == 0 ) + { + return 0; + } + + rc = acquire_image(img); + + if ( rc != 0 ) + { + img->unlock(); + img = 0; + } + + return img; +} + +/* -------------------------------------------------------------------------- */ + int ImageManager::acquire_image(Image *img) { int rc = 0; diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc index 87ff03086a..3c38972236 100644 --- a/src/image/ImagePool.cc +++ b/src/image/ImagePool.cc @@ -136,6 +136,69 @@ error_common: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +static int get_disk_uid(VectorAttribute * disk, int _uid) +{ + istringstream is; + + string uid_s ; + string uname; + int uid; + + if (!(uid_s = disk->vector_value("IMAGE_UID")).empty()) + { + is.str(uid_s); + is >> uid; + + if( is.fail() ) + { + return -1; + } + } + else if (!(uname = disk->vector_value("IMAGE_UNAME")).empty()) + { + User * user; + Nebula& nd = Nebula::instance(); + UserPool * upool = nd.get_upool(); + + user = upool->get(uname,true); + + if ( user == 0 ) + { + return -1; + } + + uid = user->get_oid(); + + user->unlock(); + } + else + { + uid = _uid; + } + + return uid; +} + +/* -------------------------------------------------------------------------- */ + +static int get_disk_id(const string& id_s) +{ + istringstream is; + int id; + + is.str(id_s); + is >> id; + + if( is.fail() ) + { + return -1; + } + + return id; +} + +/* -------------------------------------------------------------------------- */ + int ImagePool::disk_attribute(VectorAttribute * disk, int disk_id, int * index, @@ -152,36 +215,44 @@ int ImagePool::disk_attribute(VectorAttribute * disk, Nebula& nd = Nebula::instance(); ImageManager * imagem = nd.get_imagem(); - istringstream is; - - source = disk->vector_value("IMAGE"); - - if (!source.empty()) + if (!(source = disk->vector_value("IMAGE")).empty()) { - return -3; - } - - source = disk->vector_value("IMAGE_ID"); - - if (!source.empty()) - { - is.str(source); - is >> image_id; - - if( !is.fail() ) + int uiid = get_disk_uid(disk,uid); + + if ( uiid == -1) { - img = imagem->acquire_image(image_id); + return -1; + } - if (img == 0) - { - return -1; - } + img = imagem->acquire_image(source , uiid); + + if ( img == 0 ) + { + return -1; } } - - if (img == 0) + else if (!(source = disk->vector_value("IMAGE_ID")).empty()) { - string type = disk->vector_value("TYPE"); + int iid = get_disk_id(source); + + if ( iid == -1) + { + return -1; + } + + img = imagem->acquire_image(iid); + + if ( img == 0 ) + { + return -1; + } + } + else //Not using the image repository + { + string type; + + rc = -2; + type = disk->vector_value("TYPE"); transform(type.begin(),type.end(),type.begin(),(int(*)(int))toupper); @@ -198,10 +269,9 @@ int ImagePool::disk_attribute(VectorAttribute * disk, disk->replace("TARGET", dev_prefix); } } - - rc = -2; } - else + + if ( img != 0 ) { img->disk_attribute(disk, index, img_type); @@ -224,22 +294,27 @@ void ImagePool::authorize_disk(VectorAttribute * disk,int uid, AuthRequest * ar) string source; Image * img = 0; - istringstream is; - int image_id; - - source = disk->vector_value("IMAGE_ID"); - - if (source.empty()) + if (!(source = disk->vector_value("IMAGE")).empty()) { - return; + int uiid = get_disk_uid(disk,uid); + + if ( uiid == -1) + { + return; + } + + img = get(source , uiid, true); } - - is.str(source); - is >> image_id; - - if( !is.fail() ) + else if (!(source = disk->vector_value("IMAGE_ID")).empty()) { - img = get(image_id,true); + int iid = get_disk_id(source); + + if ( iid == -1) + { + return; + } + + img = get(iid, true); } if (img == 0) diff --git a/src/image/test/ImagePoolTest.cc b/src/image/test/ImagePoolTest.cc index 4564f30339..3218dd3806 100644 --- a/src/image/test/ImagePoolTest.cc +++ b/src/image/test/ImagePoolTest.cc @@ -149,7 +149,8 @@ class ImagePoolTest : public PoolTest CPPUNIT_TEST ( imagepool_disk_attribute ); CPPUNIT_TEST ( dump ); CPPUNIT_TEST ( dump_where ); - + CPPUNIT_TEST ( get_using_name ); + CPPUNIT_TEST ( wrong_get_name ); CPPUNIT_TEST_SUITE_END (); protected: @@ -904,6 +905,64 @@ public: /* ********************************************************************* */ + void get_using_name() + { + int oid_0, oid_1; + ImagePool * imp = static_cast(pool); + + // Allocate two objects + oid_0 = allocate(0); + oid_1 = allocate(1); + + // --------------------------------- + // Get first object and check its integrity + obj = pool->get(oid_0, false); + CPPUNIT_ASSERT( obj != 0 ); + check(0, obj); + + // Get using its name + obj = imp->get(names[1], uids[1], true); + CPPUNIT_ASSERT( obj != 0 ); + obj->unlock(); + + check(1, obj); + + + // --------------------------------- + // Clean the cache, forcing the pool to read the objects from the DB + pool->clean(); + + // Get first object and check its integrity + obj = imp->get(names[0], uids[0], false); + check(0, obj); + + // Get using its name + obj = imp->get(oid_1, false); + check(1, obj); + }; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + + void wrong_get_name() + { + ImagePool * imp = static_cast(pool); + + // The pool is empty + // Non existing name + obj = imp->get("Wrong name", 0, true); + CPPUNIT_ASSERT( obj == 0 ); + + // Allocate an object + allocate(0); + + // Ask again for a non-existing name + obj = imp->get("Non existing name",uids[0], true); + CPPUNIT_ASSERT( obj == 0 ); + } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ }; /* ************************************************************************* */ diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 349f57b8ba..a0adc62b1d 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -759,14 +759,6 @@ int VirtualMachine::get_disk_images(string& error_str) { goto error_image; } - else if ( rc == -3) - { - goto error_name; - } - else if ( rc != -2 ) // The only known code left - { - goto error_unknown; - } } return 0; @@ -787,13 +779,6 @@ error_image: error_str = "Could not get disk image for VM."; goto error_common; -error_name: - error_str = "IMAGE is not supported for DISK. Use IMAGE_ID instead."; - goto error_common; - -error_unknown: - error_str = "Unknown error code."; - error_common: ImageManager * imagem = nd.get_imagem();