mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-25 06:03:36 +03:00
Merge branch 'master' of dsa-research.org:one
This commit is contained in:
commit
2c4171904b
@ -45,10 +45,9 @@ public:
|
||||
enum ImageState
|
||||
{
|
||||
INIT = 0, /** < Initialization state */
|
||||
LOCKED = 1, /** < FS operation on the image in progress, don't use */
|
||||
READY = 2, /** < Image ready to use */
|
||||
USED = 3, /** < Image in use */
|
||||
DISABLED = 4 /** < Image can not be instantiated by a VM */
|
||||
READY = 1, /** < Image ready to use */
|
||||
USED = 2, /** < Image in use */
|
||||
DISABLED = 3 /** < Image can not be instantiated by a VM */
|
||||
};
|
||||
|
||||
/**
|
||||
@ -140,16 +139,16 @@ public:
|
||||
|
||||
/**
|
||||
* Get an image to be used in a VM, and updates its state.
|
||||
* @param overwrite true if the image is going to be overwritten
|
||||
* @return 0 if success
|
||||
* @return 0 if success
|
||||
*/
|
||||
int acquire_image(bool overwrite);
|
||||
int acquire_image();
|
||||
|
||||
|
||||
/**
|
||||
* Releases an image being used by a VM
|
||||
* @return true if the image needs to be updated
|
||||
*/
|
||||
void release_image();
|
||||
bool release_image();
|
||||
|
||||
/**
|
||||
* Enables the image
|
||||
@ -208,7 +207,7 @@ public:
|
||||
* automatically increased.
|
||||
* @param img_type will be set to the used image's type
|
||||
*/
|
||||
int disk_attribute(VectorAttribute * disk, int* index, ImageType& img_type);
|
||||
int disk_attribute(VectorAttribute * disk, int* index, ImageType* img_type);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Template
|
||||
|
@ -168,14 +168,16 @@ public:
|
||||
/**
|
||||
* Generates a DISK attribute for VM templates using the Image metadata
|
||||
* @param disk the disk to be generated
|
||||
* @param disk_id the id for this disk
|
||||
* @param index number of datablock images used by the same VM. Will be
|
||||
* automatically increased.
|
||||
* @param img_type will be set to the used image's type
|
||||
* @return 0 on success, -1 error, -2 not using the pool
|
||||
*/
|
||||
int disk_attribute(VectorAttribute * disk, int* index,
|
||||
Image::ImageType& img_type);
|
||||
|
||||
int disk_attribute(VectorAttribute * disk,
|
||||
int disk_id,
|
||||
int * index,
|
||||
Image::ImageType * img_type);
|
||||
/**
|
||||
* Generates an Authorization token for the DISK attribute
|
||||
* @param disk the disk to be authorized
|
||||
|
@ -438,6 +438,34 @@ private:
|
||||
UserPool * upool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
class VirtualMachineSaveDisk: public xmlrpc_c::method
|
||||
{
|
||||
public:
|
||||
VirtualMachineSaveDisk(
|
||||
VirtualMachinePool * _vmpool,
|
||||
UserPool * _upool,
|
||||
ImagePool * _ipool):
|
||||
vmpool(_vmpool),
|
||||
upool(_upool),
|
||||
ipool(_ipool)
|
||||
{
|
||||
_signature="A:siii";
|
||||
_help="Sets the disk to be saved in the given image.";
|
||||
};
|
||||
|
||||
~VirtualMachineSaveDisk(){};
|
||||
|
||||
void execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval);
|
||||
|
||||
private:
|
||||
VirtualMachinePool * vmpool;
|
||||
UserPool * upool;
|
||||
ImagePool * ipool;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
|
@ -731,6 +731,18 @@ public:
|
||||
*/
|
||||
int generate_context(string &files);
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Image repository related functions
|
||||
// ------------------------------------------------------------------------
|
||||
/**
|
||||
* Set the SAVE_AS attribute for the "disk_id"th disk.
|
||||
* @param disk_id Index of the disk to save
|
||||
* @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);
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -28,56 +28,49 @@ end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
|
||||
require 'OpenNebula'
|
||||
require 'client_utilities'
|
||||
require 'fileutils'
|
||||
|
||||
TYPES=%w{OS CDROM DATABLOCK}
|
||||
require 'OpenNebula'
|
||||
include OpenNebula
|
||||
|
||||
if !(vm_id=ARGV[0])
|
||||
exit -1
|
||||
end
|
||||
|
||||
vm=OpenNebula::VirtualMachine.new_with_id(vm_id, get_one_client)
|
||||
vm.info
|
||||
template=vm['VM/TEMPLATE']
|
||||
if template['DISK']
|
||||
i = 0
|
||||
template.each('DISK') do |disk|
|
||||
source_path=VMDIR+"/#{vm_id}/disk.#{i}"
|
||||
if disk["NAME"] and File.exists?(source_path)
|
||||
if disk["SAVE_AS"]
|
||||
# Get Type
|
||||
image=OpenNebula::Image.new_with_id(disk['IMAGE_ID'], get_one_client)
|
||||
image.info
|
||||
type=image['TYPE']
|
||||
# Perform the allocate if all goes well
|
||||
image=OpenNebula::Image.new(
|
||||
OpenNebula::Image.build_xml, get_one_client)
|
||||
|
||||
template="NAME=#{disk['SAVE_AS']}\n"
|
||||
template+="TYPE=#{TYPES[type.to_i]}\n" if type
|
||||
result=image.allocate(template)
|
||||
client = Client.new()
|
||||
|
||||
# Get the allocated image
|
||||
image=OpenNebula::Image.new_with_id(image.id, get_one_client)
|
||||
image.info
|
||||
template=image['IMAGE/TEMPLATE']
|
||||
|
||||
if !is_successful?(result)
|
||||
exit -1
|
||||
end
|
||||
elsif disk["OVERWRITE"]
|
||||
# Get the allocated image
|
||||
image=OpenNebula::Image.new_with_id(disk['IMAGE_ID'], get_one_client)
|
||||
image.info
|
||||
image.disable
|
||||
end
|
||||
# Perform the copy to the image repo if needed
|
||||
if FileUtils.copy(source_path, image['SOURCE'])
|
||||
result=image.enable
|
||||
end
|
||||
vm = VirtualMachine.new(
|
||||
VirtualMachine.build_xml(vm_id),
|
||||
client)
|
||||
vm.info
|
||||
|
||||
if vm['TEMPLATE/DISK']
|
||||
vm.each('TEMPLATE/DISK') do |disk|
|
||||
|
||||
disk_id = disk["DISK_ID"]
|
||||
source_path = VMDIR+"/#{vm_id}/disk.#{disk_id}"
|
||||
|
||||
image_id = nil
|
||||
if disk["SAVE_AS"]
|
||||
image_id = disk["SAVE_AS"]
|
||||
end
|
||||
|
||||
if image_id and source_path
|
||||
image=Image.new(
|
||||
Image.build_xml(image_id),
|
||||
client)
|
||||
|
||||
result = image.info
|
||||
exit -1 if !is_successful?(result)
|
||||
|
||||
# Disable the Image for a safe overwriting
|
||||
image.disable
|
||||
|
||||
# Save the image file
|
||||
result = image.move(source_path, image['SOURCE'])
|
||||
exit -1 if !is_successful?(result)
|
||||
|
||||
image.enable
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
@ -342,7 +342,15 @@ Commands:
|
||||
|
||||
* resume (Resumes the execution of a saved VM)
|
||||
onevm resume <vm_id>
|
||||
|
||||
|
||||
* saveas (Set the specified vm's disk to be saved in a new image (image_name)
|
||||
when the vm shutdowns)
|
||||
onevm saveas <vm_id> <disk_id> <image_name>
|
||||
|
||||
* save (Set the specified vm's disk to be saved, overwriting the original image
|
||||
when the vm shutdowns)
|
||||
onevm saveas <vm_id> <disk_id>
|
||||
|
||||
* delete (Deletes a VM from the pool and DB)
|
||||
onevm delete <vm_id>
|
||||
|
||||
@ -670,7 +678,81 @@ when "delete"
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
when "saveas"
|
||||
check_parameters("saveas", 3)
|
||||
vm_id = get_vm_id(ARGV[0])
|
||||
disk_id = ARGV[1]
|
||||
image_name = ARGV[2]
|
||||
|
||||
# Get the Image ID for this disk
|
||||
vm = OpenNebula::VirtualMachine.new(
|
||||
OpenNebula::VirtualMachine.build_xml(vm_id),
|
||||
get_one_client)
|
||||
|
||||
result = vm.info
|
||||
if !is_successful?(result)
|
||||
puts result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
image_id = vm["TEMPLATE/DISK[DISK_ID=\"#{disk_id}\"]/IMAGE_ID"]
|
||||
|
||||
# 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
|
||||
|
||||
if ops[:type]
|
||||
image_type = ops[:type]
|
||||
else
|
||||
image_type = image.type_str
|
||||
end
|
||||
|
||||
# Build the template and allocate the new Image
|
||||
template = "NAME=#{image_name}\n"
|
||||
template << "TYPE=#{image_type}\n" if type
|
||||
|
||||
|
||||
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
|
||||
|
||||
result = vm.save_disk(disk_id.to_i, image.id)
|
||||
|
||||
when "save"
|
||||
check_parameters("save", 2)
|
||||
vm_id = get_vm_id(ARGV[0])
|
||||
disk_id = ARGV[1]
|
||||
|
||||
# Get the Image ID for this disk
|
||||
vm = OpenNebula::VirtualMachine.new(
|
||||
OpenNebula::VirtualMachine.build_xml(vm_id),
|
||||
get_one_client)
|
||||
|
||||
result = vm.info
|
||||
if !is_successful?(result)
|
||||
puts result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
image_id = vm["TEMPLATE/DISK[DISK_ID=\"#{disk_id}\"]/IMAGE_ID"]
|
||||
|
||||
result = vm.save_disk(disk_id.to_i, image_id)
|
||||
|
||||
when "show"
|
||||
check_parameters("get_info", 1)
|
||||
args=expand_args(ARGV)
|
||||
|
@ -14,12 +14,6 @@ NAME = "<%= @vm_info['NAME'] %>"
|
||||
<% @vm_info.each('DISK') do |disk| %>
|
||||
<% if disk['STORAGE'] && disk.attr('STORAGE','href') %>
|
||||
DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %>
|
||||
<% if disk['OVERWRITE'] %>
|
||||
,OVERWRITE = "yes"
|
||||
<% end %>
|
||||
<% if disk['SAVE_AS'] %>
|
||||
,SAVE_AS = "<%= disk['SAVE_AS'] %>"
|
||||
<% end %>
|
||||
]
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
@ -14,12 +14,6 @@ NAME = "<%= @vm_info['NAME'] %>"
|
||||
<% @vm_info.each('DISK') do |disk| %>
|
||||
<% if disk['STORAGE'] && disk.attr('STORAGE','href') %>
|
||||
DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %>
|
||||
<% if disk['OVERWRITE'] %>
|
||||
,OVERWRITE = "yes"
|
||||
<% end %>
|
||||
<% if disk['SAVE_AS'] %>
|
||||
,SAVE_AS = "<%= disk['SAVE_AS'] %>"
|
||||
<% end %>
|
||||
]
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
@ -14,12 +14,6 @@ NAME = "<%= @vm_info['NAME'] %>"
|
||||
<% @vm_info.each('DISK') do |disk| %>
|
||||
<% if disk['STORAGE'] && disk.attr('STORAGE','href') %>
|
||||
DISK = [ IMAGE_ID = <%= disk.attr('STORAGE','href').split('/').last %>
|
||||
<% if disk['OVERWRITE'] %>
|
||||
,OVERWRITE = "yes"
|
||||
<% end %>
|
||||
<% if disk['SAVE_AS'] %>
|
||||
,SAVE_AS = "<%= disk['SAVE_AS'] %>"
|
||||
<% end %>
|
||||
]
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
@ -33,9 +33,6 @@ class VirtualMachineOCCI < VirtualMachine
|
||||
<STORAGE href="<%= base_url %>/storage/<%= disk['IMAGE_ID'] %>" name="<%= disk['IMAGE'] %>"/>
|
||||
<TYPE><%= disk['TYPE'] %></TYPE>
|
||||
<TARGET><%= disk['TARGET'] %></TARGET>
|
||||
<% if disk['CLONE']=='NO' %>
|
||||
<OVERWRITE/>
|
||||
<% end %>
|
||||
<% if disk['SAVE_AS'] %>
|
||||
<SAVE_AS><%= disk['SAVE_AS'] %></SAVE_AS>
|
||||
<% end %>
|
||||
|
@ -478,7 +478,7 @@ string& Image::to_str(string& str) const
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Image::acquire_image(bool overwrite)
|
||||
int Image::acquire_image()
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
@ -487,30 +487,14 @@ int Image::acquire_image(bool overwrite)
|
||||
{
|
||||
case READY:
|
||||
running_vms++;
|
||||
|
||||
if ( overwrite == true)
|
||||
{
|
||||
state = LOCKED;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = USED;
|
||||
}
|
||||
state = USED;
|
||||
break;
|
||||
|
||||
case USED:
|
||||
if ( overwrite == true)
|
||||
{
|
||||
rc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
running_vms++;
|
||||
}
|
||||
running_vms++;
|
||||
break;
|
||||
|
||||
case DISABLED:
|
||||
case LOCKED:
|
||||
default:
|
||||
rc = -1;
|
||||
break;
|
||||
@ -522,18 +506,21 @@ int Image::acquire_image(bool overwrite)
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void Image::release_image()
|
||||
bool Image::release_image()
|
||||
{
|
||||
bool dirty = false;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case USED:
|
||||
case LOCKED:
|
||||
running_vms--;
|
||||
|
||||
if ( running_vms == 0)
|
||||
{
|
||||
state = READY;
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
break;
|
||||
|
||||
case DISABLED:
|
||||
@ -541,31 +528,25 @@ void Image::release_image()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Image::disk_attribute( VectorAttribute * disk,
|
||||
int * index,
|
||||
ImageType& img_type)
|
||||
int * index,
|
||||
ImageType* img_type)
|
||||
{
|
||||
string overwrite;
|
||||
string saveas;
|
||||
string bus;
|
||||
|
||||
ostringstream iid;
|
||||
|
||||
img_type = type;
|
||||
|
||||
overwrite = disk->vector_value("OVERWRITE");
|
||||
saveas = disk->vector_value("SAVE_AS");
|
||||
*img_type = type;
|
||||
bus = disk->vector_value("BUS");
|
||||
iid << oid;
|
||||
|
||||
transform(overwrite.begin(), overwrite.end(), overwrite.begin(),
|
||||
(int(*)(int))toupper);
|
||||
|
||||
string template_bus;
|
||||
string prefix;
|
||||
|
||||
@ -576,7 +557,7 @@ int Image::disk_attribute( VectorAttribute * disk,
|
||||
// Acquire the image
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
if ( acquire_image(overwrite == "YES") != 0 )
|
||||
if ( acquire_image() != 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@ -591,16 +572,6 @@ int Image::disk_attribute( VectorAttribute * disk,
|
||||
new_disk.insert(make_pair("IMAGE_ID", iid.str()));
|
||||
new_disk.insert(make_pair("SOURCE", source));
|
||||
|
||||
if (!overwrite.empty())
|
||||
{
|
||||
new_disk.insert(make_pair("OVERWRITE",overwrite));
|
||||
}
|
||||
|
||||
if (!saveas.empty())
|
||||
{
|
||||
new_disk.insert(make_pair("SAVE_AS",saveas));
|
||||
}
|
||||
|
||||
if (bus.empty())
|
||||
{
|
||||
if (!template_bus.empty())
|
||||
@ -617,36 +588,20 @@ int Image::disk_attribute( VectorAttribute * disk,
|
||||
// TYPE, READONLY, CLONE, and SAVE attributes
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
new_disk.insert(make_pair("CLONE","YES"));
|
||||
new_disk.insert(make_pair("SAVE","NO"));
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case OS:
|
||||
case DATABLOCK:
|
||||
new_disk.insert(make_pair("TYPE","DISK"));
|
||||
new_disk.insert(make_pair("READONLY","NO"));
|
||||
|
||||
if (overwrite == "YES")
|
||||
{
|
||||
new_disk.insert(make_pair("CLONE","NO"));
|
||||
new_disk.insert(make_pair("SAVE","YES"));
|
||||
}
|
||||
else if (!saveas.empty())
|
||||
{
|
||||
new_disk.insert(make_pair("CLONE","YES"));
|
||||
new_disk.insert(make_pair("SAVE","YES"));
|
||||
}
|
||||
else
|
||||
{
|
||||
new_disk.insert(make_pair("CLONE","YES"));
|
||||
new_disk.insert(make_pair("SAVE","NO"));
|
||||
}
|
||||
break;
|
||||
|
||||
case CDROM:
|
||||
new_disk.insert(make_pair("TYPE","CDROM"));
|
||||
new_disk.insert(make_pair("READONLY","YES"));
|
||||
|
||||
new_disk.insert(make_pair("CLONE","YES"));
|
||||
new_disk.insert(make_pair("SAVE","NO"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -165,12 +165,16 @@ int ImagePool::dump(ostringstream& oss, const string& where)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int ImagePool::disk_attribute( VectorAttribute * disk,
|
||||
int * index,
|
||||
Image::ImageType& img_type)
|
||||
int ImagePool::disk_attribute(VectorAttribute * disk,
|
||||
int disk_id,
|
||||
int * index,
|
||||
Image::ImageType * img_type)
|
||||
{
|
||||
string source;
|
||||
Image * img = 0;
|
||||
int rc;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
source = disk->vector_value("IMAGE");
|
||||
|
||||
@ -181,32 +185,68 @@ int ImagePool::disk_attribute( VectorAttribute * disk,
|
||||
|
||||
source = disk->vector_value("IMAGE_ID");
|
||||
|
||||
if (source.empty())
|
||||
if (!source.empty())
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
is.str(source);
|
||||
is >> image_id;
|
||||
|
||||
is.str(source);
|
||||
is >> image_id;
|
||||
if( !is.fail() )
|
||||
{
|
||||
img = get(image_id,true);
|
||||
|
||||
if( !is.fail() )
|
||||
{
|
||||
img = get(image_id,true);
|
||||
if (img == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
img = get(source,true);
|
||||
|
||||
if (img == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (img == 0)
|
||||
{
|
||||
return -1;
|
||||
string type = disk->vector_value("TYPE");
|
||||
|
||||
transform(type.begin(), type.end(), type.begin(), (int(*)(int))toupper);
|
||||
|
||||
if( type == "SWAP" )
|
||||
{
|
||||
string target = disk->vector_value("TARGET");
|
||||
|
||||
if ( target.empty() )
|
||||
{
|
||||
string dev_prefix = _default_dev_prefix;
|
||||
|
||||
dev_prefix += "d";
|
||||
|
||||
disk->replace("TARGET", dev_prefix);
|
||||
}
|
||||
}
|
||||
|
||||
rc = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = img->disk_attribute(disk, index, img_type);
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
update(img);
|
||||
}
|
||||
|
||||
img->unlock();
|
||||
}
|
||||
|
||||
int rc = img->disk_attribute(disk,index, img_type);
|
||||
|
||||
img->unlock();
|
||||
oss << disk_id;
|
||||
disk->replace("DISK_ID",oss.str());
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -198,6 +198,20 @@ module OpenNebula
|
||||
|
||||
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)
|
||||
rescue Exception => e
|
||||
return OpenNebula::Error.new(e.message)
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
def dd(size, source)
|
||||
if source.nil? or size.nil?
|
||||
|
@ -10,7 +10,8 @@ module OpenNebula
|
||||
:allocate => "vm.allocate",
|
||||
:action => "vm.action",
|
||||
:migrate => "vm.migrate",
|
||||
:deploy => "vm.deploy"
|
||||
:deploy => "vm.deploy",
|
||||
:savedisk => "vm.savedisk"
|
||||
}
|
||||
|
||||
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED}
|
||||
@ -167,6 +168,15 @@ module OpenNebula
|
||||
|
||||
return rc
|
||||
end
|
||||
|
||||
def save_as(disk_id, image_id)
|
||||
return Error.new('ID not defined') if !@pe_id
|
||||
|
||||
rc = @client.call(VM_METHODS[:savedisk], @pe_id, disk_id, image_id)
|
||||
rc = nil if !OpenNebula.is_error?(rc)
|
||||
|
||||
return rc
|
||||
end
|
||||
|
||||
#######################################################################
|
||||
# Helpers to get VirtualMachine information
|
||||
|
@ -224,7 +224,10 @@ void RequestManager::register_xml_methods()
|
||||
|
||||
xmlrpc_c::methodPtr vm_action(new
|
||||
RequestManager::VirtualMachineAction(vmpool,upool));
|
||||
|
||||
|
||||
xmlrpc_c::methodPtr vm_savedisk(new
|
||||
RequestManager::VirtualMachineSaveDisk(vmpool,upool,ipool));
|
||||
|
||||
xmlrpc_c::methodPtr vm_info(new
|
||||
RequestManager::VirtualMachineInfo(vmpool,upool));
|
||||
|
||||
@ -322,6 +325,7 @@ void RequestManager::register_xml_methods()
|
||||
RequestManagerRegistry.addMethod("one.vm.action", vm_action);
|
||||
RequestManagerRegistry.addMethod("one.vm.migrate", vm_migrate);
|
||||
RequestManagerRegistry.addMethod("one.vm.info", vm_info);
|
||||
RequestManagerRegistry.addMethod("one.vm.savedisk",vm_savedisk);
|
||||
|
||||
RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info);
|
||||
|
||||
|
@ -53,12 +53,53 @@ void RequestManager::VirtualMachineDeploy::execute(
|
||||
NebulaLog::log("ReM",Log::DEBUG,"VirtualMachineDeploy invoked");
|
||||
|
||||
//Parse Arguments
|
||||
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
vid = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
hid = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
|
||||
//Get host info to deploy the VM
|
||||
// -------------------------------------------------------------------------
|
||||
// Authenticate the user
|
||||
// -------------------------------------------------------------------------
|
||||
rc = VirtualMachineDeploy::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Get user data
|
||||
// -------------------------------------------------------------------------
|
||||
vm = VirtualMachineDeploy::vmpool->get(vid,true);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
goto error_vm_get;
|
||||
}
|
||||
|
||||
uid = vm->get_uid();
|
||||
|
||||
vm->unlock();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Authorize the operation
|
||||
// -------------------------------------------------------------------------
|
||||
if ( rc != 0 ) // rc == 0 means oneadmin
|
||||
{
|
||||
AuthRequest ar(rc);
|
||||
|
||||
ar.add_auth(AuthRequest::VM,vid,AuthRequest::MANAGE,uid,false);
|
||||
ar.add_auth(AuthRequest::HOST,hid,AuthRequest::USE,0,false);
|
||||
|
||||
if (UserPool::authorize(ar) == -1)
|
||||
{
|
||||
goto error_authorize;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Get host info to deploy the VM
|
||||
// -------------------------------------------------------------------------
|
||||
host = VirtualMachineDeploy::hpool->get(hid,true);
|
||||
|
||||
if ( host == 0 )
|
||||
@ -74,7 +115,9 @@ void RequestManager::VirtualMachineDeploy::execute(
|
||||
|
||||
host->unlock();
|
||||
|
||||
//Get the VM
|
||||
// -------------------------------------------------------------------------
|
||||
// Deploy the VM
|
||||
// -------------------------------------------------------------------------
|
||||
vm = VirtualMachineDeploy::vmpool->get(vid,true);
|
||||
|
||||
if ( vm == 0 )
|
||||
@ -82,36 +125,11 @@ void RequestManager::VirtualMachineDeploy::execute(
|
||||
goto error_vm_get;
|
||||
}
|
||||
|
||||
uid = vm->get_uid();
|
||||
|
||||
if ( vm->get_state() != VirtualMachine::PENDING )
|
||||
{
|
||||
goto error_state;
|
||||
}
|
||||
|
||||
//Authenticate the user
|
||||
rc = VirtualMachineDeploy::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
//Authorize the operation
|
||||
if ( rc != 0 ) // rc == 0 means oneadmin
|
||||
{
|
||||
AuthRequest ar(rc);
|
||||
|
||||
ar.add_auth(AuthRequest::VM,vid,AuthRequest::MANAGE,uid,false);
|
||||
ar.add_auth(AuthRequest::HOST,hid,AuthRequest::USE,0,false);
|
||||
|
||||
if (UserPool::authorize(ar) == -1)
|
||||
{
|
||||
goto error_authorize;
|
||||
}
|
||||
}
|
||||
|
||||
//Update host info and share usage (cpu,mem....)
|
||||
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
|
||||
|
||||
rc = VirtualMachineDeploy::vmpool->update_history(vm);
|
||||
@ -123,12 +141,13 @@ void RequestManager::VirtualMachineDeploy::execute(
|
||||
|
||||
vmpool->update(vm); //Insert last_seq in the DB
|
||||
|
||||
//Deploy the VM
|
||||
dm->deploy(vm);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
// Send results to client
|
||||
// -------------------------------------------------------------------------
|
||||
// Results
|
||||
// -------------------------------------------------------------------------
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
@ -154,11 +173,11 @@ error_state:
|
||||
|
||||
error_authenticate:
|
||||
oss.str(authenticate_error(method_name));
|
||||
goto error_common_lock;
|
||||
goto error_common;
|
||||
|
||||
error_authorize:
|
||||
oss.str(authorization_error(method_name, "MANAGE", "VM", rc, vid));
|
||||
goto error_common_lock;
|
||||
goto error_common;
|
||||
|
||||
error_history:
|
||||
oss.str(action_error(method_name, "INSERT HISTORY", "VM", vid, rc));
|
||||
@ -182,4 +201,3 @@ error_common:
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
166
src/rm/RequestManagerSaveDisk.cc
Normal file
166
src/rm/RequestManagerSaveDisk.cc
Normal file
@ -0,0 +1,166 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void RequestManager::VirtualMachineSaveDisk::execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
xmlrpc_c::value * const retval)
|
||||
{
|
||||
string session;
|
||||
|
||||
int vm_id;
|
||||
int disk_id;
|
||||
int img_id;
|
||||
|
||||
int vm_owner;
|
||||
int img_owner;
|
||||
bool img_public;
|
||||
|
||||
int rc;
|
||||
|
||||
const string method_name = "VirtualMachineSaveDisk";
|
||||
|
||||
VirtualMachine * vm;
|
||||
Image * image;
|
||||
|
||||
vector<xmlrpc_c::value> arrayData;
|
||||
xmlrpc_c::value_array * arrayresult;
|
||||
|
||||
ostringstream oss;
|
||||
|
||||
NebulaLog::log("ReM",Log::DEBUG,"VirtualMachineSaveDisk invoked");
|
||||
|
||||
//Parse Arguments
|
||||
|
||||
session = xmlrpc_c::value_string(paramList.getString(0));
|
||||
vm_id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
disk_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
img_id = xmlrpc_c::value_int(paramList.getInt(3));
|
||||
|
||||
//Authenticate the user
|
||||
rc = VirtualMachineSaveDisk::upool->authenticate(session);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
goto error_authenticate;
|
||||
}
|
||||
|
||||
// Check that the image exists
|
||||
image = VirtualMachineSaveDisk::ipool->get(img_id,true);
|
||||
|
||||
if ( image == 0 )
|
||||
{
|
||||
goto error_image_get;
|
||||
}
|
||||
|
||||
img_owner = image->get_uid();
|
||||
img_public = image->isPublic();
|
||||
|
||||
image->unlock();
|
||||
|
||||
//Get the VM
|
||||
vm = VirtualMachineSaveDisk::vmpool->get(vm_id,true);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
goto error_vm_get;
|
||||
}
|
||||
|
||||
vm_owner = vm->get_uid();
|
||||
|
||||
vm->unlock();
|
||||
|
||||
//Authorize the operation
|
||||
if ( rc != 0 ) // rc == 0 means oneadmin
|
||||
{
|
||||
AuthRequest ar(rc);
|
||||
|
||||
ar.add_auth(AuthRequest::VM,vm_id,AuthRequest::MANAGE,vm_owner,false);
|
||||
ar.add_auth(AuthRequest::IMAGE,img_id,
|
||||
AuthRequest::MANAGE,img_owner,img_public);
|
||||
|
||||
if (UserPool::authorize(ar) == -1)
|
||||
{
|
||||
goto error_authorize;
|
||||
}
|
||||
}
|
||||
|
||||
vm = VirtualMachineSaveDisk::vmpool->get(vm_id,true);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
goto error_vm_get;
|
||||
}
|
||||
|
||||
vm->save_disk(disk_id, img_id);
|
||||
|
||||
VirtualMachineSaveDisk::vmpool->update(vm);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
// Send results to client
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(true));
|
||||
|
||||
arrayresult = new xmlrpc_c::value_array(arrayData);
|
||||
|
||||
*retval = *arrayresult;
|
||||
|
||||
delete arrayresult;
|
||||
|
||||
return;
|
||||
|
||||
error_image_get:
|
||||
oss.str(get_error(method_name, "IMAGE", img_id));
|
||||
goto error_common;
|
||||
|
||||
error_vm_get:
|
||||
oss.str(get_error(method_name, "VM", vm_id));
|
||||
goto error_common;
|
||||
|
||||
error_authenticate:
|
||||
oss.str(authenticate_error(method_name));
|
||||
goto error_common_lock;
|
||||
|
||||
error_authorize:
|
||||
oss.str(authorization_error(method_name, "MANAGE", "VM/IMAGE", rc, vm_id));
|
||||
goto error_common_lock;
|
||||
|
||||
error_common_lock:
|
||||
vm->unlock();
|
||||
|
||||
error_common:
|
||||
arrayData.push_back(xmlrpc_c::value_boolean(false));
|
||||
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;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -27,6 +27,7 @@ source_files=[
|
||||
'RequestManagerAllocate.cc',
|
||||
'RequestManagerDeploy.cc',
|
||||
'RequestManagerMigrate.cc',
|
||||
'RequestManagerSaveDisk.cc',
|
||||
'RequestManagerInfo.cc',
|
||||
'RequestManagerPoolInfo.cc',
|
||||
'RequestManagerHostAllocate.cc',
|
||||
|
@ -829,6 +829,9 @@ int VirtualMachine::get_disk_images()
|
||||
int n_cd = 0;
|
||||
string type;
|
||||
|
||||
ostringstream oss;
|
||||
Image::ImageType img_type;
|
||||
|
||||
Nebula& nd = Nebula::instance();
|
||||
ipool = nd.get_ipool();
|
||||
|
||||
@ -836,7 +839,6 @@ int VirtualMachine::get_disk_images()
|
||||
|
||||
for(int i=0, index=0; i<num_disks; i++)
|
||||
{
|
||||
|
||||
disk = dynamic_cast<VectorAttribute * >(disks[i]);
|
||||
|
||||
if ( disk == 0 )
|
||||
@ -844,70 +846,40 @@ int VirtualMachine::get_disk_images()
|
||||
continue;
|
||||
}
|
||||
|
||||
Image::ImageType img_type;
|
||||
rc = ipool->disk_attribute(disk, &index, img_type);
|
||||
rc = ipool->disk_attribute(disk, i, &index, &img_type);
|
||||
|
||||
switch(rc)
|
||||
if (rc == 0 )
|
||||
{
|
||||
case 0: // OK
|
||||
switch(img_type)
|
||||
{
|
||||
case Image::OS:
|
||||
n_os++;
|
||||
break;
|
||||
case Image::CDROM:
|
||||
n_cd++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch(img_type)
|
||||
{
|
||||
case Image::OS:
|
||||
n_os++;
|
||||
break;
|
||||
case Image::CDROM:
|
||||
n_cd++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( n_os > 1 ) // Max. number of OS images is 1
|
||||
{
|
||||
goto error_max_os;
|
||||
}
|
||||
if( n_os > 1 ) // Max. number of OS images is 1
|
||||
{
|
||||
goto error_max_os;
|
||||
}
|
||||
|
||||
if( n_cd > 1 ) // Max. number of CDROM images is 1
|
||||
{
|
||||
goto error_max_cd;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case -2: // not using the Image pool
|
||||
type = disk->vector_value("TYPE");
|
||||
|
||||
transform (type.begin(), type.end(), type.begin(),
|
||||
(int(*)(int))toupper);
|
||||
|
||||
if( type == "SWAP" )
|
||||
{
|
||||
string target = disk->vector_value("TARGET");
|
||||
|
||||
if ( target.empty() )
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
string dev_prefix;
|
||||
|
||||
nd.get_configuration_attribute("DEFAULT_DEVICE_PREFIX",
|
||||
dev_prefix);
|
||||
dev_prefix += "d";
|
||||
|
||||
disk->replace("TARGET", dev_prefix);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case -1: // ERROR
|
||||
goto error_image;
|
||||
break;
|
||||
if( n_cd > 1 ) // Max. number of CDROM images is 1
|
||||
{
|
||||
goto error_max_cd;
|
||||
}
|
||||
}
|
||||
else if ( rc == -1 )
|
||||
{
|
||||
goto error_image;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
error_max_os:
|
||||
NebulaLog::log("ONE",Log::ERROR,
|
||||
"VM can not use more than one OS image.");
|
||||
@ -967,7 +939,10 @@ void VirtualMachine::release_disk_images()
|
||||
continue;
|
||||
}
|
||||
|
||||
img->release_image();
|
||||
if (img->release_image() == true)
|
||||
{
|
||||
ipool->update(img);
|
||||
}
|
||||
|
||||
img->unlock();
|
||||
}
|
||||
@ -1123,6 +1098,52 @@ int VirtualMachine::generate_context(string &files)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int VirtualMachine::save_disk(int disk_id, int img_id)
|
||||
{
|
||||
int num_disks;
|
||||
vector<Attribute * > disks;
|
||||
VectorAttribute * disk;
|
||||
|
||||
string disk_id_str;
|
||||
int tmp_disk_id;
|
||||
|
||||
ostringstream oss;
|
||||
istringstream iss;
|
||||
|
||||
|
||||
num_disks = vm_template->get("DISK",disks);
|
||||
|
||||
for(int i=0; i<num_disks; i++)
|
||||
{
|
||||
disk = dynamic_cast<VectorAttribute * >(disks[i]);
|
||||
|
||||
if ( disk == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
disk_id_str = disk->vector_value("DISK_ID");
|
||||
|
||||
iss.str(disk_id_str);
|
||||
iss >> tmp_disk_id;
|
||||
|
||||
if( tmp_disk_id == disk_id )
|
||||
{
|
||||
disk->replace("SAVE", "YES");
|
||||
|
||||
oss << (img_id);
|
||||
disk->replace("SAVE_AS", oss.str());
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
pthread_mutex_t VirtualMachine::lex_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
extern "C"
|
||||
|
Loading…
x
Reference in New Issue
Block a user