mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-06 12:58:18 +03:00
Merge branch 'feature-1099'
This commit is contained in:
commit
2fe5e591e8
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
127
share/doc/xsd/acct.xsd
Normal file
127
share/doc/xsd/acct.xsd
Normal 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>
|
@ -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">
|
||||
|
@ -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"/>
|
||||
|
@ -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>
|
||||
|
312
src/cli/oneacct
312
src/cli/oneacct
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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 ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user