mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-23 22:50:09 +03:00
Merge branch 'master' into feature-564
This commit is contained in:
commit
18a66bccf9
21
SConstruct
21
SConstruct
@ -63,6 +63,7 @@ main_env.Append(LIBPATH=[
|
||||
cwd+'/src/pool',
|
||||
cwd+'/src/template',
|
||||
cwd+'/src/vm',
|
||||
cwd+'/src/vm_template',
|
||||
cwd+'/src/vmm',
|
||||
cwd+'/src/lcm',
|
||||
cwd+'/src/tm',
|
||||
@ -127,15 +128,27 @@ else:
|
||||
main_env.Append(parsers='no')
|
||||
|
||||
if not main_env.GetOption('clean'):
|
||||
try:
|
||||
if mysql=='yes':
|
||||
main_env.ParseConfig('mysql_config --cflags --libs')
|
||||
except Exception, e:
|
||||
print ""
|
||||
print "mysql_config was not found in the path"
|
||||
print ""
|
||||
print "Check that mysql development package is installed and"
|
||||
print "mysql_config is in the path. If your mysql config tool"
|
||||
print "is called mysql5_config make a symlink as mysql_config"
|
||||
print "to a directory in the path."
|
||||
print ""
|
||||
exit(-1)
|
||||
|
||||
|
||||
try:
|
||||
main_env.ParseConfig(("LDFLAGS='%s' share/scons/get_xmlrpc_config"+
|
||||
" server") % (os.environ['LDFLAGS'],))
|
||||
main_env.ParseConfig(("LDFLAGS='%s' share/scons/get_xmlrpc_config"+
|
||||
" client") % (os.environ['LDFLAGS'],))
|
||||
|
||||
if mysql=='yes':
|
||||
main_env.ParseConfig('mysql_config --cflags --libs')
|
||||
|
||||
except Exception, e:
|
||||
print ""
|
||||
print "Error searching for xmlrpc-c libraries. Please check this"+\
|
||||
@ -178,6 +191,7 @@ build_scripts=[
|
||||
'src/nebula/SConstruct',
|
||||
'src/pool/SConstruct',
|
||||
'src/vm/SConstruct',
|
||||
'src/vm_template/SConstruct',
|
||||
'src/vmm/SConstruct',
|
||||
'src/lcm/SConstruct',
|
||||
'src/rm/SConstruct',
|
||||
@ -228,6 +242,7 @@ if testing=='yes':
|
||||
'src/vm/test/SConstruct',
|
||||
'src/vnm/test/SConstruct',
|
||||
'src/xml/test/SConstruct',
|
||||
'src/vm_template/test/SConstruct',
|
||||
])
|
||||
else:
|
||||
main_env.Append(testing='no')
|
||||
|
@ -39,6 +39,17 @@ public:
|
||||
attribute_name.end(),
|
||||
attribute_name.begin(),
|
||||
(int(*)(int))toupper);
|
||||
|
||||
// FIX Attribute name if it does not conform XML element
|
||||
// naming conventions
|
||||
|
||||
int size = attribute_name.size();
|
||||
|
||||
if ((size >0 && !isalpha(aname[0]))||
|
||||
(size >=3 && (aname[0]=='X' && aname[1]=='M' && aname[2]=='L')))
|
||||
{
|
||||
attribute_name.insert(0,"ONE_");
|
||||
}
|
||||
};
|
||||
|
||||
virtual ~Attribute(){};
|
||||
@ -82,8 +93,12 @@ public:
|
||||
*/
|
||||
virtual AttributeType type() = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Clones the current attribute
|
||||
*/
|
||||
virtual Attribute* clone() const = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The attribute name.
|
||||
*/
|
||||
@ -107,6 +122,11 @@ public:
|
||||
SingleAttribute(const string& name, const string& value):
|
||||
Attribute(name),attribute_value(value){};
|
||||
|
||||
SingleAttribute(const SingleAttribute& sa):Attribute(sa.attribute_name)
|
||||
{
|
||||
attribute_value = sa.attribute_value;
|
||||
};
|
||||
|
||||
~SingleAttribute(){};
|
||||
|
||||
/**
|
||||
@ -173,6 +193,14 @@ public:
|
||||
return SIMPLE;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clones the current attribute
|
||||
*/
|
||||
Attribute* clone() const
|
||||
{
|
||||
return new SingleAttribute(*this);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
string attribute_value;
|
||||
@ -195,6 +223,11 @@ public:
|
||||
VectorAttribute(const string& name,const map<string,string>& value):
|
||||
Attribute(name),attribute_value(value){};
|
||||
|
||||
VectorAttribute(const VectorAttribute& va):Attribute(va.attribute_name)
|
||||
{
|
||||
attribute_value = va.attribute_value;
|
||||
};
|
||||
|
||||
~VectorAttribute(){};
|
||||
|
||||
/**
|
||||
@ -256,6 +289,14 @@ public:
|
||||
return VECTOR;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clones the current attribute
|
||||
*/
|
||||
Attribute* clone() const
|
||||
{
|
||||
return new VectorAttribute(*this);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static const char * magic_sep;
|
||||
|
@ -276,11 +276,12 @@ public:
|
||||
*/
|
||||
enum Operation
|
||||
{
|
||||
CREATE, /** Authorization to create an object (host, vm, net, image)*/
|
||||
DELETE, /** Authorization to delete an object */
|
||||
USE, /** Authorization to use an object */
|
||||
MANAGE, /** Authorization to manage an object */
|
||||
INFO /** Authorization to view an object */
|
||||
CREATE, /** Authorization to create an object */
|
||||
DELETE, /** Authorization to delete an object */
|
||||
USE, /** Authorization to use an object */
|
||||
MANAGE, /** Authorization to manage an object */
|
||||
INFO, /** Authorization to view an object */
|
||||
INSTANTIATE /** Authorization to instantiate a VM from a TEMPLATE */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -293,7 +294,8 @@ public:
|
||||
NET,
|
||||
IMAGE,
|
||||
USER,
|
||||
CLUSTER
|
||||
CLUSTER,
|
||||
TEMPLATE
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
*/
|
||||
|
213
include/Image.h
213
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,74 @@ public:
|
||||
return (persistent_img == 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the source path of the image
|
||||
* @return source of image
|
||||
*/
|
||||
const string& get_source()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source path of the image
|
||||
* @return source of image
|
||||
*/
|
||||
void set_source(const string& _source)
|
||||
{
|
||||
source = _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 +190,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,93 +259,6 @@ 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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -369,16 +311,6 @@ private:
|
||||
*/
|
||||
int running_vms;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Image Attributes
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The Image template, holds the Image attributes.
|
||||
*/
|
||||
ImageTemplate * image_template;
|
||||
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation (Private)
|
||||
// *************************************************************************
|
||||
@ -401,13 +333,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*/
|
||||
|
105
include/ImageManagerDriver.h
Normal file
105
include/ImageManagerDriver.h
Normal file
@ -0,0 +1,105 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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;
|
||||
|
||||
/**
|
||||
* Sends a move request to the MAD: "MV IMAGE_ID SRC_PATH DST_PATH"
|
||||
* @param oid the image id.
|
||||
* @param destination is a driver specific location or "-" if not
|
||||
* initialized
|
||||
* @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 fs type
|
||||
* @param size_mb of the image to be created
|
||||
*/
|
||||
void mkfs(int oid,
|
||||
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_*/
|
||||
|
@ -39,7 +39,6 @@ class ImagePool : public PoolSQL
|
||||
public:
|
||||
|
||||
ImagePool(SqlDB * db,
|
||||
const string& _source_prefix,
|
||||
const string& _default_type,
|
||||
const string& _default_dev_prefix);
|
||||
|
||||
@ -146,11 +145,6 @@ public:
|
||||
*/
|
||||
void authorize_disk(VectorAttribute * disk, int uid, AuthRequest * ar);
|
||||
|
||||
static const string& source_prefix()
|
||||
{
|
||||
return _source_prefix;
|
||||
};
|
||||
|
||||
static const string& default_type()
|
||||
{
|
||||
return _default_type;
|
||||
@ -165,10 +159,6 @@ private:
|
||||
//--------------------------------------------------------------------------
|
||||
// Configuration Attributes for Images
|
||||
// -------------------------------------------------------------------------
|
||||
/**
|
||||
* Path to the image repository
|
||||
**/
|
||||
static string _source_prefix;
|
||||
|
||||
/**
|
||||
* Default image type
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
@ -68,12 +70,11 @@ protected:
|
||||
{
|
||||
string str;
|
||||
const char * cstr;
|
||||
size_t retval;
|
||||
|
||||
str = os.str();
|
||||
cstr = str.c_str();
|
||||
|
||||
retval = ::write(nebula_mad_pipe, cstr, str.size());
|
||||
::write(nebula_mad_pipe, cstr, str.size());
|
||||
};
|
||||
|
||||
/**
|
||||
@ -89,6 +90,32 @@ protected:
|
||||
write(os);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the log message type as specify by the driver.
|
||||
* @param first character of the type string
|
||||
* @return the message type
|
||||
*/
|
||||
Log::MessageType log_type(const char r)
|
||||
{
|
||||
Log::MessageType lt;
|
||||
|
||||
switch (r)
|
||||
{
|
||||
case 'E':
|
||||
lt = Log::ERROR;
|
||||
break;
|
||||
case 'I':
|
||||
lt = Log::INFO;
|
||||
break;
|
||||
case 'D':
|
||||
lt = Log::DEBUG;
|
||||
break;
|
||||
default:
|
||||
lt = Log::INFO;
|
||||
}
|
||||
|
||||
return lt;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class MadManager;
|
||||
@ -141,7 +168,7 @@ private:
|
||||
* @return 0 on success
|
||||
*/
|
||||
int reload();
|
||||
|
||||
|
||||
/**
|
||||
* Implements the driver specific protocol, this function should trigger
|
||||
* actions on the associated manager.
|
||||
|
@ -43,11 +43,11 @@ class MySqlDB : public SqlDB
|
||||
{
|
||||
public:
|
||||
|
||||
MySqlDB(const string& server,
|
||||
int port,
|
||||
const string& user,
|
||||
const string& password,
|
||||
const char * database);
|
||||
MySqlDB(const string& _server,
|
||||
int _port,
|
||||
const string& _user,
|
||||
const string& _password,
|
||||
const string& _database);
|
||||
|
||||
~MySqlDB();
|
||||
|
||||
@ -81,6 +81,19 @@ private:
|
||||
*/
|
||||
MYSQL * db;
|
||||
|
||||
/**
|
||||
* MySQL Connection parameters
|
||||
*/
|
||||
string server;
|
||||
|
||||
int port;
|
||||
|
||||
string user;
|
||||
|
||||
string password;
|
||||
|
||||
string database;
|
||||
|
||||
/**
|
||||
* Fine-grain mutex for DB access
|
||||
*/
|
||||
@ -113,7 +126,7 @@ public:
|
||||
int port,
|
||||
string user,
|
||||
string password,
|
||||
const char * database)
|
||||
string database)
|
||||
{
|
||||
throw runtime_error("Aborting oned, MySQL support not compiled!");
|
||||
};
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "VirtualNetworkPool.h"
|
||||
#include "HostPool.h"
|
||||
#include "UserPool.h"
|
||||
#include "VMTemplatePool.h"
|
||||
|
||||
#include "VirtualMachineManager.h"
|
||||
#include "LifeCycleManager.h"
|
||||
@ -34,6 +35,7 @@
|
||||
#include "RequestManager.h"
|
||||
#include "HookManager.h"
|
||||
#include "AuthManager.h"
|
||||
#include "ImageManager.h"
|
||||
|
||||
class Nebula
|
||||
{
|
||||
@ -80,6 +82,11 @@ public:
|
||||
return cpool;
|
||||
};
|
||||
|
||||
VMTemplatePool * get_tpool()
|
||||
{
|
||||
return tpool;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Manager Accessors
|
||||
// --------------------------------------------------------------
|
||||
@ -114,12 +121,16 @@ public:
|
||||
return hm;
|
||||
};
|
||||
|
||||
|
||||
AuthManager * get_authm()
|
||||
{
|
||||
return authm;
|
||||
};
|
||||
|
||||
ImageManager * get_imagem()
|
||||
{
|
||||
return imagem;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Environment & Configuration
|
||||
// --------------------------------------------------------------
|
||||
@ -228,8 +239,9 @@ private:
|
||||
//Constructors and = are private to only access the class through instance
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
Nebula():nebula_configuration(0),db(0),vmpool(0),hpool(0),vnpool(0),
|
||||
upool(0),ipool(0),cpool(0),tpool(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");
|
||||
|
||||
@ -294,6 +306,11 @@ private:
|
||||
delete cpool;
|
||||
}
|
||||
|
||||
if ( tpool != 0)
|
||||
{
|
||||
delete tpool;
|
||||
}
|
||||
|
||||
if ( vmm != 0)
|
||||
{
|
||||
delete vmm;
|
||||
@ -334,6 +351,11 @@ private:
|
||||
delete authm;
|
||||
}
|
||||
|
||||
if ( imagem != 0)
|
||||
{
|
||||
delete imagem;
|
||||
}
|
||||
|
||||
if ( nebula_configuration != 0)
|
||||
{
|
||||
delete nebula_configuration;
|
||||
@ -381,6 +403,7 @@ private:
|
||||
UserPool * upool;
|
||||
ImagePool * ipool;
|
||||
ClusterPool * cpool;
|
||||
VMTemplatePool * tpool;
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Nebula Managers
|
||||
@ -394,6 +417,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,110 @@ 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 = new SingleAttribute(name,value);
|
||||
|
||||
obj_template->erase(sattr->name());
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an error message for the VM in the template
|
||||
* @param message
|
||||
* @return 0 on success
|
||||
*/
|
||||
void set_template_error_message(const string& message);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
@ -198,6 +302,11 @@ protected:
|
||||
*/
|
||||
bool valid;
|
||||
|
||||
/**
|
||||
* Template for this object, will be allocated if needed
|
||||
*/
|
||||
Template * obj_template;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@ -215,6 +324,11 @@ private:
|
||||
* Pointer to the SQL table for the PoolObjectSQL
|
||||
*/
|
||||
const char * table;
|
||||
|
||||
/**
|
||||
* Name for the error messages attribute
|
||||
*/
|
||||
static const char * error_attribute_name;
|
||||
};
|
||||
|
||||
#endif /*POOL_OBJECT_SQL_H_*/
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "VirtualNetworkPool.h"
|
||||
#include "ImagePool.h"
|
||||
#include "ClusterPool.h"
|
||||
#include "VMTemplatePool.h"
|
||||
|
||||
#include <xmlrpc-c/base.hpp>
|
||||
#include <xmlrpc-c/registry.hpp>
|
||||
@ -46,10 +47,11 @@ public:
|
||||
UserPool * _upool,
|
||||
ImagePool * _ipool,
|
||||
ClusterPool * _cpool,
|
||||
VMTemplatePool * _tpool,
|
||||
int _port,
|
||||
string _xml_log_file)
|
||||
:vmpool(_vmpool),hpool(_hpool),vnpool(_vnpool),upool(_upool),
|
||||
ipool(_ipool),cpool(_cpool),port(_port),socket_fd(-1),
|
||||
ipool(_ipool),cpool(_cpool),tpool(_tpool),port(_port),socket_fd(-1),
|
||||
xml_log_file(_xml_log_file)
|
||||
{
|
||||
am.addListener(this);
|
||||
@ -130,10 +132,15 @@ private:
|
||||
ImagePool * ipool;
|
||||
|
||||
/**
|
||||
* Pointer to the Image Pool, to access images
|
||||
* Pointer to the Cluster Pool, to access clusters
|
||||
*/
|
||||
ClusterPool * cpool;
|
||||
|
||||
/**
|
||||
* Pointer to the Template Pool, to access templates
|
||||
*/
|
||||
VMTemplatePool * tpool;
|
||||
|
||||
/**
|
||||
* Port number where the connection will be open
|
||||
*/
|
||||
@ -314,10 +321,12 @@ private:
|
||||
VirtualMachinePool * _vmpool,
|
||||
VirtualNetworkPool * _vnpool,
|
||||
ImagePool * _ipool,
|
||||
VMTemplatePool * _tpool,
|
||||
UserPool * _upool):
|
||||
vmpool(_vmpool),
|
||||
vnpool(_vnpool),
|
||||
ipool(_ipool),
|
||||
tpool(_tpool),
|
||||
upool(_upool)
|
||||
{
|
||||
_signature="A:ss";
|
||||
@ -333,6 +342,7 @@ private:
|
||||
VirtualMachinePool * vmpool;
|
||||
VirtualNetworkPool * vnpool;
|
||||
ImagePool * ipool;
|
||||
VMTemplatePool * tpool;
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
@ -459,8 +469,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(){};
|
||||
@ -501,6 +512,185 @@ private:
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Template Interface */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class TemplateAllocate: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
TemplateAllocate(
|
||||
VMTemplatePool * _tpool,
|
||||
UserPool * _upool):
|
||||
tpool(_tpool),
|
||||
upool(_upool)
|
||||
{
|
||||
_signature="A:ss";
|
||||
_help="Allocates a template in the pool";
|
||||
};
|
||||
|
||||
~TemplateAllocate(){};
|
||||
|
||||
void execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
VMTemplatePool * tpool;
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class TemplateDelete: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
TemplateDelete(VMTemplatePool * _tpool,
|
||||
UserPool * _upool):
|
||||
tpool(_tpool),
|
||||
upool(_upool)
|
||||
{
|
||||
_signature="A:si";
|
||||
_help="Deletes a Template";
|
||||
};
|
||||
|
||||
~TemplateDelete(){};
|
||||
|
||||
void execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
VMTemplatePool * tpool;
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class TemplateInfo: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
TemplateInfo(VMTemplatePool * _tpool,
|
||||
UserPool * _upool):
|
||||
tpool(_tpool),
|
||||
upool(_upool)
|
||||
{
|
||||
_signature="A:si";
|
||||
_help="Returns information for a Template";
|
||||
};
|
||||
|
||||
~TemplateInfo(){};
|
||||
|
||||
void execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
VMTemplatePool * tpool;
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class TemplateUpdate: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
TemplateUpdate(VMTemplatePool * _tpool,
|
||||
UserPool * _upool):
|
||||
tpool(_tpool),
|
||||
upool(_upool)
|
||||
{
|
||||
_signature="A:siss";
|
||||
_help="Modifies Template attribute";
|
||||
};
|
||||
|
||||
~TemplateUpdate(){};
|
||||
|
||||
void execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
VMTemplatePool * tpool;
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class TemplateRemoveAttribute: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
TemplateRemoveAttribute(VMTemplatePool * _tpool,
|
||||
UserPool * _upool):
|
||||
tpool(_tpool),
|
||||
upool(_upool)
|
||||
{
|
||||
_signature="A:sis";
|
||||
_help="Removes Template attribute";
|
||||
};
|
||||
|
||||
~TemplateRemoveAttribute(){};
|
||||
|
||||
void execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
VMTemplatePool * tpool;
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class TemplatePublish: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
TemplatePublish(VMTemplatePool * _tpool,
|
||||
UserPool * _upool):
|
||||
tpool(_tpool),
|
||||
upool(_upool)
|
||||
{
|
||||
_signature="A:sib";
|
||||
_help="Publish/Unpublish the Template";
|
||||
};
|
||||
|
||||
~TemplatePublish(){};
|
||||
|
||||
void execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
VMTemplatePool * tpool;
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class TemplatePoolInfo: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
TemplatePoolInfo(
|
||||
VMTemplatePool * _tpool,
|
||||
UserPool * _upool):
|
||||
tpool(_tpool),
|
||||
upool(_upool)
|
||||
{
|
||||
_signature="A:sii";
|
||||
_help="Returns the template pool";
|
||||
};
|
||||
|
||||
~TemplatePoolInfo(){};
|
||||
|
||||
void execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retvalP);
|
||||
|
||||
private:
|
||||
VMTemplatePool * tpool;
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Host Interface */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
@ -47,6 +47,20 @@ public:
|
||||
separator(_separator),
|
||||
xml_root(_xml_root){};
|
||||
|
||||
Template(const Template& t)
|
||||
{
|
||||
multimap<string,Attribute *>::const_iterator it;
|
||||
|
||||
replace_mode = t.replace_mode;
|
||||
separator = t.separator;
|
||||
xml_root = t.xml_root;
|
||||
|
||||
for (it = t.attributes.begin() ; it != t.attributes.end() ; it++)
|
||||
{
|
||||
attributes.insert(make_pair(it->first,(it->second)->clone()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The class destructor frees all the attributes conforming the template
|
||||
*/
|
||||
@ -161,8 +175,10 @@ public:
|
||||
* @param name the attribute name.
|
||||
* @param value the attribute value, an int, 0 if the attribute is not
|
||||
* defined or not Single
|
||||
*
|
||||
* @returns True if the Single attribute was found
|
||||
*/
|
||||
virtual void get(
|
||||
virtual bool get(
|
||||
string& name,
|
||||
int& value) const;
|
||||
|
||||
|
@ -134,15 +134,6 @@ private:
|
||||
*/
|
||||
int insert_replace(SqlDB *db, bool replace);
|
||||
|
||||
/**
|
||||
* Callback function to unmarshall a User object (User::select)
|
||||
* @param num the number of columns read from the DB
|
||||
* @param names the column names
|
||||
* @param vaues the column values
|
||||
* @return 0 on success
|
||||
*/
|
||||
int select_cb(void *nil, int num, char **values, char **names);
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the User
|
||||
*/
|
||||
|
190
include/VMTemplate.h
Normal file
190
include/VMTemplate.h
Normal file
@ -0,0 +1,190 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 VMTEMPLATE_H_
|
||||
#define VMTEMPLATE_H_
|
||||
|
||||
#include "PoolObjectSQL.h"
|
||||
#include "VirtualMachineTemplate.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* The VMTemplate class.
|
||||
*/
|
||||
class VMTemplate : public PoolObjectSQL
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Function to write a VMTemplate on an output stream
|
||||
*/
|
||||
friend ostream& operator<<(ostream& os, VMTemplate& u);
|
||||
|
||||
/**
|
||||
* Function to print the VMTemplate object into a string in XML format
|
||||
* @param xml the resulting XML string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
string& to_xml(string& xml) const;
|
||||
|
||||
/**
|
||||
* Returns true if the object is public
|
||||
* @return true if the Virtual Network is public
|
||||
*/
|
||||
bool isPublic()
|
||||
{
|
||||
return (public_template == 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Publish or unpublish an object
|
||||
* @param pub true to publish the object
|
||||
* @return 0 on success
|
||||
*/
|
||||
bool publish(bool pub)
|
||||
{
|
||||
if (pub == true)
|
||||
{
|
||||
public_template = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
public_template = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Template Contents
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns a copy of the VirtualMachineTemplate
|
||||
* @return A copy of the VirtualMachineTemplate
|
||||
*/
|
||||
VirtualMachineTemplate * clone_template() const
|
||||
{
|
||||
return new VirtualMachineTemplate(
|
||||
*(static_cast<VirtualMachineTemplate *>(obj_template)));
|
||||
|
||||
// TODO: Check if there is a more efficient way to do this copy.
|
||||
/*string xml_str;
|
||||
VirtualMachineTemplate * new_template = new VirtualMachineTemplate();
|
||||
|
||||
obj_template->to_xml(xml_str);
|
||||
new_template->from_xml(xml_str);
|
||||
|
||||
return new_template;*/
|
||||
};
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------------
|
||||
// Friends
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
friend class VMTemplatePool;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// VMTemplate Attributes
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Owner's name
|
||||
*/
|
||||
string user_name;
|
||||
|
||||
/**
|
||||
* Public scope of the VMTemplate
|
||||
*/
|
||||
int public_template;
|
||||
|
||||
/**
|
||||
* Registration time
|
||||
*/
|
||||
time_t regtime;
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation (Private)
|
||||
// *************************************************************************
|
||||
|
||||
/**
|
||||
* Execute an INSERT or REPLACE Sql query.
|
||||
* @param db The SQL DB
|
||||
* @param replace Execute an INSERT or a REPLACE
|
||||
* @return 0 one success
|
||||
*/
|
||||
int insert_replace(SqlDB *db, bool replace);
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the VMTemplate
|
||||
*/
|
||||
static void bootstrap(SqlDB * db)
|
||||
{
|
||||
ostringstream oss(VMTemplate::db_bootstrap);
|
||||
|
||||
db->exec(oss);
|
||||
};
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml formatted string
|
||||
* @param xml_str The xml-formatted string
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml(const string &xml_str);
|
||||
|
||||
protected:
|
||||
|
||||
// *************************************************************************
|
||||
// Constructor
|
||||
// *************************************************************************
|
||||
VMTemplate(int id, int uid, string _user_name,
|
||||
VirtualMachineTemplate * _template_contents);
|
||||
|
||||
~VMTemplate();
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation
|
||||
// *************************************************************************
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
static const char * table;
|
||||
|
||||
/**
|
||||
* Writes the VMTemplate in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int insert(SqlDB *db, string& error_str);
|
||||
|
||||
/**
|
||||
* Writes/updates the VMTemplate data fields in the database.
|
||||
* @param db pointer to the db
|
||||
* @return 0 on success
|
||||
*/
|
||||
int update(SqlDB *db)
|
||||
{
|
||||
return insert_replace(db, true);
|
||||
};
|
||||
};
|
||||
|
||||
#endif /*VMTEMPLATE_H_*/
|
146
include/VMTemplatePool.h
Normal file
146
include/VMTemplatePool.h
Normal file
@ -0,0 +1,146 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 VMTEMPLATE_POOL_H_
|
||||
#define VMTEMPLATE_POOL_H_
|
||||
|
||||
#include "PoolSQL.h"
|
||||
#include "VMTemplate.h"
|
||||
|
||||
/**
|
||||
* The VMTemplate Pool class.
|
||||
*/
|
||||
class VMTemplatePool : public PoolSQL
|
||||
{
|
||||
public:
|
||||
|
||||
VMTemplatePool(SqlDB * db) : PoolSQL(db, VMTemplate::table){};
|
||||
|
||||
~VMTemplatePool(){};
|
||||
|
||||
/**
|
||||
* Allocates a new object, writting it in the pool database. No memory is
|
||||
* allocated for the object.
|
||||
* @param uid user id (the owner of the Template)
|
||||
* @param user_name Owner's user name
|
||||
* @param template_contents a VM Template object
|
||||
* @param oid the id assigned to the Template
|
||||
* @param error_str Returns the error reason, if any
|
||||
*
|
||||
* @return the oid assigned to the object, -1 in case of failure
|
||||
*/
|
||||
int allocate(int uid,
|
||||
string user_name,
|
||||
VirtualMachineTemplate * template_contents,
|
||||
int * oid,
|
||||
string& error_str);
|
||||
|
||||
/**
|
||||
* Gets an object from the pool (if needed the object is loaded from the
|
||||
* database).
|
||||
* @param oid the object unique identifier
|
||||
* @param lock locks the object if true
|
||||
*
|
||||
* @return a pointer to the object, 0 in case of failure
|
||||
*/
|
||||
VMTemplate * get(int oid, bool lock)
|
||||
{
|
||||
return static_cast<VMTemplate *>(PoolSQL::get(oid,lock));
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets an object from the pool (if needed the object is loaded from the
|
||||
* database).
|
||||
* @param name of the object
|
||||
* @param uid id of owner
|
||||
* @param lock locks the object if true
|
||||
*
|
||||
* @return a pointer to the object, 0 in case of failure
|
||||
*/
|
||||
VMTemplate * get(const string& name, int uid, bool lock)
|
||||
{
|
||||
return static_cast<VMTemplate *>(PoolSQL::get(name,uid,lock));
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the object's data in the data base. The object mutex SHOULD be
|
||||
* locked.
|
||||
* @param objsql a pointer to the object
|
||||
*
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int update(VMTemplate * vm_template)
|
||||
{
|
||||
return vm_template->update(db);
|
||||
};
|
||||
|
||||
/**
|
||||
* Drops the object's data in the data base. The object mutex SHOULD be
|
||||
* locked.
|
||||
* @param objsql a pointer to the object
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int drop(VMTemplate * vm_template)
|
||||
{
|
||||
return PoolSQL::drop(vm_template);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dumps the pool in XML format. A filter can be also added to the
|
||||
* query
|
||||
* @param oss the output stream to dump the pool contents
|
||||
* @param where filter for the objects, defaults to all
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int dump(ostringstream& oss, const string& where)
|
||||
{
|
||||
return PoolSQL::dump(oss, "VMTEMPLATE_POOL",VMTemplate::table,where);
|
||||
};
|
||||
|
||||
/**
|
||||
* Bootstraps the database table(s) associated to the pool
|
||||
*/
|
||||
static void bootstrap(SqlDB *_db)
|
||||
{
|
||||
VMTemplate::bootstrap(_db);
|
||||
};
|
||||
|
||||
private:
|
||||
//--------------------------------------------------------------------------
|
||||
// Configuration Attributes for Images
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// TODO
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Pool Attributes
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// TODO
|
||||
|
||||
|
||||
/**
|
||||
* Factory method to produce Image objects
|
||||
* @return a pointer to the new Image
|
||||
*/
|
||||
PoolObjectSQL * create()
|
||||
{
|
||||
return new VMTemplate(-1,-1,"", 0);
|
||||
};
|
||||
};
|
||||
|
||||
#endif /*VMTEMPLATE_POOL_H_*/
|
@ -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,12 +539,11 @@ 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
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the VM state (Dispatch Manager)
|
||||
* @return the VM state
|
||||
@ -743,7 +655,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 +687,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.
|
||||
*/
|
||||
@ -914,7 +818,6 @@ private:
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Attribute Parser
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -41,8 +41,10 @@ public:
|
||||
/**
|
||||
* Function to allocate a new VM object
|
||||
* @param uid user id (the owner of the VM)
|
||||
* @param user_name Owner's user name
|
||||
* @param vm_template a VM Template object describing the VM
|
||||
* @param oid the id assigned to the VM (output)
|
||||
* @param error_str Returns the error reason, if any
|
||||
* @param on_hold flag to submit on hold
|
||||
* @return oid on success, -1 error inserting in DB or -2 error parsing
|
||||
* the template
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include "Template.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
@ -32,6 +34,8 @@ public:
|
||||
|
||||
~VirtualMachineTemplate(){};
|
||||
|
||||
VirtualMachineTemplate(VirtualMachineTemplate& vmt):Template(vmt){};
|
||||
|
||||
private:
|
||||
friend class VirtualMachine;
|
||||
};
|
||||
|
@ -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)
|
||||
// *************************************************************************
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "HostPool.h"
|
||||
#include "UserPool.h"
|
||||
#include "ClusterPool.h"
|
||||
#include "VMTemplatePool.h"
|
||||
|
||||
#include "VirtualMachineManager.h"
|
||||
#include "LifeCycleManager.h"
|
||||
@ -35,6 +36,7 @@
|
||||
#include "RequestManager.h"
|
||||
#include "HookManager.h"
|
||||
#include "AuthManager.h"
|
||||
#include "ImageManager.h"
|
||||
|
||||
class NebulaTest
|
||||
{
|
||||
@ -42,7 +44,8 @@ protected:
|
||||
|
||||
NebulaTest():mysql(false), need_host_pool(false), need_vm_pool(false),
|
||||
need_vnet_pool(false), need_image_pool(false),
|
||||
need_user_pool(false), need_cluster_pool(false),need_vmm(false),
|
||||
need_user_pool(false), need_cluster_pool(false),
|
||||
need_template_pool(false),need_vmm(false),
|
||||
need_im(false), need_tm(false),
|
||||
need_lcm(false), need_dm(false),
|
||||
need_rm(false), need_hm(false),
|
||||
@ -62,6 +65,7 @@ public:
|
||||
bool need_image_pool;
|
||||
bool need_user_pool;
|
||||
bool need_cluster_pool;
|
||||
bool need_template_pool;
|
||||
|
||||
bool need_vmm;
|
||||
bool need_im;
|
||||
@ -71,6 +75,7 @@ public:
|
||||
bool need_rm;
|
||||
bool need_hm;
|
||||
bool need_authm;
|
||||
bool need_imagem;
|
||||
|
||||
static NebulaTest * instance()
|
||||
{
|
||||
@ -92,12 +97,13 @@ public:
|
||||
virtual UserPool* create_upool(SqlDB* db);
|
||||
|
||||
virtual ImagePool* create_ipool( SqlDB* db,
|
||||
string repository_path,
|
||||
string default_image_type,
|
||||
string default_device_prefix);
|
||||
|
||||
virtual ClusterPool* create_cpool(SqlDB* db);
|
||||
|
||||
virtual VMTemplatePool* create_tpool(SqlDB* db);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Managers
|
||||
// ------------------------------------------------------------------------
|
||||
@ -127,11 +133,14 @@ public:
|
||||
UserPool * upool,
|
||||
ImagePool * ipool,
|
||||
ClusterPool * cpool,
|
||||
VMTemplatePool * tpool,
|
||||
string log_file);
|
||||
|
||||
virtual HookManager* create_hm(VirtualMachinePool * vmpool);
|
||||
|
||||
virtual AuthManager* create_authm(time_t timer_period);
|
||||
|
||||
virtual ImageManager* create_imagem(ImagePool * ipool);
|
||||
};
|
||||
|
||||
#endif /*NEBULA_TEST_H_*/
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
if (mysql)
|
||||
{
|
||||
db = new MySqlDB( "localhost",0,
|
||||
"oneadmin","oneadmin",NULL);
|
||||
"oneadmin","oneadmin",db_name);
|
||||
|
||||
ostringstream oss1;
|
||||
oss1 << "DROP DATABASE IF EXISTS " << db_name;
|
||||
|
50
install.sh
50
install.sh
@ -193,7 +193,10 @@ 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 \
|
||||
$LIB_LOCATION/sh"
|
||||
|
||||
VAR_DIRS="$VAR_LOCATION/remotes \
|
||||
$VAR_LOCATION/remotes/im \
|
||||
@ -201,7 +204,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 \
|
||||
@ -253,6 +258,12 @@ INSTALL_FILES=(
|
||||
LIB_FILES:$LIB_LOCATION
|
||||
RUBY_LIB_FILES:$LIB_LOCATION/ruby
|
||||
RUBY_OPENNEBULA_LIB_FILES:$LIB_LOCATION/ruby/OpenNebula
|
||||
MAD_RUBY_LIB_FILES:$LIB_LOCATION/ruby
|
||||
MAD_RUBY_LIB_FILES:$LIB_LOCATION/remotes
|
||||
MAD_RUBY_LIB_FILES:$VAR_LOCATION/remotes
|
||||
MAD_SH_LIB_FILES:$LIB_LOCATION/sh
|
||||
MAD_SH_LIB_FILES:$LIB_LOCATION/remotes
|
||||
MAD_SH_LIB_FILES:$VAR_LOCATION/remotes
|
||||
MADS_LIB_FILES:$LIB_LOCATION/mads
|
||||
IM_PROBES_FILES:$VAR_LOCATION/remotes/im
|
||||
IM_PROBES_KVM_FILES:$VAR_LOCATION/remotes/im/kvm.d
|
||||
@ -278,6 +289,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
|
||||
@ -354,6 +367,7 @@ BIN_FILES="src/nebula/oned \
|
||||
src/cli/oneuser \
|
||||
src/cli/oneimage \
|
||||
src/cli/onecluster \
|
||||
src/cli/onetemplate \
|
||||
share/scripts/one \
|
||||
src/authm_mad/oneauth"
|
||||
|
||||
@ -396,11 +410,21 @@ 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/Template.rb \
|
||||
src/oca/ruby/OpenNebula/TemplatePool.rb \
|
||||
src/oca/ruby/OpenNebula/XMLUtils.rb"
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# MAD Script library files, to be installed under $LIB_LOCATION/<script lang>
|
||||
# and remotes directory
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
MAD_SH_LIB_FILES="src/mad/sh/scripts_common.sh"
|
||||
MAD_RUBY_LIB_FILES="src/mad/ruby/scripts_common.rb"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Driver executable files, to be installed under $LIB_LOCATION/mads
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -428,7 +452,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 +540,16 @@ 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/fsrc \
|
||||
src/image_mad/remotes/fs/rm"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Configuration files for OpenNebula, to be installed under $ETC_LOCATION
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -700,7 +736,8 @@ CLI_BIN_FILES="src/cli/onevm \
|
||||
src/cli/onevnet \
|
||||
src/cli/oneuser \
|
||||
src/cli/oneimage \
|
||||
src/cli/onecluster"
|
||||
src/cli/onecluster \
|
||||
src/cli/onetemplate"
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Sunstone files
|
||||
@ -721,6 +758,7 @@ SUNSTONE_MODELS_JSON_FILES="src/sunstone/models/OpenNebulaJSON/ClusterJSON.rb \
|
||||
src/sunstone/models/OpenNebulaJSON/PoolJSON.rb \
|
||||
src/sunstone/models/OpenNebulaJSON/UserJSON.rb \
|
||||
src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb \
|
||||
src/sunstone/models/OpenNebulaJSON/TemplateJSON.rb \
|
||||
src/sunstone/models/OpenNebulaJSON/VirtualNetworkJSON.rb"
|
||||
|
||||
SUNSTONE_TEMPLATE_FILES="src/sunstone/templates/index.html \
|
||||
@ -736,6 +774,7 @@ SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\
|
||||
src/sunstone/public/js/plugins/dashboard-tab.js \
|
||||
src/sunstone/public/js/plugins/hosts-tab.js \
|
||||
src/sunstone/public/js/plugins/images-tab.js \
|
||||
src/sunstone/public/js/plugins/templates-tab.js \
|
||||
src/sunstone/public/js/plugins/users-tab.js \
|
||||
src/sunstone/public/js/plugins/vms-tab.js \
|
||||
src/sunstone/public/js/plugins/vnets-tab.js"
|
||||
@ -809,6 +848,7 @@ MAN_FILES="share/man/oneauth.8.gz \
|
||||
share/man/oneuser.8.gz \
|
||||
share/man/onevm.8.gz \
|
||||
share/man/onevnet.8.gz \
|
||||
share/man/onetemplate.8.gz \
|
||||
share/man/econe-describe-images.8.gz \
|
||||
share/man/econe-describe-instances.8.gz \
|
||||
share/man/econe-register.8.gz \
|
||||
|
@ -82,9 +82,6 @@ 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/images
|
||||
#
|
||||
# DEFAULT_IMAGE_TYPE: This can take values
|
||||
# OS Image file holding an operating system
|
||||
# CDROM Image file holding a CDROM
|
||||
@ -96,8 +93,6 @@ MAC_PREFIX = "02:00"
|
||||
# xvd XEN Virtual Disk
|
||||
# vd KVM virtual disk
|
||||
#*******************************************************************************
|
||||
|
||||
#IMAGE_REPOSITORY_PATH = /srv/cloud/var/images
|
||||
DEFAULT_IMAGE_TYPE = "OS"
|
||||
DEFAULT_DEVICE_PREFIX = "hd"
|
||||
|
||||
@ -285,6 +280,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 +353,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 --------------------------
|
||||
|
@ -64,7 +64,7 @@ host.info
|
||||
host_name = host.name
|
||||
|
||||
# Loop through all vms
|
||||
vms = VirtualMachinePool.new(client)
|
||||
vms = VirtualMachinePool.new(client, -2)
|
||||
exit -1 if OpenNebula.is_error?(vms)
|
||||
|
||||
vms.info
|
||||
|
@ -69,24 +69,24 @@ main(int argc, char **) {
|
||||
vector<xmlrpc_c::value> const paramArrayValue(resultArray.vectorValueValue());
|
||||
|
||||
//check posible Errors:
|
||||
xmlrpc_c::value * firstvalue;
|
||||
firstvalue = &(static_cast<xmlrpc_c::value>(paramArrayValue[0]));
|
||||
xmlrpc_c::value_boolean * status = &(static_cast<xmlrpc_c::value_boolean>(*firstvalue));
|
||||
xmlrpc_c::value firstvalue;
|
||||
firstvalue = static_cast<xmlrpc_c::value>(paramArrayValue[0]);
|
||||
xmlrpc_c::value_boolean status = static_cast<xmlrpc_c::value_boolean>(firstvalue);
|
||||
|
||||
xmlrpc_c::value * secondvalue;
|
||||
secondvalue = &(static_cast<xmlrpc_c::value>(paramArrayValue[1]));
|
||||
xmlrpc_c::value_string * valueS = &(static_cast<xmlrpc_c::value_string>(*secondvalue));
|
||||
xmlrpc_c::value secondvalue;
|
||||
secondvalue = static_cast<xmlrpc_c::value>(paramArrayValue[1]);
|
||||
xmlrpc_c::value_string valueS = static_cast<xmlrpc_c::value_string>(secondvalue);
|
||||
|
||||
if(static_cast<bool>(*status)) {
|
||||
if(static_cast<bool>(status)) {
|
||||
//Success, returns the id assigned to the VM:
|
||||
cout << "vmid returned: " << static_cast<string>(*valueS) << endl;
|
||||
cout << "vmid returned: " << static_cast<string>(valueS) << endl;
|
||||
return 0;
|
||||
}
|
||||
else{ //Failure:
|
||||
string error_value=static_cast<string>(*valueS);
|
||||
string error_value=static_cast<string>(valueS);
|
||||
if (error_value.find("Error inserting",0)!=string::npos ) cout << "Error inserting VM in the database" << endl;
|
||||
else if (error_value.find("Error parsing",0)!=string::npos ) cout << "Error parsing VM template" << endl;
|
||||
else cout << "Unknown error " << static_cast<string>(*valueS) << endl;
|
||||
else cout << "Unknown error " << static_cast<string>(valueS) << endl;
|
||||
};
|
||||
} catch (girerr::error const error) {
|
||||
cerr << "Client threw error: " << error.what() << endl;
|
||||
|
@ -17,7 +17,8 @@ TESTS="$TWD_DIR/vnm/test \
|
||||
$TWD_DIR/vm/test \
|
||||
$TWD_DIR/um/test \
|
||||
$TWD_DIR/lcm/test \
|
||||
$TWD_DIR/pool/test"
|
||||
$TWD_DIR/pool/test \
|
||||
$TWD_DIR/vm_template/test"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# COMMAND LINE PARSING
|
||||
|
@ -86,9 +86,10 @@ void AuthRequest::add_auth(Object ob,
|
||||
case IMAGE: oss << "IMAGE:" ; break;
|
||||
case USER: oss << "USER:" ; break;
|
||||
case CLUSTER: oss << "CLUSTER:" ; break;
|
||||
case TEMPLATE: oss << "TEMPLATE:" ; break;
|
||||
}
|
||||
|
||||
if (op == CREATE) //encode the ob_id, it is a template
|
||||
if (op == CREATE || op == INSTANTIATE) //encode the ob_id, it is a template
|
||||
{
|
||||
string * encoded_id = base64_encode(ob_id);
|
||||
|
||||
@ -128,6 +129,10 @@ void AuthRequest::add_auth(Object ob,
|
||||
case INFO:
|
||||
oss << "INFO:" ;
|
||||
break;
|
||||
|
||||
case INSTANTIATE:
|
||||
oss << "INSTANTIATE:" ;
|
||||
break;
|
||||
}
|
||||
|
||||
oss << owner << ":" << pub;
|
||||
@ -147,7 +152,14 @@ void AuthRequest::add_auth(Object ob,
|
||||
switch (op)
|
||||
{
|
||||
case CREATE:
|
||||
if ( ob == VM || ob == NET || ob == IMAGE )
|
||||
if ( ob == VM || ob == NET || ob == IMAGE || ob == TEMPLATE )
|
||||
{
|
||||
auth = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case INSTANTIATE:
|
||||
if ( ob == VM )
|
||||
{
|
||||
auth = true;
|
||||
}
|
||||
@ -158,7 +170,7 @@ void AuthRequest::add_auth(Object ob,
|
||||
break;
|
||||
|
||||
case USE:
|
||||
if (ob == NET || ob == IMAGE)
|
||||
if (ob == NET || ob == IMAGE || ob == TEMPLATE)
|
||||
{
|
||||
auth = (owner == uid) || pub;
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ void AuthManagerDriver::protocol(
|
||||
{
|
||||
is.clear();
|
||||
getline(is,info);
|
||||
NebulaLog::log("AuM",Log::INFO, info.c_str());
|
||||
NebulaLog::log("AuM", log_type(result[0]), info.c_str());
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -89,19 +89,43 @@ class Quota
|
||||
# Checks if the user is below resource limits. If new_vm is defined
|
||||
# checks if its requirements fit in limits
|
||||
def check(user, new_vm=nil)
|
||||
usage=@usage.total(user)
|
||||
use=@usage.total(user)
|
||||
use_after=use.clone
|
||||
user_quota=get(user)
|
||||
if new_vm
|
||||
usage.cpu+=new_vm.cpu.to_f
|
||||
usage.memory+=new_vm.memory.to_i
|
||||
usage.num_vms+=1
|
||||
use_after.cpu+=new_vm.cpu.to_f
|
||||
use_after.memory+=new_vm.memory.to_i
|
||||
use_after.num_vms+=1
|
||||
end
|
||||
|
||||
STDERR.puts [user_quota, use_after, new_vm].inspect
|
||||
|
||||
error_message=""
|
||||
|
||||
if !(!user_quota[:cpu] || use_after.cpu<=user_quota[:cpu])
|
||||
error_message<<"Cpu quota exceeded (Quota: #{user_quota[:cpu]}, "+
|
||||
"Used: #{use.cpu}"
|
||||
error_message<<", asked: #{new_vm.cpu.to_f}" if new_vm
|
||||
error_message<<")."
|
||||
end
|
||||
|
||||
if !(!user_quota[:memory] || use_after.memory<=user_quota[:memory])
|
||||
error_message<<" Memory quota exceeded (Quota: "+
|
||||
"#{user_quota[:memory]}, Used: #{use.memory}"
|
||||
error_message<<", asked: #{new_vm.memory.to_i}" if new_vm
|
||||
error_message<<")."
|
||||
end
|
||||
|
||||
if !(!user_quota[:num_vms] || use_after.num_vms<=user_quota[:num_vms])
|
||||
error_message<<" Num VMS quota exceeded (Quota: "+
|
||||
"#{user_quota[:memory]}, Used: #{use.num_vms})."
|
||||
end
|
||||
|
||||
if error_message==""
|
||||
false
|
||||
else
|
||||
error_message.strip
|
||||
end
|
||||
|
||||
STDERR.puts [user_quota, usage, new_vm].inspect
|
||||
|
||||
(!user_quota[:cpu] || usage.cpu<=user_quota[:cpu]) &&
|
||||
(!user_quota[:memory] || usage.memory<=user_quota[:memory]) &&
|
||||
(!user_quota[:num_vms] || usage.num_vms<=user_quota[:num_vms])
|
||||
end
|
||||
|
||||
# Updates user resource consuption
|
||||
|
@ -48,7 +48,20 @@ class SimplePermissions
|
||||
|
||||
VmUsage.new(cpu, memory)
|
||||
end
|
||||
|
||||
|
||||
# Checks if the quota is enabled, and if it is not exceeded
|
||||
def check_quota_enabled(uid, object, id, auth_result)
|
||||
if @quota_enabled and object=='VM' and auth_result
|
||||
STDERR.puts 'quota enabled'
|
||||
@quota.update(uid.to_i)
|
||||
if message=@quota.check(uid.to_i, get_vm_usage(id))
|
||||
auth_result=message
|
||||
end
|
||||
end
|
||||
|
||||
return auth_result
|
||||
end
|
||||
|
||||
# Method called by authorization driver
|
||||
def auth(uid, tokens)
|
||||
result=true
|
||||
@ -71,21 +84,18 @@ class SimplePermissions
|
||||
|
||||
case action
|
||||
when 'CREATE'
|
||||
auth_result=true if %w{VM NET IMAGE}.include? object
|
||||
|
||||
if @quota_enabled and object=='VM' and auth_result
|
||||
STDERR.puts 'quota enabled'
|
||||
@quota.update(uid.to_i)
|
||||
if !@quota.check(uid.to_i, get_vm_usage(id))
|
||||
auth_result="Quota exceeded"
|
||||
end
|
||||
end
|
||||
|
||||
auth_result=true if %w{VM NET IMAGE TEMPLATE}.include? object
|
||||
auth_result = check_quota_enabled(uid, object, id, auth_result)
|
||||
|
||||
when 'INSTANTIATE'
|
||||
auth_result = true if %w{VM}.include? object
|
||||
auth_result = check_quota_enabled(uid, object, id, auth_result)
|
||||
|
||||
when 'DELETE'
|
||||
auth_result = (owner == uid)
|
||||
|
||||
when 'USE'
|
||||
if %w{VM NET IMAGE}.include? object
|
||||
if %w{VM NET IMAGE TEMPLATE}.include? object
|
||||
auth_result = ((owner == uid) | (pub=='1'))
|
||||
elsif object == 'HOST'
|
||||
auth_result=true
|
||||
|
@ -60,8 +60,8 @@ describe 'Quota' do
|
||||
it 'should check for quotas' do
|
||||
@quota.update(0)
|
||||
@quota.update(1)
|
||||
@quota.check(0).should == true
|
||||
@quota.check(1).should == true
|
||||
@quota.check(0).should == false
|
||||
@quota.check(1).should == false
|
||||
|
||||
vms=@quota.get_user(0)
|
||||
vms[5]=VmUsage.new(40.0, 8192)
|
||||
@ -69,13 +69,13 @@ describe 'Quota' do
|
||||
vms=@quota.get_user(1)
|
||||
vms[6]=VmUsage.new(40.0, 8192)
|
||||
|
||||
@quota.check(0).should == false
|
||||
@quota.check(1).should == false
|
||||
@quota.check(0).class.should == String
|
||||
@quota.check(1).class.should == String
|
||||
|
||||
@quota.update(0)
|
||||
@quota.update(1)
|
||||
@quota.check(0).should == true
|
||||
@quota.check(1).should == true
|
||||
@quota.check(0).should == false
|
||||
@quota.check(1).should == false
|
||||
end
|
||||
|
||||
it 'should let update limits' do
|
||||
@ -86,8 +86,8 @@ describe 'Quota' do
|
||||
it 'should understand unlimited quotas' do
|
||||
vms=@quota.get_user(0)
|
||||
vms[7]=VmUsage.new(9999999999.0, 99999999999)
|
||||
@quota.check(0).should == true
|
||||
@quota.check(0, VmUsage.new(999999999.0, 99999999)).should == true
|
||||
@quota.check(0).should == false
|
||||
@quota.check(0, VmUsage.new(999999999.0, 99999999)).should == false
|
||||
end
|
||||
|
||||
end
|
@ -268,15 +268,19 @@ def get_entity_id(name, pool_class)
|
||||
pool=pool_class.new(get_one_client)
|
||||
result=pool.info
|
||||
|
||||
# TODO: Check for errors
|
||||
class_name=pool_class.name.split('::').last.gsub(/Pool$/, '')
|
||||
|
||||
if( OpenNebula.is_error?(result) )
|
||||
puts "Error: #{class_name} Pool info could not be retrieved. " +
|
||||
result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
objects=pool.select {|object| object.name==name }
|
||||
|
||||
class_name=pool_class.name.split('::').last.gsub(/Pool$/, '')
|
||||
|
||||
if objects.length>0
|
||||
if objects.length>1
|
||||
puts "There are multiple #{class_name}'s with name #{name}."
|
||||
puts "There are multiple #{class_name}s with name #{name}."
|
||||
exit -1
|
||||
else
|
||||
result=objects.first.id
|
||||
@ -313,6 +317,10 @@ def get_cluster_id(name)
|
||||
get_entity_id(name, OpenNebula::ClusterPool)
|
||||
end
|
||||
|
||||
def get_template_id(name)
|
||||
get_entity_id(name, OpenNebula::TemplatePool)
|
||||
end
|
||||
|
||||
def str_running_time(data)
|
||||
stime=Time.at(data["STIME"].to_i)
|
||||
if data["ETIME"]=="0"
|
||||
|
@ -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
|
||||
|
411
src/cli/onetemplate
Executable file
411
src/cli/onetemplate
Executable file
@ -0,0 +1,411 @@
|
||||
#!/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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
|
||||
|
||||
require 'OpenNebula'
|
||||
require 'CommandManager'
|
||||
require 'client_utilities'
|
||||
require 'command_parse'
|
||||
|
||||
ShowTableTemplate={
|
||||
:id => {
|
||||
:name => "ID",
|
||||
:desc => "ONE identifier for the Template",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e| d.id }
|
||||
},
|
||||
:user=> {
|
||||
:name => "USER",
|
||||
:desc => "Name of the owner",
|
||||
:size => 8,
|
||||
:proc => lambda {|d,e|
|
||||
d["USERNAME"]
|
||||
}
|
||||
},
|
||||
:name => {
|
||||
:name => "NAME",
|
||||
:desc => "Name of the Template",
|
||||
:size => 20,
|
||||
:proc => lambda {|d,e|
|
||||
d.name
|
||||
}
|
||||
},
|
||||
:regtime => {
|
||||
:name => "REGTIME",
|
||||
:desc => "Registration time of the Template",
|
||||
:size => 20,
|
||||
:proc => lambda {|d,e|
|
||||
str_register_time(d)
|
||||
}
|
||||
},
|
||||
:public => {
|
||||
:name => "PUBLIC",
|
||||
:desc => "Whether the Template is public or not",
|
||||
:size => 3,
|
||||
:proc => lambda {|d,e|
|
||||
if d["PUBLIC"].to_i == 1 then "Yes" else "No" end}
|
||||
},
|
||||
|
||||
:default => [:id, :user, :name, :regtime, :public]
|
||||
}
|
||||
|
||||
|
||||
|
||||
class TemplateShow
|
||||
|
||||
def initialize(client, filter_flag="-2")
|
||||
@templatepool=OpenNebula::TemplatePool.new(client, filter_flag.to_i)
|
||||
@table=ShowTable.new(ShowTableTemplate)
|
||||
end
|
||||
|
||||
def header_template_small
|
||||
scr_bold
|
||||
scr_underline
|
||||
print @table.header_str
|
||||
scr_restore
|
||||
puts ""
|
||||
end
|
||||
|
||||
def top(options=nil)
|
||||
delay=1
|
||||
delay=options[:delay] if options && options[:delay]
|
||||
|
||||
result=nil
|
||||
|
||||
begin
|
||||
while true
|
||||
scr_cls
|
||||
scr_move(0,0)
|
||||
result=list_short(options)
|
||||
sleep delay
|
||||
end
|
||||
rescue Exception
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def list_short(options=nil)
|
||||
res=@templatepool.info()
|
||||
|
||||
if options
|
||||
@table.columns=options[:columns] if options[:columns]
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(res)
|
||||
result=res
|
||||
puts res.message
|
||||
exit -1
|
||||
else
|
||||
|
||||
if options[:filter_flag]
|
||||
objs=@templatepool.select{|element|
|
||||
element['USERNAME']==options[:filter_flag] }
|
||||
else
|
||||
objs=@templatepool
|
||||
end
|
||||
|
||||
result=[true, ""]
|
||||
header_template_small
|
||||
|
||||
if options
|
||||
puts @table.data_str(objs, options)
|
||||
else
|
||||
puts @table.data_str(objs)
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
##########################
|
||||
## COMMAND LINE PARSING ##
|
||||
##########################
|
||||
|
||||
class OneTemplateParse < CommandParse
|
||||
|
||||
COMMANDS_HELP=<<-EOT
|
||||
|
||||
Description:
|
||||
|
||||
This command enables the user to manage templates.
|
||||
|
||||
|
||||
Commands:
|
||||
|
||||
* create (Registers a Template from a template file)
|
||||
onetemplate create <file>
|
||||
|
||||
file is a file name where the Template description is located
|
||||
|
||||
* addattr (Add a new Template attribute)
|
||||
onetemplate addattr <template_id> <attribute_name> <attribute_value>
|
||||
|
||||
* update (Modifies a Template attribute)
|
||||
onetemplate update <template_id> <attribute_name> <attribute_value>
|
||||
|
||||
* rmattr (Deletes a Template attribute)
|
||||
onetemplate rmattr <template_id> <attribute_name>
|
||||
|
||||
* publish (Publish a Template)
|
||||
onetemplate publish <template_id>
|
||||
|
||||
* unpublish (Unpublish an Template)
|
||||
onetemplate unpublish <template_id>
|
||||
|
||||
* list (Shows Templates in the pool)
|
||||
onetemplate list <filter_flag>
|
||||
|
||||
where filter_flag can be
|
||||
a, all --> all the known Templates
|
||||
m, mine --> the Templates belonging to the user in ONE_AUTH
|
||||
and all the Public Templates
|
||||
uid --> Templates of the user identified by this uid
|
||||
user --> Templates of the user identified by the username
|
||||
|
||||
* top (Lists Templates continuously)
|
||||
onetemplate top
|
||||
|
||||
* show (Gets information about an specific Template)
|
||||
onetemplate show <template_id>
|
||||
|
||||
* delete (Deletes a Template)
|
||||
onetemplate delete <template_id>
|
||||
|
||||
EOT
|
||||
|
||||
def text_commands
|
||||
COMMANDS_HELP
|
||||
end
|
||||
|
||||
def text_command_name
|
||||
"onetemplate"
|
||||
end
|
||||
|
||||
def list_options
|
||||
table=ShowTable.new(ShowTableTemplate)
|
||||
table.print_help
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def get_user_flags
|
||||
ops=Hash.new
|
||||
if ARGV[0]
|
||||
case ARGV[0]
|
||||
when "a", "all"
|
||||
ops[:filter_user]="-2"
|
||||
when "m", "mine"
|
||||
ops[:filter_user]="-1"
|
||||
else
|
||||
if !ARGV[0].match(/^[0123456789]+$/)
|
||||
ops[:filter_user]="-2"
|
||||
ops[:filter_flag]=ARGV[0]
|
||||
else
|
||||
ops[:filter_user]=ARGV[0]
|
||||
end
|
||||
end
|
||||
else
|
||||
ops[:filter_user]="-2"
|
||||
end
|
||||
|
||||
ops
|
||||
end
|
||||
|
||||
def get_template(template_path)
|
||||
begin
|
||||
template = File.read(ARGV[0])
|
||||
rescue
|
||||
result = OpenNebula::Error.new("Can not read template: #{ARGV[0]}")
|
||||
end
|
||||
|
||||
if !is_successful?(result)
|
||||
puts result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
return template
|
||||
end
|
||||
|
||||
onetemplate_opts=OneTemplateParse.new
|
||||
onetemplate_opts.parse(ARGV)
|
||||
ops=onetemplate_opts.options
|
||||
|
||||
result=[false, "Unknown error"]
|
||||
|
||||
command=ARGV.shift
|
||||
|
||||
case command
|
||||
when "create", "register", "add"
|
||||
check_parameters("create", 1)
|
||||
template_contents = get_template(ARGV[0])
|
||||
|
||||
template = OpenNebula::Template.new(OpenNebula::Template.build_xml, get_one_client)
|
||||
|
||||
result=template.allocate(template_contents)
|
||||
if !OpenNebula.is_error?(result)
|
||||
puts "ID: " + template.id.to_s if ops[:verbose]
|
||||
exit 0
|
||||
end
|
||||
|
||||
when "update", "addattr"
|
||||
check_parameters("update", 3)
|
||||
template_id = get_template_id(ARGV[0])
|
||||
|
||||
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
|
||||
|
||||
result = template.update(ARGV[1],ARGV[2])
|
||||
if is_successful?(result)
|
||||
puts "Modified template" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "rmattr"
|
||||
check_parameters("rmattr", 2)
|
||||
template_id = get_template_id(ARGV[0])
|
||||
|
||||
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
|
||||
|
||||
result = template.remove_attr(ARGV[1])
|
||||
if is_successful?(result)
|
||||
puts "Removed template attribute" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "publish"
|
||||
check_parameters("publish", 1)
|
||||
template_id = get_template_id(ARGV[0])
|
||||
|
||||
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
|
||||
|
||||
result = template.publish
|
||||
if is_successful?(result)
|
||||
puts "Template published" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "unpublish"
|
||||
check_parameters("unpublish", 1)
|
||||
template_id = get_template_id(ARGV[0])
|
||||
|
||||
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
|
||||
|
||||
result = template.unpublish
|
||||
if is_successful?(result)
|
||||
puts "Template unpublished" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "list"
|
||||
ops.merge!(get_user_flags)
|
||||
if !ops[:xml]
|
||||
templatelist = TemplateShow.new(get_one_client, ops[:filter_user].to_i)
|
||||
ops[:columns] = ops[:list] if ops[:list]
|
||||
result = templatelist.list_short(ops)
|
||||
else
|
||||
templatepool = OpenNebula::TemplatePool.new(get_one_client,
|
||||
ops[:filter_user].to_i)
|
||||
templatepool.info
|
||||
puts templatepool.to_xml
|
||||
end
|
||||
|
||||
when "top"
|
||||
ops.merge!(get_user_flags)
|
||||
templatelist = TemplateShow.new(get_one_client, ops[:filter_user].to_i)
|
||||
ops[:columns] = ops[:list] if ops[:list]
|
||||
result = templatelist.top(ops)
|
||||
|
||||
when "show"
|
||||
check_parameters("get_info", 1)
|
||||
args = expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
template_id = get_template_id(param)
|
||||
|
||||
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
|
||||
result = template.info
|
||||
|
||||
if is_successful?(result)
|
||||
if !ops[:xml]
|
||||
str="%-15s: %-20s"
|
||||
str_h1="%-80s"
|
||||
|
||||
print_header(str_h1, "TEMPLATE #{template[:id]} INFORMATION", true)
|
||||
|
||||
puts str % ["ID", template.id.to_s]
|
||||
puts str % ["NAME", template.name]
|
||||
|
||||
value = template['REGTIME'].to_i
|
||||
if value==0
|
||||
value='-'
|
||||
else
|
||||
value=Time.at(value).strftime("%m/%d %H:%M:%S")
|
||||
end
|
||||
puts str % ["REGISTER TIME", value]
|
||||
if template['PUBLIC'].to_i == 1
|
||||
public_str = "Yes"
|
||||
else
|
||||
public_str = "No"
|
||||
end
|
||||
puts str % ["PUBLIC", public_str]
|
||||
|
||||
puts
|
||||
|
||||
print_header(str_h1,"TEMPLATE CONTENTS",false)
|
||||
|
||||
puts template.template_str
|
||||
else
|
||||
puts template.to_xml
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
when "delete"
|
||||
check_parameters("delete", 1)
|
||||
args = expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
template_id = get_template_id(param)
|
||||
template = OpenNebula::Template.new(
|
||||
OpenNebula::Template.build_xml(template_id),
|
||||
get_one_client)
|
||||
|
||||
result = template.delete
|
||||
if is_successful?(result)
|
||||
puts "Template correctly deleted" if ops[:verbose]
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
onetemplate_opts.print_help
|
||||
exit -1
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(result)
|
||||
puts "Error: " + result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
|
@ -318,9 +318,15 @@ machine with the functionality present in onevm.
|
||||
Commands:
|
||||
|
||||
* create (Submits a new virtual machine, adding it to the ONE VM pool)
|
||||
onevm create <template>
|
||||
onevm create [OPTION] {<template-file-path>, <template-id>, <template-name>}
|
||||
|
||||
template is a file name where the VM description is located
|
||||
<template-file-path> is a file name where the VM description is located.
|
||||
<template-id> is the numeric ID of a registered template (using onetemplate)
|
||||
<template-name> is the name of a registered template (using onetemplate)
|
||||
|
||||
OPTION: -n STRING, --name=STRING
|
||||
Replaces the NAME attribute if the VM is being created from a registered
|
||||
Template
|
||||
|
||||
* deploy (Starts an existing VM in an specific host)
|
||||
onevm deploy <vm_id> <host_id>
|
||||
@ -462,6 +468,10 @@ EOT
|
||||
"Image type") do |o|
|
||||
options[:type]=o
|
||||
end
|
||||
opts.on_tail("-n vm_name", "--name vm_name", String,
|
||||
"Set VM name") do |o|
|
||||
options[:vm_name] = o
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -502,12 +512,32 @@ when "submit", "create"
|
||||
check_parameters("create", 1)
|
||||
vm=OpenNebula::VirtualMachine.new(
|
||||
OpenNebula::VirtualMachine.build_xml, get_one_client)
|
||||
begin
|
||||
template=File.read(ARGV[0])
|
||||
result=vm.allocate(template)
|
||||
rescue
|
||||
result=OpenNebula::Error.new("Can not read template: #{ARGV[0]}")
|
||||
|
||||
template = ""
|
||||
success = false
|
||||
|
||||
if( File.file?(ARGV[0]) )
|
||||
# argument is a file path
|
||||
begin
|
||||
template = File.read(ARGV[0])
|
||||
success = true
|
||||
rescue
|
||||
result = OpenNebula::Error.new("Can not read template: #{ARGV[0]}")
|
||||
end
|
||||
else
|
||||
# argument could be a template ID or a template name
|
||||
template_id = get_template_id(ARGV[0])
|
||||
|
||||
template = "TEMPLATE_ID = #{template_id}"
|
||||
template << "\nNAME = #{ops[:vm_name]}" if ops[:vm_name]
|
||||
|
||||
success = true
|
||||
end
|
||||
|
||||
if( success )
|
||||
result = vm.allocate(template)
|
||||
end
|
||||
|
||||
if is_successful?(result)
|
||||
puts "ID: " + vm.id.to_s if ops[:verbose]
|
||||
exit 0
|
||||
@ -785,56 +815,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>
|
||||
|
@ -30,7 +30,7 @@ class ImageOCCI < Image
|
||||
<DESCRIPTION><%= self['TEMPLATE/DESCRIPTION'] %></DESCRIPTION>
|
||||
<% end %>
|
||||
<% if size != nil %>
|
||||
<SIZE><%= size %></SIZE>
|
||||
<SIZE><%= size.to_i / 1024 %></SIZE>
|
||||
<% end %>
|
||||
<% if fstype != nil %>
|
||||
<FSTYPE><%= fstype %></FSTYPE>
|
||||
@ -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
|
||||
|
||||
|
@ -26,7 +26,6 @@ env.Prepend(LIBS=[
|
||||
'nebula_common',
|
||||
'nebula_sql',
|
||||
|
||||
|
||||
### TODO: delete not needed
|
||||
'nebula_core_test',
|
||||
'nebula_host',
|
||||
@ -40,6 +39,7 @@ env.Prepend(LIBS=[
|
||||
'nebula_mad',
|
||||
'nebula_template',
|
||||
'nebula_vm',
|
||||
'nebula_vmtemplate',
|
||||
'nebula_vnm',
|
||||
'nebula_image',
|
||||
'nebula_pool',
|
||||
|
@ -125,7 +125,7 @@ void HookManagerDriver::protocol(
|
||||
|
||||
is.clear();
|
||||
getline(is,info);
|
||||
NebulaLog::log("HKM",Log::INFO, info.c_str());
|
||||
NebulaLog::log("HKM", log_type(result[0]), info.c_str());
|
||||
}
|
||||
|
||||
return;
|
||||
@ -156,19 +156,26 @@ void HookManagerDriver::protocol(
|
||||
|
||||
if ( is.good() )
|
||||
{
|
||||
is >> hook_name >> ws;
|
||||
getline(is,hook_name);
|
||||
}
|
||||
|
||||
getline (is,info);
|
||||
|
||||
if (result == "SUCCESS")
|
||||
{
|
||||
oss << "Hook " << hook_name << " successfully executed. " << info;
|
||||
oss << "Success executing Hook: " << hook_name << ". " << info;
|
||||
vm->log("HKM",Log::INFO,oss);
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "Error executing Hook: " << hook_name << ". " << info;
|
||||
|
||||
if ( !info.empty() && info[0] != '-' )
|
||||
{
|
||||
vm->set_template_error_message(oss.str());
|
||||
vmpool->update(vm);
|
||||
}
|
||||
|
||||
vm->log("HKM",Log::ERROR,oss);
|
||||
}
|
||||
}
|
||||
@ -177,7 +184,7 @@ void HookManagerDriver::protocol(
|
||||
string info;
|
||||
|
||||
getline(is,info);
|
||||
vm->log("HKM",Log::INFO,info.c_str());
|
||||
vm->log("HKM",log_type(result[0]),info.c_str());
|
||||
}
|
||||
|
||||
vm->unlock();
|
||||
|
@ -28,14 +28,11 @@ end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
|
||||
require 'pp'
|
||||
require 'OpenNebulaDriver'
|
||||
require 'CommandManager'
|
||||
|
||||
|
||||
class HookManagerDriver < OpenNebulaDriver
|
||||
def initialize(num)
|
||||
super(num, true)
|
||||
super(num, true, 0)
|
||||
|
||||
register_action(:EXECUTE, method("action_execute"))
|
||||
end
|
||||
@ -51,13 +48,14 @@ class HookManagerDriver < OpenNebulaDriver
|
||||
end
|
||||
|
||||
if cmd.code==0
|
||||
send_message("EXECUTE", RESULT[:success], number, hook_name)
|
||||
message = "#{hook_name}: #{cmd.stdout}"
|
||||
send_message("EXECUTE", RESULT[:success], number, message)
|
||||
else
|
||||
send_message("EXECUTE", RESULT[:failure], number, hook_name)
|
||||
message = "#{hook_name}: #{cmd.get_error_message}"
|
||||
send_message("EXECUTE", RESULT[:failure], number, message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hm=HookManagerDriver.new(15)
|
||||
hm.start_driver
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -386,7 +386,7 @@ public:
|
||||
void scale_test()
|
||||
{
|
||||
time_t the_time, the_time2;
|
||||
int oid,i,j,rc;
|
||||
int oid,i,j;
|
||||
|
||||
ostringstream oss,ossdump;
|
||||
string err;
|
||||
@ -419,7 +419,7 @@ public:
|
||||
|
||||
the_time = time(0);
|
||||
|
||||
rc = hp->dump(ossdump, "");
|
||||
hp->dump(ossdump, "");
|
||||
|
||||
cout <<"\t"<<i<<"\t"<<the_time2<<"\t"<<time(0)-the_time<< endl;
|
||||
|
||||
|
@ -31,6 +31,7 @@ env.Prepend(LIBS=[
|
||||
'nebula_mad',
|
||||
'nebula_template',
|
||||
'nebula_vm',
|
||||
'nebula_vmtemplate',
|
||||
'nebula_vnm',
|
||||
'nebula_image',
|
||||
'nebula_pool',
|
||||
|
@ -110,7 +110,7 @@ void InformationManagerDriver::protocol(
|
||||
|
||||
hinfo += "\n";
|
||||
|
||||
oss << "Host " << id << " successfully monitored."; //, info: "<< hinfo;
|
||||
oss << "Host " << id << " successfully monitored.";
|
||||
NebulaLog::log("InM",Log::DEBUG,oss);
|
||||
|
||||
rc = host->update_info(hinfo);
|
||||
@ -136,22 +136,23 @@ void InformationManagerDriver::protocol(
|
||||
string info;
|
||||
|
||||
getline(is,info);
|
||||
NebulaLog::log("InM",Log::INFO,info.c_str());
|
||||
NebulaLog::log("InM",log_type(result[0]),info.c_str());
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error_driver_info:
|
||||
ess << "Error monitoring host " << id << " : " << is.str();
|
||||
NebulaLog::log("InM", Log::ERROR, ess);
|
||||
|
||||
goto error_common_info;
|
||||
|
||||
error_parse_info:
|
||||
ess << "Error parsing host information: " << hinfo;
|
||||
NebulaLog::log("InM",Log::ERROR,ess);
|
||||
goto error_common_info;
|
||||
|
||||
error_common_info:
|
||||
NebulaLog::log("InM",Log::ERROR,ess);
|
||||
|
||||
host->set_template_error_message(ess.str());
|
||||
|
||||
host->touch(false);
|
||||
|
||||
|
@ -51,7 +51,7 @@ class DummyInformationManager < OpenNebulaDriver
|
||||
#---------------------------------------------------------------------------
|
||||
def action_monitor(number, host, not_used)
|
||||
results = "HYPERVISOR=dummy,"
|
||||
results << "NAME=#{host},"
|
||||
results << "HOSTNAME=#{host},"
|
||||
|
||||
results << "TOTALCPU=800,"
|
||||
results << "CPUSPEED=2.2GHz,"
|
||||
|
@ -31,18 +31,18 @@ end
|
||||
$: << RUBY_LIB_LOCATION
|
||||
|
||||
require 'OpenNebulaDriver'
|
||||
require 'CommandManager'
|
||||
require 'getoptlong'
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# The Local Information Manager Driver
|
||||
#-------------------------------------------------------------------------------
|
||||
class InformationManager < OpenNebulaDriver
|
||||
class InformationManagerDriverSH < OpenNebulaDriver
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Init the driver
|
||||
#---------------------------------------------------------------------------
|
||||
def initialize(hypervisor, num)
|
||||
super(num, true)
|
||||
super(num, true, 0)
|
||||
|
||||
@config = read_configuration
|
||||
@hypervisor = hypervisor
|
||||
@ -57,29 +57,40 @@ class InformationManager < OpenNebulaDriver
|
||||
# Execute the run_probes in the remote host
|
||||
#---------------------------------------------------------------------------
|
||||
def action_monitor(number, host, unused)
|
||||
log_lambda=lambda do |message|
|
||||
log(number, message)
|
||||
end
|
||||
|
||||
cmd_string = "#{@cmd_path}/run_probes #{@hypervisor} #{host}"
|
||||
monitor_exe = LocalCommand.run(cmd_string, log_lambda)
|
||||
|
||||
if monitor_exe.code == 0
|
||||
send_message("MONITOR", RESULT[:success], number, monitor_exe.stdout)
|
||||
else
|
||||
send_message("MONITOR", RESULT[:failure], number,
|
||||
"Could not monitor host #{host}.")
|
||||
end
|
||||
local_action(cmd_string, number, "MONITOR")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Information Manager main program
|
||||
# IM Driver main program
|
||||
#-------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
hypervisor = ARGV[0]
|
||||
im = InformationManager.new(hypervisor, 15)
|
||||
opts = GetoptLong.new(
|
||||
[ '--threads', '-t', GetoptLong::OPTIONAL_ARGUMENT ]
|
||||
)
|
||||
|
||||
hypervisor = ''
|
||||
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
|
||||
hypervisor = ARGV.shift
|
||||
end
|
||||
|
||||
im = InformationManagerDriverSH.new(hypervisor,threads)
|
||||
im.start_driver
|
||||
|
@ -31,25 +31,23 @@ end
|
||||
$: << RUBY_LIB_LOCATION
|
||||
|
||||
require 'OpenNebulaDriver'
|
||||
require 'CommandManager'
|
||||
require 'getoptlong'
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# The SSH Information Manager Driver
|
||||
#-------------------------------------------------------------------------------
|
||||
class InformationManager < OpenNebulaDriver
|
||||
class InformationManagerDriverSSH < OpenNebulaDriver
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Init the driver
|
||||
#---------------------------------------------------------------------------
|
||||
def initialize(hypervisor, threads, retries)
|
||||
super(threads, true)
|
||||
super(threads, true, retries)
|
||||
|
||||
@config = read_configuration
|
||||
|
||||
@hypervisor = hypervisor
|
||||
@remote_dir = @config['SCRIPTS_REMOTE_DIR']
|
||||
@retries = retries
|
||||
|
||||
# register actions
|
||||
register_action(:MONITOR, method("action_monitor"))
|
||||
@ -59,34 +57,19 @@ class InformationManager < OpenNebulaDriver
|
||||
# Execute the run_probes in the remote host
|
||||
#---------------------------------------------------------------------------
|
||||
def action_monitor(number, host, do_update)
|
||||
log_lambda=lambda do |message|
|
||||
log(number, message)
|
||||
end
|
||||
|
||||
if do_update == "1"
|
||||
# Use SCP to sync:
|
||||
sync_cmd = "scp -r #{REMOTES_LOCATION}/. #{host}:#{@remote_dir}"
|
||||
|
||||
# Use rsync to sync:
|
||||
# sync_cmd = "rsync -Laz #{REMOTES_LOCATION} #{host}:#{@remote_dir}"
|
||||
LocalCommand.run(sync_cmd, log_lambda)
|
||||
LocalCommand.run(sync_cmd, log_method(number))
|
||||
end
|
||||
|
||||
cmd_string = "#{@remote_dir}/im/run_probes #{@hypervisor} #{host}"
|
||||
|
||||
cmd = RemotesCommand.run(cmd_string,
|
||||
host,
|
||||
@remote_dir,
|
||||
log_lambda,
|
||||
@retries)
|
||||
if cmd.code == 0
|
||||
send_message("MONITOR", RESULT[:success], number, cmd.stdout)
|
||||
else
|
||||
send_message("MONITOR", RESULT[:failure], number,
|
||||
"Could not monitor host #{host}.")
|
||||
end
|
||||
remotes_action(cmd_string, number, host, "MONITOR", @remote_dir)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -121,5 +104,5 @@ if ARGV.length >= 1
|
||||
hypervisor = ARGV.shift
|
||||
end
|
||||
|
||||
im = InformationManager.new(hypervisor, threads, retries)
|
||||
im = InformationManagerDriverSSH.new(hypervisor, threads, retries)
|
||||
im.start_driver
|
||||
|
@ -16,6 +16,8 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
source $(dirname $0)/../scripts_common.sh
|
||||
|
||||
export LANG=C
|
||||
|
||||
HYPERVISOR_DIR=$1.d
|
||||
@ -32,7 +34,7 @@ function run_dir {
|
||||
./$i $ARGUMENTS
|
||||
EXIT_CODE=$?
|
||||
if [ "x$EXIT_CODE" != "x0" ]; then
|
||||
echo "Error executing $i" 1>&2
|
||||
error_message "Error executing $i"
|
||||
exit $EXIT_CODE
|
||||
fi
|
||||
fi
|
||||
|
@ -41,25 +41,25 @@ Image::Image(int _uid,
|
||||
user_name(_user_name),
|
||||
type(OS),
|
||||
regtime(time(0)),
|
||||
source(""),
|
||||
source("-"),
|
||||
state(INIT),
|
||||
running_vms(0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,6 +87,7 @@ int Image::insert(SqlDB *db, string& error_str)
|
||||
string public_attr;
|
||||
string persistent_attr;
|
||||
string dev_prefix;
|
||||
string source_attr;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Check default image attributes
|
||||
@ -116,7 +117,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 +127,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);
|
||||
|
||||
@ -148,49 +149,51 @@ 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("SOURCE", source);
|
||||
get_template_attribute("PATH", path_attr);
|
||||
get_template_attribute("SOURCE", source_attr);
|
||||
|
||||
// The template should contain PATH or SOURCE
|
||||
if ( source.empty() && path_attr.empty() )
|
||||
if ( source_attr.empty() && path_attr.empty() )
|
||||
{
|
||||
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() )
|
||||
else if ( !source_attr.empty() && !path_attr.empty() )
|
||||
{
|
||||
goto error_path_and_source;
|
||||
}
|
||||
|
||||
if (source.empty())
|
||||
else if ( !source_attr.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 = source_attr;
|
||||
}
|
||||
|
||||
state = DISABLED;
|
||||
state = LOCKED; //LOCKED till the ImageManager copies it to the Repository
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Insert the Image
|
||||
@ -214,7 +217,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 +228,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 +344,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 +391,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 +404,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,41 +431,22 @@ int Image::disk_attribute( VectorAttribute * disk,
|
||||
|
||||
get_template_attribute("DEV_PREFIX", prefix);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Acquire the image
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
if ( acquire_image() != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// NEW DISK ATTRIBUTES
|
||||
// BASE DISK ATTRIBUTES
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
map<string,string> new_disk;
|
||||
disk->replace("IMAGE", name);
|
||||
disk->replace("IMAGE_ID", iid.str());
|
||||
disk->replace("SOURCE", source);
|
||||
|
||||
new_disk.insert(make_pair("IMAGE", name));
|
||||
new_disk.insert(make_pair("IMAGE_ID", iid.str()));
|
||||
new_disk.insert(make_pair("SOURCE", source));
|
||||
|
||||
if (!bus.empty())
|
||||
if (bus.empty() && !template_bus.empty()) //BUS in Image, not in DISK
|
||||
{
|
||||
new_disk.insert(make_pair("BUS",bus));
|
||||
}
|
||||
else if (!template_bus.empty())
|
||||
{
|
||||
new_disk.insert(make_pair("BUS",template_bus));
|
||||
disk->replace("BUS",template_bus);
|
||||
}
|
||||
|
||||
if (!driver.empty())
|
||||
if (driver.empty() && !template_driver.empty())//DRIVER in Image,not in DISK
|
||||
{
|
||||
new_disk.insert(make_pair("DRIVER",driver));
|
||||
}
|
||||
else if (!template_driver.empty())
|
||||
{
|
||||
new_disk.insert(make_pair("DRIVER",template_driver));
|
||||
disk->replace("DRIVER",template_driver);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -531,28 +455,26 @@ int Image::disk_attribute( VectorAttribute * disk,
|
||||
|
||||
if ( persistent_img )
|
||||
{
|
||||
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
|
||||
disk->replace("CLONE","NO");
|
||||
disk->replace("SAVE","YES");
|
||||
}
|
||||
else
|
||||
{
|
||||
new_disk.insert(make_pair("CLONE","YES"));
|
||||
new_disk.insert(make_pair("SAVE","NO"));
|
||||
disk->replace("CLONE","YES");
|
||||
disk->replace("SAVE","NO");
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case OS:
|
||||
case DATABLOCK:
|
||||
new_disk.insert(make_pair("TYPE","DISK"));
|
||||
new_disk.insert(make_pair("READONLY","NO"));
|
||||
disk->replace("TYPE","DISK");
|
||||
disk->replace("READONLY","NO");
|
||||
break;
|
||||
|
||||
case CDROM:
|
||||
new_disk.insert(make_pair("TYPE","CDROM"));
|
||||
new_disk.insert(make_pair("READONLY","YES"));
|
||||
disk->replace("TYPE","CDROM");
|
||||
disk->replace("READONLY","YES");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -560,67 +482,37 @@ int Image::disk_attribute( VectorAttribute * disk,
|
||||
// TARGET attribute
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
if (!target.empty())
|
||||
if (target.empty()) //No TARGET in DISK attribute
|
||||
{
|
||||
new_disk.insert(make_pair("TARGET", target));
|
||||
}
|
||||
else if (!template_target.empty())
|
||||
{
|
||||
new_disk.insert(make_pair("TARGET", template_target));
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(type)
|
||||
if (!template_target.empty())
|
||||
{
|
||||
case OS:
|
||||
prefix += "a";
|
||||
break;
|
||||
|
||||
case CDROM:
|
||||
prefix += "c"; // b is for context
|
||||
break;
|
||||
|
||||
case DATABLOCK:
|
||||
prefix += static_cast<char>(('e'+ *index));
|
||||
*index = *index + 1;
|
||||
break;
|
||||
|
||||
disk->replace("TARGET", template_target);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case OS:
|
||||
prefix += "a";
|
||||
break;
|
||||
|
||||
new_disk.insert(make_pair("TARGET", prefix));
|
||||
case CDROM:
|
||||
prefix += "c"; // b is for context
|
||||
break;
|
||||
|
||||
case DATABLOCK:
|
||||
prefix += static_cast<char>(('e'+ *index));
|
||||
*index = *index + 1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
disk->replace("TARGET", prefix);
|
||||
}
|
||||
}
|
||||
|
||||
disk->replace(new_disk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
string Image::sha1_digest(const string& pass)
|
||||
{
|
||||
EVP_MD_CTX mdctx;
|
||||
unsigned char md_value[EVP_MAX_MD_SIZE];
|
||||
unsigned int md_len;
|
||||
ostringstream oss;
|
||||
|
||||
EVP_MD_CTX_init(&mdctx);
|
||||
EVP_DigestInit_ex(&mdctx, EVP_sha1(), NULL);
|
||||
|
||||
EVP_DigestUpdate(&mdctx, pass.c_str(), pass.length());
|
||||
|
||||
EVP_DigestFinal_ex(&mdctx,md_value,&md_len);
|
||||
EVP_MD_CTX_cleanup(&mdctx);
|
||||
|
||||
for(unsigned int i = 0; i<md_len; i++)
|
||||
{
|
||||
oss << setfill('0') << setw(2) << hex << nouppercase
|
||||
<< (unsigned short) md_value[i];
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
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);
|
||||
}
|
||||
}
|
||||
|
432
src/image/ImageManagerActions.cc
Normal file
432
src/image/ImageManagerActions.cc
Normal file
@ -0,0 +1,432 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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();
|
||||
|
||||
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(), 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);
|
||||
oss << "Copying " << path <<" to repository for image "<<img->get_oid();
|
||||
}
|
||||
|
||||
NebulaLog::log("ImM",Log::INFO,oss);
|
||||
|
||||
img->unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
306
src/image/ImageManagerDriver.cc
Normal file
306
src/image/ImageManagerDriver.cc
Normal file
@ -0,0 +1,306 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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
|
||||
{
|
||||
ostringstream os;
|
||||
|
||||
os << "CP " << oid << " " << source << 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& fs,
|
||||
const string& size_mb) const
|
||||
{
|
||||
ostringstream os;
|
||||
|
||||
os << "MKFS " << oid << " " << 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 source;
|
||||
|
||||
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_type(result[0]), 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" )
|
||||
{
|
||||
string source;
|
||||
|
||||
if ( is.good() )
|
||||
{
|
||||
is >> source >> ws;
|
||||
}
|
||||
|
||||
if ( is.fail() )
|
||||
{
|
||||
goto error_cp;
|
||||
}
|
||||
|
||||
image->set_source(source);
|
||||
image->set_state(Image::READY);
|
||||
|
||||
ipool->update(image);
|
||||
|
||||
NebulaLog::log("ImM", Log::INFO, "Image copied and ready to use.");
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_cp;
|
||||
}
|
||||
}
|
||||
else if ( action == "MV" )
|
||||
{
|
||||
if ( result == "SUCCESS" )
|
||||
{
|
||||
if (image->get_source() == "-")
|
||||
{
|
||||
string source;
|
||||
|
||||
if ( is.good() )
|
||||
{
|
||||
is >> source >> ws;
|
||||
}
|
||||
|
||||
if ( is.fail() )
|
||||
{
|
||||
goto error_mv;
|
||||
}
|
||||
|
||||
image->set_source(source);
|
||||
}
|
||||
|
||||
image->set_state(Image::READY);
|
||||
ipool->update(image);
|
||||
|
||||
NebulaLog::log("ImM", Log::INFO, "Image saved and ready to use.");
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_mv;
|
||||
}
|
||||
}
|
||||
else if ( action == "MKFS" )
|
||||
{
|
||||
if ( result == "SUCCESS" )
|
||||
{
|
||||
string source;
|
||||
|
||||
if ( is.good() )
|
||||
{
|
||||
is >> source >> ws;
|
||||
}
|
||||
|
||||
if ( is.fail() )
|
||||
{
|
||||
goto error_mkfs;
|
||||
}
|
||||
|
||||
image->set_source(source);
|
||||
image->set_state(Image::READY);
|
||||
|
||||
ipool->update(image);
|
||||
|
||||
NebulaLog::log("ImM", Log::INFO, "Image created and ready to use");
|
||||
}
|
||||
else
|
||||
{
|
||||
goto error_mkfs;
|
||||
}
|
||||
}
|
||||
else if ( action == "RM" )
|
||||
{
|
||||
int rc;
|
||||
|
||||
source = image->get_source();
|
||||
|
||||
rc = ipool->drop(image);
|
||||
|
||||
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
|
||||
{
|
||||
goto error_rm;
|
||||
}
|
||||
}
|
||||
else if (action == "LOG")
|
||||
{
|
||||
getline(is,info);
|
||||
NebulaLog::log("ImM", log_type(result[0]), info.c_str());
|
||||
}
|
||||
|
||||
image->unlock();
|
||||
|
||||
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";
|
||||
goto error_common;
|
||||
|
||||
error_rm:
|
||||
os.str("");
|
||||
os << "Error removing image from repository. Remove file " << source
|
||||
<< " to completely delete image.";
|
||||
|
||||
error_common:
|
||||
getline(is,info);
|
||||
|
||||
if (!info.empty() && (info[0] != '-'))
|
||||
{
|
||||
os << ": " << info;
|
||||
image->set_template_error_message(os.str());
|
||||
}
|
||||
|
||||
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,10 +20,10 @@
|
||||
|
||||
#include "ImagePool.h"
|
||||
#include "AuthManager.h"
|
||||
#include "Nebula.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
string ImagePool::_source_prefix;
|
||||
string ImagePool::_default_type;
|
||||
string ImagePool::_default_dev_prefix;
|
||||
|
||||
@ -31,7 +31,6 @@ string ImagePool::_default_dev_prefix;
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
ImagePool::ImagePool(SqlDB * db,
|
||||
const string& __source_prefix,
|
||||
const string& __default_type,
|
||||
const string& __default_dev_prefix):
|
||||
PoolSQL(db,Image::table)
|
||||
@ -39,7 +38,6 @@ ImagePool::ImagePool(SqlDB * db,
|
||||
ostringstream sql;
|
||||
|
||||
// Init static defaults
|
||||
_source_prefix = __source_prefix;
|
||||
_default_type = __default_type;
|
||||
_default_dev_prefix = __default_dev_prefix;
|
||||
|
||||
@ -68,9 +66,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 +91,6 @@ int ImagePool::allocate (
|
||||
|
||||
return *oid;
|
||||
|
||||
|
||||
error_name:
|
||||
oss << "NAME cannot be empty.";
|
||||
goto error_common;
|
||||
@ -128,6 +122,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 +141,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 +152,7 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
|
||||
}
|
||||
else
|
||||
{
|
||||
img = get(source,uid,true);
|
||||
img = imagem->acquire_image(source,uid);
|
||||
|
||||
if (img == 0)
|
||||
{
|
||||
@ -167,7 +164,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 +184,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><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><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><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><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><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><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><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><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";
|
||||
|
||||
@ -70,12 +70,10 @@ class ImagePoolFriend : public ImagePool
|
||||
{
|
||||
public:
|
||||
ImagePoolFriend(SqlDB * db,
|
||||
const string& _source_prefix,
|
||||
const string& _default_type,
|
||||
const string& _default_dev_prefix):
|
||||
|
||||
ImagePool( db,
|
||||
_source_prefix,
|
||||
_default_type,
|
||||
_default_dev_prefix){};
|
||||
|
||||
@ -128,7 +126,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 );
|
||||
|
||||
@ -144,7 +145,7 @@ protected:
|
||||
PoolSQL* create_pool(SqlDB* db)
|
||||
{
|
||||
ImagePoolFriend * imp =
|
||||
new ImagePoolFriend(db, "source_prefix", "OS", "hd");
|
||||
new ImagePoolFriend(db, "OS", "hd");
|
||||
return imp;
|
||||
};
|
||||
|
||||
@ -198,7 +199,7 @@ public:
|
||||
|
||||
// Create a new pool, using the same DB. This new pool should read the
|
||||
// allocated images.
|
||||
imp = new ImagePool(db, "source_prefix", "OS", "hd");
|
||||
imp = new ImagePool(db,"OS", "hd");
|
||||
|
||||
img = imp->get(names[0], uids[0], false);
|
||||
CPPUNIT_ASSERT( img != 0 );
|
||||
@ -241,7 +242,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 +254,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 +272,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 +399,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 +452,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 +467,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 +475,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 +489,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 +497,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 +511,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 +520,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 +553,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 );
|
||||
|
||||
@ -561,11 +563,10 @@ public:
|
||||
|
||||
value = "";
|
||||
value = disk->vector_value("SOURCE");
|
||||
CPPUNIT_ASSERT( value ==
|
||||
"source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198" );
|
||||
CPPUNIT_ASSERT( value == "-" );
|
||||
|
||||
// clean up
|
||||
img->release_image();
|
||||
//img->release_image();
|
||||
delete disk;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
@ -573,7 +574,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 );
|
||||
|
||||
@ -582,8 +583,7 @@ public:
|
||||
|
||||
value = "";
|
||||
value = disk->vector_value("SOURCE");
|
||||
CPPUNIT_ASSERT( value ==
|
||||
"source_prefix/9ab4a4e021ee2883f57e3aeecc9e2aed7c3fa198" );
|
||||
CPPUNIT_ASSERT( value == "-" );
|
||||
|
||||
// clean up
|
||||
delete disk;
|
||||
@ -606,10 +606,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 +623,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 +677,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 +771,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,15 +870,15 @@ public:
|
||||
string result = oss.str();
|
||||
|
||||
result.replace(157, 10, replacement);
|
||||
result.replace(1147, 10, replacement);
|
||||
result.replace(1677, 10, replacement);
|
||||
result.replace(1076, 10, replacement);
|
||||
result.replace(1535, 10, replacement);
|
||||
|
||||
/*
|
||||
if( result != xml_dump )
|
||||
{
|
||||
cout << endl << result << endl << xml_dump << endl;
|
||||
}
|
||||
//*/
|
||||
*/
|
||||
|
||||
CPPUNIT_ASSERT( result == xml_dump );
|
||||
}
|
||||
@ -899,14 +905,14 @@ public:
|
||||
|
||||
string result = oss.str();
|
||||
result.replace(157, 10, replacement);
|
||||
result.replace(1147, 10, replacement);
|
||||
result.replace(1076, 10, replacement);
|
||||
|
||||
|
||||
/*
|
||||
if( result != xml_dump_where )
|
||||
{
|
||||
cout << endl << result << endl << xml_dump_where << endl;
|
||||
}
|
||||
//*/
|
||||
|
||||
|
||||
CPPUNIT_ASSERT( 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 $*
|
116
src/image_mad/one_image.rb
Executable file
116
src/image_mad/one_image.rb
Executable file
@ -0,0 +1,116 @@
|
||||
#!/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 '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,0)
|
||||
|
||||
@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
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Image Manager Protocol Actions (generic implementation
|
||||
# -------------------------------------------------------------------------
|
||||
def mv(id, src, dst)
|
||||
local_action("#{@actions_path}/mv #{src} #{dst} #{id}",id,ACTION[:mv])
|
||||
end
|
||||
|
||||
def cp(id, src)
|
||||
local_action("#{@actions_path}/cp #{src} #{id}",id,ACTION[:cp])
|
||||
end
|
||||
|
||||
def rm(id, dst)
|
||||
local_action("#{@actions_path}/rm #{dst} #{id}",id,ACTION[:rm])
|
||||
end
|
||||
|
||||
def mkfs(id, fs, size)
|
||||
local_action("#{@actions_path}/mkfs #{fs} #{size} #{id}",id,ACTION[: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
|
57
src/image_mad/remotes/fs/cp
Executable file
57
src/image_mad/remotes/fs/cp
Executable file
@ -0,0 +1,57 @@
|
||||
#!/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 & conf ------------
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
LIB_LOCATION=/usr/lib/one
|
||||
else
|
||||
LIB_LOCATION=$ONE_LOCATION/lib
|
||||
fi
|
||||
|
||||
. $LIB_LOCATION/sh/scripts_common.sh
|
||||
source $(dirname $0)/fsrc
|
||||
|
||||
SRC=$1
|
||||
ID=$2
|
||||
DST=`generate_image_path`
|
||||
|
||||
# ------------ Copy the image to the repository -------------
|
||||
|
||||
case $SRC in
|
||||
http://*)
|
||||
log "Downloading $SRC to the image repository"
|
||||
exec_and_log "$WGET -O $DST $SRC" \
|
||||
"Error downloading $SRC"
|
||||
;;
|
||||
|
||||
*)
|
||||
log "Copying local image $SRC to the image repository"
|
||||
exec_and_log "cp -f $SRC $DST" \
|
||||
"Error copying $SRC to $DST"
|
||||
;;
|
||||
esac
|
||||
|
||||
exec_and_log "chmod 0660 $DST"
|
||||
|
||||
echo "$DST"
|
37
src/image_mad/remotes/fs/fsrc
Normal file
37
src/image_mad/remotes/fs/fsrc
Normal file
@ -0,0 +1,37 @@
|
||||
#!/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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Configuration File for File-System based Image Repositories
|
||||
#------------------------------------------------------------------------------
|
||||
export IMAGE_REPOSITORY_PATH=$ONE_LOCATION/var/images
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function used to generate Image names, you should not need to override this
|
||||
#------------------------------------------------------------------------------
|
||||
function generate_image_path {
|
||||
|
||||
CANONICAL_STR="`$DATE +%s`:$ID"
|
||||
|
||||
CANONICAL_MD5=$($MD5SUM - << EOF
|
||||
$CANONICAL_STR
|
||||
EOF
|
||||
)
|
||||
|
||||
echo "$IMAGE_REPOSITORY_PATH/`echo $CANONICAL_MD5 | cut -d ' ' -f1`"
|
||||
}
|
49
src/image_mad/remotes/fs/mkfs
Executable file
49
src/image_mad/remotes/fs/mkfs
Executable file
@ -0,0 +1,49 @@
|
||||
#!/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
|
||||
LIB_LOCATION=/usr/lib/one
|
||||
else
|
||||
LIB_LOCATION=$ONE_LOCATION/lib
|
||||
fi
|
||||
|
||||
. $LIB_LOCATION/sh/scripts_common.sh
|
||||
source $(dirname $0)/fsrc
|
||||
|
||||
# ------------ Create the image to the repository ------------
|
||||
|
||||
FSTYPE=$1
|
||||
SIZE=$2
|
||||
ID=$3
|
||||
|
||||
DST=`generate_image_path`
|
||||
|
||||
exec_and_log "$DD if=/dev/zero of=$DST bs=1 count=1 seek=${SIZE}M" \
|
||||
"Could not create image $DST"
|
||||
exec_and_log "$MKFS -t $FSTYPE -F $DST" \
|
||||
"Unable to create filesystem $FSTYPE in $DST"
|
||||
exec_and_log "chmod 0660 $DST"
|
||||
|
||||
echo "$DST"
|
64
src/image_mad/remotes/fs/mv
Executable file
64
src/image_mad/remotes/fs/mv
Executable file
@ -0,0 +1,64 @@
|
||||
#!/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
|
||||
LIB_LOCATION=/usr/lib/one
|
||||
else
|
||||
LIB_LOCATION=$ONE_LOCATION/lib
|
||||
fi
|
||||
|
||||
. $LIB_LOCATION/sh/scripts_common.sh
|
||||
source $(dirname $0)/fsrc
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
ID=$3
|
||||
|
||||
# ------------ Generate a filename for the image ------------
|
||||
|
||||
if [ $DST -eq "-" ] ; then
|
||||
DST=`generate_image_path`
|
||||
fi
|
||||
|
||||
# ------------ Move the image to the repository ------------
|
||||
|
||||
|
||||
case $SRC in
|
||||
http://*)
|
||||
log "Downloading $SRC to the image repository"
|
||||
exec_and_log "$WGET -O $DST $SRC" \
|
||||
"Error downloading $SRC"
|
||||
;;
|
||||
|
||||
*)
|
||||
log "Moving local image $SRC to the image repository"
|
||||
exec_and_log "mv -f $SRC $DST" \
|
||||
"Could not move $SRC to $DST"
|
||||
;;
|
||||
esac
|
||||
|
||||
exec_and_log "chmod 0660 $DST"
|
||||
|
||||
echo "$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
|
||||
LIB_LOCATION=/usr/lib/one
|
||||
else
|
||||
LIB_LOCATION=$ONE_LOCATION/lib
|
||||
fi
|
||||
|
||||
. $LIB_LOCATION/sh/scripts_common.sh
|
||||
source $(dirname $0)/fsrc
|
||||
|
||||
# ------------ Remove the image to the repository ------------
|
||||
|
||||
SRC=$1
|
||||
|
||||
if [ -e $SRC ] ; then
|
||||
log "Removing $SRC from the image repository"
|
||||
exec_and_log "rm $SRC" \
|
||||
"Error deleting $SRC"
|
||||
fi
|
@ -30,6 +30,7 @@ env.Prepend(LIBS=[
|
||||
'nebula_mad',
|
||||
'nebula_template',
|
||||
'nebula_vm',
|
||||
'nebula_vmtemplate',
|
||||
'nebula_vnm',
|
||||
'nebula_image',
|
||||
'nebula_pool',
|
||||
|
@ -39,7 +39,6 @@ Mad::~Mad()
|
||||
char buf[]="FINALIZE\n";
|
||||
int status;
|
||||
pid_t rp;
|
||||
size_t retval;
|
||||
|
||||
if ( pid==-1)
|
||||
{
|
||||
@ -47,7 +46,7 @@ Mad::~Mad()
|
||||
}
|
||||
|
||||
// Finish the driver
|
||||
retval = ::write(nebula_mad_pipe, buf, strlen(buf));
|
||||
::write(nebula_mad_pipe, buf, strlen(buf));
|
||||
|
||||
close(mad_nebula_pipe);
|
||||
close(nebula_mad_pipe);
|
||||
@ -68,7 +67,6 @@ int Mad::start()
|
||||
{
|
||||
int ne_mad_pipe[2];
|
||||
int mad_ne_pipe[2];
|
||||
size_t retval;
|
||||
|
||||
map<string,string>::iterator it;
|
||||
|
||||
@ -191,7 +189,7 @@ int Mad::start()
|
||||
fcntl(nebula_mad_pipe, F_SETFD, FD_CLOEXEC);
|
||||
fcntl(mad_nebula_pipe, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
retval = ::write(nebula_mad_pipe, buf, strlen(buf));
|
||||
::write(nebula_mad_pipe, buf, strlen(buf));
|
||||
|
||||
do
|
||||
{
|
||||
@ -291,11 +289,9 @@ int Mad::reload()
|
||||
int status;
|
||||
int rc;
|
||||
pid_t rp;
|
||||
size_t retval;
|
||||
|
||||
// Finish the driver
|
||||
|
||||
retval = ::write(nebula_mad_pipe, buf, strlen(buf));
|
||||
::write(nebula_mad_pipe, buf, strlen(buf));
|
||||
|
||||
close(nebula_mad_pipe);
|
||||
close(mad_nebula_pipe);
|
||||
|
@ -147,7 +147,6 @@ int MadManager::add(Mad *mad)
|
||||
{
|
||||
char buf = 'A';
|
||||
int rc;
|
||||
size_t retval;
|
||||
|
||||
if ( mad == 0 )
|
||||
{
|
||||
@ -167,7 +166,7 @@ int MadManager::add(Mad *mad)
|
||||
|
||||
mads.push_back(mad);
|
||||
|
||||
retval = write(pipe_w, &buf, sizeof(char));
|
||||
write(pipe_w, &buf, sizeof(char));
|
||||
|
||||
unlock();
|
||||
|
||||
@ -216,7 +215,6 @@ void MadManager::listener()
|
||||
int greater;
|
||||
unsigned int i,j;
|
||||
int rc,mrc;
|
||||
size_t retval;
|
||||
|
||||
char c;
|
||||
|
||||
@ -264,7 +262,7 @@ void MadManager::listener()
|
||||
{
|
||||
if ( fd == pipe_r ) // Driver added, update the fd vector
|
||||
{
|
||||
retval = read(fd, (void *) &c, sizeof(char));
|
||||
read(fd, (void *) &c, sizeof(char));
|
||||
|
||||
lock();
|
||||
|
||||
|
@ -27,6 +27,20 @@ require 'stringio'
|
||||
# * +stdout+: string of the standard output. Read-only
|
||||
# * +stderr+: string of the standard error. Read-only
|
||||
# * +command+: command to execute. Read-only
|
||||
#
|
||||
# The protocol for scripts to log is as follows:
|
||||
#
|
||||
# * Log messages will be sent to STDOUT
|
||||
# * The script will return 0 if it succeded or any other value
|
||||
# if there was a failure
|
||||
# * In case of failure the cause of the error will be written to STDERR
|
||||
# wrapped by start and end marks as follows:
|
||||
#
|
||||
# ERROR MESSAGE --8<------
|
||||
# error message for the failure
|
||||
# ERROR MESSAGE ------>8--
|
||||
|
||||
|
||||
class GenericCommand
|
||||
attr_reader :code, :stdout, :stderr, :command
|
||||
|
||||
@ -72,13 +86,20 @@ class GenericCommand
|
||||
|
||||
if @code!=0
|
||||
log("Command execution fail: #{command}")
|
||||
log("STDERR follows.")
|
||||
log(@stderr)
|
||||
end
|
||||
|
||||
log(@stderr)
|
||||
|
||||
return @code
|
||||
end
|
||||
|
||||
# Parses error message from +stderr+ output
|
||||
def get_error_message
|
||||
tmp=@stderr.scan(/^ERROR MESSAGE --8<------\n(.*?)ERROR MESSAGE ------>8--$/m)
|
||||
return "-" if !tmp[0]
|
||||
tmp[0].join(' ').strip
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Gets exit code from STDERR
|
||||
@ -158,14 +179,14 @@ class RemotesCommand < SSHCommand
|
||||
|
||||
cmd = self.new(cmd_string, host, logger, stdin)
|
||||
cmd.run
|
||||
|
||||
|
||||
if cmd.code == MAGIC_RC
|
||||
cmd.update_remotes(host, remote_dir, logger)
|
||||
|
||||
@command = command
|
||||
cmd.run
|
||||
end
|
||||
|
||||
|
||||
while cmd.code != 0 and retries != 0
|
||||
sleep 1
|
||||
cmd.run
|
||||
|
@ -12,10 +12,12 @@
|
||||
# See the License for the specific language governing permissions and */
|
||||
# limitations under the License. */
|
||||
# -------------------------------------------------------------------------- */
|
||||
|
||||
require "ActionManager"
|
||||
require "CommandManager"
|
||||
|
||||
# Author:: dsa-research.org
|
||||
# Copyright:: (c) 2009 Universidad Computense de Madrid
|
||||
# Copyright:: (c) OpenNebula Project Leads (OpenNebula.org)
|
||||
# License:: Apache License
|
||||
|
||||
# This class provides basic messaging and logging functionality
|
||||
@ -34,14 +36,18 @@ class OpenNebulaDriver < ActionManager
|
||||
:failure => "FAILURE"
|
||||
}
|
||||
|
||||
def initialize(concurrency=10, threaded=true)
|
||||
def initialize(concurrency=10, threaded=true, retries=0)
|
||||
super(concurrency,threaded)
|
||||
|
||||
register_action(:INIT, method("init"))
|
||||
|
||||
@retries = retries
|
||||
@send_mutex=Mutex.new
|
||||
|
||||
register_action(:INIT, method("init"))
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Sends a message to the OpenNebula core through stdout
|
||||
# -------------------------------------------------------------------------
|
||||
def send_message(action="-", result=RESULT[:failure], id="-", info="-")
|
||||
@send_mutex.synchronize {
|
||||
STDOUT.puts "#{action} #{result} #{id} #{info}"
|
||||
@ -49,25 +55,103 @@ class OpenNebulaDriver < ActionManager
|
||||
}
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Execute a command associated to an action and id in a remote host.
|
||||
# -------------------------------------------------------------------------
|
||||
def remotes_action(command, id, host, aname, remote_dir, std_in=nil)
|
||||
|
||||
command_exe = RemotesCommand.run(command,
|
||||
host,
|
||||
remote_dir,
|
||||
log_method(id),
|
||||
std_in,
|
||||
@retries)
|
||||
if command_exe.code == 0
|
||||
result = RESULT[:success]
|
||||
info = command_exe.stdout
|
||||
else
|
||||
result = RESULT[:failure]
|
||||
info = command_exe.get_error_message
|
||||
end
|
||||
|
||||
info = "-" if info == nil || info.empty?
|
||||
|
||||
send_message(aname,result,id,info)
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Execute a command associated to an action and id on localhost
|
||||
# -------------------------------------------------------------------------
|
||||
def local_action(command, id, aname)
|
||||
command_exe = LocalCommand.run(command, log_method(id))
|
||||
|
||||
if command_exe.code == 0
|
||||
result = RESULT[:success]
|
||||
info = command_exe.stdout
|
||||
else
|
||||
result = RESULT[:failure]
|
||||
info = command_exe.get_error_message
|
||||
end
|
||||
|
||||
info = "-" if info == nil || info.empty?
|
||||
|
||||
send_message(aname,result,id,info)
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Sends a log message to ONE. The +message+ can be multiline, it will
|
||||
# be automatically splitted by lines.
|
||||
# -------------------------------------------------------------------------
|
||||
def log(number, message)
|
||||
in_error_message=false
|
||||
msg=message.strip
|
||||
msg.each_line {|line|
|
||||
send_message("LOG", "-", number, line.strip)
|
||||
severity='I'
|
||||
|
||||
l=line.strip
|
||||
|
||||
if l=='ERROR MESSAGE --8<------'
|
||||
in_error_message=true
|
||||
next
|
||||
elsif l=='ERROR MESSAGE ------>8--'
|
||||
in_error_message=false
|
||||
next
|
||||
else
|
||||
if in_error_message
|
||||
severity='E'
|
||||
elsif line.match(/^(ERROR|DEBUG|INFO):(.*)$/)
|
||||
line=$2
|
||||
case $1
|
||||
when 'ERROR'
|
||||
severity='E'
|
||||
when 'DEBUG'
|
||||
severity='D'
|
||||
when 'INFO'
|
||||
severity='I'
|
||||
else
|
||||
severity='I'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
send_message("LOG", severity, number, line.strip)
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Generates a proc with that calls log with a hardcoded number. It will
|
||||
# be used to add loging to command actions
|
||||
# -------------------------------------------------------------------------
|
||||
def log_method(num)
|
||||
lambda {|message|
|
||||
log(num, message)
|
||||
}
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Start the driver. Reads from STDIN and executes methods associated with
|
||||
# the messages
|
||||
# -------------------------------------------------------------------------
|
||||
def start_driver
|
||||
loop_thread = Thread.new { loop }
|
||||
start_listener
|
||||
@ -101,13 +185,17 @@ private
|
||||
if action == :DRIVER_CANCEL
|
||||
cancel_action(action_id)
|
||||
log(action_id,"Driver command for #{action_id} cancelled")
|
||||
else
|
||||
else
|
||||
trigger_action(action,action_id,*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
if __FILE__ == $0
|
||||
|
||||
class SampleDriver < OpenNebulaDriver
|
||||
|
@ -66,10 +66,9 @@ class VirtualMachineDriver < OpenNebulaDriver
|
||||
# Register default actions for the protocol
|
||||
# -------------------------------------------------------------------------
|
||||
def initialize(concurrency=10, threaded=true, retries=0)
|
||||
super(concurrency,threaded)
|
||||
super(concurrency,threaded,retries)
|
||||
|
||||
@hosts = Array.new
|
||||
@retries = retries
|
||||
|
||||
register_action(ACTION[:deploy].to_sym, method("deploy"))
|
||||
register_action(ACTION[:shutdown].to_sym, method("shutdown"))
|
||||
@ -109,43 +108,14 @@ class VirtualMachineDriver < OpenNebulaDriver
|
||||
# Execute a command associated to an action and id in a remote host.
|
||||
# -------------------------------------------------------------------------
|
||||
def remotes_action(command, id, host, action, remote_dir, std_in=nil)
|
||||
|
||||
command_exe = RemotesCommand.run(command,
|
||||
host,
|
||||
remote_dir,
|
||||
log_method(id),
|
||||
std_in,
|
||||
@retries)
|
||||
if command_exe.code == 0
|
||||
result = :success
|
||||
info = command_exe.stdout
|
||||
else
|
||||
result = :failure
|
||||
info = command_exe.stderr
|
||||
end
|
||||
|
||||
info = "-" if info == nil || info.empty?
|
||||
|
||||
send_message(ACTION[action],RESULT[result],id,info)
|
||||
super(command,id,host,ACTION[action],remote_dir,std_in)
|
||||
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 = command_exe.stdout
|
||||
else
|
||||
result = :failure
|
||||
info = command_exe.stderr
|
||||
end
|
||||
|
||||
info = "-" if info == nil || info.empty?
|
||||
|
||||
send_message(ACTION[action],RESULT[result],id,info)
|
||||
super(command,id,ACTION[action])
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
@ -187,7 +157,9 @@ class VirtualMachineDriver < OpenNebulaDriver
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Interface to handle the pending events from the ActionManager Interface
|
||||
# -------------------------------------------------------------------------
|
||||
def delete_running_action(action_id)
|
||||
action=@action_running[action_id]
|
||||
if action
|
||||
@ -227,11 +199,6 @@ private
|
||||
@action_queue.delete_at(action_index)
|
||||
end
|
||||
|
||||
STDERR.puts "action: #{action.inspect}"
|
||||
STDERR.puts "queue: #{@action_queue.inspect}"
|
||||
STDERR.puts "hosts: #{@hosts.inspect}"
|
||||
STDERR.flush
|
||||
|
||||
return action
|
||||
end
|
||||
|
||||
@ -240,6 +207,10 @@ private
|
||||
end
|
||||
end
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
if __FILE__ == $0
|
||||
|
||||
class TemplateDriver < VirtualMachineDriver
|
||||
|
70
src/mad/ruby/scripts_common.rb
Normal file
70
src/mad/ruby/scripts_common.rb
Normal file
@ -0,0 +1,70 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
module OpenNebula
|
||||
|
||||
# Generic log function
|
||||
def self.log_function(severity, message)
|
||||
STDERR.puts "#{severity}: #{File.basename $0}: #{message}"
|
||||
end
|
||||
|
||||
# Logs an info message
|
||||
def self.log_info(message)
|
||||
log_function("INFO", message)
|
||||
end
|
||||
|
||||
# Logs an error message
|
||||
def self.log_error(message)
|
||||
log_function("ERROR", message)
|
||||
end
|
||||
|
||||
# Logs a debug message
|
||||
def self.log_debug(message)
|
||||
log_function("DEBUG", message)
|
||||
end
|
||||
|
||||
# Alias log to log_info in the singleton class
|
||||
class << self
|
||||
alias :log :log_info
|
||||
end
|
||||
|
||||
# This function is used to pass error message to the mad
|
||||
def self.error_message(message)
|
||||
STDERR.puts "ERROR MESSAGE --8<------"
|
||||
STDERR.puts message
|
||||
STDERR.puts "ERROR MESSAGE ------>8--"
|
||||
end
|
||||
|
||||
# Executes a command, if it fails returns error message and exits
|
||||
# If a second parameter is present it is used as the error message when
|
||||
# the command fails
|
||||
def self.exec_and_log(command, message=nil)
|
||||
output=`#{command} 2>&1 1>/dev/null`
|
||||
code=$?
|
||||
if code!=0
|
||||
log_error "Command \"#{command}\" failed."
|
||||
log_error output
|
||||
if !message
|
||||
error_message output
|
||||
else
|
||||
error_message message
|
||||
end
|
||||
exit code
|
||||
end
|
||||
log "Executed \"#{command}\"."
|
||||
end
|
||||
|
||||
end
|
147
src/mad/sh/scripts_common.sh
Executable file
147
src/mad/sh/scripts_common.sh
Executable file
@ -0,0 +1,147 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# Paths for utilities
|
||||
AWK=awk
|
||||
BASH=/bin/bash
|
||||
CUT=cut
|
||||
DATE=/bin/date
|
||||
DD=/bin/dd
|
||||
LVCREATE=/sbin/lvcreate
|
||||
LVREMOVE=/sbin/lvremove
|
||||
LVS=/sbin/lvs
|
||||
MD5SUM=/usr/bin/md5sum
|
||||
MKFS=/sbin/mkfs
|
||||
MKISOFS=/usr/bin/mkisofs
|
||||
MKSWAP=/sbin/mkswap
|
||||
SCP=/usr/bin/scp
|
||||
SED=/bin/sed
|
||||
SSH=/usr/bin/ssh
|
||||
SUDO=/usr/bin/sudo
|
||||
WGET=/usr/bin/wget
|
||||
|
||||
# Used for log messages
|
||||
SCRIPT_NAME=`basename $0`
|
||||
|
||||
# Formats date for logs
|
||||
function log_date
|
||||
{
|
||||
$DATE +"%a %b %d %T %Y"
|
||||
}
|
||||
|
||||
# Logs a message, alias to log_info
|
||||
function log
|
||||
{
|
||||
log_info "$1"
|
||||
}
|
||||
|
||||
# Log function that knows how to deal with severities and adds the
|
||||
# script name
|
||||
function log_function
|
||||
{
|
||||
echo "$1: $SCRIPT_NAME: $2" 1>&2
|
||||
}
|
||||
|
||||
# Logs an info message
|
||||
function log_info
|
||||
{
|
||||
log_function "INFO" "$1"
|
||||
}
|
||||
|
||||
# Logs an error message
|
||||
function log_error
|
||||
{
|
||||
log_function "ERROR" "$1"
|
||||
}
|
||||
|
||||
# Logs a debug message
|
||||
function log_debug
|
||||
{
|
||||
log_function "DEBUG" "$1"
|
||||
}
|
||||
|
||||
# This function is used to pass error message to the mad
|
||||
function error_message
|
||||
{
|
||||
(
|
||||
echo "ERROR MESSAGE --8<------"
|
||||
echo "$1"
|
||||
echo "ERROR MESSAGE ------>8--"
|
||||
) 1>&2
|
||||
}
|
||||
|
||||
# Executes a command, if it fails returns error message and exits
|
||||
# If a second parameter is present it is used as the error message when
|
||||
# the command fails
|
||||
function exec_and_log
|
||||
{
|
||||
message=$2
|
||||
output=`$1 2>&1 1>/dev/null`
|
||||
code=$?
|
||||
if [ "x$code" != "x0" ]; then
|
||||
log_error "Command \"$1\" failed."
|
||||
log_error "$output"
|
||||
if [ -z "$message" ]; then
|
||||
error_message "$output"
|
||||
else
|
||||
error_message "$message"
|
||||
fi
|
||||
exit $code
|
||||
fi
|
||||
log "Executed \"$1\"."
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Like exec_and_log but the first argument is the number of seconds
|
||||
# before here is timeout and kills the command
|
||||
#
|
||||
# NOTE: if the command is killed because a timeout the exit code
|
||||
# will be 143 = 128+15 (SIGHUP)
|
||||
function timeout_exec_and_log
|
||||
{
|
||||
TIMEOUT=$1
|
||||
shift
|
||||
|
||||
CMD="$1"
|
||||
|
||||
exec_and_log "$CMD" &
|
||||
CMD_PID=$!
|
||||
|
||||
# timeout process
|
||||
(
|
||||
sleep $TIMEOUT
|
||||
kill $CMD_PID 2>/dev/null
|
||||
log_error "Timeout executing $CMD"
|
||||
error_message "Timeout executing $CMD"
|
||||
exit -1
|
||||
) &
|
||||
TIMEOUT_PID=$!
|
||||
|
||||
# stops the execution until the command finalizes
|
||||
wait $CMD_PID 2>/dev/null
|
||||
CMD_CODE=$?
|
||||
|
||||
# if the script reaches here the command finished before it
|
||||
# consumes timeout seconds so we can kill timeout process
|
||||
kill $TIMEOUT_PID 2>/dev/null 1>/dev/null
|
||||
wait $TIMEOUT_PID 2>/dev/null
|
||||
|
||||
# checks the exit code of the command and exits if it is not 0
|
||||
if [ "x$CMD_CODE" != "x0" ]; then
|
||||
exit $CMD_CODE
|
||||
fi
|
||||
}
|
@ -208,7 +208,7 @@ void Nebula::start()
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
db = new MySqlDB(server,port,user,passwd,0);
|
||||
db = new MySqlDB(server,port,user,passwd,db_name);
|
||||
|
||||
oss << "CREATE DATABASE IF NOT EXISTS " << db_name;
|
||||
rc = db->exec(oss);
|
||||
@ -235,6 +235,7 @@ void Nebula::start()
|
||||
UserPool::bootstrap(db);
|
||||
ImagePool::bootstrap(db);
|
||||
ClusterPool::bootstrap(db);
|
||||
VMTemplatePool::bootstrap(db);
|
||||
}
|
||||
catch (exception&)
|
||||
{
|
||||
@ -245,7 +246,6 @@ void Nebula::start()
|
||||
{
|
||||
string mac_prefix;
|
||||
int size;
|
||||
string repository_path;
|
||||
string default_image_type;
|
||||
string default_device_prefix;
|
||||
|
||||
@ -265,17 +265,17 @@ void Nebula::start()
|
||||
|
||||
upool = new UserPool(db);
|
||||
|
||||
nebula_configuration->get("IMAGE_REPOSITORY_PATH", repository_path);
|
||||
nebula_configuration->get("DEFAULT_IMAGE_TYPE", default_image_type);
|
||||
nebula_configuration->get("DEFAULT_DEVICE_PREFIX",
|
||||
default_device_prefix);
|
||||
|
||||
ipool = new ImagePool(db,
|
||||
repository_path,
|
||||
default_image_type,
|
||||
default_device_prefix);
|
||||
|
||||
cpool = new ClusterPool(db);
|
||||
|
||||
tpool = new VMTemplatePool(db);
|
||||
}
|
||||
catch (exception&)
|
||||
{
|
||||
@ -442,6 +442,7 @@ void Nebula::start()
|
||||
upool,
|
||||
ipool,
|
||||
cpool,
|
||||
tpool,
|
||||
rm_port,
|
||||
log_location + "one_xmlrpc.log");
|
||||
}
|
||||
@ -511,6 +512,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 +544,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 +575,7 @@ void Nebula::start()
|
||||
im->finalize();
|
||||
rm->finalize();
|
||||
hm->finalize();
|
||||
imagem->finalize();
|
||||
|
||||
//sleep to wait drivers???
|
||||
|
||||
@ -563,6 +587,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();
|
||||
|
@ -126,17 +126,10 @@ NebulaTemplate::NebulaTemplate(string& etc_location, string& var_location)
|
||||
#*******************************************************************************
|
||||
# Image Repository Configuration
|
||||
#*******************************************************************************
|
||||
# IMAGE_REPOSITORY_PATH
|
||||
# DEFAULT_IMAGE_TYPE
|
||||
# DEFAULT_DEVICE_PREFIX
|
||||
#*******************************************************************************
|
||||
*/
|
||||
//IMAGE_REPOSITORY_PATH
|
||||
value = var_location + "/images";
|
||||
|
||||
attribute = new SingleAttribute("IMAGE_REPOSITORY_PATH",value);
|
||||
conf_default.insert(make_pair(attribute->name(),attribute));
|
||||
|
||||
//DEFAULT_IMAGE_TYPE
|
||||
value = "OS";
|
||||
|
||||
|
@ -50,6 +50,7 @@ env.Prepend(LIBS=[
|
||||
'nebula_host',
|
||||
'nebula_vnm',
|
||||
'nebula_vm',
|
||||
'nebula_vmtemplate',
|
||||
'nebula_common',
|
||||
'nebula_sql',
|
||||
'nebula_log',
|
||||
|
@ -22,7 +22,6 @@ import org.opennebula.client.Client;
|
||||
import org.opennebula.client.OneResponse;
|
||||
import org.opennebula.client.Pool;
|
||||
import org.opennebula.client.PoolElement;
|
||||
import org.opennebula.client.vm.VirtualMachinePool;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
@ -42,7 +41,7 @@ public class ImagePool extends Pool implements Iterable<Image>
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
*
|
||||
* @see VirtualMachinePool#VirtualMachinePool(Client, int)
|
||||
* @see ImagePool#ImagePool(Client, int)
|
||||
*/
|
||||
public ImagePool(Client client)
|
||||
{
|
||||
@ -58,8 +57,8 @@ public class ImagePool extends Pool implements Iterable<Image>
|
||||
* {@link ImagePool#info()}. Possible values:
|
||||
* <ul>
|
||||
* <li><= -2: All Images</li>
|
||||
* <li>-1: Connected user's Images</li>
|
||||
* <li>>= 0: UID User's VMs</li>
|
||||
* <li>-1: Connected user's Images and public ones</li>
|
||||
* <li>>= 0: UID User's Images</li>
|
||||
* </ul>
|
||||
*/
|
||||
public ImagePool(Client client, int filter)
|
||||
@ -85,8 +84,8 @@ public class ImagePool extends Pool implements Iterable<Image>
|
||||
* {@link ImagePool#info()}. Possible values:
|
||||
* <ul>
|
||||
* <li><= -2: All Images</li>
|
||||
* <li>-1: Connected user's Images</li>
|
||||
* <li>>= 0: UID User's VMs</li>
|
||||
* <li>-1: Connected user's Images and public ones</li>
|
||||
* <li>>= 0: UID User's Images</li>
|
||||
* </ul>
|
||||
* @return If successful the message contains the string
|
||||
* with the information returned by OpenNebula.
|
||||
|
236
src/oca/java/src/org/opennebula/client/template/Template.java
Normal file
236
src/oca/java/src/org/opennebula/client/template/Template.java
Normal file
@ -0,0 +1,236 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
package org.opennebula.client.template;
|
||||
|
||||
import org.opennebula.client.Client;
|
||||
import org.opennebula.client.OneResponse;
|
||||
import org.opennebula.client.PoolElement;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* This class represents an OpenNebula template.
|
||||
* It also offers static XML-RPC call wrappers.
|
||||
*/
|
||||
public class Template extends PoolElement
|
||||
{
|
||||
|
||||
private static final String METHOD_PREFIX = "template.";
|
||||
private static final String ALLOCATE = METHOD_PREFIX + "allocate";
|
||||
private static final String INFO = METHOD_PREFIX + "info";
|
||||
private static final String DELETE = METHOD_PREFIX + "delete";
|
||||
private static final String UPDATE = METHOD_PREFIX + "update";
|
||||
private static final String RMATTR = METHOD_PREFIX + "rmattr";
|
||||
private static final String PUBLISH = METHOD_PREFIX + "publish";
|
||||
|
||||
/**
|
||||
* Creates a new Template representation.
|
||||
* @param id The template id.
|
||||
* @param client XML-RPC Client.
|
||||
*/
|
||||
public Template(int id, Client client)
|
||||
{
|
||||
super(id, client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PoolElement
|
||||
*/
|
||||
protected Template(Node xmlElement, Client client)
|
||||
{
|
||||
super(xmlElement, client);
|
||||
}
|
||||
|
||||
// =================================
|
||||
// Static XML-RPC methods
|
||||
// =================================
|
||||
|
||||
|
||||
/**
|
||||
* Allocates a new Template in OpenNebula.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param description A string containing the template of the template.
|
||||
* @return If successful the message contains the associated
|
||||
* id generated for this Template.
|
||||
*/
|
||||
public static OneResponse allocate(Client client, String description)
|
||||
{
|
||||
return client.call(ALLOCATE, description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the information of the given Template.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param id The template id for the template to retrieve the information from
|
||||
* @return If successful the message contains the string
|
||||
* with the information returned by OpenNebula.
|
||||
*/
|
||||
public static OneResponse info(Client client, int id)
|
||||
{
|
||||
return client.call(INFO, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a template from OpenNebula.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param id The template id of the target template we want to delete.
|
||||
* @return A encapsulated response.
|
||||
*/
|
||||
public static OneResponse delete(Client client, int id)
|
||||
{
|
||||
return client.call(DELETE, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies a template attribute.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param id The template id of the target template we want to modify.
|
||||
* @param att_name The name of the attribute to update.
|
||||
* @param att_val The new value for the attribute.
|
||||
* @return If successful the message contains the template id.
|
||||
*/
|
||||
public static OneResponse update(Client client, int id,
|
||||
String att_name, String att_val)
|
||||
{
|
||||
return client.call(UPDATE, id, att_name, att_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a template attribute.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param id The template id of the target template we want to modify.
|
||||
* @param att_name The name of the attribute to remove.
|
||||
* @return If successful the message contains the template id.
|
||||
*/
|
||||
public static OneResponse rmattr(Client client, int id, String att_name)
|
||||
{
|
||||
return client.call(RMATTR, id, att_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes or unpublishes a template.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param id The template id of the target template we want to modify.
|
||||
* @param publish True for publishing, false for unpublishing.
|
||||
* @return If successful the message contains the template id.
|
||||
*/
|
||||
public static OneResponse publish(Client client, int id, boolean publish)
|
||||
{
|
||||
return client.call(PUBLISH, id, publish);
|
||||
}
|
||||
|
||||
|
||||
// =================================
|
||||
// Instanced object XML-RPC methods
|
||||
// =================================
|
||||
|
||||
/**
|
||||
* Retrieves the information of the Template.
|
||||
*
|
||||
* @return If successful the message contains the string
|
||||
* with the information returned by OpenNebula.
|
||||
*/
|
||||
public OneResponse info()
|
||||
{
|
||||
OneResponse response = info(client, id);
|
||||
super.processInfo(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the template from OpenNebula.
|
||||
*
|
||||
* @return A encapsulated response.
|
||||
*/
|
||||
public OneResponse delete()
|
||||
{
|
||||
return delete(client, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies a template attribute.
|
||||
*
|
||||
* @param att_name The name of the attribute to update.
|
||||
* @param att_val The new value for the attribute.
|
||||
* @return If successful the message contains the template id.
|
||||
*/
|
||||
public OneResponse update(String att_name, String att_val)
|
||||
{
|
||||
return update(client, id, att_name, att_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a template attribute.
|
||||
*
|
||||
* @param att_name The name of the attribute to remove.
|
||||
* @return If successful the message contains the template id.
|
||||
*/
|
||||
public OneResponse rmattr(String att_name)
|
||||
{
|
||||
return rmattr(client, id, att_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes or unpublishes the template.
|
||||
*
|
||||
* @param publish True for publishing, false for unpublishing.
|
||||
* @return If successful the message contains the template id.
|
||||
*/
|
||||
public OneResponse publish(boolean publish)
|
||||
{
|
||||
return publish(client, id, publish);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes the template.
|
||||
*
|
||||
* @return If successful the message contains the template id.
|
||||
*/
|
||||
public OneResponse publish()
|
||||
{
|
||||
return publish(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpublishes the template.
|
||||
*
|
||||
* @return If successful the message contains the template id.
|
||||
*/
|
||||
public OneResponse unpublish()
|
||||
{
|
||||
return publish(false);
|
||||
}
|
||||
|
||||
// =================================
|
||||
// Helpers
|
||||
// =================================
|
||||
|
||||
/**
|
||||
* Returns true if the template is public.
|
||||
*
|
||||
* @return True if the template is public.
|
||||
*/
|
||||
public boolean isPublic()
|
||||
{
|
||||
String isPub = xpath("PUBLIC");
|
||||
return isPub != null && isPub.equals("1");
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
package org.opennebula.client.template;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.opennebula.client.Client;
|
||||
import org.opennebula.client.OneResponse;
|
||||
import org.opennebula.client.Pool;
|
||||
import org.opennebula.client.PoolElement;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* This class represents an OpenNebula Template pool.
|
||||
* It also offers static XML-RPC call wrappers.
|
||||
*/
|
||||
public class TemplatePool extends Pool implements Iterable<Template>
|
||||
{
|
||||
private static final String ELEMENT_NAME = "VMTEMPLATE";
|
||||
private static final String INFO_METHOD = "templatepool.info";
|
||||
|
||||
private int filter;
|
||||
|
||||
/**
|
||||
* Creates a new Template pool with the default filter flag value
|
||||
* set to 0 (Templates belonging to user with UID 0)
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
*
|
||||
* @see TemplatePool#TemplatePool(Client, int)
|
||||
*/
|
||||
public TemplatePool(Client client)
|
||||
{
|
||||
super(ELEMENT_NAME, client);
|
||||
this.filter = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Template pool.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param filter Filter flag used by default in the method
|
||||
* {@link TemplatePool#info()}. Possible values:
|
||||
* <ul>
|
||||
* <li><= -2: All Templates</li>
|
||||
* <li>-1: Connected user's Templates and public ones</li>
|
||||
* <li>>= 0: UID User's Templates</li>
|
||||
* </ul>
|
||||
*/
|
||||
public TemplatePool(Client client, int filter)
|
||||
{
|
||||
super(ELEMENT_NAME, client);
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.opennebula.client.Pool#factory(org.w3c.dom.Node)
|
||||
*/
|
||||
@Override
|
||||
public PoolElement factory(Node node)
|
||||
{
|
||||
return new Template(node, client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all or part of the templates in the pool.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param filter Filter flag used by default in the method
|
||||
* {@link TemplatePool#info()}. Possible values:
|
||||
* <ul>
|
||||
* <li><= -2: All Templates</li>
|
||||
* <li>-1: Connected user's Templates and public ones</li>
|
||||
* <li>>= 0: UID User's Templates</li>
|
||||
* </ul>
|
||||
* @return If successful the message contains the string
|
||||
* with the information returned by OpenNebula.
|
||||
*/
|
||||
public static OneResponse info(Client client, int filter)
|
||||
{
|
||||
return client.call(INFO_METHOD, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the xml representation of all or part of the
|
||||
* Templates in the pool. The filter used is the one set in
|
||||
* the constructor.
|
||||
*
|
||||
* @see TemplatePool#info(Client, int)
|
||||
*
|
||||
* @return If successful the message contains the string
|
||||
* with the information returned by OpenNebula.
|
||||
*/
|
||||
public OneResponse info()
|
||||
{
|
||||
OneResponse response = info(client, filter);
|
||||
super.processInfo(response);
|
||||
return response;
|
||||
}
|
||||
|
||||
public Iterator<Template> iterator()
|
||||
{
|
||||
AbstractList<Template> ab = new AbstractList<Template>()
|
||||
{
|
||||
public int size()
|
||||
{
|
||||
return getLength();
|
||||
}
|
||||
|
||||
public Template get(int index)
|
||||
{
|
||||
return (Template) item(index);
|
||||
}
|
||||
};
|
||||
|
||||
return ab.iterator();
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ package org.opennebula.client.vm;
|
||||
import org.opennebula.client.Client;
|
||||
import org.opennebula.client.OneResponse;
|
||||
import org.opennebula.client.PoolElement;
|
||||
import org.opennebula.client.template.Template;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
@ -134,6 +135,56 @@ public class VirtualMachine extends PoolElement{
|
||||
return client.call(ALLOCATE, description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a new VM in OpenNebula from a registered Template.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param templateId The source Template's ID
|
||||
* @param newName Name for the new VM, replaces the Template's one.
|
||||
* Can be null.
|
||||
* @return If successful the message contains the associated
|
||||
* id generated for this VM.
|
||||
*/
|
||||
public static OneResponse allocateFromTemplate(Client client,
|
||||
int templateId, String newName)
|
||||
{
|
||||
String template = "TEMPLATE_ID = " + templateId;
|
||||
if( newName != null )
|
||||
{
|
||||
template += "\nNAME = " + newName;
|
||||
}
|
||||
|
||||
return allocate(client, template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a new VM in OpenNebula from a registered Template.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param templateId The source Template's ID
|
||||
* @return If successful the message contains the associated
|
||||
* id generated for this VM.
|
||||
*/
|
||||
public static OneResponse allocateFromTemplate(Client client,
|
||||
int templateId)
|
||||
{
|
||||
return allocateFromTemplate(client, templateId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a new VM in OpenNebula from a registered Template.
|
||||
*
|
||||
* @param client XML-RPC Client.
|
||||
* @param template The source Template.
|
||||
* @return If successful the message contains the associated
|
||||
* id generated for this VM.
|
||||
*/
|
||||
public static OneResponse allocateFromTemplate(Client client,
|
||||
Template template)
|
||||
{
|
||||
return allocateFromTemplate(client, template.id());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the information of the given VM.
|
||||
*
|
||||
@ -222,12 +273,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
|
||||
|
201
src/oca/java/test/TemplateTest.java
Normal file
201
src/oca/java/test/TemplateTest.java
Normal file
@ -0,0 +1,201 @@
|
||||
/*******************************************************************************
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.opennebula.client.Client;
|
||||
import org.opennebula.client.OneResponse;
|
||||
import org.opennebula.client.template.*;
|
||||
import org.opennebula.client.vm.VirtualMachine;
|
||||
|
||||
|
||||
|
||||
public class TemplateTest
|
||||
{
|
||||
|
||||
private static Template template;
|
||||
private static TemplatePool templatePool;
|
||||
|
||||
private static Client client;
|
||||
|
||||
private static OneResponse res;
|
||||
private static String name = "new_test_template";
|
||||
|
||||
|
||||
private static String template_str =
|
||||
"NAME = \"" + name + "\"\n" +
|
||||
"ATT1 = \"val1\"";
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception
|
||||
{
|
||||
client = new Client();
|
||||
templatePool = new TemplatePool(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
res = Template.allocate(client, template_str);
|
||||
|
||||
int oid = res.isError() ? -1 : Integer.parseInt(res.getMessage());
|
||||
template = new Template(oid, client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception
|
||||
{
|
||||
template.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allocate()
|
||||
{
|
||||
template.delete();
|
||||
|
||||
res = Template.allocate(client, template_str);
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
int oid = res.isError() ? -1 : Integer.parseInt(res.getMessage());
|
||||
template = new Template(oid, client);
|
||||
|
||||
|
||||
templatePool.info();
|
||||
|
||||
boolean found = false;
|
||||
for(Template temp : templatePool)
|
||||
{
|
||||
found = found || temp.getName().equals(name);
|
||||
}
|
||||
|
||||
assertTrue( found );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void info()
|
||||
{
|
||||
res = template.info();
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
// assertTrue( template.getId().equals("0") );
|
||||
// assertTrue( template.id() == 0 );
|
||||
assertTrue( template.getName().equals(name) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void update()
|
||||
{
|
||||
// Update an existing att.
|
||||
res = template.update("ATT1", "new_val_1");
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
res = template.info();
|
||||
assertTrue( !res.isError() );
|
||||
assertTrue( template.xpath("TEMPLATE/ATT1").equals("new_val_1") );
|
||||
|
||||
// Create a new att.
|
||||
res = template.update("ATT2", "new_val_2");
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
res = template.info();
|
||||
assertTrue( !res.isError() );
|
||||
assertTrue( template.xpath("TEMPLATE/ATT2").equals("new_val_2") );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rmattr()
|
||||
{
|
||||
res = template.rmattr("ATT1");
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
res = template.info();
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
assertTrue( template.xpath("ATT1").equals("") );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publish()
|
||||
{
|
||||
res = template.publish();
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
template.info();
|
||||
assertTrue( template.isPublic() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unpublish()
|
||||
{
|
||||
res = template.unpublish();
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
template.info();
|
||||
assertTrue( !template.isPublic() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void attributes()
|
||||
{
|
||||
res = template.info();
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
// assertTrue( template.xpath("ID").equals("0") );
|
||||
assertTrue( template.xpath("NAME").equals(name) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delete()
|
||||
{
|
||||
res = template.delete();
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
res = template.info();
|
||||
assertTrue( res.isError() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allocateFromTemplate()
|
||||
{
|
||||
template.info();
|
||||
assertTrue( !res.isError() );
|
||||
|
||||
res = VirtualMachine.allocateFromTemplate(client, template);
|
||||
assertTrue( !res.isError() );
|
||||
assertTrue( res.getMessage().equals("0") );
|
||||
}
|
||||
}
|
@ -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")) );
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -z $ONE_LOCATION ]; then
|
||||
echo "ONE_LOCATION not defined."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
ONEDCONF_LOCATION="$ONE_LOCATION/etc/oned.conf"
|
||||
|
||||
if [ -f $ONEDCONF_LOCATION ]; then
|
||||
echo "$ONEDCONF_LOCATION has to be overwritten, move it to a safe place."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
cp oned.conf $ONEDCONF_LOCATION
|
||||
|
||||
export ONE_XMLRPC=http://localhost:2666/RPC2
|
||||
|
||||
|
||||
./test.sh ClusterTest
|
||||
./test.sh HostTest
|
||||
./test.sh ImageTest
|
||||
./test.sh SessionTest
|
||||
./test.sh UserTest
|
||||
./test.sh VirtualMachineTest
|
||||
./test.sh VirtualNetworkTest
|
||||
./test.sh VirtualNetworkTest
|
||||
./test.sh TemplateTest
|
@ -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,13 +31,14 @@ require 'OpenNebula/VirtualNetwork'
|
||||
require 'OpenNebula/VirtualNetworkPool'
|
||||
require 'OpenNebula/Image'
|
||||
require 'OpenNebula/ImagePool'
|
||||
require 'OpenNebula/ImageRepository'
|
||||
require 'OpenNebula/User'
|
||||
require 'OpenNebula/UserPool'
|
||||
require 'OpenNebula/Host'
|
||||
require 'OpenNebula/HostPool'
|
||||
require 'OpenNebula/Cluster'
|
||||
require 'OpenNebula/ClusterPool'
|
||||
require 'OpenNebula/Template'
|
||||
require 'OpenNebula/TemplatePool'
|
||||
|
||||
module OpenNebula
|
||||
|
||||
|
@ -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
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user