1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-06 12:58:18 +03:00

Merge remote-tracking branch 'origin/feature-1556'

This commit is contained in:
Carlos Martín 2013-01-09 12:24:25 +01:00
commit 9e0a06468e
12 changed files with 243 additions and 70 deletions

View File

@ -53,7 +53,7 @@ public:
TemplateUpdateTemplate():
RequestManagerUpdateTemplate("TemplateUpdateTemplate",
"Updates a virtual machine template")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_tpool();
auth_object = PoolObjectSQL::TEMPLATE;
@ -65,13 +65,31 @@ public:
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachineUpdateTemplate: public RequestManagerUpdateTemplate
{
public:
VirtualMachineUpdateTemplate():
RequestManagerUpdateTemplate("VirtualMachineUpdateTemplate",
"Updates a virtual machine user template")
{
Nebula& nd = Nebula::instance();
pool = nd.get_vmpool();
auth_object = PoolObjectSQL::VM;
};
~VirtualMachineUpdateTemplate(){};
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class ImageUpdateTemplate: public RequestManagerUpdateTemplate
{
public:
ImageUpdateTemplate():
RequestManagerUpdateTemplate("ImageUpdateTemplate",
"Updates an image template")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_ipool();
auth_object = PoolObjectSQL::IMAGE;
@ -89,7 +107,7 @@ public:
HostUpdateTemplate():
RequestManagerUpdateTemplate("HostUpdateTemplate",
"Updates a host template")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_hpool();
auth_object = PoolObjectSQL::HOST;
@ -107,7 +125,7 @@ public:
VirtualNetworkUpdateTemplate():
RequestManagerUpdateTemplate("VirtualNetworkUpdateTemplate",
"Updates a vnet template")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_vnpool();
auth_object = PoolObjectSQL::NET;
@ -125,7 +143,7 @@ public:
UserUpdateTemplate():
RequestManagerUpdateTemplate("UserUpdateTemplate",
"Updates a user template")
{
{
Nebula& nd = Nebula::instance();
pool = nd.get_upool();
auth_object = PoolObjectSQL::USER;

View File

@ -702,6 +702,13 @@ public:
*(static_cast<VirtualMachineTemplate *>(obj_template)));
};
/**
* This function replaces the *user template*.
* @param tmpl_str new contents
* @param error string describing the error if any
* @return 0 on success
*/
int replace_template(const string& tmpl_str, string& error);
// ------------------------------------------------------------------------
// States
@ -1044,6 +1051,12 @@ private:
*/
FileLog * _log;
/**
* User template to store custom metadata. This template can be updated
*
*/
Template * user_obj_template;
// *************************************************************************
// DataBase implementation (Private)
// *************************************************************************

View File

@ -87,6 +87,7 @@
<!-- NET_RX: Received bytes from the network -->
<xs:element name="NET_RX" type="xs:integer"/>
<xs:element name="TEMPLATE" type="xs:anyType"/>
<xs:element name="USER_TEMPLATE" type="xs:anyType"/>
<xs:element name="HISTORY_RECORDS">
<xs:complexType>
<xs:sequence>

View File

@ -623,7 +623,7 @@ EOT
end
end
def OpenNebulaHelper.update_template(id, resource, path=nil)
def OpenNebulaHelper.update_template(id, resource, path=nil, xpath='TEMPLATE')
unless path
require 'tempfile'
@ -637,7 +637,7 @@ EOT
exit -1
end
tmp << resource.template_str
tmp << resource.template_like_str(xpath)
tmp.flush
editor_path = ENV["EDITOR"] ? ENV["EDITOR"] : EDITOR_PATH

View File

@ -215,9 +215,15 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE TEMPLATE",false)
puts vm.template_str
if vm.has_elements?("/VM/HISTORY_RECORDS")
if vm.has_elements?("/VM/USER_TEMPLATE")
puts
CLIHelper.print_header(str_h1 % "USER TEMPLATE",false)
puts vm.template_like_str('USER_TEMPLATE')
end
if vm.has_elements?("/VM/HISTORY_RECORDS")
puts
CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE HISTORY",false)
format_history(vm)

View File

@ -174,6 +174,18 @@ cmd=CommandParser::CmdParser.new(ARGV) do
exit_code
end
update_desc = <<-EOT.unindent
Update the user template contents. If a path is not provided the
editor will be launched to modify the current content.
EOT
command :update, update_desc, :vmid, [:file, nil] do
helper.perform_action(args[0],options,"modified") do |vm|
str = OpenNebulaHelper.update_template(args[0], vm, args[1],'USER_TEMPLATE')
vm.update(str)
end
end
delete_desc = <<-EOT.unindent
Deletes the given VM

View File

@ -40,6 +40,7 @@ public class VirtualMachine extends PoolElement{
private static final String ATTACH = METHOD_PREFIX + "attach";
private static final String DETACH = METHOD_PREFIX + "detach";
private static final String RENAME = METHOD_PREFIX + "rename";
private static final String UPDATE = METHOD_PREFIX + "update";
private static final String[] VM_STATES =
{
@ -168,6 +169,19 @@ public class VirtualMachine extends PoolElement{
return client.call(ALLOCATE, description, onHold);
}
/**
* Replaces the user template contents for the given VM.
*
* @param client XML-RPC Client.
* @param id The id of the target vm.
* @param new_template New template contents
* @return If an error occurs the error message contains the reason.
*/
public static OneResponse update(Client client, int id, String new_template)
{
return client.call(UPDATE, id, new_template);
}
/**
* Retrieves the information of the given VM.
*
@ -544,6 +558,17 @@ public class VirtualMachine extends PoolElement{
return rename(client, id, name);
}
/**
* Replaces this VM's user template contents.
*
* @param new_template New template contents
* @return If an error occurs the error message contains the reason.
*/
public OneResponse update(String new_template)
{
return client.call(UPDATE, id, new_template);
}
// =================================
// Helpers
// =================================

View File

@ -36,10 +36,11 @@ module OpenNebula
:monitoring => "vm.monitoring",
:attach => "vm.attach",
:detach => "vm.detach",
:rename => "vm.rename"
:rename => "vm.rename",
:update => "vm.update"
}
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED
POWEROFF}
LCM_STATE=%w{LCM_INIT PROLOG BOOT RUNNING MIGRATE SAVE_STOP SAVE_SUSPEND
@ -145,6 +146,15 @@ module OpenNebula
super(VM_METHODS[:allocate], description, hold)
end
# Replaces the template contents
#
# @param new_template New template contents. If no argument is provided
# the object will be updated using the @xml variable
def update(new_template=nil)
super(VM_METHODS[:update], new_template)
end
# Initiates the instance of the VM on the target host.
#
# @param host_id [Interger] The host id (hid) of the target host where

View File

@ -345,6 +345,35 @@ module Migrator
@db.run "DROP TABLE old_cluster_pool;"
########################################################################
# Feature #1556: New elem USER_TEMPLATE
########################################################################
@db.run "ALTER TABLE vm_pool RENAME TO old_vm_pool;"
@db.run "CREATE TABLE vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER);"
@db.fetch("SELECT * FROM old_vm_pool") do |row|
doc = Document.new(row[:body])
doc.root.add_element("USER_TEMPLATE")
@db[:vm_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => doc.root.to_s,
:uid => row[:uid],
:gid => row[:gid],
:last_poll => row[:last_poll],
:state => row[:state],
:lcm_state => row[:lcm_state],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u])
end
@db.run "DROP TABLE old_vm_pool;"
########################################################################
#
# Banner for the new /var/lib/one/vms directory

View File

@ -182,7 +182,10 @@ int PoolObjectSQL::replace_template(const string& tmpl_str, string& error)
return -1;
}
delete obj_template;
if ( obj_template != 0 )
{
delete obj_template;
}
obj_template = new_tmpl;

View File

@ -46,9 +46,9 @@
#include <netinet/tcp.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <string.h>
#include <cstring>
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -64,41 +64,41 @@ extern "C" void * rm_action_loop(void *arg)
NebulaLog::log("ReM",Log::INFO,"Request Manager started.");
rm = static_cast<RequestManager *>(arg);
rm->am.loop(0,0);
NebulaLog::log("ReM",Log::INFO,"Request Manager stopped.");
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
extern "C" void * rm_xml_server_loop(void *arg)
{
RequestManager * rm;
if ( arg == 0 )
{
return 0;
}
rm = static_cast<RequestManager *>(arg);
// Set cancel state for the thread
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,0);
//Start the server
rm->AbyssServer = new xmlrpc_c::serverAbyss(xmlrpc_c::serverAbyss::constrOpt()
.registryP(&rm->RequestManagerRegistry)
.logFileName(rm->xml_log_file)
.socketFd(rm->socket_fd));
rm->AbyssServer->run();
return 0;
@ -112,20 +112,20 @@ int RequestManager::setup_socket()
int rc;
int yes = 1;
struct sockaddr_in rm_addr;
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if ( socket_fd == -1 )
{
ostringstream oss;
oss << "Cannot open server socket: " << strerror(errno);
NebulaLog::log("ReM",Log::ERROR,oss);
return -1;
return -1;
}
rc = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
rc = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
if ( rc == -1 )
{
@ -133,29 +133,29 @@ int RequestManager::setup_socket()
oss << "Cannot set socket options: " << strerror(errno);
NebulaLog::log("ReM",Log::ERROR,oss);
close(socket_fd);
return -1;
return -1;
}
fcntl(socket_fd,F_SETFD,FD_CLOEXEC); // Close socket in MADs
rm_addr.sin_family = AF_INET;
rm_addr.sin_port = htons(port);
rm_addr.sin_addr.s_addr = INADDR_ANY;
rc = bind(socket_fd,(struct sockaddr *) &(rm_addr),sizeof(struct sockaddr));
if ( rc == -1)
if ( rc == -1)
{
ostringstream oss;
oss << "Cannot bind to port " << port << " : " << strerror(errno);
NebulaLog::log("ReM",Log::ERROR,oss);
close(socket_fd);
return -1;
}
@ -169,29 +169,29 @@ int RequestManager::start()
{
pthread_attr_t pattr;
ostringstream oss;
NebulaLog::log("ReM",Log::INFO,"Starting Request Manager...");
int rc = setup_socket();
if ( rc != 0 )
{
return -1;
}
register_xml_methods();
pthread_attr_init (&pattr);
pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE);
pthread_create(&rm_thread,&pattr,rm_action_loop,(void *)this);
pthread_attr_init (&pattr);
pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE);
oss << "Starting XML-RPC server, port " << port << " ...";
NebulaLog::log("ReM",Log::INFO,oss);
pthread_create(&rm_xml_server_thread,&pattr,rm_xml_server_loop,(void *)this);
return 0;
@ -199,7 +199,7 @@ int RequestManager::start()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::do_action(
const string & action,
void * arg)
@ -207,15 +207,15 @@ void RequestManager::do_action(
if (action == ACTION_FINALIZE)
{
NebulaLog::log("ReM",Log::INFO,"Stopping Request Manager...");
pthread_cancel(rm_xml_server_thread);
pthread_cancel(rm_xml_server_thread);
pthread_join(rm_xml_server_thread,0);
NebulaLog::log("ReM",Log::INFO,"XML-RPC server stopped.");
delete AbyssServer;
if ( socket_fd != -1 )
{
close(socket_fd);
@ -225,14 +225,14 @@ void RequestManager::do_action(
{
ostringstream oss;
oss << "Unknown action name: " << action;
NebulaLog::log("ReM", Log::ERROR, oss);
}
}
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManager::register_xml_methods()
{
// User Methods
@ -249,7 +249,7 @@ void RequestManager::register_xml_methods()
// VirtualMachine Methods
xmlrpc_c::methodPtr vm_deploy(new VirtualMachineDeploy());
xmlrpc_c::methodPtr vm_migrate(new VirtualMachineMigrate());
xmlrpc_c::methodPtr vm_action(new VirtualMachineAction());
xmlrpc_c::methodPtr vm_action(new VirtualMachineAction());
xmlrpc_c::methodPtr vm_savedisk(new VirtualMachineSaveDisk());
xmlrpc_c::methodPtr vm_monitoring(new VirtualMachineMonitoring());
xmlrpc_c::methodPtr vm_attach(new VirtualMachineAttach());
@ -265,6 +265,7 @@ void RequestManager::register_xml_methods()
// Update Template Methods
xmlrpc_c::methodPtr image_update(new ImageUpdateTemplate());
xmlrpc_c::methodPtr vm_update(new VirtualMachineUpdateTemplate());
xmlrpc_c::methodPtr template_update(new TemplateUpdateTemplate());
xmlrpc_c::methodPtr host_update(new HostUpdateTemplate());
xmlrpc_c::methodPtr vn_update(new VirtualNetworkUpdateTemplate());
@ -312,7 +313,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr cluster_info(new ClusterInfo());
xmlrpc_c::methodPtr doc_info(new DocumentInfo());
// PoolInfo Methods
// PoolInfo Methods
xmlrpc_c::methodPtr hostpool_info(new HostPoolInfo());
xmlrpc_c::methodPtr grouppool_info(new GroupPoolInfo());
xmlrpc_c::methodPtr userpool_info(new UserPoolInfo());
@ -382,7 +383,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr image_rename(new ImageRename());
xmlrpc_c::methodPtr doc_rename(new DocumentRename());
/* VM related methods */
/* VM related methods */
RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy);
RequestManagerRegistry.addMethod("one.vm.action", vm_action);
RequestManagerRegistry.addMethod("one.vm.migrate", vm_migrate);
@ -395,6 +396,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vm.attach", vm_attach);
RequestManagerRegistry.addMethod("one.vm.detach", vm_detach);
RequestManagerRegistry.addMethod("one.vm.rename", vm_rename);
RequestManagerRegistry.addMethod("one.vm.update", vm_update);
RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info);
RequestManagerRegistry.addMethod("one.vmpool.accounting", vm_pool_acct);
@ -416,12 +418,12 @@ void RequestManager::register_xml_methods()
/* Host related methods*/
RequestManagerRegistry.addMethod("one.host.enable", host_enable);
RequestManagerRegistry.addMethod("one.host.update", host_update);
RequestManagerRegistry.addMethod("one.host.allocate", host_allocate);
RequestManagerRegistry.addMethod("one.host.allocate", host_allocate);
RequestManagerRegistry.addMethod("one.host.delete", host_delete);
RequestManagerRegistry.addMethod("one.host.info", host_info);
RequestManagerRegistry.addMethod("one.host.monitoring", host_monitoring);
RequestManagerRegistry.addMethod("one.hostpool.info", hostpool_info);
RequestManagerRegistry.addMethod("one.hostpool.info", hostpool_info);
RequestManagerRegistry.addMethod("one.hostpool.monitoring", host_pool_monitoring);
/* Group related methods */
@ -443,13 +445,13 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vn.allocate", vn_allocate);
RequestManagerRegistry.addMethod("one.vn.update", vn_update);
RequestManagerRegistry.addMethod("one.vn.delete", vn_delete);
RequestManagerRegistry.addMethod("one.vn.info", vn_info);
RequestManagerRegistry.addMethod("one.vn.info", vn_info);
RequestManagerRegistry.addMethod("one.vn.chown", vn_chown);
RequestManagerRegistry.addMethod("one.vn.chmod", vn_chmod);
RequestManagerRegistry.addMethod("one.vn.rename", vn_rename);
RequestManagerRegistry.addMethod("one.vnpool.info", vnpool_info);
RequestManagerRegistry.addMethod("one.vnpool.info", vnpool_info);
/* User related methods*/
RequestManagerRegistry.addMethod("one.user.allocate", user_allocate);
RequestManagerRegistry.addMethod("one.user.update", user_update);
@ -464,11 +466,11 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.userquota.info", user_get_default_quota);
RequestManagerRegistry.addMethod("one.userquota.update", user_set_default_quota);
/* Image related methods*/
RequestManagerRegistry.addMethod("one.image.persistent", image_persistent);
RequestManagerRegistry.addMethod("one.image.enable", image_enable);
RequestManagerRegistry.addMethod("one.image.update", image_update);
RequestManagerRegistry.addMethod("one.image.update", image_update);
RequestManagerRegistry.addMethod("one.image.allocate", image_allocate);
RequestManagerRegistry.addMethod("one.image.delete", image_delete);
RequestManagerRegistry.addMethod("one.image.info", image_info);
@ -529,4 +531,4 @@ void RequestManager::register_xml_methods()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -68,6 +68,8 @@ VirtualMachine::VirtualMachine(int id,
{
obj_template = new VirtualMachineTemplate;
}
user_obj_template = new Template(false,'=',"USER_TEMPLATE");
}
VirtualMachine::~VirtualMachine()
@ -77,15 +79,20 @@ VirtualMachine::~VirtualMachine()
delete history_records[i];
}
if ( _log != 0 )
if (_log != 0)
{
delete _log;
}
if ( obj_template != 0 )
if (obj_template != 0)
{
delete obj_template;
}
if (user_obj_template != 0)
{
delete user_obj_template;
}
}
/* ************************************************************************** */
@ -2220,6 +2227,7 @@ error_yy:
string& VirtualMachine::to_xml_extended(string& xml, int n_history) const
{
string template_xml;
string user_template_xml;
string history_xml;
string perm_xml;
ostringstream oss;
@ -2243,7 +2251,8 @@ string& VirtualMachine::to_xml_extended(string& xml, int n_history) const
<< "<CPU>" << cpu << "</CPU>"
<< "<NET_TX>" << net_tx << "</NET_TX>"
<< "<NET_RX>" << net_rx << "</NET_RX>"
<< obj_template->to_xml(template_xml);
<< obj_template->to_xml(template_xml)
<< user_obj_template->to_xml(user_template_xml);
if ( hasHistory() && n_history > 0 )
{
@ -2319,21 +2328,34 @@ int VirtualMachine::from_xml(const string &xml_str)
state = static_cast<VmState>(istate);
lcm_state = static_cast<LcmState>(ilcmstate);
// Get associated classes
// Virtual Machine template
ObjectXML::get_nodes("/VM/TEMPLATE", content);
if (content.empty())
{
return -1;
}
// Virtual Machine template
rc += obj_template->from_xml_node(content[0]);
// Last history entry
ObjectXML::free_nodes(content);
content.clear();
// Virtual Machine user template
ObjectXML::get_nodes("/VM/USER_TEMPLATE", content);
if (content.empty())
{
return -1;
}
rc += user_obj_template->from_xml_node(content[0]);
ObjectXML::free_nodes(content);
content.clear();
// Last history entry
ObjectXML::get_nodes("/VM/HISTORY_RECORDS/HISTORY", content);
if (!content.empty())
@ -2367,3 +2389,35 @@ string VirtualMachine::get_system_dir() const
return oss.str();
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::replace_template(const string& tmpl_str, string& error)
{
Template * new_tmpl = new Template(false,'=',"USER_TEMPLATE");
if ( new_tmpl == 0 )
{
error = "Cannot allocate a new template";
return -1;
}
if ( new_tmpl->parse_str_or_xml(tmpl_str, error) != 0 )
{
delete new_tmpl;
return -1;
}
if (user_obj_template != 0)
{
delete user_obj_template;
}
user_obj_template = new_tmpl;
return 0;
}