1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-20 10:50:08 +03:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Hector Sanjuan 2012-05-15 09:56:35 +02:00
commit 54387d2ca3
37 changed files with 1172 additions and 470 deletions

View File

@ -45,7 +45,8 @@ public:
int hid,
const string& hostname,
const string& vmm,
const string& vnm);
const string& vnm,
const string& vm_info);
~History(){};
@ -69,9 +70,8 @@ private:
// ----------------------------------------
// DataBase implementation variables
// ----------------------------------------
static const char * table;
static const char * db_names;
static const char * db_bootstrap;
@ -104,6 +104,8 @@ private:
MigrationReason reason;
string vm_info;
// -------------------------------------------------------------------------
// Non-persistent history fields
// -------------------------------------------------------------------------
@ -169,6 +171,23 @@ private:
*/
int select_cb(void *nil, int num, char **values, char **names);
/**
* Function to print the History object into a string in
* XML format, to be stored in the DB. It includes the VM template info
* @param xml the resulting XML string
* @return a reference to the generated string
*/
string& to_db_xml(string& xml) const;
/**
* Function to print the History object into a string in
* XML format. The VM info can be optionally included
* @param xml the resulting XML string
* @param database If it is true, the TEMPLATE element will be included
* @return a reference to the generated string
*/
string& to_xml(string& xml, bool database) const;
/**
* Rebuilds the object from an xml node
* @param node The xml node pointer

View File

@ -154,6 +154,47 @@ public:
*/
virtual int dump(ostringstream& oss, const string& where) = 0;
// -------------------------------------------------------------------------
// Function to generate dump filters
// -------------------------------------------------------------------------
/**
* Creates a filter for those objects (oids) or objects owned by a given
* group that an user can access based on the ACL rules
* @param uid the user id
* @param gid the group id
* @param auth_object object type
* @param all returns if the user can access all objects
* @param filter the resulting filter string
*/
static void acl_filter(int uid,
int gid,
PoolObjectSQL::ObjectType auth_object,
bool& all,
string& filter);
/**
* Creates a filter for the objects owned by a given user/group
* @param uid the user id
* @param gid the group id
* @param filter_flag query type (ALL, MINE, GROUP)
* @param all user can access all objects
* @param filter the resulting filter string
*/
static void usr_filter(int uid,
int gid,
int filter_flag,
bool all,
const string& acl_str,
string& filter);
/**
* Creates a filter for a given set of objects based on their id
* @param start_id first id
* @param end_id last id
* @param filter the resulting filter string
*/
static void oid_filter(int start_id,
int end_id,
string& filter);
protected:
/**
@ -182,8 +223,23 @@ protected:
*
* @return 0 on success
*/
int dump(ostringstream& oss, const string& elem_name,
const char * table, const string& where);
int dump(ostringstream& oss,
const string& elem_name,
const char * table,
const string& where);
/**
* Dumps the output of the custom sql query into an xml
*
* @param oss The output stream to dump the xml contents
* @param root_elem_name Name of the root xml element name
* @param sql_query The SQL query to execute
*
* @return 0 on success
*/
int dump(ostringstream& oss,
const string& root_elem_name,
ostringstream& sql_query);
/* ---------------------------------------------------------------------- */
/* Interface to access the lastOID assigned by the pool */

View File

@ -29,6 +29,16 @@ using namespace std;
class RequestManagerPoolInfoFilter: public Request
{
public:
/** Specify all objects the user has right to USE (-2) */
static const int ALL;
/** Specify user's objects in the pool (-3) */
static const int MINE;
/** Specify user's + group objects (-1) */
static const int MINE_GROUP;
protected:
RequestManagerPoolInfoFilter(const string& method_name,
const string& help,
@ -40,27 +50,26 @@ protected:
/* -------------------------------------------------------------------- */
/** Specify all objects the user has right to USE (-2) */
static const int ALL;
/** Specify user's objects in the pool (-3) */
static const int MINE;
/** Specify user's + group objects (-1) */
static const int MINE_GROUP;
/* -------------------------------------------------------------------- */
virtual void request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
/* -------------------------------------------------------------------- */
void dump(RequestAttributes& att,
void where_filter(RequestAttributes& att,
int filter_flag,
int start_id,
int end_id,
const string& and_clause,
const string& or_clause,
string& where_string);
/* -------------------------------------------------------------------- */
void dump(RequestAttributes& att,
int filter_flag,
int start_id,
int start_id,
int end_id,
const string& and_clause,
const string& and_clause,
const string& or_clause);
};
@ -98,6 +107,31 @@ public:
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachinePoolAccounting : public RequestManagerPoolInfoFilter
{
public:
VirtualMachinePoolAccounting():
RequestManagerPoolInfoFilter("VirtualMachinePoolAccounting",
"Returns the virtual machine history records",
"A:siii")
{
Nebula& nd = Nebula::instance();
pool = nd.get_vmpool();
auth_object = PoolObjectSQL::VM;
};
~VirtualMachinePoolAccounting(){};
/* -------------------------------------------------------------------- */
void request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class TemplatePoolInfo : public RequestManagerPoolInfoFilter
{
public:

View File

@ -122,7 +122,10 @@ public:
* @param xml the resulting XML string
* @return a reference to the generated string
*/
string& to_xml(string& xml) const;
string& to_xml(string& xml) const
{
return to_xml_extended(xml, 1);
}
/**
* Function to print the VirtualMachine object into a string in
@ -130,7 +133,10 @@ public:
* @param xml the resulting XML string
* @return a reference to the generated string
*/
string& to_xml_extended(string& xml) const;
string& to_xml_extended(string& xml) const
{
return to_xml_extended(xml, 2);
}
/**
* Rebuilds the object from an xml formatted string
@ -156,7 +162,7 @@ public:
/**
* Updates VM dynamic information (usage counters).
* @param _memory used by the VM (total)
* @param _memory Kilobytes used by the VM (total)
* @param _cpu used by the VM (rate)
* @param _net_tx transmitted bytes (total)
* @param _net_tx received bytes (total)
@ -199,7 +205,7 @@ public:
/**
* Sets the VM exit time
* @param _et VM exit time (when it arraived DONE/FAILED states)
* @param _et VM exit time (when it arrived DONE/FAILED states)
*/
void set_exit_time(time_t et)
{
@ -428,6 +434,22 @@ public:
history->stime=_stime;
};
/**
* Sets VM info (with monitoring info) in the history record
*/
void set_vm_info()
{
to_xml_extended(history->vm_info, 0);
};
/**
* Sets VM info (with monitoring info) in the previous history record
*/
void set_previous_vm_info()
{
to_xml_extended(previous_history->vm_info, 0);
};
/**
* Sets end time of a VM.
* @param _etime time when the VM finished
@ -757,7 +779,7 @@ private:
string deploy_id;
/**
* Memory in Megabytes used by the VM
* Memory in Kilobytes used by the VM
*/
int memory;
@ -767,12 +789,12 @@ private:
int cpu;
/**
* Network usage, transmitted Kilobytes
* Network usage, transmitted bytes
*/
int net_tx;
/**
* Network usage, received Kilobytes
* Network usage, received bytes
*/
int net_rx;
@ -916,10 +938,13 @@ private:
* Function that renders the VM in XML format optinally including
* extended information (all history records)
* @param xml the resulting XML string
* @param extended include additional info if true
* @param n_history Number of history records to include:
* 0: none
* 1: the last one
* 2: all
* @return a reference to the generated string
*/
string& to_xml_extended(string& xml, bool extended) const;
string& to_xml_extended(string& xml, int n_history) const;
protected:
@ -939,7 +964,7 @@ protected:
// *************************************************************************
// DataBase implementation
// *************************************************************************
static const char * table;
static const char * db_names;

View File

@ -143,8 +143,20 @@ public:
int dump(ostringstream& oss, const string& where)
{
return PoolSQL::dump(oss, "VM_POOL", VirtualMachine::table, where);
}
};
/**
* Dumps the VM accounting information in XML format. A filter can be also
* added to the query as well as a time frame.
* @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_acct(ostringstream& oss,
const string& where,
int time_start,
int time_end);
private:
/**
* Factory method to produce VM objects

View File

@ -883,6 +883,8 @@ ONEDB_MIGRATOR_FILES="src/onedb/2.0_to_2.9.80.rb \
src/onedb/3.2.1_to_3.3.0.rb \
src/onedb/3.3.0_to_3.3.80.rb \
src/onedb/3.3.80_to_3.4.0.rb \
src/onedb/3.4.0_to_3.4.1.rb \
src/onedb/3.4.1_to_3.5.80.rb \
src/onedb/onedb.rb \
src/onedb/onedb_backend.rb"

127
share/doc/xsd/acct.xsd Normal file
View File

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
targetNamespace="http://opennebula.org/XMLSchema" xmlns="http://opennebula.org/XMLSchema">
<xs:element name="HISTORY_RECORDS">
<xs:complexType>
<xs:sequence maxOccurs="1" minOccurs="1">
<xs:element ref="HISTORY" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="HISTORY">
<xs:complexType>
<xs:sequence>
<xs:element name="OID" type="xs:integer"/>
<xs:element name="SEQ" type="xs:integer"/>
<xs:element name="HOSTNAME" type="xs:string"/>
<xs:element name="HID" type="xs:integer"/>
<xs:element name="STIME" type="xs:integer"/>
<xs:element name="ETIME" type="xs:integer"/>
<xs:element name="VMMMAD" type="xs:string"/>
<xs:element name="VNMMAD" type="xs:string"/>
<xs:element name="PSTIME" type="xs:integer"/>
<xs:element name="PETIME" type="xs:integer"/>
<xs:element name="RSTIME" type="xs:integer"/>
<xs:element name="RETIME" type="xs:integer"/>
<xs:element name="ESTIME" type="xs:integer"/>
<xs:element name="EETIME" type="xs:integer"/>
<!-- REASON values:
NONE = 0 Normal termination
ERROR = 1 The VM ended in error
STOP_RESUME = 2 Stop/resume request
USER = 3 Migration request
CANCEL = 4 Cancel request
-->
<xs:element name="REASON" type="xs:integer"/>
<xs:element name="VM">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:integer"/>
<xs:element name="UID" type="xs:integer"/>
<xs:element name="GID" type="xs:integer"/>
<xs:element name="UNAME" type="xs:string"/>
<xs:element name="GNAME" type="xs:string"/>
<xs:element name="NAME" type="xs:string"/>
<xs:element name="PERMISSIONS" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="OWNER_U" type="xs:integer"/>
<xs:element name="OWNER_M" type="xs:integer"/>
<xs:element name="OWNER_A" type="xs:integer"/>
<xs:element name="GROUP_U" type="xs:integer"/>
<xs:element name="GROUP_M" type="xs:integer"/>
<xs:element name="GROUP_A" type="xs:integer"/>
<xs:element name="OTHER_U" type="xs:integer"/>
<xs:element name="OTHER_M" type="xs:integer"/>
<xs:element name="OTHER_A" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="LAST_POLL" type="xs:integer"/>
<!-- STATE values,
see http://opennebula.org/_media/documentation:rel3.2:states-complete.png
INIT = 0
PENDING = 1
HOLD = 2
ACTIVE = 3 In this state, the Life Cycle Manager state is relevant
STOPPED = 4
SUSPENDED = 5
DONE = 6
FAILED = 7
-->
<xs:element name="STATE" type="xs:integer"/>
<!-- LCM_STATE values, this sub-state is relevant only when STATE is
ACTIVE (4)
LCM_INIT = 0
PROLOG = 1
BOOT = 2
RUNNING = 3
MIGRATE = 4
SAVE_STOP = 5
SAVE_SUSPEND = 6
SAVE_MIGRATE = 7
PROLOG_MIGRATE = 8
PROLOG_RESUME = 9
EPILOG_STOP = 10
EPILOG = 11
SHUTDOWN = 12
CANCEL = 13
FAILURE = 14
CLEANUP = 15
UNKNOWN = 16
-->
<xs:element name="LCM_STATE" type="xs:integer"/>
<xs:element name="RESCHED" type="xs:integer"/>
<xs:element name="STIME" type="xs:integer"/>
<xs:element name="ETIME" type="xs:integer"/>
<xs:element name="DEPLOY_ID" type="xs:string"/>
<!-- MEMORY consumption in kilobytes -->
<xs:element name="MEMORY" type="xs:integer"/>
<!-- Percentage of 1 CPU consumed (two fully consumed cpu is 200) -->
<xs:element name="CPU" type="xs:integer"/>
<!-- NET_TX: Sent bytes to the network -->
<xs:element name="NET_TX" type="xs:integer"/>
<!-- 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="HISTORY_RECORDS">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -28,6 +28,7 @@
<xs:element name="DS_MAD" type="xs:string"/>
<xs:element name="TM_MAD" type="xs:string"/>
<xs:element name="BASE_PATH" type="xs:string"/>
<xs:element name="DISK_TYPE" type="xs:integer"/>
<xs:element name="CLUSTER_ID" type="xs:integer"/>
<xs:element name="CLUSTER" type="xs:string"/>
<xs:element name="IMAGES">

View File

@ -25,6 +25,7 @@
</xs:complexType>
</xs:element>
<xs:element name="TYPE" type="xs:integer"/>
<xs:element name="DISK_TYPE" type="xs:integer"/>
<xs:element name="PERSISTENT" type="xs:integer"/>
<xs:element name="REGTIME" type="xs:integer"/>
<xs:element name="SOURCE" type="xs:string"/>

View File

@ -26,14 +26,58 @@
</xs:complexType>
</xs:element>
<xs:element name="LAST_POLL" type="xs:integer"/>
<!-- STATE values,
see http://opennebula.org/_media/documentation:rel3.2:states-complete.png
INIT = 0
PENDING = 1
HOLD = 2
ACTIVE = 3 In this state, the Life Cycle Manager state is relevant
STOPPED = 4
SUSPENDED = 5
DONE = 6
FAILED = 7
-->
<xs:element name="STATE" type="xs:integer"/>
<!-- LCM_STATE values, this sub-state is relevant only when STATE is
ACTIVE (4)
LCM_INIT = 0
PROLOG = 1
BOOT = 2
RUNNING = 3
MIGRATE = 4
SAVE_STOP = 5
SAVE_SUSPEND = 6
SAVE_MIGRATE = 7
PROLOG_MIGRATE = 8
PROLOG_RESUME = 9
EPILOG_STOP = 10
EPILOG = 11
SHUTDOWN = 12
CANCEL = 13
FAILURE = 14
CLEANUP = 15
UNKNOWN = 16
-->
<xs:element name="LCM_STATE" type="xs:integer"/>
<xs:element name="RESCHED" type="xs:integer"/>
<xs:element name="STIME" type="xs:integer"/>
<xs:element name="ETIME" type="xs:integer"/>
<xs:element name="DEPLOY_ID" type="xs:string"/>
<!-- MEMORY consumption in kilobytes -->
<xs:element name="MEMORY" type="xs:integer"/>
<!-- Percentage of 1 CPU consumed (two fully consumed cpu is 200) -->
<xs:element name="CPU" type="xs:integer"/>
<!-- NET_TX: Sent bytes to the network -->
<xs:element name="NET_TX" type="xs:integer"/>
<!-- 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="HISTORY_RECORDS">
@ -42,21 +86,28 @@
<xs:element name="HISTORY" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="OID" type="xs:integer"/>
<xs:element name="SEQ" type="xs:integer"/>
<xs:element name="HOSTNAME" type="xs:string"/>
<xs:element name="VM_DIR" type="xs:string"/>
<xs:element name="HID" type="xs:integer"/>
<xs:element name="STIME" type="xs:integer"/>
<xs:element name="ETIME" type="xs:integer"/>
<xs:element name="VMMMAD" type="xs:string"/>
<xs:element name="VNMMAD" type="xs:string"/>
<xs:element name="TMMAD" type="xs:string"/>
<xs:element name="PSTIME" type="xs:integer"/>
<xs:element name="PETIME" type="xs:integer"/>
<xs:element name="RSTIME" type="xs:integer"/>
<xs:element name="RETIME" type="xs:integer"/>
<xs:element name="ESTIME" type="xs:integer"/>
<xs:element name="EETIME" type="xs:integer"/>
<!-- REASON values:
NONE = 0 Normal termination
ERROR = 1 The VM ended in error
STOP_RESUME = 2 Stop/resume request
USER = 3 Migration request
CANCEL = 4 Cancel request
-->
<xs:element name="REASON" type="xs:integer"/>
</xs:sequence>
</xs:complexType>

View File

@ -298,7 +298,7 @@ TM_MAD = [
DATASTORE_MAD = [
executable = "one_datastore",
arguments = "-t 15 -d fs,vmware,iscsi"
arguments = "-t 15 -d fs,vmware,iscsi,lvm"
]
#*******************************************************************************

View File

@ -1,25 +1,20 @@
#!/usr/bin/env ruby
# --------------------------------------------------------------------------
# Copyright 2010-2012, C12G Labs S.L.
#
# This file is part of OpenNebula addons.
#
# OpenNebula addons are free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3 of
# the License, or the hope That it will be useful, but (at your
# option) any later version.
#
# OpenNebula addons are distributed in WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License
# along with OpenNebula addons. If not, see
# <http://www.gnu.org/licenses/>
# --------------------------------------------------------------------------
# -------------------------------------------------------------------------- #
# Copyright 2002-2012, 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"]
@ -35,7 +30,6 @@ $: << RUBY_LIB_LOCATION+"/cli"
require 'rubygems'
require 'acct/oneacct'
require 'cli/one_helper'
require 'cli/command_parser'
require 'json'
@ -43,164 +37,171 @@ require 'json'
require 'optparse'
require 'optparse/time'
REG_DATE=/((\d{4})\/)?(\d\d?)(\/(\d\d?))?/
REG_TIME=/(\d\d?):(\d\d?)(:(\d\d?))?/
class AcctHelper
def format_vm(options=nil)
table = CLIHelper::ShowTable.new(nil, nil) do
column :VMID, "VM ID", :size=>4 do |d|
d[:vmid]
def initialize(client)
@client = client
end
=begin
List of <HISTORY> child elements
OID
SEQ
HOSTNAME
HID
STIME
ETIME
VMMMAD
VNMMAD
PSTIME
PETIME
RSTIME
RETIME
ESTIME
EETIME
REASON
=end
def list_history(data)
table = CLIHelper::ShowTable.new(nil, self) do
column :VID, "Virtual Machine ID", :size=>4 do |d|
d["OID"]
end
column :MEMORY, "Consumed memory", :right, :size=>8 do |d|
OpenNebulaHelper.unit_to_str(
d[:slices].first[:mem]*1024,
{})
column :SEQ, "History record sequence number", :size=>3 do |d|
d["SEQ"]
end
column :CPU, "Group of the User", :right, :size=>8 do |d|
d[:slices].first[:cpu]
column :HOSTNAME, "Host name", :size=>15 do |d|
d["HOSTNAME"]
end
column :NETRX, "Group of the User", :right, :size=>10 do |d|
OpenNebulaHelper.unit_to_str(
d[:network][:net_rx].to_i/1024.0,
{})
column :REASON, "VM state change reason", :size=>4 do |d|
VirtualMachine.get_reason d["REASON"]
end
column :NETTX, "Group of the User", :right, :size=>10 do |d|
OpenNebulaHelper.unit_to_str(
d[:network][:net_tx].to_i/1024.0,
{})
column :START_TIME, "Start time", :size=>14 do |d|
OpenNebulaHelper.time_to_str(d['STIME'])
end
column :TIME, "Group of the User", :right, :size=>15 do |d|
OpenNebulaHelper.period_to_str(d[:time])
column :END_TIME, "End time", :size=>14 do |d|
OpenNebulaHelper.time_to_str(d['ETIME'])
end
default :VMID, :MEMORY, :CPU, :NETRX, :NETTX, :TIME
column :MEMORY, "Assigned memory", :right, :size=>6 do |d|
OpenNebulaHelper.unit_to_str(d["VM/TEMPLATE/MEMORY"].to_i, {}, 'M')
end
column :CPU, "Number of CPUs", :right, :size=>3 do |d|
d["VM/TEMPLATE/CPU"]
end
column :NET_RX, "Data received from the network", :right, :size=>6 do |d|
# NET is measured in bytes, unit_to_str expects KBytes
OpenNebulaHelper.unit_to_str(d["VM/NET_RX"].to_i / 1024.0, {})
end
column :NET_TX, "Data sent to the network", :right, :size=>6 do |d|
# NET is measured in bytes, unit_to_str expects KBytes
OpenNebulaHelper.unit_to_str(d["VM/NET_TX"].to_i / 1024.0, {})
end
default :VID, :HOSTNAME, :REASON, :START_TIME, :END_TIME, :MEMORY, :CPU, :NET_RX, :NET_TX
end
table
table.show(data)
end
def list_vms(data)
format_vm().show(data)
end
public
def list_users(xml_info, options=nil)
def list_users(filters)
a=gen_accounting(filters)
xmldoc = XMLElement.new
xmldoc.initialize_xml(xml_info, 'HISTORY_RECORDS')
a.each do |user, data|
uids = xmldoc.retrieve_elements('HISTORY/VM/UID')
if uids.nil?
puts "No records found."
exit 0
end
uids.uniq!
history_elems = []
uids.each do |uid|
CLIHelper.scr_bold
CLIHelper.scr_underline
puts "# User #{user}"
# TODO: username?
puts "# User #{uid} "
CLIHelper.scr_restore
puts
vms=data[:vms].map do |k, v|
v
end
history_elems.clear
self.list_vms(vms)
vm_ids = xmldoc.retrieve_elements("HISTORY/VM[UID=#{uid}]/ID")
vm_ids.uniq!
puts
puts
vm_ids.each do |vid|
end
end
def gen_accounting(filters)
acct=AcctClient.new(filters)
acct.account()
end
def gen_json(filters)
begin
require 'json'
rescue LoadError
STDERR.puts "JSON gem is needed to give the result in this format"
exit(-1)
end
acct=gen_accounting(filters)
acct.to_json
end
def xml_tag(tag, value)
"<#{tag}>#{value}</#{tag}>\n"
end
def gen_xml(filters)
acct=gen_accounting(filters)
xml=""
acct.each do |user, data|
xml<<"<user id=\"#{user}\">\n"
data[:vms].each do |vmid, vm|
xml<<" <vm id=\"#{vmid}\">\n"
xml<<" "<<xml_tag(:name, vm[:name])
xml<<" "<<xml_tag(:time, vm[:time])
xml<<" "<<xml_tag(:cpu, vm[:slices].first[:cpu])
xml<<" "<<xml_tag(:mem, vm[:slices].first[:mem])
xml<<" "<<xml_tag(:net_rx, vm[:network][:net_rx])
xml<<" "<<xml_tag(:net_tx, vm[:network][:net_tx])
vm[:slices].each do |slice|
xml<<" <slice seq=\"#{slice[:seq]}\">\n"
slice.each do |key, value|
xml<<" "<<xml_tag(key, value)
end
xml<<" </slice>\n"
if ( options[:split] )
history_elems.clear
end
xml<<" </vm>\n"
xmldoc.each("HISTORY[OID=#{vid}]") do |history|
history_elems << history
end
if ( options[:split] )
list_history(history_elems)
puts
end
end
xml<<"</user>\n"
if ( !options[:split] )
list_history(history_elems)
puts
end
end
xml
end
end
@options=Hash.new
options = Hash.new
@options[:format]=:table
options[:format] = :table
opts=OptionParser.new do |opts|
opts = OptionParser.new do |opts|
opts.on('-s', '--start TIME', Time,
'Start date and time to take into account') do |ext|
@options[:start]=ext
options[:start]=ext
end
opts.on("-e", "--end TIME", Time,
"End date and time" ) do |ext|
@options[:end]=ext
options[:end]=ext
end
# TODO: Allow username
opts.on("-u", "--user user", Integer,
"User id to make accounting" ) do |ext|
@options[:user]=ext.to_i
options[:user]=ext.to_i
end
opts.on("-j", "--json",
"Output in json format" ) do |ext|
@options[:format]=:json
options[:format]=:json
end
opts.on("-x", "--xml",
"Output in xml format" ) do |ext|
@options[:format]=:xml
options[:format]=:xml
end
opts.on("--split",
"Split the output in a table for each VM" ) do |ext|
options[:split]=ext
end
opts.on()
@ -215,27 +216,68 @@ rescue OptionParser::ParseError => e
end
acct_helper=AcctHelper.new
client = OpenNebula::Client.new
acct_helper = AcctHelper.new(client)
time_start = -1
time_end = -1
filter_flag = VirtualMachinePool::INFO_ALL
time_start = options[:start].to_i if options[:start]
time_end = options[:end].to_i if options[:end]
filter_flag = options[:user].to_i if options[:user]
filters=Hash.new
ret = client.call("vmpool.accounting",
filter_flag,
time_start,
time_end)
filters[:start]=@options[:start].to_i if @options[:start]
filters[:end]=@options[:end].to_i if @options[:end]
filters[:user]=@options[:user].to_i if @options[:user]
case @options[:format]
when :table
acct_helper.list_users(filters)
when :json
puts acct_helper.gen_json(filters)
when :xml
puts acct_helper.gen_xml(filters)
if OpenNebula.is_error?(ret)
puts ret.message
exit -1
end
case options[:format]
when :table
if ( time_start != -1 or time_end != -1 )
print "Showing active history records from "
CLIHelper.scr_bold
if ( time_start != -1 )
print Time.at(time_start).to_s
else
print "-"
end
CLIHelper.scr_restore
print " to "
CLIHelper.scr_bold
if ( time_end != -1 )
print Time.at(time_end).to_s
else
print "-"
end
CLIHelper.scr_restore
puts
puts
end
acct_helper.list_users(ret, options)
when :xml
puts ret
when :json
xmldoc = XMLElement.new
xmldoc.initialize_xml(ret, 'HISTORY_RECORDS')
puts xmldoc.to_hash.to_json
end

View File

@ -34,9 +34,12 @@ fi
setup()
{
eval `grep ^IMAGE_DIR= $ECONE_ETC`
export TMPDIR=$IMAGE_DIR/tmp
mkdir -p $TMPDIR
TMPDIR=$(grep ^:tmpdir: $ECONE_ETC|awk '{print $2}')
if [ -n "$TMPDIR" ]; then
export TMPDIR
mkdir -p $TMPDIR
fi
if [ -f $ECONE_LOCK_FILE ]; then
if [ -f $ECONE_PID ]; then

View File

@ -18,11 +18,14 @@
# Server Configuration
#############################################################
# Directory to store temp files when uploading images
:tmpdir: /var/tmp/one
# OpenNebula sever contact information
:one_xmlrpc: http://localhost:2633/RPC2
# Host and port where econe server will run
:server: localhost
:host: localhost
:port: 4567
# SSL proxy that serves the API (set if is being used)

View File

@ -79,7 +79,14 @@ set :config, conf
include CloudLogger
enable_logging EC2_LOG, settings.config[:debug_level].to_i
if CloudServer.is_port_open?(settings.config[:server],
if settings.config[:server]
settings.config[:host] ||= settings.config[:server]
warning = "Warning: :server: configuration parameter has been deprecated."
warning << " Use :host: instead."
settings.logger.warn warning
end
if CloudServer.is_port_open?(settings.config[:host],
settings.config[:port])
settings.logger.error {
"Port #{settings.config[:port]} busy, please shutdown " <<
@ -88,7 +95,7 @@ if CloudServer.is_port_open?(settings.config[:server],
exit -1
end
set :bind, settings.config[:server]
set :bind, settings.config[:host]
set :port, settings.config[:port]
begin
@ -108,8 +115,8 @@ if conf[:ssl_server]
econe_port = uri.port
econe_path = uri.path
else
econe_host = conf[:server]
econe_port = conf[:port]
econe_host = settings.config[:host]
econe_port = settings.config[:port]
econe_path = '/'
end

View File

@ -34,9 +34,12 @@ fi
setup()
{
eval `grep ^IMAGE_DIR= $OCCI_ETC `
export TMPDIR=$IMAGE_DIR/tmp
TMPDIR=$(grep ^:tmpdir: $OCCI_ETC|awk '{print $2}')
if [ -n "$TMPDIR" ]; then
export TMPDIR
mkdir -p $TMPDIR
fi
if [ -f $OCCI_LOCK_FILE ]; then
if [ -f $OCCI_PID ]; then

View File

@ -18,6 +18,9 @@
# Server configuration
#############################################################
# Directory to store temp files when uploading images
:tmpdir: /var/tmp/one
# OpenNebula sever contact information
:one_xmlrpc: http://localhost:2633/RPC2

View File

@ -92,7 +92,14 @@ use Rack::Session::Pool, :key => 'occi'
set :public_folder, Proc.new { File.join(root, "ui/public") }
set :views, settings.root + '/ui/views'
if CloudServer.is_port_open?(settings.config[:server],
if settings.config[:server]
settings.config[:host] ||= settings.config[:server]
warning = "Warning: :server: configuration parameter has been deprecated."
warning << " Use :host: instead."
settings.logger.warn warning
end
if CloudServer.is_port_open?(settings.config[:host],
settings.config[:port])
settings.logger.error {
"Port #{settings.config[:port]} busy, please shutdown " <<
@ -101,20 +108,10 @@ if CloudServer.is_port_open?(settings.config[:server],
exit -1
end
host = settings.config[:host] || settings.config[:server]
set :bind, host
if settings.config[:server]
warning = "Warning: :server: configuration parameter has been deprecated."
warning << " Use :host: instead."
settings.logger.error warning
end
set :bind, settings.config[:host]
set :port, settings.config[:port]
# Create CloudAuth
begin
ENV["ONE_CIPHER_AUTH"] = OCCI_AUTH

View File

@ -76,8 +76,10 @@ case $SRC in
exec_and_log "cp -rf $SRC $DST" "Error copying $SRC to $DST"
if [ ! -f $DST/disk.vmdk ]; then
BASE_DISK_FILE=`ls $DST | grep -v '.*-s[0-9]*\.vmdk'`
BASE_DISK_FILE=`ls $DST | grep -v '\-\(flat\|delta\|s[0-9]*\)\.vmdk$'`
exec_and_log "mv -f $DST/$BASE_DISK_FILE $DST/disk.vmdk" \
"Error renaming disk file $BASE_DISK_FILE to disk.vmdk"

View File

@ -615,6 +615,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm)
vmpool->update(vm);
vm->set_etime(the_time);
vm->set_vm_info();
vm->set_reason(History::USER);
vm->get_requirements(cpu,mem,disk);
@ -650,6 +651,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm)
vmpool->update_history(vm);
vm->set_previous_etime(the_time);
vm->set_previous_vm_info();
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
@ -680,6 +682,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm)
vmpool->update_history(vm);
vm->set_previous_etime(the_time);
vm->set_previous_vm_info();
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);

View File

@ -49,6 +49,8 @@ void LifeCycleManager::save_success_action(int vid)
vm->set_previous_etime(the_time);
vm->set_previous_vm_info();
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
@ -84,6 +86,8 @@ void LifeCycleManager::save_success_action(int vid)
vm->set_etime(the_time);
vm->set_vm_info();
vm->set_reason(History::STOP_RESUME);
vmpool->update_history(vm);
@ -162,6 +166,8 @@ void LifeCycleManager::save_failure_action(int vid)
vm->set_etime(the_time);
vm->set_vm_info();
vm->set_reason(History::ERROR);
vmpool->update_history(vm);
@ -172,6 +178,8 @@ void LifeCycleManager::save_failure_action(int vid)
vm->set_previous_etime(the_time);
vm->set_previous_vm_info();
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
@ -251,6 +259,8 @@ void LifeCycleManager::deploy_success_action(int vid)
vm->set_previous_etime(the_time);
vm->set_previous_vm_info();
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
@ -304,10 +314,14 @@ void LifeCycleManager::deploy_failure_action(int vid)
vm->set_etime(the_time);
vm->set_vm_info();
vm->set_reason(History::ERROR);
vm->set_previous_etime(the_time);
vm->set_previous_vm_info();
vm->set_previous_running_etime(the_time);
vm->set_previous_reason(History::USER);
@ -554,6 +568,8 @@ void LifeCycleManager::epilog_success_action(int vid)
vm->set_etime(the_time);
vm->set_vm_info();
vmpool->update_history(vm);
vm->get_requirements(cpu,mem,disk);
@ -727,6 +743,8 @@ void LifeCycleManager::monitor_suspend_action(int vid)
vm->set_etime(the_time);
vm->set_vm_info();
vm->set_reason(History::STOP_RESUME);
vmpool->update_history(vm);
@ -799,6 +817,8 @@ void LifeCycleManager::failure_action(VirtualMachine * vm)
vm->set_etime(the_time);
vm->set_vm_info();
vm->set_reason(History::ERROR);
vmpool->update_history(vm);

View File

@ -35,6 +35,7 @@ public class Template extends PoolElement
private static final String CHOWN = METHOD_PREFIX + "chown";
private static final String CHMOD = METHOD_PREFIX + "chmod";
private static final String INSTANTIATE = METHOD_PREFIX + "instantiate";
private static final String CLONE = METHOD_PREFIX + "clone";
/**
* Creates a new Template representation.
@ -205,6 +206,19 @@ public class Template extends PoolElement
return client.call(INSTANTIATE, id, name);
}
/**
* Clones this template into a new one
*
* @param client XML-RPC Client.
* @param id The template id of the target template.
* @param name Name for the new template.
* @return If successful the message contains the new template ID.
*/
public static OneResponse clone(Client client, int id, String name)
{
return client.call(CLONE, id, name);
}
// =================================
// Instanced object XML-RPC methods
// =================================
@ -375,6 +389,17 @@ public class Template extends PoolElement
return instantiate(client, id, "");
}
/**
* Clones this template into a new one
*
* @param name Name for the new template.
* @return If successful the message contains the new template ID.
*/
public OneResponse clone(String name)
{
return clone(client, id, name);
}
// =================================
// Helpers
// =================================

View File

@ -0,0 +1,29 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2012, 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 Migrator
def db_version
"3.4.1"
end
def one_version
"OpenNebula 3.4.1"
end
def up
return true
end
end

View File

@ -0,0 +1,150 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2012, 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 "rexml/document"
include REXML
module Migrator
def db_version
"3.5.80"
end
def one_version
"OpenNebula 3.5.80"
end
def up
@db.run "ALTER TABLE datastore_pool RENAME TO old_datastore_pool;"
@db.run "CREATE TABLE datastore_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));"
@db.fetch("SELECT * FROM old_datastore_pool") do |row|
doc = Document.new(row[:body])
doc.root.add_element("DISK_TYPE").text = "0"
@db[:datastore_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => doc.root.to_s,
:uid => row[:uid],
:gid => row[:gid],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u])
end
@db.run "DROP TABLE old_datastore_pool;"
@db.run "ALTER TABLE image_pool RENAME TO old_image_pool;"
@db.run "CREATE TABLE image_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name,uid) );"
@db.fetch("SELECT * FROM old_image_pool") do |row|
doc = Document.new(row[:body])
ds_id = ""
doc.root.each_element("DATASTORE_ID") { |e|
ds_id = e.text
}
doc.root.add_element("DISK_TYPE").text = "0"
@db[:image_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => doc.root.to_s,
:uid => row[:uid],
:gid => row[:gid],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u])
end
@db.run "DROP TABLE old_image_pool;"
@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("RESCHED").text = "0"
@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;"
@db.run "ALTER TABLE history RENAME TO old_history;"
@db.run "CREATE TABLE history (vid INTEGER, seq INTEGER, body TEXT, stime INTEGER, etime INTEGER, PRIMARY KEY(vid,seq));"
@db.fetch("SELECT * FROM old_history") do |row|
doc = Document.new(row[:body])
doc.root.add_element("OID").text = row[:vid].to_s
stime = "0"
doc.root.each_element("STIME") { |e|
stime = e.text
}
etime = "0"
doc.root.each_element("ETIME") { |e|
etime = e.text
}
@db.fetch("SELECT body FROM vm_pool WHERE oid = #{row[:vid]}") do |vm_row|
vm_doc = Document.new(vm_row[:body])
vm_doc.root.delete_element( '/VM/HISTORY_RECORDS/HISTORY' )
["MEMORY", "CPU", "NET_TX", "NET_RX"].each { |elem_name|
vm_doc.root.each_element(elem_name) { |e|
e.text = "0"
}
}
doc.root.add_element( vm_doc )
end
@db[:history].insert(
:vid => row[:vid],
:seq => row[:seq],
:body => doc.root.to_s,
:stime => stime,
:etime => etime)
end
@db.run "DROP TABLE old_history;"
return true
end
end

View File

@ -21,6 +21,7 @@
#include <algorithm>
#include "PoolSQL.h"
#include "RequestManagerPoolInfoFilter.h"
#include <errno.h>
@ -479,14 +480,8 @@ int PoolSQL::dump(ostringstream& oss,
const char * table,
const string& where)
{
int rc;
ostringstream cmd;
oss << "<" << elem_name << ">";
set_callback(static_cast<Callbackable::Callback>(&PoolSQL::dump_cb),
static_cast<void *>(&oss));
cmd << "SELECT body FROM " << table;
if ( !where.empty() )
@ -496,9 +491,26 @@ int PoolSQL::dump(ostringstream& oss,
cmd << " ORDER BY oid";
rc = db->exec(cmd, this);
return dump(oss, elem_name, cmd);
}
oss << "</" << elem_name << ">";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int PoolSQL::dump(ostringstream& oss,
const string& root_elem_name,
ostringstream& sql_query)
{
int rc;
oss << "<" << root_elem_name << ">";
set_callback(static_cast<Callbackable::Callback>(&PoolSQL::dump_cb),
static_cast<void *>(&oss));
rc = db->exec(sql_query, this);
oss << "</" << root_elem_name << ">";
unset_callback();
@ -546,3 +558,120 @@ int PoolSQL::search(
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void PoolSQL::acl_filter(int uid,
int gid,
PoolObjectSQL::ObjectType auth_object,
bool& all,
string& filter)
{
filter.clear();
if ( uid == 0 || gid == 0 )
{
all = true;
return;
}
Nebula& nd = Nebula::instance();
AclManager* aclm = nd.get_aclm();
ostringstream acl_filter;
vector<int>::iterator it;
vector<int> oids;
vector<int> gids;
aclm->reverse_search(uid,
gid,
auth_object,
AuthRequest::USE,
all,
oids,
gids);
for ( it = oids.begin(); it < oids.end(); it++ )
{
acl_filter << " OR oid = " << *it;
}
for ( it = gids.begin(); it < gids.end(); it++ )
{
acl_filter << " OR gid = " << *it;
}
filter = acl_filter.str();
}
/* -------------------------------------------------------------------------- */
void PoolSQL::usr_filter(int uid,
int gid,
int filter_flag,
bool all,
const string& acl_str,
string& filter)
{
ostringstream uid_filter;
if ( filter_flag == RequestManagerPoolInfoFilter::MINE )
{
uid_filter << "uid = " << uid;
}
else if ( filter_flag == RequestManagerPoolInfoFilter::MINE_GROUP )
{
uid_filter << " uid = " << uid
<< " OR ( gid = " << gid << " AND group_u = 1 )";
}
else if ( filter_flag == RequestManagerPoolInfoFilter::ALL )
{
if (!all)
{
uid_filter << " uid = " << uid
<< " OR ( gid = " << gid << " AND group_u = 1 )"
<< " OR other_u = 1"
<< acl_str;
}
}
else
{
uid_filter << "uid = " << filter_flag;
if ( filter_flag != uid && !all )
{
uid_filter << " AND ("
<< " ( gid = " << gid << " AND group_u = 1)"
<< " OR other_u = 1"
<< acl_str
<< ")";
}
}
filter = uid_filter.str();
}
/* -------------------------------------------------------------------------- */
void PoolSQL::oid_filter(int start_id,
int end_id,
string& filter)
{
ostringstream idfilter;
if ( start_id != -1 )
{
idfilter << "oid >= " << start_id;
if ( end_id != -1 )
{
idfilter << " AND oid <= " << end_id;
}
}
filter = idfilter.str();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -243,6 +243,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr vm_migrate(new VirtualMachineMigrate());
xmlrpc_c::methodPtr vm_action(new VirtualMachineAction());
xmlrpc_c::methodPtr vm_savedisk(new VirtualMachineSaveDisk());
xmlrpc_c::methodPtr vm_pool_acct(new VirtualMachinePoolAccounting());
// VirtualNetwork Methods
xmlrpc_c::methodPtr vn_addleases(new VirtualNetworkAddLeases());
@ -348,6 +349,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vm.chmod", vm_chmod);
RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info);
RequestManagerRegistry.addMethod("one.vmpool.accounting", vm_pool_acct);
/* VM Template related methods*/
RequestManagerRegistry.addMethod("one.template.update", template_update);

View File

@ -91,6 +91,46 @@ void VirtualMachinePoolInfo::request_execute(
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void VirtualMachinePoolAccounting::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
int filter_flag = xmlrpc_c::value_int(paramList.getInt(1));
int time_start = xmlrpc_c::value_int(paramList.getInt(2));
int time_end = xmlrpc_c::value_int(paramList.getInt(3));
ostringstream oss;
string where;
int rc;
if ( filter_flag < MINE )
{
failure_response(XML_RPC_API,
request_error("Incorrect filter_flag",""),
att);
return;
}
where_filter(att, filter_flag, -1, -1, "", "", where);
rc = (static_cast<VirtualMachinePool *>(pool))->dump_acct(oss,
where,
time_start,
time_end);
if ( rc != 0 )
{
failure_response(INTERNAL,request_error("Internal Error",""), att);
return;
}
success_response(oss.str(), att);
return;
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void HostPoolInfo::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
@ -141,6 +181,79 @@ void ClusterPoolInfo::request_execute(
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void RequestManagerPoolInfoFilter::where_filter(
RequestAttributes& att,
int filter_flag,
int start_id,
int end_id,
const string& and_clause,
const string& or_clause,
string& filter_str)
{
bool empty = true;
bool all;
string acl_str;
string uid_str;
string oid_str;
ostringstream filter;
PoolSQL::acl_filter(att.uid, att.gid, auth_object, all, acl_str);
PoolSQL::usr_filter(att.uid, att.gid, filter_flag, all, acl_str, uid_str);
PoolSQL::oid_filter(start_id, end_id, oid_str);
// -------------------------------------------------------------------------
// Compound WHERE clause
// WHERE ( id_str ) AND ( uid_str ) AND ( and_clause ) OR ( or_clause )
// -------------------------------------------------------------------------
if (!oid_str.empty())
{
filter << "(" << oid_str << ")" ;
empty = false;
}
if (!uid_str.empty())
{
if (!empty)
{
filter << " AND ";
}
filter << "(" << uid_str << ")";
empty = false;
}
if (!and_clause.empty())
{
if (!empty)
{
filter << " AND ";
}
filter << "(" << and_clause << ")";
empty = false;
}
if (!or_clause.empty())
{
if (!empty)
{
filter << " OR ";
}
filter << "(" << or_clause << ")";
}
filter_str = filter.str();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void RequestManagerPoolInfoFilter::dump(
RequestAttributes& att,
int filter_flag,
@ -149,20 +262,9 @@ void RequestManagerPoolInfoFilter::dump(
const string& and_clause,
const string& or_clause)
{
set<int>::iterator it;
ostringstream oss;
bool empty = true;
ostringstream where_string;
ostringstream uid_filter;
ostringstream id_filter;
string uid_str;
string acl_str;
string id_str;
int rc;
string where_string;
int rc;
if ( filter_flag < MINE )
{
@ -172,148 +274,15 @@ void RequestManagerPoolInfoFilter::dump(
return;
}
Nebula& nd = Nebula::instance();
AclManager* aclm = nd.get_aclm();
bool all;
vector<int> oids;
vector<int> gids;
where_filter(att,
filter_flag,
start_id,
end_id,
and_clause,
or_clause,
where_string);
// -------------------------------------------------------------------------
// User ID filter
// -------------------------------------------------------------------------
if ( att.uid == 0 || att.gid == 0 )
{
all = true;
}
else
{
ostringstream acl_filter;
vector<int>::iterator it;
aclm->reverse_search(att.uid,
att.gid,
auth_object,
AuthRequest::USE,
all,
oids,
gids);
for ( it = oids.begin(); it < oids.end(); it++ )
{
acl_filter << " OR oid = " << *it;
}
for ( it = gids.begin(); it < gids.end(); it++ )
{
acl_filter << " OR gid = " << *it;
}
acl_str = acl_filter.str();
}
switch ( filter_flag )
{
case MINE:
uid_filter << "uid = " << att.uid;
break;
case MINE_GROUP:
uid_filter << " uid = " << att.uid
<< " OR ( gid = " << att.gid << " AND group_u = 1 )";
break;
case ALL:
if (!all)
{
uid_filter << " uid = " << att.uid
<< " OR ( gid = " << att.gid << " AND group_u = 1 )"
<< " OR other_u = 1"
<< acl_str;
}
break;
default:
uid_filter << "uid = " << filter_flag;
if ( filter_flag != att.uid && !all )
{
uid_filter << " AND ("
<< " ( gid = " << att.gid << " AND group_u = 1)"
<< " OR other_u = 1"
<< acl_str
<< ")";
}
break;
}
uid_str = uid_filter.str();
// ------------------------------------------
// Resource ID filter
// ------------------------------------------
if ( start_id != -1 )
{
id_filter << "oid >= " << start_id;
if ( end_id != -1 )
{
id_filter << " AND oid <= " << end_id;
}
}
id_str = id_filter.str();
// ------------------------------------------
// Compound WHERE clause
// ------------------------------------------
// WHERE ( id_str ) AND ( uid_str ) AND ( and_clause ) OR ( or_clause )
if (!id_str.empty())
{
where_string << "(" << id_str << ")" ;
empty = false;
}
if (!uid_str.empty())
{
if (!empty)
{
where_string << " AND ";
}
where_string << "(" << uid_str << ")";
empty = false;
}
if (!and_clause.empty())
{
if (!empty)
{
where_string << " AND ";
}
where_string << "(" << and_clause << ")";
empty = false;
}
if (!or_clause.empty())
{
if (!empty)
{
where_string << " OR ";
}
where_string << "(" << or_clause << ")";
}
// ------------------------------------------
// Get the pool
// ------------------------------------------
rc = pool->dump(oss,where_string.str());
rc = pool->dump(oss, where_string);
if ( rc != 0 )
{
@ -325,4 +294,3 @@ void RequestManagerPoolInfoFilter::dump(
return;
}

View File

@ -35,6 +35,12 @@ fi
setup()
{
TMPDIR=$(grep ^:tmpdir: $SUNSTONE_CONF|awk '{print $2}')
if [ -n "$TMPDIR" ]; then
export TMPDIR
mkdir -p $TMPDIR
fi
if [ -f $SUNSTONE_LOCK_FILE ]; then
if [ -f $SUNSTONE_PID ]; then

View File

@ -18,6 +18,9 @@
# Server Configuration
#############################################################
# Directory to store temp files when uploading images
:tmpdir: /var/tmp/one
# OpenNebula sever contact information
:one_xmlrpc: http://localhost:2633/RPC2

View File

@ -25,7 +25,7 @@
SRC=$1
DST=$2
VM_ID=$3
DS_ID=$3
DS_ID=$4
if [ -z "${ONE_LOCATION}" ]; then
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh

View File

@ -1,83 +0,0 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2012, 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. #
#--------------------------------------------------------------------------- #
# ln fe:SOURCE host:remote_system_ds/disk.i
# - fe is the front-end hostname
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
# - host is the target host to deploy the VM
# - remote_system_ds is the path for the system datastore in the host
SRC=$1
DST=$2
if [ -z "${ONE_LOCATION}" ]; then
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
else
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
fi
. $TMCOMMON
#-------------------------------------------------------------------------------
# Set dst path and dir
#-------------------------------------------------------------------------------
SRC_PATH=`arg_path $SRC`
SRC_PATH="../../${SRC_PATH##"$DS_DIR/"}"
DST_PATH=`arg_path $DST`
DST_HOST=`arg_host $DST`
DST_DIR=`dirname $DST_PATH`
#-------------------------------------------------------------------------------
# Link (ln) SRC into DST
#-------------------------------------------------------------------------------
# Is it a file or a folder (VMware)?
if [ -d `arg_path $SRC` ]; then
ssh_make_path $DST_HOST $DST_PATH
# It's a folder, make links for all elements
SRC_FOLDER_NAME=`basename $SRC_PATH`
SRC_WITH_NO_FOLDER=`dirname $SRC_PATH`
SRC_DS_NAME=`basename $SRC_WITH_NO_FOLDER`
REL_SRC_PATH="../../../$SRC_DS_NAME/$SRC_FOLDER_NAME"
log "Link all files in $SRC_PATH to $DST_PATH"
LINK_SCRIPT=$(cat <<EOF
for file in \$(cd $DST_DIR ; find $SRC_PATH -type f); do
FNAME=\$(basename \$file)
(cd $DST_PATH ; ln -sf $REL_SRC_PATH/\$FNAME $DST_PATH/$FNAME)
done
EOF
)
ssh_exec_and_log $DST_HOST "$LINK_SCRIPT" "Could not link dir files from source DS to system DS"
else
ssh_make_path $DST_HOST $DST_DIR
# Just link a file
log "Linking $SRC_PATH in $DST"
ssh_exec_and_log $DST_HOST \
"cd $DST_DIR; ln -s $SRC_PATH $DST_PATH" \
"Error linking $SRC to $DST"
fi
exit 0

1
src/tm_mad/qcow2/ln Symbolic link
View File

@ -0,0 +1 @@
../shared/ln

View File

@ -58,7 +58,7 @@ umask 0007
SRC_READLN=\$($READLINK -f $SRC_PATH)
DST_READLN=\$($READLINK -f $DST_PATH)
if [ \( -L $SRC \) -a \( "\$SRC_READLN" = "\$DST_READLN" \) ] ; then
if [ \( -L $SRC_PATH \) -a \( "\$SRC_READLN" = "\$DST_READLN" \) ] ; then
echo "Not moving files to image repo, they are the same"
else
qemu-img convert $SRC_PATH -O qcow2 $DST_PATH

View File

@ -25,10 +25,11 @@
const char * History::table = "history";
const char * History::db_names = "vid, seq, body";
const char * History::db_names = "vid, seq, body, stime, etime";
const char * History::db_bootstrap = "CREATE TABLE IF NOT EXISTS "
"history (vid INTEGER, seq INTEGER, body TEXT, PRIMARY KEY(vid,seq))";
"history (vid INTEGER, seq INTEGER, body TEXT, "
"stime INTEGER, etime INTEGER,PRIMARY KEY(vid,seq))";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -51,7 +52,8 @@ History::History(
running_etime(0),
epilog_stime(0),
epilog_etime(0),
reason(NONE){};
reason(NONE),
vm_info("<VM/>"){};
/* -------------------------------------------------------------------------- */
@ -61,7 +63,8 @@ History::History(
int _hid,
const string& _hostname,
const string& _vmm,
const string& _vnm):
const string& _vnm,
const string& _vm_info):
oid(_oid),
seq(_seq),
hostname(_hostname),
@ -76,7 +79,8 @@ History::History(
running_etime(0),
epilog_stime(0),
epilog_etime(0),
reason(NONE)
reason(NONE),
vm_info(_vm_info)
{
non_persistent_data();
};
@ -149,7 +153,7 @@ int History::insert_replace(SqlDB *db, bool replace)
return 0;
}
sql_xml = db->escape_str(to_xml(xml_body).c_str());
sql_xml = db->escape_str(to_db_xml(xml_body).c_str());
if ( sql_xml == 0 )
{
@ -168,7 +172,9 @@ int History::insert_replace(SqlDB *db, bool replace)
oss << " INTO " << table << " ("<< db_names <<") VALUES ("
<< oid << ","
<< seq << ","
<< "'" << sql_xml << "')";
<< "'" << sql_xml << "',"
<< stime << ","
<< etime << ")";
rc = db->exec(oss);
@ -259,11 +265,26 @@ ostream& operator<<(ostream& os, const History& history)
/* -------------------------------------------------------------------------- */
string& History::to_xml(string& xml) const
{
return to_xml(xml, false);
}
/* -------------------------------------------------------------------------- */
string& History::to_db_xml(string& xml) const
{
return to_xml(xml, true);
}
/* -------------------------------------------------------------------------- */
string& History::to_xml(string& xml, bool database) const
{
ostringstream oss;
oss <<
"<HISTORY>" <<
"<OID>" << oid << "</OID>" <<
"<SEQ>" << seq << "</SEQ>" <<
"<HOSTNAME>" << hostname << "</HOSTNAME>"<<
"<HID>" << hid << "</HID>" <<
@ -277,7 +298,14 @@ string& History::to_xml(string& xml) const
"<RETIME>" << running_etime << "</RETIME>"<<
"<ESTIME>" << epilog_stime << "</ESTIME>"<<
"<EETIME>" << epilog_etime << "</EETIME>"<<
"<REASON>" << reason << "</REASON>"<<
"<REASON>" << reason << "</REASON>";
if ( database )
{
oss << vm_info;
}
oss <<
"</HISTORY>";
xml = oss.str();

View File

@ -735,6 +735,7 @@ void VirtualMachine::add_history(
{
ostringstream os;
int seq;
string vm_xml;
if (history == 0)
{
@ -747,12 +748,15 @@ void VirtualMachine::add_history(
previous_history = history;
}
to_xml_extended(vm_xml, 0);
history = new History(oid,
seq,
hid,
hostname,
vmm_mad,
vnm_mad);
vnm_mad,
vm_xml);
history_records.push_back(history);
};
@ -763,18 +767,22 @@ void VirtualMachine::add_history(
void VirtualMachine::cp_history()
{
History * htmp;
string vm_xml;
if (history == 0)
{
return;
}
to_xml_extended(vm_xml, 0);
htmp = new History(oid,
history->seq + 1,
history->hid,
history->hostname,
history->vmm_mad_name,
history->vnm_mad_name);
history->vnm_mad_name,
vm_xml);
previous_history = history;
history = htmp;
@ -788,18 +796,22 @@ void VirtualMachine::cp_history()
void VirtualMachine::cp_previous_history()
{
History * htmp;
string vm_xml;
if ( previous_history == 0 || history == 0)
{
return;
}
to_xml_extended(vm_xml, 0);
htmp = new History(oid,
history->seq + 1,
previous_history->hid,
previous_history->hostname,
previous_history->vmm_mad_name,
previous_history->vnm_mad_name);
previous_history->vnm_mad_name,
vm_xml);
previous_history = history;
history = htmp;
@ -1470,26 +1482,11 @@ error_yy:
pthread_mutex_unlock(&lex_mutex);
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& VirtualMachine::to_xml(string& xml) const
{
return to_xml_extended(xml,false);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& VirtualMachine::to_xml_extended(string& xml) const
{
return to_xml_extended(xml,true);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& VirtualMachine::to_xml_extended(string& xml, bool extended) const
string& VirtualMachine::to_xml_extended(string& xml, int n_history) const
{
string template_xml;
string history_xml;
@ -1517,11 +1514,11 @@ string& VirtualMachine::to_xml_extended(string& xml, bool extended) const
<< "<NET_RX>" << net_rx << "</NET_RX>"
<< obj_template->to_xml(template_xml);
if ( hasHistory() )
if ( hasHistory() && n_history > 0 )
{
oss << "<HISTORY_RECORDS>";
if ( extended )
if ( n_history == 2 )
{
for (unsigned int i=0; i < history_records.size(); i++)
{

View File

@ -266,3 +266,37 @@ int VirtualMachinePool::get_pending(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachinePool::dump_acct(ostringstream& oss,
const string& where,
int time_start,
int time_end)
{
ostringstream cmd;
cmd << "SELECT " << History::table << ".body FROM " << History::table
<< " INNER JOIN " << VirtualMachine::table
<< " WHERE vid=oid";
if ( !where.empty() )
{
cmd << " AND " << where;
}
if ( time_start != -1 || time_end != -1 )
{
if ( time_start != -1 )
{
cmd << " AND (etime > " << time_start << " OR etime = 0)";
}
if ( time_end != -1 )
{
cmd << " AND stime < " << time_end;
}
}
cmd << " GROUP BY vid,seq";
return PoolSQL::dump(oss, "HISTORY_RECORDS", cmd);
};

View File

@ -546,8 +546,10 @@ void VirtualMachineManagerDriver::protocol(
}
vm->update_info(memory,cpu,net_tx,net_rx);
vm->set_vm_info();
vmpool->update(vm);
vmpool->update_history(vm);
if (state != '-' &&
(vm->get_lcm_state() == VirtualMachine::RUNNING ||

View File

@ -193,7 +193,7 @@ class EC2Driver < VirtualMachineDriver
return
end
deploy_exe = exec_and_log_ec2(:run, ec2_info, id)
deploy_exe = exec_and_log_ec2(:run, ec2_info, "", id)
if deploy_exe.code != 0
msg = deploy_exe.stderr
send_message(ACTION[:deploy], RESULT[:failure], id, msg)
@ -360,7 +360,7 @@ private
# +action+: Symbol, one of the keys of the EC2 hash constant (i.e :run)
# +xml+: REXML Document, containing EC2 information
# +extra_params+: String, extra information to be added to the command
def exec_and_log_ec2(action, xml, extra_params="", id)
def exec_and_log_ec2(action, xml, extra_params, id)
cmd = EC2[action][:cmd].clone
cmd << ' ' << extra_params << ' ' if extra_params