1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

Merge branch 'bug-295' into one-2.0

Conflicts:
	include/Image.h
	src/image/Image.cc
This commit is contained in:
Ruben S. Montero 2010-08-04 17:42:53 +02:00
commit 4f82f078b8
22 changed files with 694 additions and 282 deletions

View File

@ -109,6 +109,15 @@ public:
return (public_img == 1);
};
/**
* Returns true if the image is persistent
* @return true if the image is persistent
*/
bool isPersistent()
{
return (persistent_img == 1);
};
/**
* Set enum type
* @return 0 on success, -1 otherwise
@ -183,16 +192,51 @@ public:
* @param pub true to publish the image
* @return 0 on success
*/
void publish(bool pub)
bool publish(bool pub)
{
bool success = false;
if (pub == true)
{
public_img = 1;
if (!isPersistent())
{
public_img = 1;
success = true;
}
}
else
{
public_img = 0;
success = true;
}
return success;
}
/**
* Set/Unset an image as persistant
* @param persistent true to make an image persistant
* @return 0 on success
*/
bool persistent(bool persis)
{
bool success = false;
if (persis == true)
{
if (!isPublic() && running_vms == 0)
{
persistent_img = 1;
success = true;
}
}
else
{
persistent_img = 0;
success = true;
}
return success;
}
/**
@ -331,6 +375,11 @@ private:
*/
int public_img;
/**
* Persistency of the Image
*/
int persistent_img;
/**
* Registration time
*/
@ -421,13 +470,13 @@ protected:
NAME = 2, /* Image name */
TYPE = 3, /* 0) OS 1) CDROM 2) DATABLOCK */
PUBLIC = 4, /* Public scope (YES OR NO) */
REGTIME = 5, /* Time of registration */
SOURCE = 6, /* Path to the image */
STATE = 7, /* 0) INIT 1) ALLOCATED */
/* 2) READY 3) USED */
RUNNING_VMS = 8, /* Number of VMs using the img */
TEMPLATE = 9, /* Image template xml data */
LIMIT = 10
PERSISTENT = 5, /* Peristency (YES OR NO) */
REGTIME = 6, /* Time of registration */
SOURCE = 7, /* Path to the image */
STATE = 8, /* 0) INIT 1) ALLOCATED */
RUNNING_VMS = 9, /* Number of VMs using the img */
TEMPLATE = 10, /* Image template xml data */
LIMIT = 11
};
static const char * db_names;

View File

@ -236,6 +236,7 @@ private:
etc_location = "/etc/one/";
log_location = "/var/log/one/";
var_location = "/var/lib/one/";
hook_location= "/usr/share/one/hooks/";
}
else
{
@ -250,6 +251,7 @@ private:
etc_location = nebula_location + "etc/";
log_location = nebula_location + "var/";
var_location = nebula_location + "var/";
hook_location= nebula_location + "share/hooks/";
}
};
@ -345,6 +347,7 @@ private:
string etc_location;
string log_location;
string var_location;
string hook_location;
string hostname;
// ---------------------------------------------------------------

View File

@ -46,7 +46,7 @@ public:
* @param table the name of the table supporting the pool (to set the oid
* counter). If null the OID counter is not updated.
*/
PoolSQL(SqlDB * _db, const char * table=0);
PoolSQL(SqlDB * _db, const char * table);
virtual ~PoolSQL();

View File

@ -1156,6 +1156,31 @@ private:
/* ---------------------------------------------------------------------- */
class ImagePersistent: public xmlrpc_c::method
{
public:
ImagePersistent(ImagePool * _ipool,
UserPool * _upool):
ipool(_ipool),
upool(_upool)
{
_signature="A:sib";
_help="Make an Image (non)persistent";
};
~ImagePersistent(){};
void execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retvalP);
private:
ImagePool * ipool;
UserPool * upool;
};
/* ---------------------------------------------------------------------- */
class ImageEnable: public xmlrpc_c::method
{
public:

View File

@ -32,7 +32,9 @@ class VirtualMachinePool : public PoolSQL
{
public:
VirtualMachinePool(SqlDB * db, vector<const Attribute *> hook_mads);
VirtualMachinePool(SqlDB * db,
vector<const Attribute *> hook_mads,
const string& hook_location);
~VirtualMachinePool(){};

View File

@ -99,7 +99,7 @@ if [ -z "$ROOT" ] ; then
RUN_LOCATION="/var/run/one"
LOCK_LOCATION="/var/lock/one"
INCLUDE_LOCATION="/usr/include"
SHARE_LOCATION="/usr/share/doc/opennebula"
SHARE_LOCATION="/usr/share/one"
if [ "$CLIENT" = "no" ]; then
MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $ETC_LOCATION $VAR_LOCATION \
@ -306,6 +306,7 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \
src/oca/ruby/OpenNebula/VirtualNetworkPool.rb \
src/oca/ruby/OpenNebula/Image.rb \
src/oca/ruby/OpenNebula/ImagePool.rb \
src/oca/ruby/OpenNebula/ImageRepository.rb \
src/oca/ruby/OpenNebula/Cluster.rb \
src/oca/ruby/OpenNebula/ClusterPool.rb \
src/oca/ruby/OpenNebula/XMLUtils.rb"

View File

@ -37,6 +37,7 @@ end
client = Client.new()
img_repo = ImageRepository.new
vm = VirtualMachine.new(
VirtualMachine.build_xml(vm_id),
@ -52,17 +53,8 @@ vm.each('TEMPLATE/DISK') do |disk|
Image.build_xml(image_id),
client)
result = image.info
exit -1 if OpenNebula.is_error?(result)
# Disable the Image for a safe overwriting
# image.disable
# Save the image file
result = image.move(source_path, image['SOURCE'])
result = img_repo.update_source(image, source_path)
exit -1 if OpenNebula.is_error?(result)
# image.enable
end
end

View File

@ -78,6 +78,13 @@ ShowTableImage={
:proc => lambda {|d,e|
if d["PUBLIC"].to_i == 1 then "Yes" else "No" end}
},
:persistent => {
:name => "PERSISTENT",
:desc => "Whether the Image is persistent or not",
:size => 3,
:proc => lambda {|d,e|
if d["PERSISTENT"].to_i == 1 then "Yes" else "No" end}
},
:state => {
:name => "STAT",
:desc => "State of the Image",
@ -94,7 +101,7 @@ ShowTableImage={
},
:default => [:id, :user, :name, :type, :regtime,
:public, :state, :runningvms]
:public, :persistent, :state, :runningvms]
}
@ -217,6 +224,12 @@ Commands:
* unpublish (Unpublish an Image)
oneimage unpublish <image_id>
* persistent (Makes an Image persistent)
oneimage persistent <image_id>
* nonpersistent (Makes an Image non persistent)
oneimage nonpersistent <image_id>
* list (Shows Images in the pool)
oneimage list <filter_flag>
@ -251,6 +264,11 @@ EOT
table.print_help
end
def special_options(opts, options)
opts.on_tail("-n", "--no-cp", "Do not copy the source") do |o|
options[:no_cp]=true
end
end
end
@ -300,58 +318,18 @@ result=[false, "Unknown error"]
command=ARGV.shift
img_repo = OpenNebula::ImageRepository.new
case command
when "register", "create", "add"
# ---------- Get the Template ------------
when "register", "create", "add"
check_parameters("register", 1)
template = get_template(ARGV[0])
# ---------- Allocate the Image file ------------
image = OpenNebula::Image.new(
OpenNebula::Image.build_xml,
get_one_client)
result = image.allocate(template)
if !is_successful?(result)
puts result.message
exit -1
end
image = OpenNebula::Image.new(OpenNebula::Image.build_xml, get_one_client)
# ---------- Copy the Image file ------------
image.info
if image['TEMPLATE/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
result = image.copy(file_path, image['SOURCE'])
elsif image['TEMPLATE/SIZE'] and
image['TEMPLATE/FSTYPE'] and
image['TEMPLATE/TYPE'] == 'DATABLOCK'
result = image.mk_datablock(
image['TEMPLATE/SIZE'],
image['TEMPLATE/FSTYPE'],
image['SOURCE'])
else
error_msg = "Image not present, aborting."
result = OpenNebula::Error.new(error_msg)
end
if is_successful?(result)
image.enable
result = img_repo.create(image, template, !ops[:no_cp])
if is_successful?(result)
puts "ID: " + image.id.to_s if ops[:verbose]
exit 0
else
image.delete
end
@ -421,6 +399,28 @@ when "unpublish"
puts "Image unpublished" if ops[:verbose]
end
when "persistent"
check_parameters("publish", 1)
image_id=get_image_id(ARGV[0])
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
result=image.persistent
if is_successful?(result)
puts "Image made persistent" if ops[:verbose]
end
when "nonpersistent"
check_parameters("nonpersistent", 1)
image_id=get_image_id(ARGV[0])
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
result=image.nonpersistent
if is_successful?(result)
puts "Image made nonpersistent" if ops[:verbose]
end
when "list"
ops.merge!(get_user_flags)
if !ops[:xml]
@ -494,22 +494,14 @@ when "delete"
args=expand_args(ARGV)
args.each do |param|
image_id=get_image_id(param)
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
result = image.info
image_id = get_image_id(param)
image = OpenNebula::Image.new(
OpenNebula::Image.build_xml(image_id),
get_one_client)
result = img_repo.delete(image)
if is_successful?(result)
file_path = image['SOURCE']
result=image.delete
if is_successful?(result)
FileUtils.rm(file_path) if File.exists?(file_path)
puts "Image correctly deleted" if ops[:verbose]
end
puts "Image correctly deleted" if ops[:verbose]
end
end

View File

@ -58,6 +58,7 @@ class CloudServer
@one_client = Client.new()
@user_pool = UserPool.new(@one_client)
@img_repo = OpenNebula::ImageRepository.new
end
#
@ -110,47 +111,23 @@ class CloudServer
if file
if file[:tempfile]
file_path = file[:tempfile].path
template = image.to_one_template
template << "\nPATH = #{file_path}"
else
error_msg = "Image not present, aborting."
error = OpenNebula::Error.new(error_msg)
return error
end
if !File.exists?(file_path)
error_msg = "Image file could not be found, aborting."
error = OpenNebula::Error.new(error_msg)
return error
end
end
# ---------- Allocate the Image file ------------
rc = @img_repo.create(image, template)
rc = image.allocate(image.to_one_template)
file[:tempfile].unlink
if OpenNebula.is_error?(rc)
return rc
end
# ---------- Copy the Image file ------------
image.info
if file_path
rc = image.copy(file_path, image['SOURCE'])
file[:tempfile].unlink
elsif image['TEMPLATE/SIZE'] and
image['TEMPLATE/FSTYPE'] and
image['TEMPLATE/TYPE'] == 'DATABLOCK'
rc = image.mk_datablock(
image['TEMPLATE/SIZE'],
image['TEMPLATE/FSTYPE'],
image['SOURCE'])
end
if OpenNebula.is_error?(rc)
image.delete
return rc
end
return nil
end

View File

@ -355,7 +355,7 @@ class OCCIServer < CloudServer
get_client(request.env))
# --- Delete the Image ---
rc = image.delete
rc = @img_repo.delete(image)
return rc, 500 if OpenNebula::is_error?(rc)
return "", 204

View File

@ -66,12 +66,12 @@ Image::~Image()
const char * Image::table = "image_pool";
const char * Image::db_names = "(oid, uid, name, type, public, regtime, "
const char * Image::db_names = "(oid, uid, name, type, public, persistent, regtime, "
"source, state, running_vms, template)";
const char * Image::db_bootstrap = "CREATE TABLE IF NOT EXISTS image_pool ("
"oid INTEGER PRIMARY KEY, uid INTEGER, name VARCHAR(128), "
"type INTEGER, public INTEGER, regtime INTEGER, source TEXT, state INTEGER, "
"type INTEGER, public INTEGER, persistent INTEGER, regtime INTEGER, source TEXT, state INTEGER, "
"running_vms INTEGER, template TEXT, UNIQUE(name) )";
/* ------------------------------------------------------------------------ */
@ -84,6 +84,7 @@ int Image::select_cb(void * nil, int num, char **values, char ** names)
(!values[NAME]) ||
(!values[TYPE]) ||
(!values[PUBLIC]) ||
(!values[PERSISTENT]) ||
(!values[REGTIME]) ||
(!values[SOURCE]) ||
(!values[STATE]) ||
@ -99,9 +100,10 @@ int Image::select_cb(void * nil, int num, char **values, char ** names)
name = values[NAME];
type = static_cast<ImageType>(atoi(values[TYPE]));
public_img = atoi(values[PUBLIC]);
regtime = static_cast<time_t>(atoi(values[REGTIME]));
type = static_cast<ImageType>(atoi(values[TYPE]));
public_img = atoi(values[PUBLIC]);
persistent_img = atoi(values[PERSISTENT]);
regtime = static_cast<time_t>(atoi(values[REGTIME]));
source = values[SOURCE];
@ -151,6 +153,7 @@ int Image::insert(SqlDB *db)
string source_att;
string type_att;
string public_attr;
string persistent_attr;
string dev_prefix;
ostringstream tmp_hashstream;
@ -196,6 +199,23 @@ int Image::insert(SqlDB *db)
public_img = (public_attr == "YES");
// ------------ PERSISTENT --------------------
get_template_attribute("PERSISTENT", persistent_attr);
image_template->erase("PERSISTENT");
transform (persistent_attr.begin(), persistent_attr.end(), persistent_attr.begin(),
(int(*)(int))toupper);
persistent_img = (persistent_attr == "YES");
// An image cannot be public and persistent simultaneously
if ( public_img && persistent_img )
{
goto error_public_and_persistent;
}
// ------------ PREFIX --------------------
get_template_attribute("DEV_PREFIX", dev_prefix);
@ -236,6 +256,10 @@ error_type:
NebulaLog::log("IMG", Log::ERROR, "Incorrect TYPE in image template");
goto error_common;
error_public_and_persistent:
NebulaLog::log("IMG", Log::ERROR, "Image cannot be public and persistant");
goto error_common;
error_common:
return -1;
}
@ -304,6 +328,7 @@ int Image::insert_replace(SqlDB *db, bool replace)
<< "'" << sql_name << "',"
<< type << ","
<< public_img << ","
<< persistent_img << ","
<< regtime << ","
<< "'" << sql_source << "',"
<< state << ","
@ -336,6 +361,7 @@ int Image::dump(ostringstream& oss, int num, char **values, char **names)
(!values[NAME]) ||
(!values[TYPE]) ||
(!values[PUBLIC]) ||
(!values[PERSISTENT]) ||
(!values[REGTIME]) ||
(!values[SOURCE]) ||
(!values[STATE]) ||
@ -354,6 +380,7 @@ int Image::dump(ostringstream& oss, int num, char **values, char **names)
"<NAME>" << values[NAME] << "</NAME>" <<
"<TYPE>" << values[TYPE] << "</TYPE>" <<
"<PUBLIC>" << values[PUBLIC] << "</PUBLIC>" <<
"<PERSISTENT>" << values[PERSISTENT] << "</PERSISTENT>" <<
"<REGTIME>" << values[REGTIME] << "</REGTIME>" <<
"<SOURCE>" << values[SOURCE] << "</SOURCE>" <<
"<STATE>" << values[STATE] << "</STATE>" <<
@ -413,20 +440,19 @@ string& Image::to_xml(string& xml) const
string template_xml;
ostringstream oss;
oss <<
"<IMAGE>" <<
"<ID>" << oid << "</ID>" <<
"<UID>" << uid << "</UID>" <<
"<NAME>" << name << "</NAME>" <<
"<TYPE>" << type << "</TYPE>" <<
"<PUBLIC>" << public_img << "</PUBLIC>" <<
"<REGTIME>" << regtime << "</REGTIME>" <<
"<SOURCE>" << source << "</SOURCE>" <<
"<STATE>" << state << "</STATE>" <<
"<RUNNING_VMS>" << running_vms << "</RUNNING_VMS>" <<
image_template->to_xml(template_xml) <<
"<ID>" << oid << "</ID>" <<
"<UID>" << uid << "</UID>" <<
"<NAME>" << name << "</NAME>" <<
"<TYPE>" << type << "</TYPE>" <<
"<PUBLIC>" << public_img << "</PUBLIC>" <<
"<PERSISTENT>" << persistent_img << "</PERSISTENT>" <<
"<REGTIME>" << regtime << "</REGTIME>" <<
"<SOURCE>" << source << "</SOURCE>" <<
"<STATE>" << state << "</STATE>" <<
"<RUNNING_VMS>" << running_vms << "</RUNNING_VMS>" <<
image_template->to_xml(template_xml) <<
"</IMAGE>";
xml = oss.str();
@ -444,15 +470,16 @@ string& Image::to_str(string& str) const
ostringstream os;
os <<
"ID = " << oid << endl <<
"UID = " << uid << endl <<
"NAME = " << name << endl <<
"TYPE = " << type << endl <<
"PUBLIC = " << public_img << endl <<
"REGTIME = " << regtime << endl <<
"SOURCE = " << source << endl <<
"STATE = " << state << endl <<
"RUNNING_VMS = " << running_vms << endl <<
"ID = " << oid << endl <<
"UID = " << uid << endl <<
"NAME = " << name << endl <<
"TYPE = " << type << endl <<
"PUBLIC = " << public_img << endl <<
"PERSISTENT = " << persistent_img << endl <<
"REGTIME = " << regtime << endl <<
"SOURCE = " << source << endl <<
"STATE = " << state << endl <<
"RUNNING_VMS = " << running_vms << endl <<
"TEMPLATE" << endl
<< image_template->to_str(template_str)
<< endl;
@ -478,7 +505,14 @@ int Image::acquire_image()
break;
case USED:
running_vms++;
if (persistent_img)
{
rc = -1;
}
else
{
running_vms++;
}
break;
case DISABLED:
@ -527,17 +561,21 @@ int Image::disk_attribute( VectorAttribute * disk,
ImageType* img_type)
{
string bus;
string target;
ostringstream iid;
*img_type = type;
bus = disk->vector_value("BUS");
target = disk->vector_value("TARGET");
iid << oid;
string template_bus;
string template_target;
string prefix;
get_template_attribute("BUS", template_bus);
get_template_attribute("TARGET", template_target);
get_template_attribute("DEV_PREFIX", prefix);
//--------------------------------------------------------------------------
@ -559,24 +597,31 @@ int Image::disk_attribute( VectorAttribute * disk,
new_disk.insert(make_pair("IMAGE_ID", iid.str()));
new_disk.insert(make_pair("SOURCE", source));
if (bus.empty())
{
if (!template_bus.empty())
{
new_disk.insert(make_pair("BUS",template_bus));
}
}
else
if (!bus.empty())
{
new_disk.insert(make_pair("BUS",bus));
}
else if (!template_bus.empty())
{
new_disk.insert(make_pair("BUS",template_bus));
}
//---------------------------------------------------------------------------
// TYPE, READONLY, CLONE, and SAVE attributes
//---------------------------------------------------------------------------
new_disk.insert(make_pair("CLONE","YES"));
new_disk.insert(make_pair("SAVE","NO"));
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
}
else
{
new_disk.insert(make_pair("CLONE","YES"));
new_disk.insert(make_pair("SAVE","NO"));
}
switch(type)
{
@ -596,23 +641,35 @@ int Image::disk_attribute( VectorAttribute * disk,
// TARGET attribute
//---------------------------------------------------------------------------
switch(type)
if (!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;
new_disk.insert(make_pair("TARGET", target));
}
else if (!template_target.empty())
{
new_disk.insert(make_pair("TARGET", template_target));
}
else
{
switch(type)
{
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;
}
new_disk.insert(make_pair("TARGET", prefix));
}
new_disk.insert(make_pair("TARGET", prefix));
disk->replace(new_disk);

View File

@ -230,7 +230,7 @@ void Nebula::start()
nebula_configuration->get("VM_HOOK", vm_hooks);
vmpool = new VirtualMachinePool(db, vm_hooks);
vmpool = new VirtualMachinePool(db, vm_hooks,hook_location);
hpool = new HostPool(db);
nebula_configuration->get("MAC_PREFIX", mac_prefix);

View File

@ -15,6 +15,7 @@ require 'OpenNebula/VirtualNetwork'
require 'OpenNebula/VirtualNetworkPool'
require 'OpenNebula/Image'
require 'OpenNebula/ImagePool'
require 'OpenNebula/ImageRepository'
require 'OpenNebula/User'
require 'OpenNebula/UserPool'
require 'OpenNebula/Host'

View File

@ -7,13 +7,14 @@ module OpenNebula
# Constants and Class Methods
# ---------------------------------------------------------------------
IMAGE_METHODS = {
:info => "image.info",
:allocate => "image.allocate",
:update => "image.update",
:rmattr => "image.rmattr",
:enable => "image.enable",
:publish => "image.publish",
:delete => "image.delete"
:info => "image.info",
:allocate => "image.allocate",
:update => "image.update",
:rmattr => "image.rmattr",
:enable => "image.enable",
:publish => "image.publish",
:persistent => "image.persistent",
:delete => "image.delete"
}
IMAGE_STATES=%w{INIT READY USED DISABLED}
@ -55,7 +56,6 @@ module OpenNebula
super(xml,client)
@client = client
@immanager = ImageManager.new
end
#######################################################################
@ -109,27 +109,22 @@ module OpenNebula
def unpublish
set_publish(false)
end
# Makes the Image persistent
def persistent
set_persistent(true)
end
# Makes the Image non persistent
def nonpersistent
set_persistent(false)
end
# Deletes the Image
def delete()
super(IMAGE_METHODS[:delete])
end
def copy(path, source)
@immanager.copy(path, source)
end
def move(path, source)
@immanager.move(path, source)
end
def mk_datablock(size, fstype, source)
rc = @immanager.dd(size, source)
return rc if OpenNebula.is_error?(rc)
@immanager.mkfs(fstype, source)
end
#######################################################################
# Helpers to get Image information
@ -184,6 +179,15 @@ module OpenNebula
return rc
end
def set_persistent(persistence)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(IMAGE_METHODS[:persistent], @pe_id, persistence)
rc = nil if !OpenNebula.is_error?(rc)
return rc
end
def do_rm_attr(name)
return Error.new('ID not defined') if !@pe_id
@ -195,81 +199,4 @@ module OpenNebula
end
end
class ImageManager
# ---------------------------------------------------------------------
# Constants and Class Methods
# ---------------------------------------------------------------------
FS_UTILS = {
:dd => "env dd",
:mkfs => "env mkfs"
}
def copy(path, source)
if source.nil? or path.nil?
return OpenNebula::Error.new("copy Image: missing parameters.")
end
begin
FileUtils.copy(path, source)
FileUtils.chmod(0660, source)
rescue Exception => e
return OpenNebula::Error.new(e.message)
end
return nil
end
def move(path, source)
if source.nil? or path.nil?
return OpenNebula::Error.new("copy Image: missing parameters.")
end
begin
FileUtils.move(path, source)
FileUtils.chmod(0660, 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
end
end

View File

@ -0,0 +1,185 @@
require 'OpenNebula/Image'
require 'fileutils'
module OpenNebula
class ImageRepository
def create(image, template, copy=true)
if image.nil?
error_msg = "Image could not be found, aborting."
result = OpenNebula::Error.new(error_msg)
end
# ------ Allocate the Image ------
result = image.allocate(template)
if OpenNebula.is_error?(result)
puts result.message
exit -1
end
# ------ Copy the Image file ------
image.info
if image['TEMPLATE/PATH']
if copy
# --- 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
result = copy(file_path, 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
else
error_msg = "Image not present, aborting."
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."
result = 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."
result = 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 copy(path, source)
if source.nil? or path.nil?
return OpenNebula::Error.new("copy Image: missing parameters.")
end
begin
FileUtils.copy(path, source)
FileUtils.chmod(0660, source)
rescue Exception => e
return OpenNebula::Error.new(e.message)
end
return nil
end
def move(path, source)
if source.nil? or path.nil?
return OpenNebula::Error.new("copy Image: missing parameters.")
end
begin
FileUtils.move(path, source)
FileUtils.chmod(0660, 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)
begin
FileUtils.rm(source)
rescue Exception => e
return OpenNebula::Error.new(e.message)
end
end
return nil
end
end
end

View File

@ -312,6 +312,9 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr image_publish(new
RequestManager::ImagePublish(ipool, upool));
xmlrpc_c::methodPtr image_persistent(new
RequestManager::ImagePersistent(ipool, upool));
xmlrpc_c::methodPtr image_enable(new
RequestManager::ImageEnable(ipool, upool));
@ -368,15 +371,16 @@ void RequestManager::register_xml_methods()
/* Image related methods*/
RequestManagerRegistry.addMethod("one.image.allocate",image_allocate);
RequestManagerRegistry.addMethod("one.image.delete", image_delete);
RequestManagerRegistry.addMethod("one.image.info", image_info);
RequestManagerRegistry.addMethod("one.image.update", image_update);
RequestManagerRegistry.addMethod("one.image.rmattr", image_rm_attribute);
RequestManagerRegistry.addMethod("one.image.publish", image_publish);
RequestManagerRegistry.addMethod("one.image.enable", image_enable);
RequestManagerRegistry.addMethod("one.image.allocate", image_allocate);
RequestManagerRegistry.addMethod("one.image.delete", image_delete);
RequestManagerRegistry.addMethod("one.image.info", image_info);
RequestManagerRegistry.addMethod("one.image.update", image_update);
RequestManagerRegistry.addMethod("one.image.rmattr", image_rm_attribute);
RequestManagerRegistry.addMethod("one.image.publish", image_publish);
RequestManagerRegistry.addMethod("one.image.persistent", image_persistent);
RequestManagerRegistry.addMethod("one.image.enable", image_enable);
RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info);
RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info);
};

View File

@ -0,0 +1,157 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2010, 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 "RequestManager.h"
#include "NebulaLog.h"
#include "Nebula.h"
#include "AuthManager.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::ImagePersistent::execute(
xmlrpc_c::paramList const& paramList,
xmlrpc_c::value * const retval)
{
string session;
int iid;
bool persistent_flag;
int uid;
int image_owner;
bool is_public;
Image * image;
ostringstream oss;
bool response;
const string method_name = "ImagePersistent";
vector<xmlrpc_c::value> arrayData;
xmlrpc_c::value_array * arrayresult;
NebulaLog::log("ReM",Log::DEBUG,"ImagePersistent invoked");
session = xmlrpc_c::value_string (paramList.getString(0));
iid = xmlrpc_c::value_int (paramList.getInt(1));
persistent_flag = xmlrpc_c::value_boolean(paramList.getBoolean(2));
// First, we need to authenticate the user
uid = ImagePersistent::upool->authenticate(session);
if ( uid == -1 )
{
goto error_authenticate;
}
// Get image from the ImagePool
image = ImagePersistent::ipool->get(iid,true);
if ( image == 0 )
{
goto error_image_get;
}
image_owner = image->get_uid();
is_public = image->isPublic();
image->unlock();
//Authorize the operation
if ( uid != 0 ) // uid == 0 means oneadmin
{
AuthRequest ar(uid);
ar.add_auth(AuthRequest::IMAGE,
iid,
AuthRequest::MANAGE,
image_owner,
is_public);
if (UserPool::authorize(ar) == -1)
{
goto error_authorize;
}
}
// Get the image locked again
image = ImagePersistent::ipool->get(iid,true);
if ( image == 0 )
{
goto error_image_get;
}
response = image->persistent(persistent_flag);
if (!response)
{
goto error_persistent;
}
ImagePersistent::ipool->update(image);
image->unlock();
arrayData.push_back(xmlrpc_c::value_boolean(true));
arrayData.push_back(xmlrpc_c::value_int(iid));
// Copy arrayresult into retval mem space
arrayresult = new xmlrpc_c::value_array(arrayData);
*retval = *arrayresult;
delete arrayresult; // and get rid of the original
return;
error_authenticate:
oss.str(authenticate_error(method_name));
goto error_common;
error_image_get:
oss.str(get_error(method_name, "IMAGE", iid));
goto error_common;
error_authorize:
oss.str(authorization_error(method_name, "MANAGE", "IMAGE", uid, iid));
goto error_common;
error_persistent:
oss << action_error(method_name, "MANAGE", "IMAGE", iid, NULL)
<< " Is the image public? An Image cannot be public and persistent.";
goto error_common;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));
NebulaLog::log("ReM",Log::ERROR,oss);
xmlrpc_c::value_array arrayresult_error(arrayData);
*retval = arrayresult_error;
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -38,6 +38,8 @@ void RequestManager::ImagePublish::execute(
bool is_public;
Image * image;
bool response;
ostringstream oss;
@ -99,7 +101,12 @@ void RequestManager::ImagePublish::execute(
goto error_image_get;
}
image->publish(publish_flag);
response = image->publish(publish_flag);
if (!response)
{
goto error_publish;
}
ImagePublish::ipool->update(image);
@ -128,6 +135,11 @@ error_authorize:
oss.str(authorization_error(method_name, "MANAGE", "IMAGE", uid, iid));
goto error_common;
error_publish:
oss << action_error(method_name, "MANAGE", "IMAGE", iid, NULL)
<< " Is the image persistent? An Image cannot be public and persistent.";
goto error_common;
error_common:
arrayData.push_back(xmlrpc_c::value_boolean(false)); // FAILURE
arrayData.push_back(xmlrpc_c::value_string(oss.str()));

View File

@ -41,6 +41,7 @@ source_files=[
'RequestManagerImageUpdate.cc',
'RequestManagerImageRemoveAttribute.cc',
'RequestManagerImagePublish.cc',
'RequestManagerImagePersistent.cc',
'RequestManagerImageEnable.cc',
'RequestManagerImagePoolInfo.cc',
'RequestManagerClusterAdd.cc',

View File

@ -815,8 +815,9 @@ int VirtualMachine::get_disk_images()
ImagePool * ipool;
VectorAttribute * disk;
int n_os = 0;
int n_cd = 0;
int n_os = 0; // Number of OS images
int n_cd = 0; // Number of CDROMS
int n_db = 0; // Number of DATABLOCKS
string type;
ostringstream oss;
@ -848,6 +849,9 @@ int VirtualMachine::get_disk_images()
case Image::CDROM:
n_cd++;
break;
case Image::DATABLOCK:
n_db++;
break;
default:
break;
}
@ -861,6 +865,11 @@ int VirtualMachine::get_disk_images()
{
goto error_max_cd;
}
if( n_db > 10 ) // Max. number of DATABLOCK images is 10
{
goto error_max_db;
}
}
else if ( rc == -1 )
{
@ -879,6 +888,11 @@ error_max_cd:
NebulaLog::log("ONE",Log::ERROR,
"VM can not use more than one CDROM image.");
goto error_common;
error_max_db:
NebulaLog::log("ONE",Log::ERROR,
"VM can not use more than 10 DATABLOCK images.");
goto error_common;
error_image:
NebulaLog::log("ONE",Log::ERROR, "Could not get disk image for VM");
@ -894,6 +908,7 @@ error_common:
void VirtualMachine::release_disk_images()
{
string iid;
string saveas;
int num_disks;
vector<Attribute const * > disks;
@ -929,11 +944,17 @@ void VirtualMachine::release_disk_images()
continue;
}
if (img->release_image() == true)
img->release_image();
saveas = disk->vector_value("SAVE_AS");
if ( !saveas.empty() && saveas == iid )
{
ipool->update(img);
img->enable(false);
}
ipool->update(img);
img->unlock();
}
}

View File

@ -25,7 +25,8 @@
/* -------------------------------------------------------------------------- */
VirtualMachinePool::VirtualMachinePool(SqlDB * db,
vector<const Attribute *> hook_mads)
vector<const Attribute *> hook_mads,
const string& hook_location)
: PoolSQL(db,VirtualMachine::table)
{
const VectorAttribute * vattr;
@ -79,6 +80,11 @@ VirtualMachinePool::VirtualMachinePool(SqlDB * db,
}
}
if (cmd[0] != '/')
{
cmd = hook_location + cmd;
}
if ( on == "CREATE" )
{
VirtualMachineAllocateHook * hook;

View File

@ -88,7 +88,7 @@ class VirtualMachinePoolFriend : public VirtualMachinePool
{
public:
VirtualMachinePoolFriend(SqlDB * db, vector<const Attribute *> hook_mads):
VirtualMachinePool(db, hook_mads)
VirtualMachinePool(db, hook_mads, "./")
{};