mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-11 04:58:16 +03:00
Merge branch 'feature-523' into feature-575
This commit is contained in:
commit
abe4ff6894
@ -181,63 +181,6 @@ public:
|
||||
return 0;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Template
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets the values of a template attribute
|
||||
* @param name of the attribute
|
||||
* @param values of the attribute
|
||||
* @return the number of values
|
||||
*/
|
||||
int get_template_attribute(
|
||||
string& name,
|
||||
vector<const Attribute*>& values) const
|
||||
{
|
||||
return host_template.get(name,values);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the values of a template attribute
|
||||
* @param name of the attribute
|
||||
* @param values of the attribute
|
||||
* @return the number of values
|
||||
*/
|
||||
int get_template_attribute(
|
||||
const char *name,
|
||||
vector<const Attribute*>& values) const
|
||||
{
|
||||
string str=name;
|
||||
return host_template.get(str,values);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a string based host attribute
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute (a string), will be "" if not defined
|
||||
*/
|
||||
void get_template_attribute(
|
||||
const char * name,
|
||||
string& value) const
|
||||
{
|
||||
string str=name;
|
||||
host_template.get(str,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string based host attribute
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute (an int), will be 0 if not defined
|
||||
*/
|
||||
void get_template_attribute(
|
||||
const char * name,
|
||||
int& value) const
|
||||
{
|
||||
string str=name;
|
||||
host_template.get(str,value);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Share functions
|
||||
// ------------------------------------------------------------------------
|
||||
@ -394,12 +337,6 @@ private:
|
||||
// -------------------------------------------------------------------------
|
||||
// Host Attributes
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The Host template, holds the Host attributes.
|
||||
*/
|
||||
HostTemplate host_template;
|
||||
|
||||
/**
|
||||
* The Share represents the logical capacity associated with the host
|
||||
*/
|
||||
|
206
include/Image.h
206
include/Image.h
@ -47,7 +47,9 @@ public:
|
||||
INIT = 0, /** < Initialization state */
|
||||
READY = 1, /** < Image ready to use */
|
||||
USED = 2, /** < Image in use */
|
||||
DISABLED = 3 /** < Image can not be instantiated by a VM */
|
||||
DISABLED = 3, /** < Image can not be instantiated by a VM */
|
||||
LOCKED = 4, /** < FS operation for the Image in process */
|
||||
ERROR = 5 /** < Error state the operation FAILED*/
|
||||
};
|
||||
|
||||
/**
|
||||
@ -92,6 +94,65 @@ public:
|
||||
return (persistent_img == 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the source path of the image
|
||||
* @return source of image
|
||||
*/
|
||||
const string& get_source()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the image
|
||||
* @return type
|
||||
*/
|
||||
ImageType get_type()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* Returns the image state
|
||||
* @return state of image
|
||||
*/
|
||||
ImageState get_state()
|
||||
{
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the image state
|
||||
* @param state of image
|
||||
*/
|
||||
void set_state(ImageState _state)
|
||||
{
|
||||
state = _state;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
int dec_running ()
|
||||
{
|
||||
return --running_vms;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
int inc_running()
|
||||
{
|
||||
return ++running_vms;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
int get_running()
|
||||
{
|
||||
return running_vms;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set enum type
|
||||
* @return 0 on success, -1 otherwise
|
||||
@ -120,47 +181,6 @@ public:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an image to be used in a VM, and updates its state.
|
||||
* @return 0 if success
|
||||
*/
|
||||
int acquire_image();
|
||||
|
||||
|
||||
/**
|
||||
* Releases an image being used by a VM
|
||||
* @return true if the image needs to be updated
|
||||
*/
|
||||
bool release_image();
|
||||
|
||||
/**
|
||||
* Enables the image
|
||||
* @param to_enable true will enable the image.
|
||||
* @return 0 on success
|
||||
*/
|
||||
int enable(bool to_enable)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if ( to_enable == true )
|
||||
{
|
||||
if(state == DISABLED)
|
||||
{
|
||||
state = READY;
|
||||
}
|
||||
}
|
||||
else if (state != USED) // to_enable == false
|
||||
{
|
||||
state = DISABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish or unpublish an image
|
||||
* @param pub true to publish the image
|
||||
@ -230,92 +250,13 @@ public:
|
||||
*/
|
||||
int disk_attribute(VectorAttribute * disk, int* index, ImageType* img_type);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Template
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets the values of a template attribute
|
||||
* @param name of the attribute
|
||||
* @param values of the attribute
|
||||
* @return the number of values
|
||||
* Generates the source path for the repository.
|
||||
* @param uid of the image owner
|
||||
* @param name of the image
|
||||
* @return source for the image
|
||||
*/
|
||||
int get_template_attribute(
|
||||
string& name,
|
||||
vector<const Attribute*>& values) const
|
||||
{
|
||||
return image_template->get(name,values);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the values of a template attribute
|
||||
* @param name of the attribute
|
||||
* @param values of the attribute
|
||||
* @return the number of values
|
||||
*/
|
||||
int get_template_attribute(
|
||||
const char *name,
|
||||
vector<const Attribute*>& values) const
|
||||
{
|
||||
string str=name;
|
||||
return image_template->get(str,values);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a string based Image attribute
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute (a string), will be "" if not defined
|
||||
*/
|
||||
void get_template_attribute(
|
||||
const char * name,
|
||||
string& value) const
|
||||
{
|
||||
string str=name;
|
||||
image_template->get(str,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string based Image attribute
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute (an int), will be 0 if not defined
|
||||
*/
|
||||
void get_template_attribute(
|
||||
const char * name,
|
||||
int& value) const
|
||||
{
|
||||
string str=name;
|
||||
image_template->get(str,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an Image attribute
|
||||
* @param name of the attribute
|
||||
*/
|
||||
int remove_template_attribute(const string& name)
|
||||
{
|
||||
return image_template->erase(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new attribute to the template (replacing it if
|
||||
* already defined), the image's mutex SHOULD be locked
|
||||
* @param name of the new attribute
|
||||
* @param value of the new attribute
|
||||
* @return 0 on success
|
||||
*/
|
||||
int replace_template_attribute(
|
||||
const string& name,
|
||||
const string& value)
|
||||
{
|
||||
SingleAttribute * sattr;
|
||||
|
||||
image_template->erase(name);
|
||||
|
||||
sattr = new SingleAttribute(name,value);
|
||||
image_template->set(sattr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static string generate_source(int uid, const string& name);
|
||||
|
||||
private:
|
||||
|
||||
@ -369,16 +310,6 @@ private:
|
||||
*/
|
||||
int running_vms;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Image Attributes
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The Image template, holds the Image attributes.
|
||||
*/
|
||||
ImageTemplate * image_template;
|
||||
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation (Private)
|
||||
// *************************************************************************
|
||||
@ -401,13 +332,12 @@ private:
|
||||
db->exec(oss_image);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* "Encrypts" the password with SHA1 digest
|
||||
* @param password
|
||||
* @return sha1 encrypted password
|
||||
*/
|
||||
string sha1_digest(const string& pass);
|
||||
static string sha1_digest(const string& pass);
|
||||
|
||||
protected:
|
||||
|
||||
|
204
include/ImageManager.h
Normal file
204
include/ImageManager.h
Normal file
@ -0,0 +1,204 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef IMAGE_MANAGER_H_
|
||||
#define IMAGE_MANAGER_H_
|
||||
|
||||
#include "MadManager.h"
|
||||
#include "ActionManager.h"
|
||||
#include "ImageManagerDriver.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" void * image_action_loop(void *arg);
|
||||
|
||||
class Image;
|
||||
|
||||
class ImageManager : public MadManager, public ActionListener
|
||||
{
|
||||
public:
|
||||
|
||||
ImageManager(ImagePool * _ipool, vector<const Attribute*>& _mads):
|
||||
MadManager(_mads), ipool(_ipool)
|
||||
{
|
||||
am.addListener(this);
|
||||
};
|
||||
|
||||
~ImageManager(){};
|
||||
|
||||
/**
|
||||
* This functions starts the associated listener thread, and creates a
|
||||
* new thread for the Information Manager. This thread will wait in
|
||||
* an action loop till it receives ACTION_FINALIZE.
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int start();
|
||||
|
||||
/**
|
||||
* Loads the Image Driver defined in configuration file
|
||||
* @param uid of the user executing the driver. When uid is 0 the nebula
|
||||
* identity will be used. Otherwise the Mad will be loaded through the
|
||||
* sudo application.
|
||||
*/
|
||||
void load_mads(int uid=0);
|
||||
|
||||
/**
|
||||
* Gets the thread identification.
|
||||
* @return pthread_t for the manager thread (that in the action loop).
|
||||
*/
|
||||
pthread_t get_thread_id() const
|
||||
{
|
||||
return imagem_thread;
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalizes the Image Manager
|
||||
*/
|
||||
void finalize()
|
||||
{
|
||||
am.trigger(ACTION_FINALIZE,0);
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/* Image Manager Actions */
|
||||
/* Operates in a semi-sinchronous mode. Operations will be granted or not */
|
||||
/* , when needed the image repository drivers will be used to perform FS */
|
||||
/* operations in the background. */
|
||||
/**************************************************************************/
|
||||
|
||||
/**
|
||||
* Try to acquire an image from the repository for a VM.
|
||||
* @param image_id id of image
|
||||
* @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
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Enables the image
|
||||
* @param to_enable true will enable the image.
|
||||
* @return 0 on success
|
||||
*/
|
||||
int enable_image(int iid, bool to_enable);
|
||||
|
||||
/**
|
||||
* Adds a new image to the repository copying or creating it as needed
|
||||
* @param iid id of image
|
||||
* @return 0 on success
|
||||
*/
|
||||
int register_image(int iid);
|
||||
|
||||
/**
|
||||
* Deletes an image from the repository and the DB
|
||||
* @param iid id of image
|
||||
* @return 0 on success
|
||||
*/
|
||||
int delete_image(int iid);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Generic name for the Image driver
|
||||
*/
|
||||
static const char * image_driver_name;
|
||||
|
||||
/**
|
||||
* Thread id for the Transfer Manager
|
||||
*/
|
||||
pthread_t imagem_thread;
|
||||
|
||||
/**
|
||||
* Pointer to the Image Pool to access VMs
|
||||
*/
|
||||
ImagePool * ipool;
|
||||
|
||||
/**
|
||||
* Action engine for the Manager
|
||||
*/
|
||||
ActionManager am;
|
||||
|
||||
/**
|
||||
* Returns a pointer to the Image Manager Driver used for the Repository
|
||||
* @return the Image Manager driver or 0 in not found
|
||||
*/
|
||||
const ImageManagerDriver * get()
|
||||
{
|
||||
string name("NAME");
|
||||
|
||||
return static_cast<const ImageManagerDriver *>
|
||||
(MadManager::get(0,name,image_driver_name));
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to execute the Manager action loop method within a new pthread
|
||||
* (requires C linkage)
|
||||
*/
|
||||
friend void * image_action_loop(void *arg);
|
||||
|
||||
/**
|
||||
* The action function executed when an action is triggered.
|
||||
* @param action the name of the action
|
||||
* @param arg arguments for the action function
|
||||
*/
|
||||
void do_action(
|
||||
const string & action,
|
||||
void * arg);
|
||||
|
||||
/**
|
||||
* Acquires an image updating its state.
|
||||
* @param image pointer to image, it should be locked
|
||||
* @return 0 on success
|
||||
*/
|
||||
int acquire_image(Image *img);
|
||||
|
||||
/**
|
||||
* Moves a file to an image in the repository
|
||||
* @param image to be updated (it's source attribute)
|
||||
* @param source path of the disk file
|
||||
*/
|
||||
void move_image(Image *img, const string& source);
|
||||
};
|
||||
|
||||
#endif /*IMAGE_MANAGER_H*/
|
||||
|
106
include/ImageManagerDriver.h
Normal file
106
include/ImageManagerDriver.h
Normal file
@ -0,0 +1,106 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef IMAGE_MANAGER_DRIVER_H_
|
||||
#define IMAGE_MANAGER_DRIVER_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include "Mad.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
//Forward definition of related classes
|
||||
class ImagePool;
|
||||
class ImageManager;
|
||||
|
||||
/**
|
||||
* ImageManagerDriver represents the basic abstraction for Image Repository
|
||||
* drivers. It implements the protocol and recover functions from the Mad
|
||||
* interface.
|
||||
*/
|
||||
class ImageManagerDriver : public Mad
|
||||
{
|
||||
public:
|
||||
|
||||
ImageManagerDriver(int userid,
|
||||
const map<string,string>& attrs,
|
||||
bool sudo,
|
||||
ImagePool* _ipool):
|
||||
Mad(userid,attrs,sudo),ipool(_ipool){};
|
||||
|
||||
virtual ~ImageManagerDriver(){};
|
||||
|
||||
/**
|
||||
* Implements the Image Manager driver protocol.
|
||||
* @param message the string read from the driver
|
||||
*/
|
||||
void protocol(string& message);
|
||||
|
||||
/**
|
||||
* TODO: What do we need here? Check on-going xfr?
|
||||
*/
|
||||
void recover();
|
||||
|
||||
private:
|
||||
friend class ImageManager;
|
||||
|
||||
/**
|
||||
* Reference to the ImagePool
|
||||
*/
|
||||
ImagePool * ipool;
|
||||
|
||||
/**
|
||||
* Configuration file for the driver
|
||||
*/
|
||||
//Template driver_conf;
|
||||
|
||||
void cp(int oid, const string& source, const string& destination) const;
|
||||
|
||||
/**
|
||||
* Sends a move request to the MAD: "MV IMAGE_ID SRC_PATH DST_PATH"
|
||||
* @param oid the image id.
|
||||
* @param destination is the path to the image to be created
|
||||
* @param size_mb of the image to be created
|
||||
*/
|
||||
void mv(int oid, const string& source, const string& destination) const;
|
||||
|
||||
/**
|
||||
* Sends a make filesystem request to the MAD: "MKFS IMAGE_ID PATH SIZE_MB"
|
||||
* @param oid the image id.
|
||||
* @param destination is the path to the image to be created
|
||||
* @param fs type
|
||||
* @param size_mb of the image to be created
|
||||
*/
|
||||
void mkfs(int oid,
|
||||
const string& destination,
|
||||
const string& fs,
|
||||
const string& size_mb) const;
|
||||
/**
|
||||
* Sends a delete request to the MAD: "DELETE IMAGE_ID PATH"
|
||||
* @param oid the image id.
|
||||
* @param destination is the path to the image to be removed
|
||||
*/
|
||||
void rm(int oid, const string& destination) const;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#endif /*IMAGE_MANAGER_DRIVER_H_*/
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "RequestManager.h"
|
||||
#include "HookManager.h"
|
||||
#include "AuthManager.h"
|
||||
#include "ImageManager.h"
|
||||
|
||||
class Nebula
|
||||
{
|
||||
@ -114,12 +115,16 @@ public:
|
||||
return hm;
|
||||
};
|
||||
|
||||
|
||||
AuthManager * get_authm()
|
||||
{
|
||||
return authm;
|
||||
};
|
||||
|
||||
ImageManager * get_imagem()
|
||||
{
|
||||
return imagem;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Environment & Configuration
|
||||
// --------------------------------------------------------------
|
||||
@ -229,7 +234,8 @@ private:
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0),upool(0),
|
||||
ipool(0),cpool(0),lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0),hm(0),authm(0)
|
||||
ipool(0),cpool(0),lcm(0),vmm(0),im(0),tm(0),dm(0),rm(0),hm(0),authm(0),
|
||||
imagem(0)
|
||||
{
|
||||
const char * nl = getenv("ONE_LOCATION");
|
||||
|
||||
@ -334,6 +340,11 @@ private:
|
||||
delete authm;
|
||||
}
|
||||
|
||||
if ( imagem != 0)
|
||||
{
|
||||
delete imagem;
|
||||
}
|
||||
|
||||
if ( nebula_configuration != 0)
|
||||
{
|
||||
delete nebula_configuration;
|
||||
@ -394,6 +405,7 @@ private:
|
||||
RequestManager * rm;
|
||||
HookManager * hm;
|
||||
AuthManager * authm;
|
||||
ImageManager * imagem;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Implementation functions
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "ObjectSQL.h"
|
||||
#include "ObjectXML.h"
|
||||
#include "Template.h"
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -32,14 +33,13 @@ using namespace std;
|
||||
* implementation assumes that the mutex IS LOCKED when the class destructor
|
||||
* is called.
|
||||
*/
|
||||
|
||||
class PoolObjectSQL : public ObjectSQL, public ObjectXML
|
||||
{
|
||||
public:
|
||||
|
||||
PoolObjectSQL(int id, const string& _name, int _uid,const char *_table)
|
||||
:ObjectSQL(),ObjectXML(),oid(id),name(_name),uid(_uid),
|
||||
valid(true),table(_table)
|
||||
valid(true),obj_template(0),table(_table)
|
||||
{
|
||||
pthread_mutex_init(&mutex,0);
|
||||
};
|
||||
@ -119,6 +119,104 @@ public:
|
||||
*/
|
||||
virtual int from_xml(const string &xml_str) = 0;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Template
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets the values of a template attribute
|
||||
* @param name of the attribute
|
||||
* @param values of the attribute
|
||||
* @return the number of values
|
||||
*/
|
||||
int get_template_attribute(
|
||||
string& name,
|
||||
vector<const Attribute*>& values) const
|
||||
{
|
||||
return obj_template->get(name,values);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the values of a template attribute
|
||||
* @param name of the attribute
|
||||
* @param values of the attribute
|
||||
* @return the number of values
|
||||
*/
|
||||
int get_template_attribute(
|
||||
const char *name,
|
||||
vector<const Attribute*>& values) const
|
||||
{
|
||||
string str=name;
|
||||
return obj_template->get(str,values);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a string based attribute (single)
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute (a string), will be "" if not defined or
|
||||
* not a single attribute
|
||||
*/
|
||||
void get_template_attribute(
|
||||
const char * name,
|
||||
string& value) const
|
||||
{
|
||||
string str=name;
|
||||
obj_template->get(str,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an int based attribute (single)
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute (an int), will be 0 if not defined or
|
||||
* not a single attribute
|
||||
*/
|
||||
void get_template_attribute(
|
||||
const char * name,
|
||||
int& value) const
|
||||
{
|
||||
string str=name;
|
||||
obj_template->get(str,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new attribute to the template (replacing it if
|
||||
* already defined), the object's mutex SHOULD be locked
|
||||
* @param name of the new attribute
|
||||
* @param value of the new attribute
|
||||
* @return 0 on success
|
||||
*/
|
||||
int replace_template_attribute(
|
||||
const string& name,
|
||||
const string& value)
|
||||
{
|
||||
SingleAttribute * sattr;
|
||||
|
||||
obj_template->erase(name);
|
||||
|
||||
sattr = new SingleAttribute(name,value);
|
||||
obj_template->set(sattr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a XML string for the template of the Object
|
||||
* @param xml the string to store the XML description.
|
||||
*/
|
||||
void template_to_xml(string &xml) const
|
||||
{
|
||||
obj_template->to_xml(xml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an Image attribute
|
||||
* @param name of the attribute
|
||||
*/
|
||||
int remove_template_attribute(const string& name)
|
||||
{
|
||||
return obj_template->erase(name);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
@ -198,6 +296,11 @@ protected:
|
||||
*/
|
||||
bool valid;
|
||||
|
||||
/**
|
||||
* Template for this object, will be allocated if needed
|
||||
*/
|
||||
Template * obj_template;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
@ -459,8 +459,9 @@ private:
|
||||
upool(_upool),
|
||||
ipool(_ipool)
|
||||
{
|
||||
_signature="A:siii";
|
||||
_help="Sets the disk to be saved in the given image.";
|
||||
_signature="A:siis";
|
||||
_help = "Sets the disk to be saved in a new Image with the given "
|
||||
"name.";
|
||||
};
|
||||
|
||||
~VirtualMachineSaveDisk(){};
|
||||
|
@ -532,93 +532,6 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
// Template
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets the values of a template attribute
|
||||
* @param name of the attribute
|
||||
* @param values of the attribute
|
||||
* @return the number of values
|
||||
*/
|
||||
int get_template_attribute(
|
||||
string& name,
|
||||
vector<const Attribute*>& values) const
|
||||
{
|
||||
return vm_template->get(name,values);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the values of a template attribute
|
||||
* @param name of the attribute
|
||||
* @param values of the attribute
|
||||
* @return the number of values
|
||||
*/
|
||||
int get_template_attribute(
|
||||
const char *name,
|
||||
vector<const Attribute*>& values) const
|
||||
{
|
||||
string str=name;
|
||||
return vm_template->get(str,values);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a string based VM attribute (single)
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute (a string), will be "" if not defined or
|
||||
* not a single attribute
|
||||
*/
|
||||
void get_template_attribute(
|
||||
const char * name,
|
||||
string& value) const
|
||||
{
|
||||
string str=name;
|
||||
vm_template->get(str,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an int based VM attribute (single)
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute (an int), will be 0 if not defined or
|
||||
* not a single attribute
|
||||
*/
|
||||
void get_template_attribute(
|
||||
const char * name,
|
||||
int& value) const
|
||||
{
|
||||
string str=name;
|
||||
vm_template->get(str,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new attribute to the template (replacing it if
|
||||
* already defined), the vm's mutex SHOULD be locked
|
||||
* @param name of the new attribute
|
||||
* @param value of the new attribute
|
||||
* @return 0 on success
|
||||
*/
|
||||
int replace_template_attribute(
|
||||
string& name,
|
||||
string& value)
|
||||
{
|
||||
SingleAttribute * sattr;
|
||||
|
||||
vm_template->erase(name);
|
||||
|
||||
sattr = new SingleAttribute(name,value);
|
||||
vm_template->set(sattr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a XML string for the template of the VM
|
||||
* @param xml the string to store the XML description.
|
||||
*/
|
||||
void template_to_xml(string &xml) const
|
||||
{
|
||||
vm_template->to_xml(xml);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string and substitute variables (e.g. $NAME) using the VM
|
||||
* template values:
|
||||
@ -626,8 +539,8 @@ public:
|
||||
* @param parsed, the resulting parsed string
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int parse_template_attribute(const string& attribute,
|
||||
string& parsed);
|
||||
int parse_template_attribute(const string& attribute, string& parsed);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// States
|
||||
// ------------------------------------------------------------------------
|
||||
@ -743,7 +656,7 @@ public:
|
||||
* @param img_id ID of the image this disk will be saved to.
|
||||
* @return 0 if success
|
||||
*/
|
||||
int save_disk(int disk_id, int img_id);
|
||||
int save_disk(int disk_id, int img_id, string& error_str);
|
||||
|
||||
private:
|
||||
|
||||
@ -775,14 +688,6 @@ private:
|
||||
// -------------------------------------------------------------------------
|
||||
// Virtual Machine Description
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The Virtual Machine template, holds the VM attributes.
|
||||
*/
|
||||
VirtualMachineTemplate* vm_template;
|
||||
|
||||
// Dynamic state of the Virtual Machine
|
||||
|
||||
/**
|
||||
* The state of the virtual machine.
|
||||
*/
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
|
||||
#include "PoolSQL.h"
|
||||
#include "VirtualNetworkTemplate.h"
|
||||
#include "Leases.h"
|
||||
|
||||
#include <vector>
|
||||
@ -33,10 +32,11 @@ using namespace std;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
class VirtualNetworkTemplate;
|
||||
|
||||
/**
|
||||
* The Virtual Network class. It represents a Virtual Network at manages its leases.
|
||||
* One lease is formed by one IP and one MAC address.
|
||||
* The Virtual Network class. It represents a Virtual Network at manages its
|
||||
* leases. One lease is formed by one IP and one MAC address.
|
||||
* MAC address are derived from IP addresses.
|
||||
*/
|
||||
class VirtualNetwork : public PoolObjectSQL
|
||||
@ -176,63 +176,6 @@ public:
|
||||
*/
|
||||
int nic_attribute(VectorAttribute * nic, int vid);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// Template
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets the values of a template attribute
|
||||
* @param name of the attribute
|
||||
* @param values of the attribute
|
||||
* @return the number of values
|
||||
*/
|
||||
int get_template_attribute(
|
||||
string& name,
|
||||
vector<const Attribute*>& values) const
|
||||
{
|
||||
return vn_template->get(name,values);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the values of a template attribute
|
||||
* @param name of the attribute
|
||||
* @param values of the attribute
|
||||
* @return the number of values
|
||||
*/
|
||||
int get_template_attribute(
|
||||
const char *name,
|
||||
vector<const Attribute*>& values) const
|
||||
{
|
||||
string str=name;
|
||||
return vn_template->get(str,values);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a string based VN attribute
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute (a string), will be "" if not defined
|
||||
*/
|
||||
void get_template_attribute(
|
||||
const char * name,
|
||||
string& value) const
|
||||
{
|
||||
string str=name;
|
||||
vn_template->get(str,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string based VN attribute
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute (an int), will be 0 if not defined
|
||||
*/
|
||||
void get_template_attribute(
|
||||
const char * name,
|
||||
int& value) const
|
||||
{
|
||||
string str=name;
|
||||
vn_template->get(str,value);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -280,11 +223,6 @@ private:
|
||||
*/
|
||||
Leases * leases;
|
||||
|
||||
/**
|
||||
* The Virtual Network template, holds the VNW attributes.
|
||||
*/
|
||||
VirtualNetworkTemplate * vn_template;
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation (Private)
|
||||
// *************************************************************************
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "RequestManager.h"
|
||||
#include "HookManager.h"
|
||||
#include "AuthManager.h"
|
||||
#include "ImageManager.h"
|
||||
|
||||
class NebulaTest
|
||||
{
|
||||
@ -71,6 +72,7 @@ public:
|
||||
bool need_rm;
|
||||
bool need_hm;
|
||||
bool need_authm;
|
||||
bool need_imagem;
|
||||
|
||||
static NebulaTest * instance()
|
||||
{
|
||||
@ -132,6 +134,8 @@ public:
|
||||
virtual HookManager* create_hm(VirtualMachinePool * vmpool);
|
||||
|
||||
virtual AuthManager* create_authm(time_t timer_period);
|
||||
|
||||
virtual ImageManager* create_imagem(ImagePool * ipool);
|
||||
};
|
||||
|
||||
#endif /*NEBULA_TEST_H_*/
|
||||
|
24
install.sh
24
install.sh
@ -193,7 +193,9 @@ LIB_DIRS="$LIB_LOCATION/ruby \
|
||||
$LIB_LOCATION/remotes/im/xen.d \
|
||||
$LIB_LOCATION/remotes/im/ganglia.d \
|
||||
$LIB_LOCATION/remotes/vmm/xen \
|
||||
$LIB_LOCATION/remotes/vmm/kvm"
|
||||
$LIB_LOCATION/remotes/vmm/kvm \
|
||||
$LIB_LOCATION/remotes/image \
|
||||
$LIB_LOCATION/remotes/image/fs"
|
||||
|
||||
VAR_DIRS="$VAR_LOCATION/remotes \
|
||||
$VAR_LOCATION/remotes/im \
|
||||
@ -201,7 +203,9 @@ VAR_DIRS="$VAR_LOCATION/remotes \
|
||||
$VAR_LOCATION/remotes/im/xen.d \
|
||||
$VAR_LOCATION/remotes/im/ganglia.d \
|
||||
$VAR_LOCATION/remotes/vmm/xen \
|
||||
$VAR_LOCATION/remotes/vmm/kvm"
|
||||
$VAR_LOCATION/remotes/vmm/kvm \
|
||||
$VAR_LOCATION/remotes/image \
|
||||
$VAR_LOCATION/remotes/image/fs"
|
||||
|
||||
SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \
|
||||
$SUNSTONE_LOCATION/models/OpenNebulaJSON \
|
||||
@ -278,6 +282,8 @@ INSTALL_FILES=(
|
||||
SSH_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/ssh
|
||||
DUMMY_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/dummy
|
||||
LVM_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/lvm
|
||||
IMAGE_DRIVER_FS_SCRIPTS:$LIB_LOCATION/remotes/image/fs
|
||||
IMAGE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/image/fs
|
||||
EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples
|
||||
TM_EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples/tm
|
||||
HOOK_SHARE_FILES:$SHARE_LOCATION/hooks
|
||||
@ -396,7 +402,6 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualNetworkPool.rb \
|
||||
src/oca/ruby/OpenNebula/Image.rb \
|
||||
src/oca/ruby/OpenNebula/ImagePool.rb \
|
||||
src/oca/ruby/OpenNebula/ImageRepository.rb \
|
||||
src/oca/ruby/OpenNebula/Cluster.rb \
|
||||
src/oca/ruby/OpenNebula/ClusterPool.rb \
|
||||
src/oca/ruby/OpenNebula/XMLUtils.rb"
|
||||
@ -428,7 +433,9 @@ MADS_LIB_FILES="src/mad/sh/madcommon.sh \
|
||||
src/hm_mad/one_hm.rb \
|
||||
src/hm_mad/one_hm \
|
||||
src/authm_mad/one_auth_mad.rb \
|
||||
src/authm_mad/one_auth_mad"
|
||||
src/authm_mad/one_auth_mad \
|
||||
src/image_mad/one_image.rb \
|
||||
src/image_mad/one_image"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# VMM SH Driver KVM scripts, to be installed under $REMOTES_LOCATION/vmm/kvm
|
||||
@ -514,6 +521,15 @@ LVM_TM_COMMANDS_LIB_FILES="src/tm_mad/lvm/tm_clone.sh \
|
||||
src/tm_mad/lvm/tm_mv.sh \
|
||||
src/tm_mad/lvm/tm_context.sh"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Image Repository drivers, to be installed under $REMOTES_LOCTION/image
|
||||
# - FS based Image Repository, $REMOTES_LOCATION/image/fs
|
||||
#-------------------------------------------------------------------------------
|
||||
IMAGE_DRIVER_FS_SCRIPTS="src/image_mad/remotes/fs/cp \
|
||||
src/image_mad/remotes/fs/mkfs \
|
||||
src/image_mad/remotes/fs/mv \
|
||||
src/image_mad/remotes/fs/rm"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Configuration files for OpenNebula, to be installed under $ETC_LOCATION
|
||||
#-------------------------------------------------------------------------------
|
||||
|
@ -285,6 +285,25 @@ TM_MAD = [
|
||||
# arguments = "tm_lvm/tm_lvm.conf" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#*******************************************************************************
|
||||
# Image Manager Driver Configuration
|
||||
#*******************************************************************************
|
||||
# Drivers to manage the image repository, specialized for the storage backend
|
||||
# executable: path of the transfer driver executable, can be an
|
||||
# absolute path or relative to $ONE_LOCATION/lib/mads (or
|
||||
# /usr/lib/one/mads/ if OpenNebula was installed in /)
|
||||
#
|
||||
# arguments : for the driver executable
|
||||
#*******************************************************************************
|
||||
#-------------------------------------------------------------------------------
|
||||
# FS based Image Manager Driver Configuration
|
||||
# -t number of threads, i.e. number of repo operations at the same time
|
||||
#-------------------------------------------------------------------------------
|
||||
IMAGE_MAD = [
|
||||
executable = "one_image",
|
||||
arguments = "fs -t 15" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#*******************************************************************************
|
||||
# Hook Manager Configuration
|
||||
#*******************************************************************************
|
||||
@ -339,16 +358,6 @@ TM_MAD = [
|
||||
HM_MAD = [
|
||||
executable = "one_hm" ]
|
||||
|
||||
#-------------------------------- Image Hook -----------------------------------
|
||||
# This hook is used to handle image saving and overwriting when virtual machines
|
||||
# reach the DONE state after being shutdown.
|
||||
|
||||
VM_HOOK = [
|
||||
name = "image",
|
||||
on = "DONE",
|
||||
command = "image.rb",
|
||||
arguments = "$VMID" ]
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#------------------------------ Fault Tolerance Hooks --------------------------
|
||||
|
@ -321,8 +321,6 @@ result=[false, "Unknown error"]
|
||||
|
||||
command=ARGV.shift
|
||||
|
||||
img_repo = OpenNebula::ImageRepository.new
|
||||
|
||||
case command
|
||||
when "register", "create", "add"
|
||||
check_parameters("register", 1)
|
||||
@ -330,7 +328,7 @@ when "register", "create", "add"
|
||||
|
||||
image = OpenNebula::Image.new(OpenNebula::Image.build_xml, get_one_client)
|
||||
|
||||
result = img_repo.create(image, template)
|
||||
result = image.allocate(template)
|
||||
if is_successful?(result)
|
||||
puts "ID: " + image.id.to_s if ops[:verbose]
|
||||
end
|
||||
@ -506,7 +504,7 @@ when "delete"
|
||||
OpenNebula::Image.build_xml(image_id),
|
||||
get_one_client)
|
||||
|
||||
result = img_repo.delete(image)
|
||||
result = image.delete
|
||||
if is_successful?(result)
|
||||
puts "Image correctly deleted" if ops[:verbose]
|
||||
end
|
||||
|
@ -785,56 +785,17 @@ when "saveas"
|
||||
exit -1
|
||||
end
|
||||
|
||||
if ops[:type]
|
||||
image_type = ops[:type]
|
||||
else
|
||||
image_id = vm["TEMPLATE/DISK[DISK_ID=\"#{disk_id}\"]/IMAGE_ID"]
|
||||
|
||||
if (image_id != nil)
|
||||
if vm["TEMPLATE/DISK[DISK_ID=\"#{disk_id}\"]/SAVE_AS"]
|
||||
puts "Error: The disk #{disk_id} is already" <<
|
||||
" suppossed to be saved"
|
||||
exit -1
|
||||
end
|
||||
|
||||
# Get the image type
|
||||
image = OpenNebula::Image.new(
|
||||
OpenNebula::Image.build_xml(image_id),
|
||||
get_one_client)
|
||||
|
||||
result = image.info
|
||||
if !is_successful?(result)
|
||||
puts result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
image_type = image.type_str
|
||||
end
|
||||
end
|
||||
|
||||
# Build the template and allocate the new Image
|
||||
template = "NAME=\"#{image_name}\"\n"
|
||||
template << "TYPE=#{image_type}\n" if image_type
|
||||
|
||||
|
||||
image = OpenNebula::Image.new(
|
||||
OpenNebula::Image.build_xml,
|
||||
get_one_client)
|
||||
|
||||
result = image.allocate(template)
|
||||
if !is_successful?(result)
|
||||
puts result.message
|
||||
if vm["TEMPLATE/DISK[DISK_ID=\"#{disk_id}\"]/SAVE_AS"]
|
||||
puts "Error: The disk #{disk_id} is already" <<
|
||||
" suppossed to be saved"
|
||||
exit -1
|
||||
end
|
||||
|
||||
result = vm.save_as(disk_id.to_i, image.id)
|
||||
|
||||
result = vm.save_as(disk_id.to_i, image_name)
|
||||
if is_successful?(result)
|
||||
puts "VM disk with ID #{disk_id} is prepared to be" <<
|
||||
" saved" if ops[:verbose]
|
||||
else
|
||||
image.delete
|
||||
end
|
||||
|
||||
|
||||
when "show"
|
||||
check_parameters("get_info", 1)
|
||||
|
@ -62,8 +62,6 @@ class CloudServer
|
||||
|
||||
@one_client = Client.new(nil,@config[:one_xmlrpc])
|
||||
@user_pool = UserPool.new(@one_client)
|
||||
|
||||
@img_repo = OpenNebula::ImageRepository.new
|
||||
end
|
||||
|
||||
#
|
||||
@ -103,39 +101,6 @@ class CloudServer
|
||||
return @user_pool["USER[NAME=\"#{name}\"]/PASSWORD"]
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
# Repository Methods
|
||||
###########################################################################
|
||||
|
||||
# Adds a new image to the repository and deletes the temp_file
|
||||
# uid:: _Integer_ owner of the image
|
||||
# path:: _String_ path of the tmp file
|
||||
# metadata:: Additional metadata for the file
|
||||
# [return] _Image_ Newly created image object
|
||||
def add_image(image, file=nil)
|
||||
template = image.to_one_template
|
||||
|
||||
if file
|
||||
if file[:tempfile]
|
||||
file_path = file[:tempfile].path
|
||||
template << "\nPATH = #{file_path}"
|
||||
else
|
||||
error_msg = "Image not present, aborting."
|
||||
error = OpenNebula::Error.new(error_msg)
|
||||
return error
|
||||
end
|
||||
end
|
||||
|
||||
rc = @img_repo.create(image, template)
|
||||
|
||||
file[:tempfile].unlink if file
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
return rc
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
# Finds out if a port is available on ip
|
||||
# ip:: _String_ IP address where the port to check is
|
||||
|
@ -140,7 +140,7 @@ module EC2QueryClient
|
||||
def upload_image(file_name, curb=true)
|
||||
params = { "Action" => "UploadImage",
|
||||
"SignatureVersion" => "2",
|
||||
"SignatureMethod" => 'HmacSHA1',
|
||||
"SignatureMethod" => 'HmacSHA256',
|
||||
"AWSAccessKeyId" => @access_key_id,
|
||||
"Version" => API_VERSION,
|
||||
"Timestamp" => Time.now.getutc.iso8601 }
|
||||
|
@ -122,11 +122,16 @@ class EC2QueryServer < CloudServer
|
||||
###########################################################################
|
||||
|
||||
def upload_image(params, one_client)
|
||||
image = ImageEC2.new(Image.build_xml, one_client)
|
||||
image = ImageEC2.new(Image.build_xml, one_client, params['file'])
|
||||
|
||||
rc = add_image(image, params['file'])
|
||||
template = image.to_one_template
|
||||
if OpenNebula.is_error?(template)
|
||||
return OpenNebula::Error.new('Unsupported'), 400
|
||||
end
|
||||
|
||||
rc = image.allocate(template)
|
||||
if OpenNebula.is_error?(rc)
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
return OpenNebula::Error.new('Unsupported'), 400
|
||||
end
|
||||
|
||||
erb_version = params['Version']
|
||||
|
@ -24,8 +24,21 @@ class ImageEC2 < Image
|
||||
ONE_IMAGE = %q{
|
||||
NAME = "ec2-<%= uuid %>"
|
||||
TYPE = OS
|
||||
<% if @image_file != nil %>
|
||||
PATH = "<%= @image_file %>"
|
||||
<% end %>
|
||||
}.gsub(/^ /, '')
|
||||
|
||||
|
||||
def initialize(xml, client, file=nil)
|
||||
super(xml, client)
|
||||
@image_info = nil
|
||||
@image_file = file
|
||||
|
||||
if file && file[:tempfile]
|
||||
@image_file = file[:tempfile].path
|
||||
end
|
||||
end
|
||||
|
||||
def to_one_template()
|
||||
uuid = UUID.generate
|
||||
|
||||
|
@ -1,25 +1,27 @@
|
||||
<?xml version="1.0"?>
|
||||
<DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/<%=erb_version%>/">
|
||||
<imagesSet>
|
||||
<imagesSet>
|
||||
<% impool.each do |im| %>
|
||||
<% im.info %>
|
||||
<item>
|
||||
<item>
|
||||
<imageId>ami-<%= sprintf('%08i', im.id) %></imageId>
|
||||
<imageLocation><%= im['SOURCE'].split('/').last %></imageLocation>
|
||||
<% if im['STATE'] == '3' %>
|
||||
<imageState>deregistered</imageState>
|
||||
<% if im['STATE'] == '3' || im['STATE'] == '5' %>
|
||||
<imageState>failed</imageState>
|
||||
<% elsif im['STATE'] == '1' || im['STATE'] == '2' %>
|
||||
<imageState>available</imageState>
|
||||
<imageState>available</imageState>
|
||||
<% elsif im['STATE'] == '4'%>
|
||||
<imageState>pending</imageState>
|
||||
<% end %>
|
||||
<imageOwnerId><%= erb_user_name %></imageOwnerId>
|
||||
<imageOwnerId><%= erb_user_name %></imageOwnerId>
|
||||
<% if im['PUBLIC'] == '0' %>
|
||||
<isPublic>false</isPublic>
|
||||
<isPublic>false</isPublic>
|
||||
<% elsif im['PUBLIC'] == '1' %>
|
||||
<isPublic>true</isPublic>
|
||||
<isPublic>true</isPublic>
|
||||
<% end %>
|
||||
<architecture>i386</architecture>
|
||||
<imageType>machine</imageType>
|
||||
</item>
|
||||
<architecture>i386</architecture>
|
||||
<imageType>machine</imageType>
|
||||
</item>
|
||||
<% end %>
|
||||
</imagesSet>
|
||||
</DescribeImagesResponse>
|
||||
</imagesSet>
|
||||
</DescribeImagesResponse>
|
||||
|
@ -46,6 +46,9 @@ class ImageOCCI < Image
|
||||
<% if @image_info['DESCRIPTION'] != nil %>
|
||||
DESCRIPTION = "<%= @image_info['DESCRIPTION'] %>"
|
||||
<% end %>
|
||||
<% if @image_file != nil %>
|
||||
PATH = "<%= @image_file %>"
|
||||
<% end %>
|
||||
<% if @image_info['PUBLIC'] != nil %>
|
||||
PUBLIC = "<%= @image_info['PUBLIC'] %>"
|
||||
<% end %>
|
||||
@ -64,9 +67,14 @@ class ImageOCCI < Image
|
||||
}.gsub(/^ /, '')
|
||||
|
||||
# Class constructor
|
||||
def initialize(xml, client, xml_info=nil)
|
||||
def initialize(xml, client, xml_info=nil, file=nil)
|
||||
super(xml, client)
|
||||
@image_info = nil
|
||||
@image_file = file
|
||||
|
||||
if file && file[:tempfile]
|
||||
@image_file = file[:tempfile].path
|
||||
end
|
||||
|
||||
if xml_info != nil
|
||||
xmldoc = XMLElement.build_xml(xml_info, 'STORAGE')
|
||||
|
@ -170,18 +170,18 @@ module OCCIClient
|
||||
return error
|
||||
end
|
||||
|
||||
if image_info.elements['URL'] == nil
|
||||
if image_info.elements['URL']
|
||||
file_path = image_info.elements['URL'].text
|
||||
|
||||
m = file_path.match(/^\w+:\/\/(.*)$/)
|
||||
|
||||
if m
|
||||
file_path="/"+m[1]
|
||||
end
|
||||
elsif !image_info.elements['TYPE'] == "DATABLOCK"
|
||||
return CloudClient::Error.new("Can not find URL")
|
||||
end
|
||||
|
||||
file_path = image_info.elements['URL'].text
|
||||
|
||||
m = file_path.match(/^\w+:\/\/(.*)$/)
|
||||
|
||||
if m
|
||||
file_path="/"+m[1]
|
||||
end
|
||||
|
||||
if curb
|
||||
if !CURL_LOADED
|
||||
error_msg = "curb gem not loaded"
|
||||
@ -197,10 +197,14 @@ module OCCIClient
|
||||
curl.multipart_form_post = true
|
||||
|
||||
begin
|
||||
curl.http_post(
|
||||
Curl::PostField.content('occixml', xml),
|
||||
Curl::PostField.file('file', file_path)
|
||||
)
|
||||
postfields = Array.new
|
||||
postfields << Curl::PostField.content('occixml', xml)
|
||||
|
||||
if file_path
|
||||
postfields << Curl::PostField.file('file', file_path)
|
||||
end
|
||||
|
||||
curl.http_post(*postfields)
|
||||
rescue Exception => e
|
||||
return CloudClient::Error.new(e.message)
|
||||
end
|
||||
@ -213,11 +217,13 @@ module OCCIClient
|
||||
return error
|
||||
end
|
||||
|
||||
file=File.open(file_path)
|
||||
|
||||
params=Hash.new
|
||||
params["file"]=UploadIO.new(file,
|
||||
'application/octet-stream', file_path)
|
||||
|
||||
if file_path
|
||||
file=File.open(file_path)
|
||||
params["file"]=UploadIO.new(file,
|
||||
'application/octet-stream', file_path)
|
||||
end
|
||||
|
||||
params['occixml'] = xml
|
||||
|
||||
@ -231,8 +237,8 @@ module OCCIClient
|
||||
http.request(req)
|
||||
end
|
||||
|
||||
file.close
|
||||
pp res
|
||||
file.close if file_path
|
||||
|
||||
if CloudClient::is_error?(res)
|
||||
return res
|
||||
else
|
||||
|
@ -401,16 +401,18 @@ class OCCIServer < CloudServer
|
||||
image = ImageOCCI.new(
|
||||
Image.build_xml,
|
||||
get_client(request.env),
|
||||
occixml)
|
||||
occixml,
|
||||
request.params['file'])
|
||||
|
||||
rc = add_image(image, request.params['file'])
|
||||
return rc, 500 if OpenNebula.is_error?(rc)
|
||||
# --- Generate the template and Allocate the new Instance ---
|
||||
template = image.to_one_template
|
||||
return template, 500 if OpenNebula.is_error?(template)
|
||||
|
||||
# --- Enable the new Image ---
|
||||
rc = image.enable
|
||||
rc = image.allocate(template)
|
||||
return rc, 500 if OpenNebula.is_error?(rc)
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
image.info
|
||||
return to_occi_xml(image, 201)
|
||||
end
|
||||
|
||||
|
@ -40,11 +40,18 @@ Host::Host(
|
||||
vmm_mad_name(_vmm_mad_name),
|
||||
tm_mad_name(_tm_mad_name),
|
||||
last_monitored(0),
|
||||
cluster(_cluster),
|
||||
host_template()
|
||||
{}
|
||||
cluster(_cluster)
|
||||
{
|
||||
obj_template = new HostTemplate;
|
||||
}
|
||||
|
||||
Host::~Host(){}
|
||||
Host::~Host()
|
||||
{
|
||||
if ( obj_template != 0 )
|
||||
{
|
||||
delete obj_template;
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* Host :: Database Access Functions */
|
||||
@ -167,7 +174,7 @@ int Host::update_info(string &parse_str)
|
||||
char * error_msg;
|
||||
int rc;
|
||||
|
||||
rc = host_template.parse(parse_str, &error_msg);
|
||||
rc = obj_template->parse(parse_str, &error_msg);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
@ -222,7 +229,7 @@ string& Host::to_xml(string& xml) const
|
||||
"<LAST_MON_TIME>" << last_monitored << "</LAST_MON_TIME>" <<
|
||||
"<CLUSTER>" << cluster << "</CLUSTER>" <<
|
||||
host_share.to_xml(share_xml) <<
|
||||
host_template.to_xml(template_xml) <<
|
||||
obj_template->to_xml(template_xml) <<
|
||||
"</HOST>";
|
||||
|
||||
xml = oss.str();
|
||||
@ -276,7 +283,7 @@ int Host::from_xml(const string& xml)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc += host_template.from_xml_node( content[0] );
|
||||
rc += obj_template->from_xml_node( content[0] );
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
|
@ -47,19 +47,19 @@ Image::Image(int _uid,
|
||||
{
|
||||
if (_image_template != 0)
|
||||
{
|
||||
image_template = _image_template;
|
||||
obj_template = _image_template;
|
||||
}
|
||||
else
|
||||
{
|
||||
image_template = new ImageTemplate;
|
||||
obj_template = new ImageTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
if (image_template != 0)
|
||||
if (obj_template != 0)
|
||||
{
|
||||
delete image_template;
|
||||
delete obj_template;
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +78,22 @@ const char * Image::db_bootstrap = "CREATE TABLE IF NOT EXISTS image_pool ("
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
string Image::generate_source(int uid, const string& name)
|
||||
{
|
||||
ostringstream tmp_hashstream;
|
||||
ostringstream tmp_sourcestream;
|
||||
|
||||
tmp_hashstream << uid << ":" << name;
|
||||
|
||||
tmp_sourcestream << ImagePool::source_prefix() << "/";
|
||||
tmp_sourcestream << sha1_digest(tmp_hashstream.str());
|
||||
|
||||
return tmp_sourcestream.str();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Image::insert(SqlDB *db, string& error_str)
|
||||
{
|
||||
int rc;
|
||||
@ -116,7 +132,7 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
|
||||
get_template_attribute("PUBLIC", public_attr);
|
||||
|
||||
image_template->erase("PUBLIC");
|
||||
obj_template->erase("PUBLIC");
|
||||
|
||||
TO_UPPER(public_attr);
|
||||
|
||||
@ -126,7 +142,7 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
|
||||
get_template_attribute("PERSISTENT", persistent_attr);
|
||||
|
||||
image_template->erase("PERSISTENT");
|
||||
obj_template->erase("PERSISTENT");
|
||||
|
||||
TO_UPPER(persistent_attr);
|
||||
|
||||
@ -147,14 +163,12 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
{
|
||||
SingleAttribute * dev_att = new SingleAttribute("DEV_PREFIX",
|
||||
ImagePool::default_dev_prefix());
|
||||
|
||||
image_template->set(dev_att);
|
||||
obj_template->set(dev_att);
|
||||
}
|
||||
|
||||
// ------------ PATH --------------------
|
||||
get_template_attribute("PATH", path_attr);
|
||||
// ------------ PATH & SOURCE --------------------
|
||||
|
||||
// ------------ SOURCE (path to store the image) --------------------
|
||||
get_template_attribute("PATH", path_attr);
|
||||
get_template_attribute("SOURCE", source);
|
||||
|
||||
// The template should contain PATH or SOURCE
|
||||
@ -163,14 +177,26 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
string size_attr;
|
||||
string fstype_attr;
|
||||
|
||||
istringstream iss;
|
||||
int size_mb;
|
||||
|
||||
get_template_attribute("SIZE", size_attr);
|
||||
get_template_attribute("FSTYPE", fstype_attr);
|
||||
|
||||
// It could be an empty DATABLOCK image, if it declares SIZE and FSTYPE
|
||||
if ( type_att != "DATABLOCK" || size_attr.empty() || fstype_attr.empty() )
|
||||
// DATABLOCK image needs SIZE and FSTYPE
|
||||
if (type != DATABLOCK || size_attr.empty() || fstype_attr.empty())
|
||||
{
|
||||
goto error_no_path;
|
||||
}
|
||||
|
||||
iss.str(size_attr);
|
||||
|
||||
iss >> size_mb;
|
||||
|
||||
if (iss.fail() == true)
|
||||
{
|
||||
goto error_size_format;
|
||||
}
|
||||
}
|
||||
else if ( !source.empty() && !path_attr.empty() )
|
||||
{
|
||||
@ -179,18 +205,10 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
|
||||
if (source.empty())
|
||||
{
|
||||
ostringstream tmp_hashstream;
|
||||
ostringstream tmp_sourcestream;
|
||||
|
||||
tmp_hashstream << uid << ":" << name;
|
||||
|
||||
tmp_sourcestream << ImagePool::source_prefix() << "/";
|
||||
tmp_sourcestream << sha1_digest(tmp_hashstream.str());
|
||||
|
||||
source = tmp_sourcestream.str();
|
||||
source = Image::generate_source(uid,name);
|
||||
}
|
||||
|
||||
state = DISABLED;
|
||||
state = LOCKED; //LOCKED till the ImageManager copies it to the Repository
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Insert the Image
|
||||
@ -214,7 +232,7 @@ error_public_and_persistent:
|
||||
goto error_common;
|
||||
|
||||
error_no_path:
|
||||
if ( type_att == "DATABLOCK" )
|
||||
if ( type == DATABLOCK )
|
||||
{
|
||||
error_str = "A DATABLOCK type IMAGE has to declare a PATH, or both "
|
||||
"SIZE and FSTYPE.";
|
||||
@ -225,6 +243,10 @@ error_no_path:
|
||||
}
|
||||
goto error_common;
|
||||
|
||||
error_size_format:
|
||||
error_str = "Wrong number in SIZE.";
|
||||
goto error_common;
|
||||
|
||||
error_path_and_source:
|
||||
error_str = "Template malformed, PATH and SOURCE are mutuallly exclusive.";
|
||||
goto error_common;
|
||||
@ -337,7 +359,7 @@ string& Image::to_xml(string& xml) const
|
||||
"<SOURCE>" << source << "</SOURCE>" <<
|
||||
"<STATE>" << state << "</STATE>" <<
|
||||
"<RUNNING_VMS>" << running_vms << "</RUNNING_VMS>" <<
|
||||
image_template->to_xml(template_xml) <<
|
||||
obj_template->to_xml(template_xml) <<
|
||||
"</IMAGE>";
|
||||
|
||||
xml = oss.str();
|
||||
@ -384,7 +406,7 @@ int Image::from_xml(const string& xml)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc += image_template->from_xml_node(content[0]);
|
||||
rc += obj_template->from_xml_node(content[0]);
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
@ -397,70 +419,6 @@ int Image::from_xml(const string& xml)
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Image::acquire_image()
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case READY:
|
||||
running_vms++;
|
||||
state = USED;
|
||||
break;
|
||||
|
||||
case USED:
|
||||
if (persistent_img)
|
||||
{
|
||||
rc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
running_vms++;
|
||||
}
|
||||
break;
|
||||
|
||||
case DISABLED:
|
||||
default:
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
bool Image::release_image()
|
||||
{
|
||||
bool dirty = false;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case USED:
|
||||
running_vms--;
|
||||
|
||||
if ( running_vms == 0)
|
||||
{
|
||||
state = READY;
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
break;
|
||||
|
||||
case DISABLED:
|
||||
case READY:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Image::disk_attribute( VectorAttribute * disk,
|
||||
int * index,
|
||||
ImageType* img_type)
|
||||
@ -488,15 +446,6 @@ int Image::disk_attribute( VectorAttribute * disk,
|
||||
|
||||
get_template_attribute("DEV_PREFIX", prefix);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Acquire the image
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
if ( acquire_image() != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// NEW DISK ATTRIBUTES
|
||||
//---------------------------------------------------------------------------
|
||||
@ -533,8 +482,6 @@ int Image::disk_attribute( VectorAttribute * disk,
|
||||
{
|
||||
new_disk.insert(make_pair("CLONE","NO"));
|
||||
new_disk.insert(make_pair("SAVE","YES"));
|
||||
|
||||
new_disk.insert(make_pair("SAVE_AS", iid.str())); // Tells the hook to overwrite
|
||||
}
|
||||
else
|
||||
{
|
||||
|
126
src/image/ImageManager.cc
Normal file
126
src/image/ImageManager.cc
Normal file
@ -0,0 +1,126 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "ImageManager.h"
|
||||
#include "NebulaLog.h"
|
||||
#include "ImagePool.h"
|
||||
|
||||
const char * ImageManager::image_driver_name = "image_exe";
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
extern "C" void * image_action_loop(void *arg)
|
||||
{
|
||||
ImageManager * im;
|
||||
|
||||
if ( arg == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
NebulaLog::log("ImM",Log::INFO,"Image Manager started.");
|
||||
|
||||
im = static_cast<ImageManager *>(arg);
|
||||
|
||||
im->am.loop(0,0);
|
||||
|
||||
NebulaLog::log("ImM",Log::INFO,"Image Manager stopped.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void ImageManager::load_mads(int uid)
|
||||
{
|
||||
ImageManagerDriver * imagem_mad;
|
||||
ostringstream oss;
|
||||
const VectorAttribute * vattr;
|
||||
int rc;
|
||||
|
||||
NebulaLog::log("ImM",Log::INFO,"Loading Image Manager driver.");
|
||||
|
||||
vattr = static_cast<const VectorAttribute *>(mad_conf[0]);
|
||||
|
||||
if ( vattr == 0 )
|
||||
{
|
||||
NebulaLog::log("ImM",Log::INFO,"Failed to load Image Manager driver.");
|
||||
return;
|
||||
}
|
||||
|
||||
VectorAttribute image_conf("IMAGE_MAD",vattr->value());
|
||||
|
||||
image_conf.replace("NAME",image_driver_name);
|
||||
|
||||
imagem_mad = new ImageManagerDriver(0,image_conf.value(),false,ipool);
|
||||
|
||||
rc = add(imagem_mad);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
oss.str("");
|
||||
oss << "\tImage Manager loaded";
|
||||
|
||||
NebulaLog::log("ImM",Log::INFO,oss);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImageManager::start()
|
||||
{
|
||||
int rc;
|
||||
pthread_attr_t pattr;
|
||||
|
||||
rc = MadManager::start();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
NebulaLog::log("ImM",Log::INFO,"Starting Image Manager...");
|
||||
|
||||
pthread_attr_init (&pattr);
|
||||
pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
rc = pthread_create(&imagem_thread,&pattr,image_action_loop,(void *) this);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void ImageManager::do_action(const string &action, void * arg)
|
||||
{
|
||||
if (action == ACTION_FINALIZE)
|
||||
{
|
||||
NebulaLog::log("ImM",Log::INFO,"Stopping Image Manager...");
|
||||
MadManager::stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << "Unknown action name: " << action;
|
||||
|
||||
NebulaLog::log("ImM", Log::ERROR, oss);
|
||||
}
|
||||
}
|
||||
|
433
src/image/ImageManagerActions.cc
Normal file
433
src/image/ImageManagerActions.cc
Normal file
@ -0,0 +1,433 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "ImageManager.h"
|
||||
#include "NebulaLog.h"
|
||||
#include "ImagePool.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
Image * ImageManager::acquire_image(int image_id)
|
||||
{
|
||||
Image * img;
|
||||
int rc;
|
||||
|
||||
img = ipool->get(image_id,true);
|
||||
|
||||
if ( img == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = acquire_image(img);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
img->unlock();
|
||||
img = 0;
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
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;
|
||||
|
||||
switch (img->get_state())
|
||||
{
|
||||
case Image::READY:
|
||||
img->inc_running();
|
||||
img->set_state(Image::USED);
|
||||
ipool->update(img);
|
||||
break;
|
||||
|
||||
case Image::USED:
|
||||
if (img->isPersistent())
|
||||
{
|
||||
rc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
img->inc_running();
|
||||
ipool->update(img);
|
||||
}
|
||||
break;
|
||||
|
||||
case Image::DISABLED:
|
||||
case Image::LOCKED:
|
||||
case Image::ERROR:
|
||||
default:
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
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() << " as " << img->get_source();
|
||||
|
||||
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(const string& image_id,
|
||||
const string& disk_path,
|
||||
int disk_num,
|
||||
const string& save_id)
|
||||
{
|
||||
int rvms;
|
||||
|
||||
int iid;
|
||||
int sid = -1;
|
||||
|
||||
istringstream iss;
|
||||
Image * img;
|
||||
|
||||
ostringstream disk_file;
|
||||
|
||||
iss.str(image_id);
|
||||
|
||||
iss >> iid;
|
||||
|
||||
if ( save_id.empty() == false )
|
||||
{
|
||||
iss.clear();
|
||||
iss.str(save_id);
|
||||
|
||||
iss >> sid;
|
||||
}
|
||||
|
||||
img = ipool->get(iid,true);
|
||||
|
||||
if ( img == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (img->get_state())
|
||||
{
|
||||
case Image::USED:
|
||||
rvms = img->dec_running();
|
||||
|
||||
if ( img->isPersistent() )
|
||||
{
|
||||
disk_file << disk_path << "/disk." << disk_num;
|
||||
|
||||
img->set_state(Image::LOCKED);
|
||||
|
||||
move_image(img,disk_file.str());
|
||||
|
||||
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:
|
||||
case Image::READY:
|
||||
case Image::ERROR:
|
||||
case Image::LOCKED:
|
||||
NebulaLog::log("ImM",Log::ERROR,
|
||||
"Trying to release image in wrong state.");
|
||||
default:
|
||||
img->unlock();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImageManager::enable_image(int iid, bool to_enable)
|
||||
{
|
||||
int rc = 0;
|
||||
Image * img;
|
||||
|
||||
img = ipool->get(iid,true);
|
||||
|
||||
if ( img == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( to_enable == true )
|
||||
{
|
||||
switch (img->get_state())
|
||||
{
|
||||
case Image::DISABLED:
|
||||
case Image::ERROR:
|
||||
img->set_state(Image::READY);
|
||||
ipool->update(img);
|
||||
case Image::READY:
|
||||
break;
|
||||
default:
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (img->get_state())
|
||||
{
|
||||
case Image::READY:
|
||||
case Image::ERROR:
|
||||
img->set_state(Image::DISABLED);
|
||||
ipool->update(img);
|
||||
case Image::DISABLED:
|
||||
break;
|
||||
default:
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
img->unlock();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImageManager::delete_image(int iid)
|
||||
{
|
||||
Image * img;
|
||||
|
||||
img = ipool->get(iid,true);
|
||||
|
||||
if ( img == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(img->get_state())
|
||||
{
|
||||
case Image::READY:
|
||||
if ( img->get_running() != 0 )
|
||||
{
|
||||
img->unlock();
|
||||
return -1; //Can not remove images in use
|
||||
}
|
||||
break;
|
||||
|
||||
case Image::USED:
|
||||
img->unlock();
|
||||
return -1; //Can not remove images in use
|
||||
break;
|
||||
|
||||
case Image::INIT:
|
||||
case Image::DISABLED:
|
||||
case Image::LOCKED:
|
||||
case Image::ERROR:
|
||||
break;
|
||||
}
|
||||
|
||||
const ImageManagerDriver* imd = get();
|
||||
|
||||
if ( imd == 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
imd->rm(img->get_oid(),img->get_source());
|
||||
|
||||
img->unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImageManager::register_image(int iid)
|
||||
{
|
||||
const ImageManagerDriver* imd = get();
|
||||
ostringstream oss;
|
||||
|
||||
string path;
|
||||
Image* img;
|
||||
|
||||
if ( imd == 0 )
|
||||
{
|
||||
NebulaLog::log("ImM",Log::ERROR,
|
||||
"Could not get driver to update repository");
|
||||
return -1;
|
||||
}
|
||||
|
||||
img = ipool->get(iid,true);
|
||||
|
||||
if (img == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
img->get_template_attribute("PATH",path);
|
||||
|
||||
if ( path.empty() == true ) //NO PATH -> USE SOURCE OR MKFS FOR DATABLOCK
|
||||
{
|
||||
string fs;
|
||||
string size;
|
||||
|
||||
img->get_template_attribute("SIZE", size);
|
||||
img->get_template_attribute("FSTYPE", fs);
|
||||
|
||||
if ( img->get_type() == Image::DATABLOCK &&
|
||||
!size.empty() && !fs.empty() )
|
||||
{
|
||||
imd->mkfs(img->get_oid(), img->get_source(), fs, size);
|
||||
|
||||
oss << "Creating disk at " << img->get_source() << " of "
|
||||
<< size << "Mb with format " << fs;
|
||||
}
|
||||
else
|
||||
{
|
||||
img->set_state(Image::READY);
|
||||
ipool->update(img);
|
||||
|
||||
oss << "Using source " << img->get_source()
|
||||
<< " from template for image " << img->get_name();
|
||||
}
|
||||
}
|
||||
else //PATH -> COPY TO REPOSITORY AS SOURCE
|
||||
{
|
||||
imd->cp(img->get_oid(), path, img->get_source());
|
||||
oss << "Copying image " << path
|
||||
<< " to repository as " << img->get_source();
|
||||
}
|
||||
|
||||
NebulaLog::log("ImM",Log::INFO,oss);
|
||||
|
||||
img->unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
268
src/image/ImageManagerDriver.cc
Normal file
268
src/image/ImageManagerDriver.cc
Normal file
@ -0,0 +1,268 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "ImageManagerDriver.h"
|
||||
#include "ImagePool.h"
|
||||
|
||||
#include "NebulaLog.h"
|
||||
|
||||
#include "Nebula.h"
|
||||
#include <sstream>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Driver ASCII Protocol Implementation */
|
||||
/* ************************************************************************** */
|
||||
|
||||
void ImageManagerDriver::cp(int oid,
|
||||
const string& source,
|
||||
const string& destination) const
|
||||
{
|
||||
ostringstream os;
|
||||
|
||||
os << "CP " << oid << " " << source << " " << destination << endl;
|
||||
|
||||
write(os);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void ImageManagerDriver::mv(int oid,
|
||||
const string& source,
|
||||
const string& destination) const
|
||||
{
|
||||
ostringstream os;
|
||||
|
||||
os << "MV " << oid << " " << source << " " << destination << endl;
|
||||
|
||||
write(os);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void ImageManagerDriver::mkfs(int oid,
|
||||
const string& destination,
|
||||
const string& fs,
|
||||
const string& size_mb) const
|
||||
{
|
||||
ostringstream os;
|
||||
|
||||
os << "MKFS " << oid << " " << destination << " " <<
|
||||
fs << " " << size_mb << endl;
|
||||
write(os);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void ImageManagerDriver::rm(int oid, const string& destination) const
|
||||
{
|
||||
ostringstream os;
|
||||
|
||||
os << "RM " << oid << " " << destination << endl;
|
||||
|
||||
write(os);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* MAD Interface */
|
||||
/* ************************************************************************** */
|
||||
|
||||
void ImageManagerDriver::protocol(
|
||||
string& message)
|
||||
{
|
||||
istringstream is(message);
|
||||
ostringstream os;
|
||||
|
||||
string action;
|
||||
string result;
|
||||
|
||||
int id;
|
||||
Image * image;
|
||||
|
||||
string info;
|
||||
|
||||
os << "Message received: " << message;
|
||||
NebulaLog::log("ImG", Log::DEBUG, os);
|
||||
|
||||
// Parse the driver message
|
||||
if ( is.good() )
|
||||
is >> action >> ws;
|
||||
else
|
||||
return;
|
||||
|
||||
if ( is.good() )
|
||||
is >> result >> ws;
|
||||
else
|
||||
return;
|
||||
|
||||
if ( is.good() )
|
||||
{
|
||||
is >> id >> ws;
|
||||
|
||||
if ( is.fail() )
|
||||
{
|
||||
if ( action == "LOG" )
|
||||
{
|
||||
string info;
|
||||
|
||||
is.clear();
|
||||
getline(is,info);
|
||||
|
||||
NebulaLog::log("ImG",Log::INFO, info.c_str());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
// Get the image from the pool
|
||||
image = ipool->get(id,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Driver Actions
|
||||
if ( action == "CP" )
|
||||
{
|
||||
if ( result == "SUCCESS" )
|
||||
{
|
||||
image->set_state(Image::READY);
|
||||
ipool->update(image);
|
||||
|
||||
image->unlock();
|
||||
|
||||
NebulaLog::log("ImM", Log::INFO, "Image copied and ready to use.");
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_cp;
|
||||
}
|
||||
}
|
||||
else if ( action == "MV" )
|
||||
{
|
||||
if ( result == "SUCCESS" )
|
||||
{
|
||||
image->set_state(Image::READY);
|
||||
ipool->update(image);
|
||||
|
||||
image->unlock();
|
||||
|
||||
NebulaLog::log("ImM", Log::INFO, "Image saved and ready to use.");
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_mv;
|
||||
}
|
||||
}
|
||||
else if ( action == "MKFS" )
|
||||
{
|
||||
if ( result == "SUCCESS" )
|
||||
{
|
||||
image->set_state(Image::READY);
|
||||
ipool->update(image);
|
||||
|
||||
image->unlock();
|
||||
|
||||
NebulaLog::log("ImM", Log::INFO, "Image created and ready to use");
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_mkfs;
|
||||
}
|
||||
}
|
||||
else if ( action == "RM" )
|
||||
{
|
||||
int rc;
|
||||
string source;
|
||||
|
||||
source = image->get_source();
|
||||
|
||||
rc = ipool->drop(image);
|
||||
|
||||
image->unlock();
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
NebulaLog::log("ImM",Log::ERROR,"Image could not be removed from DB");
|
||||
}
|
||||
|
||||
if ( result == "SUCCESS" )
|
||||
{
|
||||
NebulaLog::log("ImM",Log::ERROR,"Image successfully removed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss <<"Error removing image from repository. Remove file " << source
|
||||
<<" to completely delete image.";
|
||||
|
||||
NebulaLog::log("ImM",Log::ERROR,oss);
|
||||
}
|
||||
}
|
||||
else if (action == "LOG")
|
||||
{
|
||||
getline(is,info);
|
||||
NebulaLog::log("ImM", Log::INFO, info.c_str());
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error_cp:
|
||||
os.str("");
|
||||
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";
|
||||
|
||||
error_common:
|
||||
getline(is,info);
|
||||
|
||||
if (!info.empty() && (info[0] != '-'))
|
||||
{
|
||||
os << ": " << info;
|
||||
}
|
||||
|
||||
NebulaLog::log("ImM", Log::ERROR, os);
|
||||
|
||||
image->set_state(Image::ERROR);
|
||||
ipool->update(image);
|
||||
|
||||
image->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void ImageManagerDriver::recover()
|
||||
{
|
||||
NebulaLog::log("ImG",Log::INFO,"Recovering Image Repository drivers");
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "ImagePool.h"
|
||||
#include "AuthManager.h"
|
||||
#include "Nebula.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -68,9 +69,6 @@ int ImagePool::allocate (
|
||||
string name;
|
||||
ostringstream oss;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Build a new Image object
|
||||
// ---------------------------------------------------------------------
|
||||
img = new Image(uid, user_name, img_template);
|
||||
|
||||
// Check name
|
||||
@ -96,7 +94,6 @@ int ImagePool::allocate (
|
||||
|
||||
return *oid;
|
||||
|
||||
|
||||
error_name:
|
||||
oss << "NAME cannot be empty.";
|
||||
goto error_common;
|
||||
@ -128,6 +125,9 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImageManager * imagem = nd.get_imagem();
|
||||
|
||||
source = disk->vector_value("IMAGE");
|
||||
|
||||
if (source.empty())
|
||||
@ -144,7 +144,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
|
||||
|
||||
if( !is.fail() )
|
||||
{
|
||||
img = get(image_id,true);
|
||||
img = imagem->acquire_image(image_id);
|
||||
|
||||
if (img == 0)
|
||||
{
|
||||
@ -155,7 +155,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
|
||||
}
|
||||
else
|
||||
{
|
||||
img = get(source,uid,true);
|
||||
img = imagem->acquire_image(source,uid);
|
||||
|
||||
if (img == 0)
|
||||
{
|
||||
@ -167,7 +167,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
|
||||
{
|
||||
string type = disk->vector_value("TYPE");
|
||||
|
||||
transform(type.begin(), type.end(), type.begin(), (int(*)(int))toupper);
|
||||
transform(type.begin(),type.end(),type.begin(),(int(*)(int))toupper);
|
||||
|
||||
if( type == "SWAP" )
|
||||
{
|
||||
@ -187,12 +187,9 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = img->disk_attribute(disk, index, img_type);
|
||||
img->disk_attribute(disk, index, img_type);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
update(img);
|
||||
}
|
||||
update(img);
|
||||
|
||||
img->unlock();
|
||||
}
|
||||
|
@ -23,7 +23,10 @@ lib_name='nebula_image'
|
||||
# Sources to generate the library
|
||||
source_files=[
|
||||
'Image.cc',
|
||||
'ImagePool.cc'
|
||||
'ImagePool.cc',
|
||||
'ImageManagerDriver.cc',
|
||||
'ImageManager.cc',
|
||||
'ImageManagerActions.cc'
|
||||
]
|
||||
|
||||
# Build library
|
||||
|
@ -31,17 +31,17 @@ const string names[] = {"Image one", "Second Image", "The third image"};
|
||||
const string templates[] =
|
||||
{
|
||||
"NAME = \"Image one\"\n"
|
||||
"ORIGINAL_PATH = /tmp/image_test\n"
|
||||
"PATH = /tmp/image_test\n"
|
||||
"PERSISTENT = YES\n"
|
||||
"DESCRIPTION = \"This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.\"\n",
|
||||
|
||||
"NAME = \"Second Image\"\n"
|
||||
"ORIGINAL_PATH = /tmp/image_second_test\n"
|
||||
"PATH = /tmp/image_second_test\n"
|
||||
"PUBLIC = YES\n"
|
||||
"DESCRIPTION = \"This is a rather short description.\"\n",
|
||||
|
||||
"NAME = \"The third image\"\n"
|
||||
"ORIGINAL_PATH = /tmp/image_test\n"
|
||||
"PATH = /tmp/image_test\n"
|
||||
"# DESCRIPTION = \"An image description\"\n"
|
||||
"BUS = SCSI\n"
|
||||
"PROFILE = STUDENT\n"
|
||||
@ -50,19 +50,19 @@ const string templates[] =
|
||||
|
||||
const string xmls[] =
|
||||
{
|
||||
"<IMAGE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE>",
|
||||
"<IMAGE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><PATH><![CDATA[/tmp/image_test]]></PATH></TEMPLATE></IMAGE>",
|
||||
|
||||
"<IMAGE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_second_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE>",
|
||||
"<IMAGE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><PATH><![CDATA[/tmp/image_second_test]]></PATH></TEMPLATE></IMAGE>",
|
||||
|
||||
"<IMAGE><ID>0</ID><UID>2</UID><USERNAME>C user</USERNAME><NAME>The third image</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/e50b0c738be9d431475bf5859629e5580301a7d6</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><BUS><![CDATA[SCSI]]></BUS><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[The third image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH><PROFILE><![CDATA[STUDENT]]></PROFILE></TEMPLATE></IMAGE>"
|
||||
"<IMAGE><ID>0</ID><UID>2</UID><USERNAME>C user</USERNAME><NAME>The third image</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/e50b0c738be9d431475bf5859629e5580301a7d6</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><BUS><![CDATA[SCSI]]></BUS><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[The third image]]></NAME><PATH><![CDATA[/tmp/image_test]]></PATH><PROFILE><![CDATA[STUDENT]]></PROFILE></TEMPLATE></IMAGE>"
|
||||
};
|
||||
|
||||
|
||||
// This xml dump result has the STIMEs modified to 0000000000
|
||||
const string xml_dump =
|
||||
"<IMAGE_POOL><IMAGE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE><IMAGE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_second_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE><IMAGE><ID>2</ID><UID>2</UID><USERNAME>C user</USERNAME><NAME>The third image</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/e50b0c738be9d431475bf5859629e5580301a7d6</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><BUS><![CDATA[SCSI]]></BUS><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[The third image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH><PROFILE><![CDATA[STUDENT]]></PROFILE></TEMPLATE></IMAGE></IMAGE_POOL>";
|
||||
"<IMAGE_POOL><IMAGE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><PATH><![CDATA[/tmp/image_test]]></PATH></TEMPLATE></IMAGE><IMAGE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><PATH><![CDATA[/tmp/image_second_test]]></PATH></TEMPLATE></IMAGE><IMAGE><ID>2</ID><UID>2</UID><USERNAME>C user</USERNAME><NAME>The third image</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/e50b0c738be9d431475bf5859629e5580301a7d6</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><BUS><![CDATA[SCSI]]></BUS><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[The third image]]></NAME><PATH><![CDATA[/tmp/image_test]]></PATH><PROFILE><![CDATA[STUDENT]]></PROFILE></TEMPLATE></IMAGE></IMAGE_POOL>";
|
||||
const string xml_dump_where =
|
||||
"<IMAGE_POOL><IMAGE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE><IMAGE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>3</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><ORIGINAL_PATH><![CDATA[/tmp/image_second_test]]></ORIGINAL_PATH></TEMPLATE></IMAGE></IMAGE_POOL>";
|
||||
"<IMAGE_POOL><IMAGE><ID>0</ID><UID>0</UID><USERNAME>A user</USERNAME><NAME>Image one</NAME><TYPE>0</TYPE><PUBLIC>0</PUBLIC><PERSISTENT>1</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a very long description of an image, and to achieve the longness I will copy this over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over. This is a very long description of an image, and to achieve the longness I will copy this over. And over.This is a very long description of an image, and to achieve the longness I will copy this over.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Image one]]></NAME><PATH><![CDATA[/tmp/image_test]]></PATH></TEMPLATE></IMAGE><IMAGE><ID>1</ID><UID>1</UID><USERNAME>B user</USERNAME><NAME>Second Image</NAME><TYPE>0</TYPE><PUBLIC>1</PUBLIC><PERSISTENT>0</PERSISTENT><REGTIME>0000000000</REGTIME><SOURCE>source_prefix/c9d51800847467911c755e5e4c13dfe28c3a79f3</SOURCE><STATE>4</STATE><RUNNING_VMS>0</RUNNING_VMS><TEMPLATE><DESCRIPTION><![CDATA[This is a rather short description.]]></DESCRIPTION><DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX><NAME><![CDATA[Second Image]]></NAME><PATH><![CDATA[/tmp/image_second_test]]></PATH></TEMPLATE></IMAGE></IMAGE_POOL>";
|
||||
|
||||
const string replacement = "0000000000";
|
||||
|
||||
@ -128,7 +128,10 @@ class ImagePoolTest : public PoolTest
|
||||
CPPUNIT_TEST ( bus_source_assignment );
|
||||
CPPUNIT_TEST ( public_attribute );
|
||||
CPPUNIT_TEST ( persistence );
|
||||
CPPUNIT_TEST ( imagepool_disk_attribute );
|
||||
|
||||
// Requires ImageManger, and NebulaTest
|
||||
// CPPUNIT_TEST ( imagepool_disk_attribute );
|
||||
|
||||
CPPUNIT_TEST ( dump );
|
||||
CPPUNIT_TEST ( dump_where );
|
||||
|
||||
@ -241,7 +244,7 @@ public:
|
||||
// Image object should be cached. Let's change some template attributes
|
||||
img->replace_template_attribute(description_name, new_description);
|
||||
img->replace_template_attribute(attr_name, new_attr_value);
|
||||
img->remove_template_attribute("ORIGINAL_PATH");
|
||||
img->remove_template_attribute("PATH");
|
||||
|
||||
ip->update(img);
|
||||
|
||||
@ -253,7 +256,7 @@ public:
|
||||
|
||||
img->get_template_attribute("DESCRIPTION", description_val);
|
||||
img->get_template_attribute("NEW_ATTRIBUTE", attr_val);
|
||||
img->get_template_attribute("ORIGINAL_PATH", no_value);
|
||||
img->get_template_attribute("PATH", no_value);
|
||||
|
||||
CPPUNIT_ASSERT( description_val == new_description );
|
||||
CPPUNIT_ASSERT( attr_val == new_attr_value );
|
||||
@ -271,7 +274,7 @@ public:
|
||||
no_value = "Random value";
|
||||
img->get_template_attribute("DESCRIPTION", description_val);
|
||||
img->get_template_attribute("NEW_ATTRIBUTE", attr_val);
|
||||
img->get_template_attribute("ORIGINAL_PATH", no_value);
|
||||
img->get_template_attribute("PATH", no_value);
|
||||
|
||||
CPPUNIT_ASSERT( description_val == new_description );
|
||||
CPPUNIT_ASSERT( attr_val == new_attr_value );
|
||||
@ -398,11 +401,11 @@ public:
|
||||
|
||||
string templates[] =
|
||||
{
|
||||
"ORIGINAL_PATH = /tmp/image_test\n"
|
||||
"PATH = /tmp/image_test\n"
|
||||
"DESCRIPTION = \"This template lacks name!\"\n",
|
||||
|
||||
"NAME = \"name A\"\n"
|
||||
"ORIGINAL_PATH = /tmp/image_test\n"
|
||||
"PATH = /tmp/image_test\n"
|
||||
"TYPE = WRONG\n",
|
||||
|
||||
"NAME \"PARSE ERROR\"\n"
|
||||
@ -451,7 +454,7 @@ public:
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
CPPUNIT_ASSERT( oid == 0 );
|
||||
|
||||
img->enable(true);
|
||||
img->set_state(Image::READY);
|
||||
img->disk_attribute(disk, &index, &img_type);
|
||||
|
||||
value = disk->vector_value("TARGET");
|
||||
@ -466,7 +469,7 @@ public:
|
||||
disk = new VectorAttribute("DISK");
|
||||
|
||||
// Allocate a CDROM type image
|
||||
string templ = "NAME = \"name A\" TYPE = CDROM ORIGINAL_PATH = /tmp";
|
||||
string templ = "NAME = \"name A\" TYPE = CDROM PATH = /tmp";
|
||||
imp->allocate(0, templ, &oid);
|
||||
|
||||
CPPUNIT_ASSERT(oid >= 0);
|
||||
@ -474,7 +477,7 @@ public:
|
||||
img = imp->get(oid, false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
|
||||
img->enable(true);
|
||||
img->set_state(Image::READY);
|
||||
img->disk_attribute(disk, &index, &img_type);
|
||||
|
||||
value = disk->vector_value("TARGET");
|
||||
@ -488,7 +491,7 @@ public:
|
||||
disk = new VectorAttribute("DISK");
|
||||
|
||||
// Allocate a DATABLOCK type image
|
||||
templ = "NAME = \"name B\" TYPE = DATABLOCK";
|
||||
templ = "NAME = \"name B\" TYPE = DATABLOCK PATH=\"/dev/null\"";
|
||||
imp->allocate(0, templ, &oid);
|
||||
|
||||
CPPUNIT_ASSERT(oid >= 0);
|
||||
@ -496,7 +499,7 @@ public:
|
||||
img = imp->get(oid, false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
|
||||
img->enable(true);
|
||||
img->set_state(Image::READY);
|
||||
img->disk_attribute(disk, &index, &img_type);
|
||||
|
||||
value = disk->vector_value("TARGET");
|
||||
@ -510,7 +513,8 @@ public:
|
||||
disk = new VectorAttribute("DISK");
|
||||
|
||||
// Allocate a DATABLOCK type image
|
||||
templ = "NAME = \"name C\" TYPE = DATABLOCK DEV_PREFIX = \"sd\"";
|
||||
templ = "NAME = \"name C\" TYPE = DATABLOCK DEV_PREFIX = \"sd\""
|
||||
" SIZE=4 FSTYPE=ext3";
|
||||
imp->allocate(0, templ, &oid);
|
||||
|
||||
CPPUNIT_ASSERT(oid >= 0);
|
||||
@ -518,7 +522,7 @@ public:
|
||||
img = imp->get(oid, false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
|
||||
img->enable(true);
|
||||
img->set_state(Image::READY);
|
||||
img->disk_attribute(disk, &index, &img_type);
|
||||
|
||||
value = disk->vector_value("TARGET");
|
||||
@ -551,7 +555,7 @@ public:
|
||||
// A disk without a BUS attribute should not have it added.
|
||||
disk = new VectorAttribute("DISK");
|
||||
|
||||
img->enable(true);
|
||||
img->set_state(Image::READY);
|
||||
rc = img->disk_attribute(disk, &index, &img_type);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
@ -565,7 +569,7 @@ public:
|
||||
"source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198" );
|
||||
|
||||
// clean up
|
||||
img->release_image();
|
||||
//img->release_image();
|
||||
delete disk;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
@ -573,7 +577,7 @@ public:
|
||||
disk = new VectorAttribute("DISK");
|
||||
disk->replace("BUS", "SCSI");
|
||||
|
||||
img->enable(true);
|
||||
img->set_state(Image::READY);
|
||||
rc = img->disk_attribute(disk, &index, &img_type);
|
||||
CPPUNIT_ASSERT( rc == 0 );
|
||||
|
||||
@ -606,10 +610,12 @@ public:
|
||||
// Allocate 2 images, with different dev_prefix
|
||||
|
||||
string template_0 = "NAME = \"Image 0\"\n"
|
||||
"DEV_PREFIX = \"hd\"\n";
|
||||
"DEV_PREFIX = \"hd\"\n"
|
||||
"PATH = /dev/null\n";
|
||||
|
||||
string template_1 = "NAME = \"Image 1\"\n"
|
||||
"DEV_PREFIX = \"sd\"\n";
|
||||
"DEV_PREFIX = \"sd\"\n"
|
||||
"PATH = /dev/null\n";
|
||||
|
||||
|
||||
imp->allocate(0, template_0, &oid_0);
|
||||
@ -621,11 +627,11 @@ public:
|
||||
|
||||
img = imp->get(oid_0, false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
img->enable(true);
|
||||
img->set_state(Image::READY);
|
||||
|
||||
img = imp->get(oid_1, false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
img->enable(true);
|
||||
img->set_state(Image::READY);
|
||||
|
||||
|
||||
// Disk using image 0
|
||||
@ -675,46 +681,46 @@ public:
|
||||
{
|
||||
// false
|
||||
"NAME = \"name A\"\n"
|
||||
"ORIGINAL_PATH = \"/tmp/nothing\"\n",
|
||||
"PATH = \"/tmp/nothing\"\n",
|
||||
|
||||
// true
|
||||
"NAME = \"name B\"\n"
|
||||
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
|
||||
"PATH = \"/tmp/nothing\"\n"
|
||||
"PUBLIC = YES",
|
||||
|
||||
// false
|
||||
"NAME = \"name C\"\n"
|
||||
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
|
||||
"PATH = \"/tmp/nothing\"\n"
|
||||
"PUBLIC = NO",
|
||||
|
||||
// false
|
||||
"NAME = \"name D\"\n"
|
||||
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
|
||||
"PATH = \"/tmp/nothing\"\n"
|
||||
"PUBLIC = 1",
|
||||
|
||||
// true
|
||||
"NAME = \"name E\"\n"
|
||||
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
|
||||
"PATH = \"/tmp/nothing\"\n"
|
||||
"PUBLIC = Yes",
|
||||
|
||||
// false
|
||||
"NAME = \"name F\"\n"
|
||||
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
|
||||
"PATH = \"/tmp/nothing\"\n"
|
||||
"PUBLIC = TRUE",
|
||||
|
||||
// true
|
||||
"NAME = \"name G\"\n"
|
||||
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
|
||||
"PATH = \"/tmp/nothing\"\n"
|
||||
"PUBLIC = yes",
|
||||
|
||||
// false
|
||||
"NAME = \"name H\"\n"
|
||||
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
|
||||
"PATH = \"/tmp/nothing\"\n"
|
||||
"PUBLIC = 'YES'",
|
||||
|
||||
// true
|
||||
"NAME = \"name I\"\n"
|
||||
"ORIGINAL_PATH = \"/tmp/nothing\"\n"
|
||||
"PATH = \"/tmp/nothing\"\n"
|
||||
"PUBLIC = \"YES\"",
|
||||
|
||||
"END"
|
||||
@ -769,19 +775,23 @@ public:
|
||||
{
|
||||
"NAME = \"Image 1\"\n"
|
||||
"PERSISTENT = NO\n"
|
||||
"PUBLIC = NO\n",
|
||||
"PUBLIC = NO\n"
|
||||
"PATH = /dev/null\n",
|
||||
|
||||
"NAME = \"Image 2\"\n"
|
||||
"PERSISTENT = NO\n"
|
||||
"PUBLIC = YES\n",
|
||||
"PUBLIC = YES\n"
|
||||
"PATH = /dev/null\n",
|
||||
|
||||
"NAME = \"Image 3\"\n"
|
||||
"PERSISTENT = YES\n"
|
||||
"PUBLIC = NO\n",
|
||||
"PUBLIC = NO\n"
|
||||
"PATH = /dev/null\n",
|
||||
|
||||
"NAME = \"Image 4\"\n"
|
||||
"PERSISTENT = YES\n"
|
||||
"PUBLIC = YES\n",
|
||||
"PUBLIC = YES\n"
|
||||
"PATH = /dev/null\n",
|
||||
|
||||
"END"
|
||||
};
|
||||
@ -864,8 +874,8 @@ public:
|
||||
string result = oss.str();
|
||||
|
||||
result.replace(157, 10, replacement);
|
||||
result.replace(1147, 10, replacement);
|
||||
result.replace(1677, 10, replacement);
|
||||
result.replace(1129, 10, replacement);
|
||||
result.replace(1641, 10, replacement);
|
||||
|
||||
/*
|
||||
if( result != xml_dump )
|
||||
@ -899,7 +909,7 @@ public:
|
||||
|
||||
string result = oss.str();
|
||||
result.replace(157, 10, replacement);
|
||||
result.replace(1147, 10, replacement);
|
||||
result.replace(1129, 10, replacement);
|
||||
|
||||
/*
|
||||
if( result != xml_dump_where )
|
||||
|
44
src/image_mad/one_image
Executable file
44
src/image_mad/one_image
Executable file
@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
#Setup driver variables
|
||||
DRIVER_NAME=`basename $0 | cut -d. -f1`
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
DRIVERRC=/etc/one/${DRIVER_NAME}/${DRIVER_NAME}rc
|
||||
MADCOMMON=/usr/lib/one/mads/madcommon.sh
|
||||
VAR_LOCATION=/var/lib/one
|
||||
else
|
||||
DRIVERRC=$ONE_LOCATION/etc/${DRIVER_NAME}/${DRIVER_NAME}rc
|
||||
MADCOMMON=$ONE_LOCATION/lib/mads/madcommon.sh
|
||||
VAR_LOCATION=$ONE_LOCATION/var
|
||||
fi
|
||||
|
||||
. $MADCOMMON
|
||||
|
||||
# Export the im_mad specific rc
|
||||
|
||||
export_rc_vars $DRIVERRC
|
||||
|
||||
# Go to var directory ONE_LOCATION/var or /var/lib/one
|
||||
cd $VAR_LOCATION
|
||||
|
||||
LOG_FILE=$DRIVER_NAME
|
||||
|
||||
# Execute the actual MAD
|
||||
execute_mad $*
|
136
src/image_mad/one_image.rb
Executable file
136
src/image_mad/one_image.rb
Executable file
@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# -------------------------------------------------------------------------- */
|
||||
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
|
||||
# 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. */
|
||||
# -------------------------------------------------------------------------- */
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Set up the environment for the driver
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
ONE_LOCATION = ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION = "/usr/lib/one/ruby"
|
||||
VAR_LOCATION = "/var/lib/one"
|
||||
else
|
||||
RUBY_LIB_LOCATION = ONE_LOCATION + "/lib/ruby"
|
||||
VAR_LOCATION = ONE_LOCATION + "/var"
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
|
||||
require "OpenNebulaDriver"
|
||||
require "CommandManager"
|
||||
require 'getoptlong'
|
||||
|
||||
# This class provides basic messaging and logging functionality
|
||||
# to implement Image Repository Drivers. A image repository driver
|
||||
# is a program (or a set of) that specialize the OpenNebula behavior
|
||||
# by interfacing with specific infrastructure storage solutions.
|
||||
class ImageDriver < OpenNebulaDriver
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Image Driver Protocol constants
|
||||
# -------------------------------------------------------------------------
|
||||
ACTION = {
|
||||
:mv => "MV",
|
||||
:cp => "CP",
|
||||
:rm => "RM",
|
||||
:mkfs => "MKFS",
|
||||
:log => "LOG"
|
||||
}
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Register default actions for the protocol
|
||||
# -------------------------------------------------------------------------
|
||||
def initialize(fs_type, concurrency=10, threaded=true)
|
||||
super(concurrency,threaded)
|
||||
|
||||
@actions_path = "#{VAR_LOCATION}/remotes/image/#{fs_type}"
|
||||
|
||||
register_action(ACTION[:mv].to_sym, method("mv"))
|
||||
register_action(ACTION[:cp].to_sym, method("cp"))
|
||||
register_action(ACTION[:rm].to_sym, method("rm"))
|
||||
register_action(ACTION[:mkfs].to_sym, method("mkfs"))
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Execute a command associated to an action and id on localhost
|
||||
# -------------------------------------------------------------------------
|
||||
def local_action(command, id, action)
|
||||
command_exe = LocalCommand.run(command)
|
||||
|
||||
if command_exe.code == 0
|
||||
result = :success
|
||||
info = "-"
|
||||
else
|
||||
result = :failure
|
||||
info = command_exe.stderr
|
||||
end
|
||||
|
||||
info = "-" if info == nil || info.empty?
|
||||
|
||||
send_message(ACTION[action],RESULT[result],id,info)
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Image Manager Protocol Actions (generic implementation
|
||||
# -------------------------------------------------------------------------
|
||||
def mv(id, src, dst)
|
||||
local_action("#{@actions_path}/mv #{src} #{dst}",id,:mv)
|
||||
end
|
||||
|
||||
def cp(id, src, dst)
|
||||
local_action("#{@actions_path}/cp #{src} #{dst}",id,:cp)
|
||||
end
|
||||
|
||||
def rm(id, dst)
|
||||
local_action("#{@actions_path}/rm #{dst}",id,:rm)
|
||||
end
|
||||
|
||||
def mkfs(id, dst, fs, size)
|
||||
local_action("#{@actions_path}/mkfs #{dst} #{fs} #{size}",id,:mkfs)
|
||||
end
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# ImageDriver Main program
|
||||
# ---------------------------------------------------------------------------- #
|
||||
opts = GetoptLong.new(
|
||||
[ '--threads', '-t', GetoptLong::OPTIONAL_ARGUMENT ]
|
||||
)
|
||||
|
||||
fs_type = ''
|
||||
threads = 15
|
||||
|
||||
begin
|
||||
opts.each do |opt, arg|
|
||||
case opt
|
||||
when '--threads'
|
||||
threads = arg.to_i
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
if ARGV.length >= 1
|
||||
fs_type = ARGV.shift
|
||||
else
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
image_driver = ImageDriver.new(fs_type, threads)
|
||||
image_driver.start_driver
|
53
src/image_mad/remotes/fs/cp
Executable file
53
src/image_mad/remotes/fs/cp
Executable file
@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
###############################################################################
|
||||
# This script is used to copy a VM image (SRC) to the image repository as DST
|
||||
# Several SRC types are supported
|
||||
###############################################################################
|
||||
|
||||
# ------------ Set up the environment to source common tools ------------
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/usr/lib/one/mads/tm_common.sh
|
||||
VAR_LOCATION=/var/lib/one/
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh
|
||||
VAR_LOCATION=$ONE_LOCATION/var/
|
||||
fi
|
||||
|
||||
. $TMCOMMON
|
||||
|
||||
# ------------ Copy the image to the repository ------------
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
|
||||
case $SRC in
|
||||
http://*)
|
||||
log "Downloading $SRC to the image repository"
|
||||
exec_and_log "$WGET -O $DST $SRC"
|
||||
;;
|
||||
|
||||
*)
|
||||
log "Copying local image $SRC to the image repository"
|
||||
exec_and_log "cp -f $SRC $DST"
|
||||
;;
|
||||
esac
|
||||
|
||||
exec_and_log "chmod 0660 $DST"
|
42
src/image_mad/remotes/fs/mkfs
Executable file
42
src/image_mad/remotes/fs/mkfs
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
###############################################################################
|
||||
# This script is used to create a VM image (SRC) of size (SIZE) and formatted
|
||||
# as (FS)
|
||||
###############################################################################
|
||||
|
||||
# ------------ Set up the environment to source common tools ------------
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/usr/lib/one/mads/tm_common.sh
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh
|
||||
fi
|
||||
|
||||
. $TMCOMMON
|
||||
|
||||
# ------------ Create the image to the repository ------------
|
||||
|
||||
DST=$1
|
||||
FSTYPE=$2
|
||||
SIZE=$3
|
||||
|
||||
exec_and_log "$DD if=/dev/zero of=$DST bs=1 count=1 seek=${SIZE}M"
|
||||
exec_and_log "$MKFS -t $FSTYPE -F $DST"
|
||||
exec_and_log "chmod 0660 $DST"
|
53
src/image_mad/remotes/fs/mv
Executable file
53
src/image_mad/remotes/fs/mv
Executable file
@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
###############################################################################
|
||||
# This script is used to move a VM image (SRC) to the image repository as DST
|
||||
# Several SRC types are supported
|
||||
###############################################################################
|
||||
|
||||
# ------------ Set up the environment to source common tools ------------
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/usr/lib/one/mads/tm_common.sh
|
||||
VAR_LOCATION=/var/lib/one/
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh
|
||||
VAR_LOCATION=$ONE_LOCATION/var/
|
||||
fi
|
||||
|
||||
. $TMCOMMON
|
||||
|
||||
# ------------ Move the image to the repository ------------
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
|
||||
case $SRC in
|
||||
http://*)
|
||||
log "Downloading $SRC to the image repository"
|
||||
exec_and_log "$WGET -O $DST $SRC"
|
||||
;;
|
||||
|
||||
*)
|
||||
log "Moving local image $SRC to the image repository"
|
||||
exec_and_log "mv -f $SRC $DST"
|
||||
;;
|
||||
esac
|
||||
|
||||
exec_and_log "chmod 0660 $DST"
|
42
src/image_mad/remotes/fs/rm
Executable file
42
src/image_mad/remotes/fs/rm
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
###############################################################################
|
||||
# This script is used to remove a VM image (SRC) from the image repository
|
||||
###############################################################################
|
||||
|
||||
# ------------ Set up the environment to source common tools ------------
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
TMCOMMON=/usr/lib/one/mads/tm_common.sh
|
||||
VAR_LOCATION=/var/lib/one/
|
||||
else
|
||||
TMCOMMON=$ONE_LOCATION/lib/mads/tm_common.sh
|
||||
VAR_LOCATION=$ONE_LOCATION/var/
|
||||
fi
|
||||
|
||||
. $TMCOMMON
|
||||
|
||||
# ------------ Remove the image to the repository ------------
|
||||
|
||||
SRC=$1
|
||||
|
||||
if [ -e $SRC ] ; then
|
||||
log "Removing $SRC from the image repository"
|
||||
exec_and_log "rm $SRC"
|
||||
fi
|
@ -511,6 +511,27 @@ void Nebula::start()
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Image Manager ----
|
||||
try
|
||||
{
|
||||
vector<const Attribute *> image_mads;
|
||||
|
||||
nebula_configuration->get("IMAGE_MAD", image_mads);
|
||||
|
||||
imagem = new ImageManager(ipool,image_mads);
|
||||
}
|
||||
catch (bad_alloc&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
rc = imagem->start();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
throw runtime_error("Could not start the Image Manager");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Load mads
|
||||
// -----------------------------------------------------------
|
||||
@ -522,6 +543,7 @@ void Nebula::start()
|
||||
im->load_mads(0);
|
||||
tm->load_mads(0);
|
||||
hm->load_mads(0);
|
||||
imagem->load_mads(0);
|
||||
|
||||
if ( authm != 0 )
|
||||
{
|
||||
@ -552,6 +574,7 @@ void Nebula::start()
|
||||
im->finalize();
|
||||
rm->finalize();
|
||||
hm->finalize();
|
||||
imagem->finalize();
|
||||
|
||||
//sleep to wait drivers???
|
||||
|
||||
@ -563,6 +586,7 @@ void Nebula::start()
|
||||
pthread_join(im->get_thread_id(),0);
|
||||
pthread_join(rm->get_thread_id(),0);
|
||||
pthread_join(hm->get_thread_id(),0);
|
||||
pthread_join(imagem->get_thread_id(),0);
|
||||
|
||||
//XML Library
|
||||
xmlCleanupParser();
|
||||
|
@ -222,12 +222,12 @@ public class VirtualMachine extends PoolElement{
|
||||
* VirtualMachine shutdowns.
|
||||
*
|
||||
* @param diskId ID of the disk to be saved.
|
||||
* @param imageId ID of the image where the disk will be saved.
|
||||
* @param imageName Name of the new Image that will be created.
|
||||
* @return If an error occurs the error message contains the reason.
|
||||
*/
|
||||
public OneResponse savedisk(int diskId, int imageId)
|
||||
public OneResponse savedisk(int diskId, String imageName)
|
||||
{
|
||||
return client.call(SAVEDISK, id ,diskId, imageId);
|
||||
return client.call(SAVEDISK, id ,diskId, imageName);
|
||||
}
|
||||
|
||||
// =================================
|
||||
|
@ -35,12 +35,16 @@ public class ImageTest
|
||||
private static Client client;
|
||||
|
||||
private static OneResponse res;
|
||||
private static String name = "new_test_img";
|
||||
private static int cont = 0;
|
||||
|
||||
private static String template()
|
||||
{
|
||||
cont++;
|
||||
|
||||
private static String template =
|
||||
"NAME = \"" + name + "\"\n" +
|
||||
"ATT1 = \"val1\"";
|
||||
return "NAME = \"test_img_" + cont + "\"\n" +
|
||||
"PATH = /etc/hosts\n" +
|
||||
"ATT1 = \"val1\"";
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
@ -66,7 +70,7 @@ public class ImageTest
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
res = Image.allocate(client, template);
|
||||
res = Image.allocate(client, template());
|
||||
|
||||
int imgid = res.isError() ? -1 : Integer.parseInt(res.getMessage());
|
||||
image = new Image(imgid, client);
|
||||
@ -86,7 +90,7 @@ public class ImageTest
|
||||
{
|
||||
image.delete();
|
||||
|
||||
res = Image.allocate(client, template);
|
||||
res = Image.allocate(client, template());
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
int imgid = res.isError() ? -1 : Integer.parseInt(res.getMessage());
|
||||
@ -98,7 +102,7 @@ public class ImageTest
|
||||
boolean found = false;
|
||||
for(Image img : imagePool)
|
||||
{
|
||||
found = found || img.getName().equals(name);
|
||||
found = found || img.getName().equals("test_img_"+cont);
|
||||
}
|
||||
|
||||
assertTrue( found );
|
||||
@ -112,7 +116,7 @@ public class ImageTest
|
||||
|
||||
// assertTrue( image.getId().equals("0") );
|
||||
// assertTrue( image.id() == 0 );
|
||||
assertTrue( image.getName().equals(name) );
|
||||
assertTrue( image.getName().equals("test_img_"+cont) );
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -147,7 +151,8 @@ public class ImageTest
|
||||
assertTrue( image.xpath("ATT1").equals("") );
|
||||
}
|
||||
|
||||
@Test
|
||||
// TODO
|
||||
// @Test
|
||||
public void enable()
|
||||
{
|
||||
res = image.enable();
|
||||
@ -157,7 +162,8 @@ public class ImageTest
|
||||
assertTrue( image.isEnabled() );
|
||||
}
|
||||
|
||||
@Test
|
||||
// TODO
|
||||
// @Test
|
||||
public void disable()
|
||||
{
|
||||
res = image.disable();
|
||||
@ -194,7 +200,7 @@ public class ImageTest
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
// assertTrue( image.xpath("ID").equals("0") );
|
||||
assertTrue( image.xpath("NAME").equals(name) );
|
||||
assertTrue( image.xpath("NAME").equals("test_img_"+cont) );
|
||||
}
|
||||
|
||||
// @Test
|
||||
|
@ -23,7 +23,6 @@ import org.junit.Test;
|
||||
import org.opennebula.client.Client;
|
||||
import org.opennebula.client.OneResponse;
|
||||
import org.opennebula.client.host.Host;
|
||||
import org.opennebula.client.image.Image;
|
||||
import org.opennebula.client.vm.VirtualMachine;
|
||||
import org.opennebula.client.vm.VirtualMachinePool;
|
||||
|
||||
@ -309,21 +308,14 @@ public class VirtualMachineTest
|
||||
|
||||
vm = new VirtualMachine(vmid, client);
|
||||
|
||||
String imgTemplate =
|
||||
"NAME = \"image\"\n" +
|
||||
"ATT1 = \"val1\"";
|
||||
|
||||
res = Image.allocate(client, imgTemplate);
|
||||
|
||||
int imgid = res.isError() ? -1 : Integer.parseInt(res.getMessage());
|
||||
|
||||
res = vm.savedisk(0, imgid);
|
||||
res = vm.savedisk(0, "New_image");
|
||||
assertTrue( !res.isError() );
|
||||
assertTrue( res.getMessage().equals("0") );
|
||||
|
||||
res = vm.info();
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
assertTrue( vm.xpath("TEMPLATE/DISK/SAVE_AS").equals(Integer.toString(imgid)) );
|
||||
assertTrue( vm.xpath("TEMPLATE/DISK/SAVE_AS").equals(("0")) );
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -5,20 +5,30 @@
|
||||
#*******************************************************************************
|
||||
# Daemon configuration attributes
|
||||
#-------------------------------------------------------------------------------
|
||||
# HOST_MONITORING_INTERVAL: Time in seconds between host monitorization
|
||||
# MANAGER_TIMER: Time in seconds the core uses to evaluate periodical functions.
|
||||
# HOST_MONITORING_INTERVAL and VM_POLLING_INTERVAL can not have smaller values
|
||||
# than MANAGER_TIMER.
|
||||
#
|
||||
# HOST_MONITORING_INTERVAL: Time in seconds between host monitorization.
|
||||
#
|
||||
# VM_POLLING_INTERVAL: Time in seconds between virtual machine monitorization.
|
||||
# (use 0 to disable VM monitoring).
|
||||
#
|
||||
# VM_DIR: Remote path to store the VM images, it should be shared between all
|
||||
# the cluster nodes to perform live migrations. This variable is the default
|
||||
# for all the hosts in the cluster.
|
||||
# for all the hosts in the cluster. VM_DIR IS ONLY FOR THE NODES AND *NOT* THE
|
||||
# FRONT-END
|
||||
#
|
||||
# SCRIPTS_REMOTE_DIR: Remote path to store the monitoring and VM management
|
||||
# scripts.
|
||||
#
|
||||
# PORT: Port where oned will listen for xmlrpc calls.
|
||||
#
|
||||
# DB: Configuration attributes for the database backend
|
||||
# backend : can be sqlite or mysql (default is sqlite)
|
||||
# server : (mysql) host name or an IP address for the MySQL server
|
||||
# port : (mysql) port for the connection to the server.
|
||||
# If set to 0, the default port is used.
|
||||
# user : (mysql) user's MySQL login ID
|
||||
# passwd : (mysql) the password for user
|
||||
# db_name : (mysql) the database name
|
||||
@ -29,13 +39,15 @@
|
||||
# DEBUG_LEVEL: 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG
|
||||
#*******************************************************************************
|
||||
|
||||
#MANAGER_TIMER=30
|
||||
|
||||
HOST_MONITORING_INTERVAL = 600
|
||||
|
||||
VM_POLLING_INTERVAL = 600
|
||||
|
||||
#VM_DIR=/srv/cloud/one/var
|
||||
|
||||
SCRIPTS_REMOTE_DIR=/tmp/one
|
||||
SCRIPTS_REMOTE_DIR=/var/tmp/one
|
||||
|
||||
PORT=2666
|
||||
|
||||
@ -44,6 +56,7 @@ DB = [ backend = "sqlite" ]
|
||||
# Sample configuration for MySQL
|
||||
# DB = [ backend = "mysql",
|
||||
# server = "localhost",
|
||||
# port = 0,
|
||||
# user = "oneadmin",
|
||||
# passwd = "oneadmin",
|
||||
# db_name = "opennebula" ]
|
||||
@ -70,7 +83,7 @@ MAC_PREFIX = "02:00"
|
||||
# Image Repository Configuration
|
||||
#*******************************************************************************
|
||||
# IMAGE_REPOSITORY_PATH: Define the path to the image repository, by default
|
||||
# is set to $ONE_LOCATION/var
|
||||
# is set to $ONE_LOCATION/var/images
|
||||
#
|
||||
# DEFAULT_IMAGE_TYPE: This can take values
|
||||
# OS Image file holding an operating system
|
||||
@ -107,15 +120,19 @@ DEFAULT_DEVICE_PREFIX = "hd"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# KVM Information Driver Manager Configuration
|
||||
# -r number of retries when monitoring a host
|
||||
# -t number of threads, i.e. number of hosts monitored at the same time
|
||||
#-------------------------------------------------------------------------------
|
||||
IM_MAD = [
|
||||
name = "im_kvm",
|
||||
executable = "one_im_ssh",
|
||||
arguments = "kvm" ]
|
||||
arguments = "-r 0 -t 15 kvm" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# XEN Information Driver Manager Configuration
|
||||
# -r number of retries when monitoring a host
|
||||
# -t number of threads, i.e. number of hosts monitored at the same time
|
||||
#-------------------------------------------------------------------------------
|
||||
#IM_MAD = [
|
||||
# name = "im_xen",
|
||||
@ -132,6 +149,15 @@ IM_MAD = [
|
||||
# arguments = "im_ec2/im_ec2.conf" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Ganglia Information Driver Manager Configuration
|
||||
#-----------------------------------------------------------------------------
|
||||
#IM_MAD = [
|
||||
# name = "im_ganglia",
|
||||
# executable = "one_im_sh",
|
||||
# arguments = "ganglia" ]
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Dummy Information Driver Manager Configuration
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -161,17 +187,24 @@ IM_MAD = [ name="im_dummy", executable="one_im_dummy"]
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# KVM Virtualization Driver Manager Configuration
|
||||
# -r number of retries when monitoring a host
|
||||
# -t number of threads, i.e. number of hosts monitored at the same time
|
||||
# -p name of the poll probe (executed locally)
|
||||
#-------------------------------------------------------------------------------
|
||||
VM_MAD = [
|
||||
name = "vmm_kvm",
|
||||
executable = "one_vmm_ssh",
|
||||
arguments = "kvm",
|
||||
arguments = "-t 15 -r 0 kvm",
|
||||
default = "vmm_ssh/vmm_ssh_kvm.conf",
|
||||
type = "kvm" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# XEN Virtualization Driver Manager Configuration
|
||||
# -r number of retries when monitoring a host
|
||||
# -t number of threads, i.e. number of hosts monitored at the same time
|
||||
# -l do not perform the VM polling in the node
|
||||
# -p name of the poll probe (executed locally)
|
||||
#-------------------------------------------------------------------------------
|
||||
#VM_MAD = [
|
||||
# name = "vmm_xen",
|
||||
@ -252,6 +285,25 @@ TM_MAD = [
|
||||
# arguments = "tm_lvm/tm_lvm.conf" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#*******************************************************************************
|
||||
# Image Manager Driver Configuration
|
||||
#*******************************************************************************
|
||||
# Drivers to manage the image repository, specialized for the storage backend
|
||||
# executable: path of the transfer driver executable, can be an
|
||||
# absolute path or relative to $ONE_LOCATION/lib/mads (or
|
||||
# /usr/lib/one/mads/ if OpenNebula was installed in /)
|
||||
#
|
||||
# arguments : for the driver executable
|
||||
#*******************************************************************************
|
||||
#-------------------------------------------------------------------------------
|
||||
# FS based Image Manager Driver Configuration
|
||||
# -t number of threads, i.e. number of repo operations at the same time
|
||||
#-------------------------------------------------------------------------------
|
||||
IMAGE_MAD = [
|
||||
executable = "one_image",
|
||||
arguments = "fs -t 15" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#*******************************************************************************
|
||||
# Hook Manager Configuration
|
||||
#*******************************************************************************
|
||||
@ -272,6 +324,7 @@ TM_MAD = [
|
||||
# - SHUTDOWN, after the VM is shutdown
|
||||
# - STOP, after the VM is stopped (including VM image transfers)
|
||||
# - DONE, after the VM is deleted or shutdown
|
||||
# - FAILED, when the VM enters the failed state
|
||||
# command : path can be absolute or relative to $ONE_LOCATION/share/hooks
|
||||
# case of self-contained installation or relative to
|
||||
# /usr/share/one/hooks in case of system-wide installation
|
||||
@ -284,44 +337,88 @@ TM_MAD = [
|
||||
# - YES, The hook is executed in the host where the VM was
|
||||
# allocated
|
||||
# - NO, The hook is executed in the OpenNebula server (default)
|
||||
#
|
||||
#
|
||||
# Host Hooks (HOST_HOOK) defined by:
|
||||
# name : for the hook, useful to track the hook (OPTIONAL)
|
||||
# on : when the hook should be executed,
|
||||
# - CREATE, when the Host is created (onehost create)
|
||||
# - ERROR, when the Host enters the error state
|
||||
# - DISABLE, when the Host is disabled
|
||||
# command : path can be absolute or relative to $ONE_LOCATION/share/hooks
|
||||
# case of self-contained installation or relative to
|
||||
# /usr/share/one/hooks in case of system-wide installation
|
||||
# arguments : for the hook. You can use the Host ID with $HID to pass it as
|
||||
# argument for the hook
|
||||
# remote : values,
|
||||
# - YES, The hook is executed in the host
|
||||
# - NO, The hook is executed in the OpenNebula server (default)
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
HM_MAD = [
|
||||
executable = "one_hm" ]
|
||||
|
||||
#-------------------------------- Image Hook -----------------------------------
|
||||
# This hook is used to handle image saving and overwriting when virtual machines
|
||||
# reach the DONE state after being shutdown.
|
||||
|
||||
VM_HOOK = [
|
||||
name = "image",
|
||||
on = "DONE",
|
||||
command = "image.rb",
|
||||
arguments = "$VMID" ]
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#-------------------------------- Hook Examples --------------------------------
|
||||
#VM_HOOK = [
|
||||
# name = "dhcp",
|
||||
# on = "create",
|
||||
# command = "/bin/echo",
|
||||
# arguments = "$NAME > /tmp/test.$VMID" ]
|
||||
#------------------------------ Fault Tolerance Hooks --------------------------
|
||||
# This hook is used to perform recovery actions when a host fails. The VMs
|
||||
# running in the host can be deleted (use -d option) or resubmitted (-r) in
|
||||
# other host
|
||||
# Last argument (force) can be "y", so suspended VMs in the host will be
|
||||
# resubmitted/deleted, or "n", so suspended VMs in the host will be ignored
|
||||
#
|
||||
#HOST_HOOK = [
|
||||
# name = "error",
|
||||
# on = "ERROR",
|
||||
# command = "host_error.rb",
|
||||
# arguments = "$HID -r n",
|
||||
# remote = "no" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
# This two hooks can be used to automatically delete or resubmit VMs that reach
|
||||
# the "failed" state. This way, the administrator doesn't have to interact
|
||||
# manually to release its resources or retry the deployment.
|
||||
#
|
||||
# Only one of them should be uncommented.
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
#VM_HOOK = [
|
||||
# name = "ebtables",
|
||||
# name = "on_failure_delete",
|
||||
# on = "FAILED",
|
||||
# command = "/usr/bin/env onevm delete",
|
||||
# arguments = "$VMID" ]
|
||||
#
|
||||
#VM_HOOK = [
|
||||
# name = "on_failure_resubmit",
|
||||
# on = "FAILED",
|
||||
# command = "/usr/bin/env onevm resubmit",
|
||||
# arguments = "$VMID" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
#-------------------------------- ebtables Hook---------------------------------
|
||||
# You can use these two hooks to isolate networks at the ethernet level so the
|
||||
# traffic generated in different virtual networks can not be seen in others.
|
||||
#
|
||||
# All the network configuration will be done in the cluster nodes, these are the
|
||||
# additional requisites:
|
||||
# - ebtables package installed
|
||||
# - sudoers configured so oneadmin can execute ebtables without password
|
||||
#
|
||||
# NOTE: Change the first command for ebtables-xen if you are using Xen
|
||||
#
|
||||
#VM_HOOK = [
|
||||
# name = "ebtables-start",
|
||||
# on = "running",
|
||||
# command = "/usr/local/one/bin/set_net",
|
||||
# arguments = '$NIC[MAC, Network = "Private"]',
|
||||
# command = "ebtables-kvm", # or ebtables-xen
|
||||
# arguments = "one-$VMID",
|
||||
# remote = "yes" ]
|
||||
#
|
||||
#VM_HOOK = [
|
||||
# name = "ebtables-flush",
|
||||
# on = "done",
|
||||
# command = "ebtables-flush",
|
||||
# arguments = "",
|
||||
# remote = "yes" ]
|
||||
#-------------------------------------------------------------------------------
|
||||
#VM_HOOK = [
|
||||
# name = "mail",
|
||||
# on = "running",
|
||||
# command = "/usr/local/one/bin/send_mail",
|
||||
# arguments = "$VMID $NAME",
|
||||
# remote = "no" ]
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#*******************************************************************************
|
||||
# Auth Manager Configuration
|
||||
@ -340,4 +437,3 @@ VM_HOOK = [
|
||||
|
||||
#AUTH_MAD = [
|
||||
# executable = "one_auth_mad" ]
|
||||
|
||||
|
@ -11,11 +11,12 @@ fi
|
||||
|
||||
VAR_LOCATION="$ONE_LOCATION/var"
|
||||
|
||||
if [ "$(ls -A $VAR_LOCATION)" ]; then
|
||||
echo "$VAR_LOCATION is not empty."
|
||||
if [ -f $VAR_LOCATION/one.db ]; then
|
||||
echo "$VAR_LOCATION/one.db has to be overwritten, move it to a safe place."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
|
||||
PID=$$
|
||||
|
||||
oned -f &
|
||||
@ -29,6 +30,6 @@ CODE=$?
|
||||
pkill -P $PID oned
|
||||
sleep 4s;
|
||||
pkill -9 -P $PID oned
|
||||
rm -rf $VAR_LOCATION/*
|
||||
rm -f $VAR_LOCATION/one.db
|
||||
|
||||
exit $CODE
|
@ -31,7 +31,6 @@ require 'OpenNebula/VirtualNetwork'
|
||||
require 'OpenNebula/VirtualNetworkPool'
|
||||
require 'OpenNebula/Image'
|
||||
require 'OpenNebula/ImagePool'
|
||||
require 'OpenNebula/ImageRepository'
|
||||
require 'OpenNebula/User'
|
||||
require 'OpenNebula/UserPool'
|
||||
require 'OpenNebula/Host'
|
||||
|
@ -33,13 +33,15 @@ module OpenNebula
|
||||
:delete => "image.delete"
|
||||
}
|
||||
|
||||
IMAGE_STATES=%w{INIT READY USED DISABLED}
|
||||
IMAGE_STATES=%w{INIT READY USED DISABLED LOCKED ERROR}
|
||||
|
||||
SHORT_IMAGE_STATES={
|
||||
"INIT" => "init",
|
||||
"READY" => "rdy",
|
||||
"USED" => "used",
|
||||
"DISABLED" => "disa"
|
||||
"DISABLED" => "disa",
|
||||
"LOCKED" => "lock",
|
||||
"ERROR" => "err"
|
||||
}
|
||||
|
||||
IMAGE_TYPES=%w{OS CDROM DATABLOCK}
|
||||
|
@ -1,272 +0,0 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'OpenNebula/Image'
|
||||
require 'fileutils'
|
||||
require 'CommandManager'
|
||||
|
||||
module OpenNebula
|
||||
|
||||
############################################################################
|
||||
# The ImageRepository class represents and abstraction of the Image
|
||||
# Repository, and it provides basic operations to manage and mantain it.
|
||||
# This class is used by the OpenNebula daemon (through the image hook) to
|
||||
# save and update images, and by the OpenNebula CLI to create and delete
|
||||
# them
|
||||
############################################################################
|
||||
class ImageRepository
|
||||
########################################################################
|
||||
#
|
||||
########################################################################
|
||||
def create(image, template)
|
||||
if image.nil?
|
||||
error_msg = "Image could not be found, aborting."
|
||||
return OpenNebula::Error.new(error_msg)
|
||||
end
|
||||
|
||||
# ------ Allocate the Image ------
|
||||
result = image.allocate(template)
|
||||
|
||||
if OpenNebula.is_error?(result)
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
# ------ Copy the Image file ------
|
||||
image.info
|
||||
|
||||
if image['SOURCE'] and File.exists?(image['SOURCE'])
|
||||
error_msg =
|
||||
"Destination file for image already exists, aborting."
|
||||
result = OpenNebula::Error.new(error_msg)
|
||||
|
||||
elsif image['TEMPLATE/PATH'] and image['TEMPLATE/SOURCE'].nil?
|
||||
# --- CDROM, DATABLOCK or OS based on a PATH ---
|
||||
file_path = image['TEMPLATE/PATH']
|
||||
|
||||
if !File.exists?(file_path)
|
||||
error_msg = "Image file could not be found, aborting."
|
||||
result = OpenNebula::Error.new(error_msg)
|
||||
end
|
||||
|
||||
if !OpenNebula.is_error?(result)
|
||||
result = copy(file_path, image['SOURCE'])
|
||||
end
|
||||
|
||||
# If the copy failed, the file should be removed
|
||||
if OpenNebula.is_error?(result)
|
||||
remove(image['SOURCE'])
|
||||
end
|
||||
|
||||
elsif image['TEMPLATE/SIZE'] and image['TEMPLATE/FSTYPE'] and \
|
||||
image['TEMPLATE/TYPE'] == 'DATABLOCK'
|
||||
# --- Empty DATABLOCK ---
|
||||
result = dd(image['TEMPLATE/SIZE'], image['SOURCE'])
|
||||
|
||||
if !OpenNebula.is_error?(result)
|
||||
result = mkfs(image['TEMPLATE/FSTYPE'], image['SOURCE'])
|
||||
end
|
||||
|
||||
# If the dd or mkfs failed, the file should be removed
|
||||
if OpenNebula.is_error?(result)
|
||||
remove(image['SOURCE'])
|
||||
end
|
||||
|
||||
elsif image['TEMPLATE/PATH'].nil? and image['TEMPLATE/SOURCE'].nil?
|
||||
error_msg = "Image path not present, aborting."
|
||||
result = OpenNebula::Error.new(error_msg)
|
||||
|
||||
elsif image['TEMPLATE/PATH'] and image['TEMPLATE/SOURCE']
|
||||
error_msg = "Template malformed, PATH and SOURCE are" <<
|
||||
" mutuallly exclusive"
|
||||
result = OpenNebula::Error.new(error_msg)
|
||||
|
||||
end
|
||||
|
||||
# ------ Enable the Image ------
|
||||
if !OpenNebula.is_error?(result)
|
||||
image.enable
|
||||
else
|
||||
image.delete
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
########################################################################
|
||||
#
|
||||
########################################################################
|
||||
def delete(image)
|
||||
if image.nil?
|
||||
error_msg = "Image could not be found, aborting."
|
||||
return OpenNebula::Error.new(error_msg)
|
||||
end
|
||||
|
||||
result = image.info
|
||||
|
||||
if !OpenNebula.is_error?(result)
|
||||
file_path = image['SOURCE']
|
||||
|
||||
result = image.delete
|
||||
|
||||
if !OpenNebula.is_error?(result)
|
||||
result = remove(file_path)
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
########################################################################
|
||||
#
|
||||
########################################################################
|
||||
def update_source(image, source)
|
||||
if image.nil?
|
||||
error_msg = "Image could not be found, aborting."
|
||||
return OpenNebula::Error.new(error_msg)
|
||||
end
|
||||
|
||||
result = image.info
|
||||
|
||||
if !OpenNebula.is_error?(result)
|
||||
result = move(source, image['SOURCE'])
|
||||
|
||||
image.enable
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
private
|
||||
FS_UTILS = {
|
||||
:dd => "env dd",
|
||||
:mkfs => "env mkfs"
|
||||
}
|
||||
|
||||
########################################################################
|
||||
#
|
||||
########################################################################
|
||||
def set_permissions(source)
|
||||
if File.directory?(source)
|
||||
perms = 0770
|
||||
else
|
||||
perms = 0660
|
||||
end
|
||||
|
||||
FileUtils.chmod(perms, source)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
#
|
||||
########################################################################
|
||||
def copy(path, source)
|
||||
if source.nil? or path.nil?
|
||||
return OpenNebula::Error.new("copy Image: missing parameters.")
|
||||
end
|
||||
|
||||
begin
|
||||
FileUtils.copy(path, source)
|
||||
set_permissions(source)
|
||||
rescue Exception => e
|
||||
return OpenNebula::Error.new(e.message)
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
########################################################################
|
||||
#
|
||||
########################################################################
|
||||
def move(path, source)
|
||||
if source.nil? || path.nil? || File.identical?(path,source)
|
||||
return nil
|
||||
end
|
||||
|
||||
begin
|
||||
FileUtils.move(path, source)
|
||||
set_permissions(source)
|
||||
rescue Exception => e
|
||||
return OpenNebula::Error.new(e.message)
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
########################################################################
|
||||
#
|
||||
########################################################################
|
||||
def dd(size, source)
|
||||
if source.nil? or size.nil?
|
||||
return OpenNebula::Error.new("dd Image: missing parameters.")
|
||||
end
|
||||
|
||||
command = ""
|
||||
command << FS_UTILS[:dd]
|
||||
command << " if=/dev/zero of=#{source} ibs=1 count=1"
|
||||
command << " obs=1048576 seek=#{size}"
|
||||
|
||||
local_command=LocalCommand.run(command)
|
||||
|
||||
if local_command.code!=0
|
||||
return OpenNebula::Error.new("dd Image: in dd command.")
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
########################################################################
|
||||
#
|
||||
########################################################################
|
||||
def mkfs(fstype, source)
|
||||
if source.nil? or fstype.nil?
|
||||
return OpenNebula::Error.new("mkfs Image: missing parameters.")
|
||||
end
|
||||
|
||||
command = ""
|
||||
command << FS_UTILS[:mkfs]
|
||||
command << " -t #{fstype} -F #{source}"
|
||||
|
||||
local_command=LocalCommand.run(command)
|
||||
|
||||
if local_command.code!=0
|
||||
return OpenNebula::Error.new("mkfs Image: in mkfs command.")
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
########################################################################
|
||||
#
|
||||
########################################################################
|
||||
def remove(source)
|
||||
if !File.exists?(source)
|
||||
return nil
|
||||
end
|
||||
|
||||
begin
|
||||
if File.directory?(source)
|
||||
FileUtils.rmdir(source)
|
||||
else
|
||||
FileUtils.rm(source)
|
||||
end
|
||||
rescue Exception => e
|
||||
return OpenNebula::Error.new(e.message)
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
@ -214,11 +214,11 @@ module OpenNebula
|
||||
#
|
||||
# +disk_id+ ID of the disk to be saved
|
||||
#
|
||||
# +image_id+ ID of the new image where the disk will be saved
|
||||
def save_as(disk_id, image_id)
|
||||
# +image_name+ Name for the new image where the disk will be saved
|
||||
def save_as(disk_id, image_name)
|
||||
return Error.new('ID not defined') if !@pe_id
|
||||
|
||||
rc = @client.call(VM_METHODS[:savedisk], @pe_id, disk_id, image_id)
|
||||
rc = @client.call(VM_METHODS[:savedisk], @pe_id, disk_id, image_name)
|
||||
rc = nil if !OpenNebula.is_error?(rc)
|
||||
|
||||
return rc
|
||||
|
@ -27,7 +27,6 @@ void RequestManager::ClusterInfo::execute(
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
string info;
|
||||
|
||||
Cluster * cluster;
|
||||
ostringstream oss;
|
||||
@ -70,7 +69,7 @@ void RequestManager::ClusterInfo::execute(
|
||||
|
||||
// All nice, return the cluster info to the client
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true)); // SUCCESS
|
||||
arrayData.push_back(xmlrpc_c::value_string(info));
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
||||
// Copy arrayresult into retval mem space
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
|
@ -48,6 +48,9 @@ void RequestManager::ImageAllocate::execute(
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImageManager * imagem = nd.get_imagem();
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImageAllocate invoked");
|
||||
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
@ -55,7 +58,7 @@ void RequestManager::ImageAllocate::execute(
|
||||
str_template += "\n";
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Authorize this request
|
||||
// Authenticate this request
|
||||
//--------------------------------------------------------------------------
|
||||
uid = ImageAllocate::upool->authenticate(session);
|
||||
|
||||
@ -98,7 +101,6 @@ void RequestManager::ImageAllocate::execute(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Get the User Name
|
||||
//--------------------------------------------------------------------------
|
||||
@ -124,7 +126,14 @@ void RequestManager::ImageAllocate::execute(
|
||||
if ( rc < 0 )
|
||||
{
|
||||
goto error_allocate;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Register the Image in the repository
|
||||
//--------------------------------------------------------------------------
|
||||
if ( imagem->register_image(rc) == -1 )
|
||||
{
|
||||
goto error_register;
|
||||
}
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
@ -169,6 +178,11 @@ error_allocate:
|
||||
oss << " " << error_str;
|
||||
goto error_common;
|
||||
|
||||
error_register:
|
||||
oss << action_error(method_name, "CREATE", "IMAGE", -2, 0);
|
||||
oss << " Failed to copy image to repository. Image left in ERROR state.";
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
|
||||
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
|
||||
|
@ -46,6 +46,8 @@ void RequestManager::ImageDelete::execute(
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImageManager * imagem = nd.get_imagem();
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImageDelete invoked");
|
||||
|
||||
@ -91,17 +93,8 @@ void RequestManager::ImageDelete::execute(
|
||||
}
|
||||
}
|
||||
|
||||
// Get image from the ImagePool
|
||||
image = ImageDelete::ipool->get(iid,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
rc = ImageDelete::ipool->drop(image);
|
||||
|
||||
image->unlock();
|
||||
// Delete the Image from the repository
|
||||
rc = imagem->delete_image(iid);
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
@ -133,7 +126,7 @@ error_authorize:
|
||||
|
||||
error_delete:
|
||||
oss << action_error(method_name, "DELETE", "IMAGE", iid, rc)
|
||||
<< ". Reason: VMs might be running on it.";
|
||||
<< ". Image is in use.";
|
||||
image->unlock();
|
||||
goto error_common;
|
||||
|
||||
|
@ -48,6 +48,8 @@ void RequestManager::ImageEnable::execute(
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImageManager * imagem = nd.get_imagem();
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"ImageEnable invoked");
|
||||
|
||||
@ -93,26 +95,14 @@ void RequestManager::ImageEnable::execute(
|
||||
}
|
||||
}
|
||||
|
||||
// Get image from the ImagePool
|
||||
image = ImageEnable::ipool->get(iid,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
rc = image->enable(enable_flag);
|
||||
// Enable the Image
|
||||
rc = imagem->enable_image(iid,enable_flag);
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
goto error_enable;
|
||||
|
||||
}
|
||||
|
||||
ImageEnable::ipool->update(image);
|
||||
|
||||
image->unlock();
|
||||
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
arrayData.push_back(xmlrpc_c::value_int(iid));
|
||||
|
||||
|
@ -137,8 +137,7 @@ error_authorize:
|
||||
|
||||
error_persistent:
|
||||
image->unlock();
|
||||
oss << action_error(method_name, "MANAGE", "IMAGE", iid, 0)
|
||||
<< " Is the image public? An Image cannot be public and persistent.";
|
||||
oss.str(action_error(method_name, "MANAGE", "IMAGE", iid, 0));
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
|
@ -50,7 +50,7 @@ void RequestManager::VirtualMachinePoolInfo::execute(
|
||||
state = -1;
|
||||
break;
|
||||
case 3:
|
||||
state = xmlrpc_c::value_int (paramList.getInt(3));
|
||||
state = xmlrpc_c::value_int (paramList.getInt(2));
|
||||
break;
|
||||
default:
|
||||
paramList.verifyEnd(3);
|
||||
|
@ -26,63 +26,98 @@ void RequestManager::VirtualMachineSaveDisk::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
string session;
|
||||
|
||||
int vm_id;
|
||||
int disk_id;
|
||||
int img_id;
|
||||
int vm_id;
|
||||
int disk_id;
|
||||
int iid;
|
||||
string img_name;
|
||||
|
||||
int vm_owner;
|
||||
int img_owner;
|
||||
bool img_public;
|
||||
int vm_owner;
|
||||
string user_name;
|
||||
|
||||
int rc;
|
||||
int rc;
|
||||
int uid;
|
||||
string estr;
|
||||
char * error_char;
|
||||
string error_str;
|
||||
|
||||
const string method_name = "VirtualMachineSaveDisk";
|
||||
|
||||
VirtualMachine * vm;
|
||||
Image * image;
|
||||
VirtualMachine * vm;
|
||||
Image * image;
|
||||
ImageTemplate * img_template;
|
||||
User * user;
|
||||
|
||||
Image * source_img;
|
||||
int source_img_id;
|
||||
bool source_img_persistent = false;
|
||||
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
ostringstream oss;
|
||||
ostringstream oss;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
ImageManager * imagem = nd.get_imagem();
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"VirtualMachineSaveDisk invoked");
|
||||
|
||||
//Parse Arguments
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
vm_id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
disk_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
img_name = xmlrpc_c::value_string(paramList.getString(3));
|
||||
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
vm_id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
disk_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
img_id = xmlrpc_c::value_int(paramList.getInt(3));
|
||||
//-------------------------------------------------------------------------
|
||||
// Authenticate the user
|
||||
//-------------------------------------------------------------------------
|
||||
uid = VirtualMachineSaveDisk::upool->authenticate(session);
|
||||
|
||||
//Authenticate the user
|
||||
rc = VirtualMachineSaveDisk::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
if ( uid == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
// Check that the image exists
|
||||
image = VirtualMachineSaveDisk::ipool->get(img_id,true);
|
||||
user = VirtualMachineSaveDisk::upool->get(uid,true);
|
||||
|
||||
if ( image == 0 )
|
||||
if ( user == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
goto error_user_get;
|
||||
}
|
||||
|
||||
img_owner = image->get_uid();
|
||||
img_public = image->isPublic();
|
||||
user_name = user->get_name();
|
||||
|
||||
image->unlock();
|
||||
user->unlock();
|
||||
|
||||
//Get the VM
|
||||
//-------------------------------------------------------------------------
|
||||
// Check that the image does not exist & prepare the template
|
||||
//-------------------------------------------------------------------------
|
||||
image = VirtualMachineSaveDisk::ipool->get(img_name,uid,false);
|
||||
|
||||
if ( image != 0 )
|
||||
{
|
||||
goto error_image_exists;
|
||||
}
|
||||
|
||||
oss << "NAME= " << img_name << endl;
|
||||
oss << "PUBLIC = NO " << endl;
|
||||
oss << "SOURCE = " << Image::generate_source(uid,img_name);
|
||||
|
||||
img_template = new ImageTemplate;
|
||||
|
||||
img_template->parse(oss.str(),&error_char);
|
||||
|
||||
oss.str("");
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Get the VM
|
||||
//--------------------------------------------------------------------------
|
||||
vm = VirtualMachineSaveDisk::vmpool->get(vm_id,true);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
delete img_template;
|
||||
goto error_vm_get;
|
||||
}
|
||||
|
||||
@ -90,14 +125,20 @@ void RequestManager::VirtualMachineSaveDisk::execute(
|
||||
|
||||
vm->unlock();
|
||||
|
||||
//Authorize the operation
|
||||
if ( rc != 0 ) // rc == 0 means oneadmin
|
||||
//--------------------------------------------------------------------------
|
||||
// Authorize the operation
|
||||
//--------------------------------------------------------------------------
|
||||
if ( uid != 0 )
|
||||
{
|
||||
AuthRequest ar(rc);
|
||||
AuthRequest ar(uid);
|
||||
string t64;
|
||||
|
||||
ar.add_auth(AuthRequest::VM,vm_id,AuthRequest::MANAGE,vm_owner,false);
|
||||
ar.add_auth(AuthRequest::IMAGE,img_id,
|
||||
AuthRequest::MANAGE,img_owner,img_public);
|
||||
ar.add_auth(AuthRequest::IMAGE,
|
||||
img_template->to_xml(t64),
|
||||
AuthRequest::CREATE,
|
||||
uid,
|
||||
false);
|
||||
|
||||
if (UserPool::authorize(ar) == -1)
|
||||
{
|
||||
@ -105,6 +146,25 @@ void RequestManager::VirtualMachineSaveDisk::execute(
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Create the image
|
||||
//--------------------------------------------------------------------------
|
||||
rc = VirtualMachineSaveDisk::ipool->allocate(uid,user_name,img_template,
|
||||
&iid,estr);
|
||||
|
||||
if ( rc < 0 )
|
||||
{
|
||||
goto error_allocate;
|
||||
}
|
||||
|
||||
oss << "Image " << img_name << " created to store disk.";
|
||||
|
||||
NebulaLog::log("ReM",Log::INFO,oss);
|
||||
oss.str("");
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Get the VM
|
||||
//--------------------------------------------------------------------------
|
||||
vm = VirtualMachineSaveDisk::vmpool->get(vm_id,true);
|
||||
|
||||
if ( vm == 0 )
|
||||
@ -112,11 +172,36 @@ void RequestManager::VirtualMachineSaveDisk::execute(
|
||||
goto error_vm_get;
|
||||
}
|
||||
|
||||
rc = vm->save_disk(disk_id, img_id);
|
||||
//--------------------------------------------------------------------------
|
||||
// Check if the disk has a persistent source image
|
||||
//--------------------------------------------------------------------------
|
||||
oss << "/VM/TEMPLATE/DISK[DISK_ID=" << disk_id << "]/IMAGE_ID";
|
||||
rc = vm->xpath(source_img_id, oss.str().c_str(), -1);
|
||||
oss.str("");
|
||||
|
||||
if( rc == 0 ) //The disk was created from an Image
|
||||
{
|
||||
source_img = VirtualMachineSaveDisk::ipool->get(source_img_id, true);
|
||||
|
||||
if( source_img != 0 ) //The Image still exists
|
||||
{
|
||||
source_img_persistent = source_img->isPersistent();
|
||||
source_img->unlock();
|
||||
|
||||
if( source_img_persistent )
|
||||
{
|
||||
goto error_img_persistent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Store image id to save the disk in the VM template
|
||||
//--------------------------------------------------------------------------
|
||||
rc = vm->save_disk(disk_id, iid, error_str);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
vm->unlock();
|
||||
goto error_vm_get_disk_id;
|
||||
}
|
||||
|
||||
@ -124,8 +209,11 @@ void RequestManager::VirtualMachineSaveDisk::execute(
|
||||
|
||||
vm->unlock();
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Send results to client
|
||||
//--------------------------------------------------------------------------
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
arrayData.push_back(xmlrpc_c::value_int(iid));
|
||||
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
|
||||
@ -135,16 +223,31 @@ void RequestManager::VirtualMachineSaveDisk::execute(
|
||||
|
||||
return;
|
||||
|
||||
error_image_get:
|
||||
oss.str(get_error(method_name, "IMAGE", img_id));
|
||||
error_image_exists:
|
||||
oss << action_error(method_name, "CREATE", "IMAGE", -2, 0);
|
||||
oss << " Image " << img_name << " already exists in the repository.";
|
||||
goto error_common;
|
||||
|
||||
error_vm_get:
|
||||
oss.str(get_error(method_name, "VM", vm_id));
|
||||
goto error_common;
|
||||
|
||||
error_img_persistent:
|
||||
oss << action_error(method_name, "SAVEDISK", "DISK", disk_id, 0);
|
||||
oss << " Source IMAGE " << source_img_id << " is persistent.";
|
||||
vm->unlock();
|
||||
goto error_common;
|
||||
|
||||
error_vm_get_disk_id:
|
||||
oss.str(get_error(method_name, "DISK from VM", vm_id));
|
||||
oss << " " << error_str;
|
||||
oss << " Deleting Image " << img_name;
|
||||
imagem->delete_image(iid);
|
||||
vm->unlock();
|
||||
goto error_common;
|
||||
|
||||
error_user_get:
|
||||
oss.str(get_error(method_name, "USER", uid));
|
||||
goto error_common;
|
||||
|
||||
error_authenticate:
|
||||
@ -152,7 +255,13 @@ error_authenticate:
|
||||
goto error_common;
|
||||
|
||||
error_authorize:
|
||||
oss.str(authorization_error(method_name, "MANAGE", "VM/IMAGE", rc, vm_id));
|
||||
oss.str(authorization_error(method_name, "MANAGE", "VM/IMAGE", uid, vm_id));
|
||||
delete img_template;
|
||||
goto error_common;
|
||||
|
||||
error_allocate:
|
||||
oss << action_error(method_name, "CREATE", "IMAGE", -2, 0);
|
||||
oss << " " << estr;
|
||||
goto error_common;
|
||||
|
||||
error_common:
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "NebulaLog.h"
|
||||
#include "Nebula.h"
|
||||
|
||||
#include "VirtualNetworkTemplate.h"
|
||||
#include "AuthManager.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "RequestManager.h"
|
||||
#include "NebulaLog.h"
|
||||
#include "VirtualNetworkTemplate.h"
|
||||
|
||||
#include "AuthManager.h"
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include "RequestManager.h"
|
||||
#include "VirtualNetworkTemplate.h"
|
||||
|
||||
#include "NebulaLog.h"
|
||||
#include "Nebula.h"
|
||||
|
@ -66,11 +66,10 @@ int VirtualMachinePoolXML::load_info(xmlrpc_c::value &result)
|
||||
{
|
||||
client->call(client->get_endpoint(), // serverUrl
|
||||
"one.vmpool.info", // methodName
|
||||
"sibi", // arguments format
|
||||
"sii", // arguments format
|
||||
&result, // resultP
|
||||
client->get_oneauth().c_str(), // auth string
|
||||
-2, // VM from all users
|
||||
false, // not extended info
|
||||
1); // in pending state
|
||||
return 0;
|
||||
}
|
||||
|
@ -424,6 +424,29 @@ void Nebula::start()
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Auth Manager ----
|
||||
if (tester->need_imagem)
|
||||
{
|
||||
try
|
||||
{
|
||||
imagem = tester->create_imagem(ipool);
|
||||
}
|
||||
catch (bad_alloc&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
if (imagem != 0)
|
||||
{
|
||||
rc = imagem->start();
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
throw runtime_error("Could not start the Image Manager");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Load mads
|
||||
// -----------------------------------------------------------
|
||||
|
@ -145,3 +145,18 @@ AuthManager* NebulaTest::create_authm(time_t timer_period)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ImageManager* NebulaTest::create_imagem(ImagePool * ipool)
|
||||
{
|
||||
map<string,string> mad_value;
|
||||
VectorAttribute * mad;
|
||||
|
||||
vector<const Attribute *> im_mads;
|
||||
|
||||
mad_value.insert(make_pair("executable","one_image"));
|
||||
|
||||
mad = new VectorAttribute("HM_MAD",mad_value);
|
||||
im_mads.push_back(mad);
|
||||
|
||||
return new ImageManager(ipool,im_mads);
|
||||
}
|
||||
|
@ -58,11 +58,11 @@ VirtualMachine::VirtualMachine(int id,
|
||||
{
|
||||
if (_vm_template != 0)
|
||||
{
|
||||
vm_template = _vm_template;
|
||||
obj_template = _vm_template;
|
||||
}
|
||||
else
|
||||
{
|
||||
vm_template = new VirtualMachineTemplate;
|
||||
obj_template = new VirtualMachineTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,9 +83,9 @@ VirtualMachine::~VirtualMachine()
|
||||
delete _log;
|
||||
}
|
||||
|
||||
if ( vm_template != 0 )
|
||||
if ( obj_template != 0 )
|
||||
{
|
||||
delete vm_template;
|
||||
delete obj_template;
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ int VirtualMachine::select(SqlDB * db)
|
||||
return rc;
|
||||
}
|
||||
|
||||
//Get History Records. Current history is record is built in from_xml() (if any).
|
||||
//Get History Records. Current history is built in from_xml() (if any).
|
||||
if( hasHistory() )
|
||||
{
|
||||
last_seq = history->seq;
|
||||
@ -191,7 +191,7 @@ int VirtualMachine::insert(SqlDB * db, string& error_str)
|
||||
|
||||
attr = new SingleAttribute("VMID",value);
|
||||
|
||||
vm_template->set(attr);
|
||||
obj_template->set(attr);
|
||||
|
||||
get_template_attribute("NAME",name);
|
||||
|
||||
@ -202,7 +202,7 @@ int VirtualMachine::insert(SqlDB * db, string& error_str)
|
||||
name = oss.str();
|
||||
|
||||
attr = new SingleAttribute("NAME",name);
|
||||
vm_template->set(attr);
|
||||
obj_template->set(attr);
|
||||
}
|
||||
|
||||
this->name = name;
|
||||
@ -301,7 +301,7 @@ int VirtualMachine::parse_context(string& error_str)
|
||||
string * str;
|
||||
string parsed;
|
||||
|
||||
num = vm_template->remove("CONTEXT", array_context);
|
||||
num = obj_template->remove("CONTEXT", array_context);
|
||||
|
||||
if ( num == 0 )
|
||||
{
|
||||
@ -352,7 +352,7 @@ int VirtualMachine::parse_context(string& error_str)
|
||||
context_parsed->replace("TARGET", dev_prefix);
|
||||
}
|
||||
|
||||
vm_template->set(context_parsed);
|
||||
obj_template->set(context_parsed);
|
||||
}
|
||||
|
||||
/* --- Delete old context attributes --- */
|
||||
@ -378,7 +378,7 @@ void VirtualMachine::parse_graphics()
|
||||
vector<Attribute *> array_graphics;
|
||||
VectorAttribute * graphics;
|
||||
|
||||
num = vm_template->get("GRAPHICS", array_graphics);
|
||||
num = obj_template->get("GRAPHICS", array_graphics);
|
||||
|
||||
if ( num == 0 )
|
||||
{
|
||||
@ -425,7 +425,7 @@ int VirtualMachine::parse_requirements(string& error_str)
|
||||
|
||||
string parsed;
|
||||
|
||||
num = vm_template->remove("REQUIREMENTS", array_reqs);
|
||||
num = obj_template->remove("REQUIREMENTS", array_reqs);
|
||||
|
||||
if ( num == 0 )
|
||||
{
|
||||
@ -452,7 +452,7 @@ int VirtualMachine::parse_requirements(string& error_str)
|
||||
SingleAttribute * reqs_parsed;
|
||||
|
||||
reqs_parsed = new SingleAttribute("REQUIREMENTS",parsed);
|
||||
vm_template->set(reqs_parsed);
|
||||
obj_template->set(reqs_parsed);
|
||||
}
|
||||
|
||||
/* --- Delete old requirements attributes --- */
|
||||
@ -677,7 +677,7 @@ int VirtualMachine::get_disk_images(string& error_str)
|
||||
Nebula& nd = Nebula::instance();
|
||||
ipool = nd.get_ipool();
|
||||
|
||||
num_disks = vm_template->get("DISK",disks);
|
||||
num_disks = obj_template->get("DISK",disks);
|
||||
|
||||
for(int i=0, index=0; i<num_disks; i++)
|
||||
{
|
||||
@ -760,14 +760,20 @@ void VirtualMachine::release_disk_images()
|
||||
int num_disks;
|
||||
|
||||
vector<Attribute const * > disks;
|
||||
Image * img;
|
||||
ImagePool * ipool;
|
||||
ImageManager * imagem;
|
||||
|
||||
string disk_base_path = "";
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
ipool = nd.get_ipool();
|
||||
imagem = nd.get_imagem();
|
||||
|
||||
num_disks = get_template_attribute("DISK",disks);
|
||||
|
||||
if (hasHistory() != 0)
|
||||
{
|
||||
disk_base_path = get_local_dir();
|
||||
}
|
||||
|
||||
for(int i=0; i<num_disks; i++)
|
||||
{
|
||||
VectorAttribute const * disk =
|
||||
@ -778,32 +784,20 @@ void VirtualMachine::release_disk_images()
|
||||
continue;
|
||||
}
|
||||
|
||||
iid = disk->vector_value("IMAGE_ID");
|
||||
iid = disk->vector_value("IMAGE_ID");
|
||||
saveas = disk->vector_value("SAVE_AS");
|
||||
|
||||
if ( iid.empty() )
|
||||
{
|
||||
continue;
|
||||
if (!saveas.empty())
|
||||
{
|
||||
imagem->disk_to_image(disk_base_path,i,saveas);
|
||||
}
|
||||
}
|
||||
|
||||
img = ipool->get(atoi(iid.c_str()),true);
|
||||
|
||||
if ( img == 0 )
|
||||
else
|
||||
{
|
||||
continue;
|
||||
imagem->release_image(iid,disk_base_path,i,saveas);
|
||||
}
|
||||
|
||||
img->release_image();
|
||||
|
||||
saveas = disk->vector_value("SAVE_AS");
|
||||
|
||||
if ( !saveas.empty() && saveas == iid )
|
||||
{
|
||||
img->enable(false);
|
||||
}
|
||||
|
||||
ipool->update(img);
|
||||
|
||||
img->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -820,7 +814,7 @@ int VirtualMachine::get_network_leases()
|
||||
Nebula& nd = Nebula::instance();
|
||||
vnpool = nd.get_vnpool();
|
||||
|
||||
num_nics = vm_template->get("NIC",nics);
|
||||
num_nics = obj_template->get("NIC",nics);
|
||||
|
||||
for(int i=0; i<num_nics; i++)
|
||||
{
|
||||
@ -957,7 +951,7 @@ int VirtualMachine::generate_context(string &files)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::save_disk(int disk_id, int img_id)
|
||||
int VirtualMachine::save_disk(int disk_id, int img_id, string& error_str)
|
||||
{
|
||||
int num_disks;
|
||||
vector<Attribute * > disks;
|
||||
@ -970,7 +964,7 @@ int VirtualMachine::save_disk(int disk_id, int img_id)
|
||||
istringstream iss;
|
||||
|
||||
|
||||
num_disks = vm_template->get("DISK",disks);
|
||||
num_disks = obj_template->get("DISK",disks);
|
||||
|
||||
for(int i=0; i<num_disks; i++, iss.clear())
|
||||
{
|
||||
@ -986,8 +980,13 @@ int VirtualMachine::save_disk(int disk_id, int img_id)
|
||||
iss.str(disk_id_str);
|
||||
iss >> tmp_disk_id;
|
||||
|
||||
if( tmp_disk_id == disk_id )
|
||||
if ( tmp_disk_id == disk_id )
|
||||
{
|
||||
if(!((disk->vector_value("SAVE_AS")).empty()))
|
||||
{
|
||||
goto error_saved;
|
||||
}
|
||||
|
||||
disk->replace("SAVE", "YES");
|
||||
|
||||
oss << (img_id);
|
||||
@ -997,6 +996,19 @@ int VirtualMachine::save_disk(int disk_id, int img_id)
|
||||
}
|
||||
}
|
||||
|
||||
goto error_not_found;
|
||||
|
||||
error_saved:
|
||||
oss << "The DISK " << disk_id << " is already suppossed to be saved.";
|
||||
goto error_common;
|
||||
|
||||
error_not_found:
|
||||
oss << "The DISK " << disk_id << " does not exist for VM " << oid << ".";
|
||||
|
||||
error_common:
|
||||
NebulaLog::log("VM",Log::ERROR, oss);
|
||||
error_str = oss.str();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1106,7 +1118,7 @@ string& VirtualMachine::to_xml(string& xml) const
|
||||
<< "<CPU>" << cpu << "</CPU>"
|
||||
<< "<NET_TX>" << net_tx << "</NET_TX>"
|
||||
<< "<NET_RX>" << net_rx << "</NET_RX>"
|
||||
<< vm_template->to_xml(template_xml);
|
||||
<< obj_template->to_xml(template_xml);
|
||||
|
||||
if ( hasHistory() )
|
||||
{
|
||||
@ -1162,7 +1174,7 @@ int VirtualMachine::from_xml(const string &xml_str)
|
||||
}
|
||||
|
||||
// Virtual Machine template
|
||||
rc += vm_template->from_xml_node(content[0]);
|
||||
rc += obj_template->from_xml_node(content[0]);
|
||||
|
||||
// Last history entry
|
||||
content.clear();
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "VirtualNetwork.h"
|
||||
#include "VirtualNetworkPool.h"
|
||||
#include "VirtualNetworkTemplate.h"
|
||||
|
||||
#include "NebulaLog.h"
|
||||
#include "RangedLeases.h"
|
||||
@ -40,11 +41,11 @@ VirtualNetwork::VirtualNetwork(int uid,
|
||||
{
|
||||
if (_vn_template != 0)
|
||||
{
|
||||
vn_template = _vn_template;
|
||||
obj_template = _vn_template;
|
||||
}
|
||||
else
|
||||
{
|
||||
vn_template = new VirtualNetworkTemplate;
|
||||
obj_template = new VirtualNetworkTemplate;
|
||||
}
|
||||
};
|
||||
|
||||
@ -58,9 +59,9 @@ VirtualNetwork::~VirtualNetwork()
|
||||
delete leases;
|
||||
}
|
||||
|
||||
if (vn_template != 0)
|
||||
if (obj_template != 0)
|
||||
{
|
||||
delete vn_template;
|
||||
delete obj_template;
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,11 +71,11 @@ VirtualNetwork::~VirtualNetwork()
|
||||
|
||||
const char * VirtualNetwork::table = "network_pool";
|
||||
|
||||
const char * VirtualNetwork::db_names = "oid, name, body, uid";
|
||||
const char * VirtualNetwork::db_names = "oid, name, body, uid, public";
|
||||
|
||||
const char * VirtualNetwork::db_bootstrap = "CREATE TABLE IF NOT EXISTS"
|
||||
" network_pool (oid INTEGER PRIMARY KEY, name VARCHAR(256),"
|
||||
" body TEXT, uid INTEGER, UNIQUE(name,uid))";
|
||||
" body TEXT, uid INTEGER, public INTEGER, UNIQUE(name,uid))";
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -263,7 +264,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
|
||||
|
||||
public_vnet = (pub == "YES");
|
||||
|
||||
vn_template->erase("PUBLIC");
|
||||
obj_template->erase("PUBLIC");
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Get the leases
|
||||
@ -307,7 +308,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
|
||||
oss << default_size;
|
||||
|
||||
attribute = new SingleAttribute("NETWORK_SIZE",oss.str());
|
||||
vn_template->set(attribute);
|
||||
obj_template->set(attribute);
|
||||
|
||||
size = default_size;
|
||||
}
|
||||
@ -423,7 +424,8 @@ int VirtualNetwork::insert_replace(SqlDB *db, bool replace)
|
||||
<< oid << ","
|
||||
<< "'" << sql_name << "',"
|
||||
<< "'" << sql_xml << "',"
|
||||
<< uid << ")";
|
||||
<< uid << ","
|
||||
<< public_vnet << ")";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
@ -505,7 +507,7 @@ string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const
|
||||
"<BRIDGE>" << bridge << "</BRIDGE>" <<
|
||||
"<PUBLIC>" << public_vnet << "</PUBLIC>" <<
|
||||
"<TOTAL_LEASES>"<< total_leases << "</TOTAL_LEASES>"<<
|
||||
vn_template->to_xml(template_xml);
|
||||
obj_template->to_xml(template_xml);
|
||||
|
||||
if (extended && leases != 0)
|
||||
{
|
||||
@ -552,7 +554,7 @@ int VirtualNetwork::from_xml(const string &xml_str)
|
||||
}
|
||||
|
||||
// Virtual Network template
|
||||
rc += vn_template->from_xml_node( content[0] );
|
||||
rc += obj_template->from_xml_node( content[0] );
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "VirtualNetworkPool.h"
|
||||
#include "VirtualNetworkTemplate.h"
|
||||
#include "PoolTest.h"
|
||||
#include "ObjectXML.h"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user