1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-19 06:50:07 +03:00

Merge branch 'feature-863'

Conflicts:
	src/rm/RequestManagerVirtualMachine.cc
	src/sunstone/etc/sunstone-server.conf
This commit is contained in:
Ruben S. Montero 2011-12-04 16:40:27 +01:00
commit 87e855ed9f
94 changed files with 3137 additions and 1802 deletions

View File

@ -46,6 +46,7 @@ public:
const string& hostname,
const string& vm_dir,
const string& vmm,
const string& vnm,
const string& tm);
~History(){};
@ -91,6 +92,7 @@ private:
int hid;
string vmm_mad_name;
string vnm_mad_name;
string tm_mad_name;
time_t stime;

View File

@ -130,6 +130,15 @@ public:
return vmm_mad_name;
};
/**
* Retrives VNM mad name
* @return string vnm mad name
*/
const string& get_vnm_mad() const
{
return vnm_mad_name;
};
/**
* Retrives TM mad name
* @return string tm mad name
@ -311,6 +320,11 @@ private:
*/
string vmm_mad_name;
/**
* Name of the VN driver used to manage networking in this host
*/
string vnm_mad_name;
/**
* Name of the TM driver used to transfer file to and from this host
*/
@ -338,6 +352,7 @@ private:
const string& hostname="",
const string& im_mad_name="",
const string& vmm_mad_name="",
const string& vnm_mad_name="",
const string& tm_mad_name="");
virtual ~Host();

View File

@ -51,6 +51,7 @@ public:
const string& hostname,
const string& im_mad_name,
const string& vmm_mad_name,
const string& vnm_mad_name,
const string& tm_mad_name,
string& error_str);

View File

@ -259,9 +259,9 @@ public:
* Generates a XML string for the template of the Object
* @param xml the string to store the XML description.
*/
void template_to_xml(string &xml) const
string& template_to_xml(string &xml) const
{
obj_template->to_xml(xml);
return obj_template->to_xml(xml);
}
/**

View File

@ -51,13 +51,14 @@ protected:
bool vm_authorization(int id, int hid, ImageTemplate *tmpl,
RequestAttributes& att);
int get_host_information(int hid, string& name, string& vmm, string& tm,
RequestAttributes& att);
int get_host_information(int hid, string& name, string& vmm, string& vnm,
string& tm, RequestAttributes& att);
int add_history(VirtualMachine * vm,
int hid,
const string& hostname,
const string& vmm_mad,
const string& vnm_mad,
const string& tm_mad,
RequestAttributes& att);
@ -107,12 +108,9 @@ class VirtualMachineMigrate : public RequestManagerVirtualMachine
{
public:
VirtualMachineMigrate():
RequestManagerVirtualMachine("VirtualMachineDeploy",
RequestManagerVirtualMachine("VirtualMachineMigrate",
"Migrates a virtual machine",
"A:siib")
{
auth_op = AuthRequest::DEPLOY;
};
"A:siib"){};
~VirtualMachineMigrate(){};

View File

@ -217,6 +217,7 @@ public:
const string& hostname,
const string& vm_dir,
const string& vmm_mad,
const string& vnm_mad,
const string& tm_mad);
/**
@ -273,6 +274,26 @@ public:
return previous_history->vmm_mad_name;
};
/**
* Returns the VNM driver name for the current host. The hasHistory()
* function MUST be called before this one.
* @return the VNM mad name
*/
const string & get_vnm_mad() const
{
return history->vnm_mad_name;
};
/**
* Returns the VNM driver name for the previous host. The hasPreviousHistory()
* function MUST be called before this one.
* @return the VNM mad name
*/
const string & get_previous_vnm_mad() const
{
return previous_history->vnm_mad_name;
};
/**
* Returns the TM driver name for the current host. The hasHistory()
* function MUST be called before this one.

View File

@ -175,6 +175,41 @@ private:
const string & action,
void * arg);
/**
* Function to format a VMM Driver message in the form:
* <VMM_DRIVER_ACTION_DATA>
* <HOST> hostname </HOST>
* <NET_DRV> net_drv </NET_DRV>
* <MIGR_HOST> m_hostname </MIGR_HOST>
* <MIGR_NET_DRV> m_net_drv </MIGR_NET_DRV>
* <DOMAIN> domain_id </DOMAIN>
* <DEPLOYMENT_FILE> dfile </DEPLOYMENT_FILE>
* <CHECKPOINT_FILE> cfile </CHECKPOINT_FILE>
* <VM>
* VM representation in XML
* </VM>
* </VMM_DRIVER_ACTION_DATA>
*
* @param hostname of the host to perform the action
* @param net_drv name of the vlan driver
* @param m_hostname name of the host to migrate the VM
* @param m_net_drv name of the vlan driver
* @param domain domain id as returned by the hypervisor
* @param dfile deployment file to boot the VM
* @param cfile checkpoint file to save the VM
* @param tmpl the VM information in XML
*/
string * format_message(
const string& hostname,
const string& net_drv,
const string& m_hostname,
const string& m_net_drv,
const string& domain,
const string& ldfile,
const string& rdfile,
const string& cfile,
const string& tmpl);
/**
* Function executed when a DEPLOY action is received. It deploys a VM on
* a Host.

View File

@ -110,108 +110,76 @@ private:
friend class VirtualMachineManager;
/**
* Sends a deploy request to the MAD: "DEPLOY ID HOST CONF -"
* Sends a deploy request to the MAD: "DEPLOY ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param host the hostname
* @param conf the filename of the deployment file
* @param drv_msg xml data for the mad operation
*/
void deploy (
const int oid,
const string& host,
const string& conf) const;
const string& drv_msg) const;
/**
* Sends a shutdown request to the MAD: "SHUTDOWN ID HOST NAME -"
* Sends a shutdown request to the MAD: "SHUTDOWN ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param host the hostname
* @param name of the Virtual Machine (deployment id), as returned by the
* driver
* @param drv_msg xml data for the mad operation
*/
void shutdown (
const int oid,
const string& host,
const string& name) const;
const string& drv_msg) const;
/**
* Sends a cancel request to the MAD: "CANCEL ID HOST NAME -"
* Sends a cancel request to the MAD: "CANCEL ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param host the hostname
* @param name of the Virtual Machine (deployment id), as returned by the
* driver
* @param drv_msg xml data for the mad operation
*/
void cancel (
const int oid,
const string& host,
const string& name) const;
const string& drv_msg) const;
/**
* Sends a checkpoint request to the MAD: "CHECKPOINT ID HOST NAME FILE"
* Sends a checkpoint request to the MAD: "CHECKPOINT ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param host the hostname
* @param name of the Virtual Machine (deployment id), as returned by the
* driver
* @param file the filename to generate the checkpoint file
* @param drv_msg xml data for the mad operation
*/
void checkpoint (
const int oid,
const string& host,
const string& name,
const string& file) const;
const string& drv_msg) const;
/**
* Sends a save request to the MAD: "SAVE ID HOST NAME FILE"
* Sends a save request to the MAD: "SAVE ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param host the hostname
* @param name of the Virtual Machine (deployment id), as returned by the
* driver
* @param file the filename to generate the checkpoint file
* @param drv_msg xml data for the mad operation
*/
void save (
const int oid,
const string& host,
const string& name,
const string& file) const;
const string& drv_msg) const;
/**
* Sends a save request to the MAD: "RESTORE ID HOST FILE -"
* Sends a save request to the MAD: "RESTORE ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param host the hostname
* @param name of the Virtual Machine (deployment id), as returned by the
* driver
* @param file the filename of the checkpoint file to restore the VM
* from
* @param drv_msg xml data for the mad operation
*/
void restore (
const int oid,
const string& host,
const string& name,
const string& file) const;
const string& drv_msg) const;
/**
* Sends a migrate request to the MAD: "MIGRATE ID HOST NAME DEST"
* Sends a migrate request to the MAD: "MIGRATE ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param shost the original host (source)
* @param name of the Virtual Machine (deployment id), as returned by the
* driver
* @param dhost the destination host
* @param drv_msg xml data for the mad operation
*/
void migrate (
const int oid,
const string& shost,
const string& name,
const string& dhost) const;
const string& drv_msg) const;
/**
* Sends a poll request to the MAD: "POLL ID HOST NAME -"
* Sends a poll request to the MAD: "POLL ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param host the hostname
* @param name of the Virtual Machine (deployment id), as returned by the
* driver
* @param drv_msg xml data for the mad operation
*/
void poll (
const int oid,
const string& host,
const string& name) const;
const string& drv_msg) const;
};
/* -------------------------------------------------------------------------- */

View File

@ -208,6 +208,11 @@ private:
*/
string vlan_id;
/**
* Whether or not to isolate this network with the vnm driver
*/
int vlan;
// -------------------------------------------------------------------------
// Virtual Network Description
// -------------------------------------------------------------------------

View File

@ -122,9 +122,9 @@ if [ -z "$ROOT" ] ; then
elif [ "$OZONES" = "yes" ]; then
MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $VAR_LOCATION $OZONES_LOCATION \
$ETC_LOCATION"
DELETE_DIRS="$MAKE_DIRS"
CHOWN_DIRS=""
else
MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $ETC_LOCATION $VAR_LOCATION \
@ -162,8 +162,8 @@ else
elif [ "$OZONES" = "yes" ]; then
MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $VAR_LOCATION $OZONES_LOCATION \
$ETC_LOCATION"
DELETE_DIRS="$MAKE_DIRS"
DELETE_DIRS="$MAKE_DIRS"
else
MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $ETC_LOCATION $VAR_LOCATION \
$INCLUDE_LOCATION $SHARE_LOCATION $IMAGES_LOCATION \
@ -223,10 +223,15 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/im/vmware.d \
$VAR_LOCATION/remotes/im/ganglia.d \
$VAR_LOCATION/remotes/vmm/kvm \
$VAR_LOCATION/remotes/vnm \
$VAR_LOCATION/remotes/vnm/802.1Q \
$VAR_LOCATION/remotes/vnm/dummy \
$VAR_LOCATION/remotes/vnm/ebtables \
$VAR_LOCATION/remotes/vnm/fw \
$VAR_LOCATION/remotes/vnm/ovswitch \
$VAR_LOCATION/remotes/vmm/xen \
$VAR_LOCATION/remotes/vmm/vmware \
$VAR_LOCATION/remotes/hooks \
$VAR_LOCATION/remotes/hooks/vnm \
$VAR_LOCATION/remotes/hooks/ft \
$VAR_LOCATION/remotes/image \
$VAR_LOCATION/remotes/image/fs \
@ -258,7 +263,7 @@ SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \
$SUNSTONE_LOCATION/public/images \
$SUNSTONE_LOCATION/templates \
$SUNSTONE_LOCATION/views"
OZONES_DIRS="$OZONES_LOCATION/lib \
$OZONES_LOCATION/lib/OZones \
$OZONES_LOCATION/models \
@ -340,8 +345,8 @@ INSTALL_FILES=(
AUTH_SERVER_X509_FILES:$VAR_LOCATION/remotes/auth/server_x509
AUTH_SERVER_CIPHER_FILES:$VAR_LOCATION/remotes/auth/server_cipher
AUTH_DUMMY_FILES:$VAR_LOCATION/remotes/auth/dummy
AUTH_PLAIN_FILES:$VAR_LOCATION/remotes/auth/plain
AUTH_QUOTA_FILES:$VAR_LOCATION/remotes/auth/quota
AUTH_PLAIN_FILES:$VAR_LOCATION/remotes/auth/plain
AUTH_QUOTA_FILES:$VAR_LOCATION/remotes/auth/quota
VMM_EXEC_KVM_SCRIPTS:$VAR_LOCATION/remotes/vmm/kvm
VMM_EXEC_XEN_SCRIPTS:$VAR_LOCATION/remotes/vmm/xen
VMM_EXEC_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/vmm/vmware
@ -351,13 +356,17 @@ INSTALL_FILES=(
DUMMY_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/dummy
LVM_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/lvm
IMAGE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/image/fs
NETWORK_HOOK_SCRIPTS:$VAR_LOCATION/remotes/vnm
NETWORK_FILES:$VAR_LOCATION/remotes/vnm
NETWORK_8021Q_FILES:$VAR_LOCATION/remotes/vnm/802.1Q
NETWORK_DUMMY_FILES:$VAR_LOCATION/remotes/vnm/dummy
NETWORK_EBTABLES_FILES:$VAR_LOCATION/remotes/vnm/ebtables
NETWORK_FW_FILES:$VAR_LOCATION/remotes/vnm/fw
NETWORK_OVSWITCH_FILES:$VAR_LOCATION/remotes/vnm/ovswitch
EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples
INSTALL_NOVNC_SHARE_FILE:$SHARE_LOCATION
INSTALL_GEMS_SHARE_FILE:$SHARE_LOCATION
TM_EXAMPLE_SHARE_FILES:$SHARE_LOCATION/examples/tm
HOOK_FT_FILES:$VAR_LOCATION/remotes/hooks/ft
HOOK_NETWORK_FILES:$VAR_LOCATION/remotes/hooks/vnm
COMMON_CLOUD_LIB_FILES:$LIB_LOCATION/ruby/cloud
CLOUD_AUTH_LIB_FILES:$LIB_LOCATION/ruby/cloud/CloudAuth
ECO_LIB_FILES:$LIB_LOCATION/ruby/cloud/econe
@ -513,6 +522,9 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \
src/mad/ruby/CommandManager.rb \
src/mad/ruby/OpenNebulaDriver.rb \
src/mad/ruby/VirtualMachineDriver.rb \
src/mad/ruby/DriverExecHelper.rb \
src/mad/ruby/ssh_stream.rb \
src/vnm_mad/one_vnm.rb \
src/mad/ruby/Ganglia.rb \
src/mad/ruby/vmwarelib.rb \
src/oca/ruby/OpenNebula.rb \
@ -645,6 +657,38 @@ AUTH_PLAIN_FILES="src/authm_mad/remotes/plain/authenticate"
AUTH_QUOTA_FILES="src/authm_mad/remotes/quota/authorize"
#-------------------------------------------------------------------------------
# Virtual Network Manager drivers to be installed under $REMOTES_LOCATION/vnm
#-------------------------------------------------------------------------------
NETWORK_FILES="src/vnm_mad/remotes/OpenNebulaNetwork.rb \
src/vnm_mad/remotes/Firewall.rb \
src/vnm_mad/remotes/OpenNebulaNic.rb"
NETWORK_8021Q_FILES="src/vnm_mad/remotes/802.1Q/clean \
src/vnm_mad/remotes/802.1Q/post \
src/vnm_mad/remotes/802.1Q/pre \
src/vnm_mad/remotes/802.1Q/HostManaged.rb"
NETWORK_DUMMY_FILES="src/vnm_mad/remotes/dummy/clean \
src/vnm_mad/remotes/dummy/post \
src/vnm_mad/remotes/dummy/pre"
NETWORK_EBTABLES_FILES="src/vnm_mad/remotes/ebtables/clean \
src/vnm_mad/remotes/ebtables/post \
src/vnm_mad/remotes/ebtables/pre \
src/vnm_mad/remotes/ebtables/Ebtables.rb"
NETWORK_FW_FILES="src/vnm_mad/remotes/fw/post \
src/vnm_mad/remotes/fw/pre \
src/vnm_mad/remotes/fw/clean"
NETWORK_OVSWITCH_FILES="src/vnm_mad/remotes/ovswitch/clean \
src/vnm_mad/remotes/ovswitch/post \
src/vnm_mad/remotes/ovswitch/pre \
src/vnm_mad/remotes/ovswitch/OpenvSwitch.rb"
#-------------------------------------------------------------------------------
# Transfer Manager commands, to be installed under $LIB_LOCATION/tm_commands
# - SHARED TM, $LIB_LOCATION/tm_commands/shared
@ -800,20 +844,9 @@ TM_EXAMPLE_SHARE_FILES="share/examples/tm/tm_clone.sh \
HOOK_FT_FILES="share/hooks/host_error.rb"
#-------------------------------------------------------------------------------
# Network Hook scripts, to be installed under $VAR_LOCATION/remotes/hooks
# Installation scripts, to be installed under $SHARE_LOCATION
#-------------------------------------------------------------------------------
HOOK_NETWORK_FILES="src/vnm_mad/hm-vlan \
src/vnm_mad/ebtables-vlan \
src/vnm_mad/firewall \
src/vnm_mad/HostManaged.rb \
src/vnm_mad/OpenNebulaNetwork.rb \
src/vnm_mad/OpenNebulaNic.rb \
src/vnm_mad/OpenvSwitch.rb \
src/vnm_mad/openvswitch-vlan \
src/vnm_mad/Firewall.rb \
src/vnm_mad/Ebtables.rb"
INSTALL_NOVNC_SHARE_FILE="share/install_novnc.sh"
INSTALL_GEMS_SHARE_FILE="share/install_gems/install_gems"
@ -1080,7 +1113,7 @@ SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \
src/sunstone/public/images/Refresh-icon.png \
src/sunstone/public/images/vnc_off.png \
src/sunstone/public/images/vnc_on.png"
#-----------------------------------------------------------------------------
# Ozones files
#-----------------------------------------------------------------------------
@ -1095,10 +1128,10 @@ OZONES_ETC_FILES="src/ozones/Server/etc/ozones-server.conf"
OZONES_MODELS_FILES="src/ozones/Server/models/OzonesServer.rb \
src/ozones/Server/models/Auth.rb \
src/sunstone/models/OpenNebulaJSON/JSONUtils.rb"
OZONES_TEMPLATE_FILES="src/ozones/Server/templates/index.html \
src/ozones/Server/templates/login.html"
OZONES_LIB_FILES="src/ozones/Server/lib/OZones.rb"
OZONES_LIB_ZONE_FILES="src/ozones/Server/lib/OZones/Zones.rb \
@ -1112,7 +1145,7 @@ OZONES_LIB_ZONE_FILES="src/ozones/Server/lib/OZones/Zones.rb \
src/ozones/Server/lib/OZones/AggregatedPool.rb \
src/ozones/Server/lib/OZones/AggregatedImages.rb \
src/ozones/Server/lib/OZones/AggregatedTemplates.rb"
OZONES_LIB_API_FILES="src/ozones/Client/lib/zona.rb"
OZONES_LIB_API_ZONA_FILES="src/ozones/Client/lib/zona/ZoneElement.rb \
@ -1124,7 +1157,7 @@ OZONES_LIB_API_ZONA_FILES="src/ozones/Client/lib/zona/ZoneElement.rb \
src/ozones/Client/lib/zona/ZonePool.rb"
OZONES_PUBLIC_VENDOR_JQUERY=$SUNSTONE_PUBLIC_VENDOR_JQUERY
OZONES_PUBLIC_VENDOR_DATATABLES=$SUNSTONE_PUBLIC_VENDOR_DATATABLES
OZONES_PUBLIC_VENDOR_JGROWL=$SUNSTONE_PUBLIC_VENDOR_JGROWL
@ -1134,18 +1167,18 @@ OZONES_PUBLIC_VENDOR_JQUERYUI=$SUNSTONE_PUBLIC_VENDOR_JQUERYUI
OZONES_PUBLIC_VENDOR_JQUERYUIIMAGES=$SUNSTONE_PUBLIC_VENDOR_JQUERYUIIMAGES
OZONES_PUBLIC_VENDOR_JQUERYLAYOUT=$SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT
OZONES_PUBLIC_JS_FILES="src/ozones/Server/public/js/ozones.js \
src/ozones/Server/public/js/login.js \
src/ozones/Server/public/js/ozones-util.js \
src/sunstone/public/js/layout.js \
src/sunstone/public/js/sunstone.js \
src/sunstone/public/js/sunstone-util.js"
OZONES_PUBLIC_CSS_FILES="src/ozones/Server/public/css/application.css \
src/ozones/Server/public/css/layout.css \
src/ozones/Server/public/css/login.css"
OZONES_PUBLIC_IMAGES_FILES="src/ozones/Server/public/images/panel.png \
src/ozones/Server/public/images/login.png \
src/ozones/Server/public/images/login_over.png \
@ -1159,16 +1192,16 @@ OZONES_PUBLIC_JS_PLUGINS_FILES="src/ozones/Server/public/js/plugins/zones-tab.js
src/ozones/Server/public/js/plugins/vdcs-tab.js \
src/ozones/Server/public/js/plugins/aggregated-tab.js \
src/ozones/Server/public/js/plugins/dashboard-tab.js"
OZONES_LIB_CLIENT_CLI_FILES="src/ozones/Client/lib/cli/ozones_helper.rb"
OZONES_LIB_CLIENT_CLI_FILES="src/ozones/Client/lib/cli/ozones_helper.rb"
OZONES_LIB_CLIENT_CLI_HELPER_FILES="\
src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb \
src/ozones/Client/lib/cli/ozones_helper/zones_helper.rb"
src/ozones/Client/lib/cli/ozones_helper/zones_helper.rb"
OZONES_BIN_CLIENT_FILES="src/ozones/Client/bin/onevdc \
src/ozones/Client/bin/onezone"
OZONES_RUBY_LIB_FILES="src/oca/ruby/OpenNebula.rb"
#-----------------------------------------------------------------------------
@ -1246,7 +1279,7 @@ if [ "$CLIENT" = "yes" ]; then
elif [ "$SUNSTONE" = "yes" ]; then
INSTALL_SET="${INSTALL_SUNSTONE_RUBY_FILES[@]} ${INSTALL_SUNSTONE_FILES[@]}"
elif [ "$OZONES" = "yes" ]; then
INSTALL_SET="${INSTALL_OZONES_RUBY_FILES[@]} ${INSTALL_OZONES_FILES[@]}"
INSTALL_SET="${INSTALL_OZONES_RUBY_FILES[@]} ${INSTALL_OZONES_FILES[@]}"
else
INSTALL_SET="${INSTALL_FILES[@]} ${INSTALL_OZONES_FILES[@]} \
${INSTALL_SUNSTONE_FILES[@]}"

View File

@ -438,136 +438,6 @@ HM_MAD = [
# arguments = "$VMID" ]
#-------------------------------------------------------------------------------
#*******************************************************************************
# Networking Hooks
#*******************************************************************************
# The following network hooks can be activated in order to manage network
# isolation and firewalls.
#*******************************************************************************
#-------------------------------------------------------------------------------
# Firewall
#-------------------------------------------------------------------------------
#
# Firewalling rules activated in the physical host executing the VM. Can be used
# to filter TCP and UDP ports, and to define a policy for ICMP connections. To
# use it specify under the NIC section of the VM one or more of the following
# attributes:
#
# - WHITE_PORTS_TCP = iptables_range
# Permits access to the VM only through the specified ports in the TCP
# protocol. Supersedes BLACK_PORTS_TCP if defined.
#
# - BLACK_PORTS_TCP = iptables_range
# Doesn't permit access to the VM through the specified ports in the TCP
# protocol. Superseded by WHITE_PORTS_TCP if defined.
#
# - WHITE_PORTS_UDP = iptables_range
# Permits access to the VM only through the specified ports in the UDP
# protocol. Supersedes BLACK_PORTS_UDP if defined.
#
# - BLACK_PORTS_UDP = iptables_range
# Doesn't permit access to the VM through the specified ports in the UDP
# protocol. Superseded by WHITE_PORTS_UDP if defined.
#
# - ICMP = no | drop
# Blocks ICMP connections to the VM. By default it's enabled.
#
# This hook requires the sudoers file to be configured so oneadmin can execute
# iptables without a password.
#
#-------------------------------------------------------------------------------
#
# VM_HOOK = [
# name = "firewall-on",
# on = "RUNNING",
# command = "vnm/firewall",
# arguments = "on $TEMPLATE",
# remote = "yes" ]
#
# VM_HOOK = [
# name = "firewall-off",
# on = "DONE",
# command = "vnm/firewall",
# arguments = "off $TEMPLATE",
# remote = "yes" ]
#-------------------------------------------------------------------------------
# Host-managed VLANs
#-------------------------------------------------------------------------------
#
# Network isolation provided through host-managed vlans. This hook will create a
# bridge for each OpenNebula virtual network and attach a tagged network
# interface to the bridge.
#
# For this hook to be effective you need to specify the attribute PHYDEV in your
# VNET template, which should contain the name of the physical network interface
# each VM should be attached to. If BRIDGE is not defined it will be
# automatically generated.
#
# In order to use this hook you need to:
# - load module 8021q
# - install vconfig
# - configure passwordless sudo in the worker nodes for oneadmin for these
# commands: brctl, ip, vconfig.
#
#-------------------------------------------------------------------------------
#
# VM_HOOK = [
# name = "hm-vlan",
# on = "PROLOG",
# command = "vnm/hm-vlan",
# arguments = "$TEMPLATE",
# remote = "yes" ]
#
#-------------------------------------------------------------------------------
# Ebtables Network Isolation
#-------------------------------------------------------------------------------
#
# Network isolation provided through ebtables rules applied on the bridges. This
# method will only permit isolation with a mask of 255.255.255.0.
#
# This hook requires the sudoers file to be configured so oneadmin can execute
# ebtables without a password, and the ebtables package to be installed.
#
#-------------------------------------------------------------------------------
#
# VM_HOOK = [
# name = "ebtables-vlan-on",
# on = "RUNNING",
# command = "vnm/ebtables-vlan",
# arguments = "on $TEMPLATE",
# remote = "yes" ]
#
# VM_HOOK = [
# name = "ebtables-vlan-off",
# on = "DONE",
# command = "vnm/ebtables-vlan",
# arguments = "off $TEMPLATE",
# remote = "yes" ]
#
#-------------------------------------------------------------------------------
# Open vSwitch Network Isolation
#-------------------------------------------------------------------------------
#
# Network isolation provided through Open vSwitch. Each virtual network
# interface will receive an VLAN tag enabling network isolation.
#
# This hook requires Open vSwitch to be installed along with the Open vSwitch
# compatibility layer for Linux bridging, on each worker node.
# See http://openvswitch.org/ for more information.
#
# Passwordless sudo permissions for oneadmin to execute ovs_vsctl.
#
#-------------------------------------------------------------------------------
#
# VM_HOOK = [
# name = "openvswitch-vlan",
# on = "RUNNING",
# command = "vnm/openvswitch-vlan",
# arguments = "$TEMPLATE",
# remote = "yes" ]
#
#-------------------------------------------------------------------------------
#*******************************************************************************
# Auth Manager Configuration
#*******************************************************************************

View File

@ -111,7 +111,8 @@ class AuthDriver < OpenNebulaDriver
command = File.join(authN_path,ACTION[:authN].downcase)
command << " '" << user.gsub("'", '\'"\'"\'') << "' '" << password.gsub("'", '\'"\'"\'') << "' " << secret
local_action(command, request_id, ACTION[:authN])
do_action(command, request_id, nil, ACTION[:authN],
:local => true)
end
# Authenticate a user based in a string of the form user:secret when using the
@ -141,7 +142,8 @@ class AuthDriver < OpenNebulaDriver
command = @authZ_cmd.clone
command << ' ' << user_id << ' ' << requests.join(' ')
local_action(command, request_id, ACTION[:authZ])
do_action(command, request_id, nil, ACTION[:authZ],
:local => true)
end
end
end

View File

@ -59,6 +59,7 @@ class OneHostHelper < OpenNebulaHelper::OneHelper
puts str % ["STATE", host.state_str]
puts str % ["IM_MAD", host['IM_MAD']]
puts str % ["VM_MAD", host['VM_MAD']]
puts str % ["VN_MAD", host['VN_MAD']]
puts str % ["TM_MAD", host['TM_MAD']]
puts str % ["LAST MONITORING TIME", host['LAST_MON_TIME']]
puts

View File

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

View File

@ -59,6 +59,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
puts str % ["PUBLIC", OpenNebulaHelper.boolean_to_str(vn['PUBLIC'])]
puts str % ["TYPE", vn.type_str]
puts str % ["BRIDGE", vn["BRIDGE"]]
puts str % ["VLAN", OpenNebulaHelper.boolean_to_str(vn['VLAN'])]
puts str % ["PHYSICAL DEVICE", vn["PHYDEV"]] if vn["PHYDEV"]
puts str % ["VLAN ID", vn["VLAN_ID"]] if vn["VLAN_ID"]
puts str % ["USED LEASES", vn['TOTAL_LEASES']]
@ -128,4 +129,4 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
table
end
end
end

View File

@ -60,9 +60,10 @@ cmd=CommandParser::CmdParser.new(ARGV) do
Creates a new Host
EOT
command :create, create_desc, :hostname, :im_mad, :vmm_mad, :tm_mad do
command :create, create_desc, :hostname, :im_mad, :vmm_mad,
:tm_mad, :vnm_mad do
helper.create_resource(options) do |host|
host.allocate(args[0], args[1], args[2], args[3])
host.allocate(args[0], args[1], args[2], args[4], args[3])
end
end

View File

@ -33,11 +33,13 @@ Host::Host(
const string& _hostname,
const string& _im_mad_name,
const string& _vmm_mad_name,
const string& _vnm_mad_name,
const string& _tm_mad_name):
PoolObjectSQL(id,_hostname,-1,-1,"","",table),
state(INIT),
im_mad_name(_im_mad_name),
vmm_mad_name(_vmm_mad_name),
vnm_mad_name(_vnm_mad_name),
tm_mad_name(_tm_mad_name),
last_monitored(0)
{
@ -200,6 +202,7 @@ string& Host::to_xml(string& xml) const
"<STATE>" << state << "</STATE>" <<
"<IM_MAD>" << im_mad_name << "</IM_MAD>" <<
"<VM_MAD>" << vmm_mad_name << "</VM_MAD>" <<
"<VN_MAD>" << vnm_mad_name << "</VN_MAD>" <<
"<TM_MAD>" << tm_mad_name << "</TM_MAD>" <<
"<LAST_MON_TIME>" << last_monitored << "</LAST_MON_TIME>" <<
host_share.to_xml(share_xml) <<
@ -231,6 +234,7 @@ int Host::from_xml(const string& xml)
rc += xpath(im_mad_name, "/HOST/IM_MAD", "not_found");
rc += xpath(vmm_mad_name, "/HOST/VM_MAD", "not_found");
rc += xpath(vnm_mad_name, "/HOST/VN_MAD", "not_found");
rc += xpath(tm_mad_name, "/HOST/TM_MAD", "not_found");
rc += xpath(last_monitored, "/HOST/LAST_MON_TIME", 0);

View File

@ -139,6 +139,7 @@ int HostPool::allocate (
const string& hostname,
const string& im_mad_name,
const string& vmm_mad_name,
const string& vnm_mad_name,
const string& tm_mad_name,
string& error_str)
{
@ -165,6 +166,11 @@ int HostPool::allocate (
goto error_vmm;
}
if ( vnm_mad_name.empty() )
{
goto error_vnm;
}
if ( tm_mad_name.empty() )
{
goto error_tm;
@ -179,7 +185,8 @@ int HostPool::allocate (
// Build a new Host object
host = new Host(-1, hostname, im_mad_name, vmm_mad_name, tm_mad_name);
host = new Host(-1, hostname, im_mad_name, vmm_mad_name, vnm_mad_name,
tm_mad_name);
// Insert the Object in the pool
@ -204,6 +211,10 @@ error_vmm:
oss << "VMM_MAD_NAME cannot be empty.";
goto error_common;
error_vnm:
oss << "VNM_MAD_NAME cannot be empty.";
goto error_common;
error_tm:
oss << "TM_MAD_NAME cannot be empty.";
goto error_common;

View File

@ -96,7 +96,7 @@ public:
{
string err;
hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "tm_mad", err);
hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", "tm_mad", err);
CPPUNIT_ASSERT( oid >= 0 );
sleep(1);
@ -114,7 +114,7 @@ public:
{
string err;
hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "tm_mad", err);
hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", "tm_mad", err);
CPPUNIT_ASSERT( oid >= 0 );
host = hpool->get(oid, true);
@ -140,7 +140,7 @@ public:
{
string err;
hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "tm_mad", err);
hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", "tm_mad", err);
CPPUNIT_ASSERT( oid >= 0 );
host = hpool->get(oid, true);
@ -166,7 +166,7 @@ public:
{
string err;
hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "tm_mad", err);
hpool->allocate(&oid, "host_test", "im_mad", "vmm_mad", "vnm_mad", "tm_mad", err);
CPPUNIT_ASSERT( oid >= 0 );
host = hpool->get(oid, true);

View File

@ -25,6 +25,7 @@ using namespace std;
const string im_mad = "im_mad";
const string vmm_mad = "vmm_mad";
const string vnm_mad = "vnm_mad";
const string tm_mad = "tm_mad";
const string names[] = {"Host one", "Second host"};
@ -32,7 +33,7 @@ const string names[] = {"Host one", "Second host"};
const string xmls[] =
{
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE>"
"<IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD>"
"<IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD>"
"<LAST_MON_TIME>0</LAST_MON_TIME><HOST_SHARE>"
"<DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE>"
"<MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU>"
@ -41,7 +42,7 @@ const string xmls[] =
"<RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST>",
"<HOST><ID>1</ID><NAME>Second host</NAME><STATE>0</STATE>"
"<IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD>"
"<IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD>"
"<LAST_MON_TIME>0</LAST_MON_TIME><HOST_SHARE>"
"<DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE>"
"<MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU>"
@ -53,34 +54,34 @@ const string xmls[] =
// This xml dump result has the LAST_MON_TIMEs modified to 0000000000
const string xml_dump =
"<HOST_POOL><HOST><ID>0</ID><NAME>a</NAME><STATE>0</STATE><IM_MAD>im_mad</I"
"M_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0"
"M_MAD><VM_MAD>vmm_mad</VM_MAD><VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0"
"</LAST_MON_TIME><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM"
"_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM"
">0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_"
"MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><U"
"SED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST>"
"<ID>1</ID><NAME>a name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MA"
"D>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_M"
"D>vmm_mad</VM_MAD><VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_M"
"ON_TIME><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</ME"
"M_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM>"
"<MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CP"
"U>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</U"
"SED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST><ID>2</ID><N"
"AME>a_name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</V"
"M_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><HOS"
"M_MAD><VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><HOS"
"T_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU"
"_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</"
"MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CP"
"U><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUN"
"NING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST><ID>3</ID><NAME>another "
"name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD>"
"<TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><HOST_SHAR"
"<VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><HOST_SHAR"
"E><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE"
">0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CP"
"U><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USE"
"D_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_V"
"MS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST><ID>4</ID><NAME>host</NAME><ST"
"ATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad"
"ATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad"
"</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><HOST_SHARE>"
"<DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE>"
"<MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0"
@ -90,28 +91,28 @@ const string xml_dump =
const string xml_dump_like_a =
"<HOST_POOL><HOST><ID>0</ID><NAME>a</NAME><STATE>0</STATE><IM_MAD>im_mad</I"
"M_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0"
"M_MAD><VM_MAD>vmm_mad</VM_MAD><VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0"
"</LAST_MON_TIME><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM"
"_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM"
">0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_"
"MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><U"
"SED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST>"
"<ID>1</ID><NAME>a name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MA"
"D>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_M"
"D>vmm_mad</VM_MAD><VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_M"
"ON_TIME><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</ME"
"M_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM>"
"<MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CP"
"U>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</U"
"SED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST><ID>2</ID><N"
"AME>a_name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</V"
"M_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><HOS"
"M_MAD><VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><HOS"
"T_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU"
"_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</"
"MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CP"
"U><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUN"
"NING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST><HOST><ID>3</ID><NAME>another "
"name</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD>"
"<TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><HOST_SHAR"
"<VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><HOST_SHAR"
"E><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE"
">0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CP"
"U><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USE"
@ -119,10 +120,10 @@ const string xml_dump_like_a =
"MS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST></HOST_POOL>";
const string host0_updated =
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE><ATT_A><![CDATA[VALUE_A]]></ATT_A><ATT_B><![CDATA[VALUE_B]]></ATT_B></TEMPLATE></HOST>";
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE><ATT_A><![CDATA[VALUE_A]]></ATT_A><ATT_B><![CDATA[VALUE_B]]></ATT_B></TEMPLATE></HOST>";
const string host_0_cluster =
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>cluster_a</CLUSTER><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST>";
"<HOST><ID>0</ID><NAME>Host one</NAME><STATE>0</STATE><IM_MAD>im_mad</IM_MAD><VM_MAD>vmm_mad</VM_MAD><VN_MAD>vnm_mad</VN_MAD><TM_MAD>tm_mad</TM_MAD><LAST_MON_TIME>0</LAST_MON_TIME><CLUSTER>cluster_a</CLUSTER><HOST_SHARE><DISK_USAGE>0</DISK_USAGE><MEM_USAGE>0</MEM_USAGE><CPU_USAGE>0</CPU_USAGE><MAX_DISK>0</MAX_DISK><MAX_MEM>0</MAX_MEM><MAX_CPU>0</MAX_CPU><FREE_DISK>0</FREE_DISK><FREE_MEM>0</FREE_MEM><FREE_CPU>0</FREE_CPU><USED_DISK>0</USED_DISK><USED_MEM>0</USED_MEM><USED_CPU>0</USED_CPU><RUNNING_VMS>0</RUNNING_VMS></HOST_SHARE><TEMPLATE></TEMPLATE></HOST>";
/* ************************************************************************* */
/* ************************************************************************* */
@ -162,7 +163,7 @@ protected:
int oid;
string err;
return ((HostPool*)pool)->allocate(&oid, names[index], im_mad,
vmm_mad, tm_mad, err);
vmm_mad, vnm_mad, tm_mad, err);
};
void check(int index, PoolObjectSQL* obj)
@ -184,7 +185,7 @@ protected:
if( xml_str != xmls[index] )
{
cout << endl << xml_str << endl << "========"
<< endl << xmls[index];
<< endl << xmls[index] << endl;
}
//*/
CPPUNIT_ASSERT( xml_str == xmls[index]);
@ -242,16 +243,16 @@ public:
// If we try to allocate two hosts with the same name and drivers,
// should fail
rc = hp->allocate(&oid_0, names[0], im_mad, vmm_mad, tm_mad, err);
rc = hp->allocate(&oid_0, names[0], im_mad, vmm_mad, vnm_mad, tm_mad, err);
CPPUNIT_ASSERT( oid_0 == 0 );
CPPUNIT_ASSERT( rc == oid_0 );
rc = hp->allocate(&oid_1, names[0], im_mad, vmm_mad, tm_mad, err);
rc = hp->allocate(&oid_1, names[0], im_mad, vmm_mad, vnm_mad, tm_mad, err);
CPPUNIT_ASSERT( oid_1 == -1 );
CPPUNIT_ASSERT( rc == oid_1 );
// the hostname can not be repeated if the drivers change
rc = hp->allocate(&oid_1, names[0], im_mad, vmm_mad, tm_mad_2, err);
rc = hp->allocate(&oid_1, names[0], im_mad, vmm_mad, vnm_mad, tm_mad_2, err);
CPPUNIT_ASSERT( oid_1 == -1 );
CPPUNIT_ASSERT( rc == oid_1 );
@ -272,7 +273,7 @@ public:
for(int i=0; i<5; i++)
{
((HostPool*)pool)->allocate(&oid, names[i],
im_mad, vmm_mad, tm_mad, err);
im_mad, vmm_mad, vnm_mad, tm_mad, err);
}
ostringstream oss;
@ -287,7 +288,7 @@ public:
if( result != xml_dump )
{
cout << endl << result << endl << "========"
<< endl << xml_dump;
<< endl << xml_dump << endl;
}
//*/
@ -305,7 +306,7 @@ public:
for(int i=0; i<5; i++)
{
((HostPool*)pool)->allocate(&oid, names[i],
im_mad, vmm_mad, tm_mad, err);
im_mad, vmm_mad, vnm_mad, tm_mad, err);
}
@ -321,7 +322,7 @@ public:
if( result != xml_dump_like_a )
{
cout << endl << result << endl << "========"
<< endl << xml_dump_like_a;
<< endl << xml_dump_like_a << endl;
}
//*/
@ -346,7 +347,7 @@ public:
{
oss << "host" << i;
hp->allocate(&oid, oss.str().c_str(), im_mad, vmm_mad, tm_mad, err);
hp->allocate(&oid, oss.str().c_str(), im_mad, vmm_mad, vnm_mad, tm_mad, err);
CPPUNIT_ASSERT(oid == i);
if (i >=8 )
@ -404,7 +405,7 @@ public:
{
oss << "host" << j;
hp->allocate(&oid, oss.str().c_str(),im_mad,vmm_mad,tm_mad,err);
hp->allocate(&oid, oss.str().c_str(),im_mad,vmm_mad,vnm_mad,tm_mad,err);
}
the_time2 = time(0) - the_time;
@ -433,7 +434,7 @@ public:
for (i=10000,oss.str(""); i<30000 ; i++,oss.str(""))
{
oss << "host" << i;
hp->allocate(&oid,oss.str().c_str(),im_mad,vmm_mad,tm_mad,err);
hp->allocate(&oid,oss.str().c_str(),im_mad,vmm_mad,vnm_mad,tm_mad,err);
host = hp->get(oid, false);

View File

@ -54,12 +54,16 @@ class ImageDriver < OpenNebulaDriver
@options={
:concurrency => 10,
:threaded => true,
:retries => 0
:retries => 0,
:local_actions => {
'MV' => nil,
'CP' => nil,
'RM' => nil,
'MKFS' => nil
}
}.merge!(options)
super('', @options)
@actions_path = "#{VAR_LOCATION}/remotes/image/#{fs_type}"
super("image/#{fs_type}", @options)
register_action(ACTION[:mv].to_sym, method("mv"))
register_action(ACTION[:cp].to_sym, method("cp"))
@ -69,19 +73,21 @@ class ImageDriver < OpenNebulaDriver
# Image Manager Protocol Actions (generic implementation
def mv(id, src, dst)
local_action("#{@actions_path}/mv #{src} #{dst} #{id}",id,ACTION[:mv])
do_action("#{src} #{dst} #{id}", id, nil,
ACTION[:mv])
end
def cp(id, src)
local_action("#{@actions_path}/cp #{src} #{id}",id,ACTION[:cp])
do_action("#{src} #{id}", id, nil, ACTION[:cp])
end
def rm(id, dst)
local_action("#{@actions_path}/rm #{dst} #{id}",id,ACTION[:rm])
do_action("#{dst} #{id}", id, nil, ACTION[:rm])
end
def mkfs(id, fs, size)
local_action("#{@actions_path}/mkfs #{fs} #{size} #{id}",id,ACTION[:mkfs])
do_action("#{fs} #{size} #{id}", id, nil,
ACTION[:mkfs])
end
end

View File

@ -47,6 +47,7 @@ const string templates[] =
static int hid = 123;
static string hostname = "test_hostname";
static string vmm_mad = "vmm_mad";
static string vnm_mad = "vnm_mad";
static string tm_mad = "tm_mad";
static string vmdir = "vmdir";
@ -225,7 +226,7 @@ private:
vm->lock();
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -489,7 +490,7 @@ public:
{
vm = allocate_running(0);
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -573,7 +574,7 @@ public:
{
vm = allocate_running(0);
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -594,7 +595,7 @@ public:
{
vm = allocate_running(0);
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -615,7 +616,7 @@ public:
{
vm = allocate_running(0);
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -637,7 +638,7 @@ public:
{
vm = allocate_running(0);
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -661,7 +662,7 @@ public:
{
vm = allocate_running(0);
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -685,7 +686,7 @@ public:
{
vm = allocate_running(0);
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -749,7 +750,7 @@ public:
{
vm = allocate_running(0);
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -772,7 +773,7 @@ public:
{
vm = allocate_running(0);
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -795,7 +796,7 @@ public:
{
vm = allocate_running(0);
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );

View File

@ -16,6 +16,7 @@
require 'thread'
=begin rdoc
This class provides support to handle actions. Class methods, or actions, can be
registered in the action manager. The manager will wait for actions to be
triggered (thread-safe), and will execute them concurrently. The action manager

View File

@ -0,0 +1,194 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
# This module provides an abstraction to generate an execution context for
# OpenNebula Drivers. The module has been designed to be included as part
# of a driver and not to be used standalone.
module DriverExecHelper
# Action result strings for messages
RESULT = {
:success => "SUCCESS",
:failure => "FAILURE"
}
def self.failed?(rc_str)
return rc_str == RESULT[:failure]
end
#Initialize module variables
def initialize_helper(directory, options)
@config = read_configuration
@remote_scripts_base_path = @config['SCRIPTS_REMOTE_DIR']
@local_actions = options[:local_actions]
if ENV['ONE_LOCATION'] == nil
@local_scripts_base_path = "/var/lib/one/remotes"
else
@local_scripts_base_path = "#{ENV['ONE_LOCATION']}/var/remotes"
end
# dummy paths
@remote_scripts_path = File.join(@remote_scripts_base_path, directory)
@local_scripts_path = File.join(@local_scripts_base_path, directory)
end
#
# METHODS FOR COMMAND LINE & ACTION PATHS
#
# Given the action name and the parameter returns full path of the script
# and appends its parameters. It uses @local_actions hash to know if the
# actions is remote or local. If the local actions has defined an special
# script name this is used, otherwise the action name in downcase is
# used as the script name.
#
# @param [String, Symbol] action name of the action
# @param [String] parameters arguments for the script
# @param [String, nil] default_name alternative name for the script
# @return [String] command line needed to execute the action
def action_command_line(action, parameters, default_name=nil)
if action_is_local? action
script_path=@local_scripts_path
else
script_path=@remote_scripts_path
end
File.join(script_path, action_script_name(action, default_name))+
" "+parameters
end
# True if the action is meant to be executed locally
#
# @param [String, Symbol] action name of the action
def action_is_local?(action)
@local_actions.include? action.to_s.upcase
end
# Name of the script file for the given action
#
# @param [String, Symbol] action name of the action
# @param [String, nil] default_name alternative name for the script
def action_script_name(action, default_name=nil)
name=@local_actions[action.to_s.upcase]
if name
name
else
default_name || action.to_s.downcase
end
end
#
# METHODS FOR LOGS & COMMAND OUTPUT
#
# Sends a log message to ONE. The +message+ can be multiline, it will
# be automatically splitted by lines.
def log(number, message)
in_error_message=false
msg=message.strip
msg.each_line {|line|
severity='I'
l=line.strip
if l=='ERROR MESSAGE --8<------'
in_error_message=true
next
elsif l=='ERROR MESSAGE ------>8--'
in_error_message=false
next
else
if in_error_message
severity='E'
elsif line.match(/^(ERROR|DEBUG|INFO):(.*)$/)
line=$2
case $1
when 'ERROR'
severity='E'
when 'DEBUG'
severity='D'
when 'INFO'
severity='I'
else
severity='I'
end
end
end
send_message("LOG", severity, number, line.strip)
}
end
# Generates a proc with that calls log with a hardcoded number. It will
# be used to add loging to command actions
def log_method(num)
lambda {|message|
log(num, message)
}
end
#This method returns the result in terms
def get_info_from_execution(command_exe)
if command_exe.code == 0
result = RESULT[:success]
info = command_exe.stdout
else
result = RESULT[:failure]
info = command_exe.get_error_message
end
info = "-" if info == nil || info.empty?
[result, info]
end
#
#
# Simple parser for the config file generated by OpenNebula
def read_configuration
one_config=nil
if ENV['ONE_LOCATION']
one_config = ENV['ONE_LOCATION']+'/var/config'
else
one_config = '/var/lib/one/config'
end
config=Hash.new
cfg=''
begin
open(one_config) do |file|
cfg=file.read
end
cfg.split(/\n/).each do |line|
m=line.match(/^([^=]+)=(.*)$/)
if m
name=m[1].strip.upcase
value=m[2].strip
config[name]=value
end
end
rescue Exception => e
STDERR.puts "Error reading config: #{e.inspect}"
STDERR.flush
end
config
end
end

View File

@ -17,9 +17,7 @@
require "ActionManager"
require "CommandManager"
# Author:: dsa-research.org
# Copyright:: (c) OpenNebula Project Leads (OpenNebula.org)
# License:: Apache License
require "DriverExecHelper"
# This class provides basic messaging and logging functionality
# to implement OpenNebula Drivers. A driver is a program that
@ -30,11 +28,117 @@ require "CommandManager"
# for each action it wants to receive. The method must be associated
# with the action name through the register_action function
class OpenNebulaDriver < ActionManager
include DriverExecHelper
# @return [String] Base path for scripts
attr_reader :local_scripts_base_path, :remote_scripts_base_path
# @return [String] Path for scripts
attr_reader :local_scripts_path, :remote_scripts_path
# Initialize OpenNebulaDriver object
#
# @param [String] directory path inside the remotes directory where the
# scripts are located
# @param [Hash] options named options to change the object's behaviour
# @option options [Number] :concurrency (10) max number of threads
# @option options [Boolean] :threaded (true) enables or disables threads
# @option options [Number] :retries (0) number of retries to copy scripts
# to the remote host
# @option options [Hash] :local_actions ({}) hash with the actions
# executed locally and the name of the script if it differs from the
# default one. This hash can be constructed using {parse_actions_list}
def initialize(directory, options={})
@options={
:concurrency => 10,
:threaded => true,
:retries => 0,
:local_actions => {}
}.merge!(options)
super(@options[:concurrency], @options[:threaded])
@retries = @options[:retries]
@send_mutex = Mutex.new
#Set default values
initialize_helper(directory, @options)
register_action(:INIT, method("init"))
end
# Sends a message to the OpenNebula core through stdout
def send_message(action="-", result=RESULT[:failure], id="-", info="-")
@send_mutex.synchronize {
STDOUT.puts "#{action} #{result} #{id} #{info}"
STDOUT.flush
}
end
# Calls remotes or local action checking the action name and
# @local_actions. Optional arguments can be specified as a hash
#
# @param [String] parameters arguments passed to the script
# @param [Number, String] id action identifier
# @param [String] host hostname where the action is going to be executed
# @param [String, Symbol] aname name of the action
# @param [Hash] ops extra options for the command
# @option ops [String] :stdin text to be writen to stdin
# @option ops [String] :script_name default script name for the action,
# action name is used by defaults
# @option ops [String] :respond if defined will send result to ONE core
# @option ops [String] :local if defined will execute the action locally
def do_action(parameters, id, host, aname, ops={})
options={
:stdin => nil,
:script_name => nil,
:respond => true,
:ssh_stream => nil
}.merge(ops)
params = parameters+" #{id} #{host}"
command = action_command_line(aname, params, options[:script_name])
if options[:local] || action_is_local?(aname)
execution = LocalCommand.run(command, log_method(id))
elsif options[:ssh_stream]
if options[:stdin]
cmdin = "cat << EOT | #{command}"
stdin = "#{options[:stdin]}\nEOT\n"
else
cmdin = command
stdin = nil
end
execution = options[:ssh_stream].run(cmdin, stdin, command)
else
execution = RemotesCommand.run(command,
host,
@remote_scripts_base_path,
log_method(id),
options[:stdin],
@retries)
end
result, info = get_info_from_execution(execution)
if options[:respond]
send_message(aname,result,id,info)
end
[result, info]
end
# Start the driver. Reads from STDIN and executes methods associated with
# the messages
def start_driver
loop_thread = Thread.new { loop }
start_listener
loop_thread.kill
end
# This function parses a string with this form:
#
# 'deploy,shutdown,poll=poll_ganglia, cancel '
@ -69,238 +173,6 @@ class OpenNebulaDriver < ActionManager
actions
end
# Action result strings for messages
RESULT = {
:success => "SUCCESS",
:failure => "FAILURE"
}
# Initialize OpenNebulaDriver object
#
# @param [String] directory path inside the remotes directory where the
# scripts are located
# @param [Hash] options named options to change the object's behaviour
# @option options [Number] :concurrency (10) max number of threads
# @option options [Boolean] :threaded (true) enables or disables threads
# @option options [Number] :retries (0) number of retries to copy scripts
# to the remote host
# @option options [Hash] :local_actions ({}) hash with the actions
# executed locally and the name of the script if it differs from the
# default one. This hash can be constructed using {parse_actions_list}
def initialize(directory, options={})
@options={
:concurrency => 10,
:threaded => true,
:retries => 0,
:local_actions => {}
}.merge!(options)
super(@options[:concurrency], @options[:threaded])
@retries = @options[:retries]
@local_actions = @options[:local_actions]
@send_mutex = Mutex.new
# set default values
@config = read_configuration
@remote_scripts_base_path = @config['SCRIPTS_REMOTE_DIR']
if ENV['ONE_LOCATION'] == nil
@local_scripts_base_path = "/var/lib/one/remotes"
else
@local_scripts_base_path = "#{ENV['ONE_LOCATION']}/var/remotes"
end
# dummy paths
@remote_scripts_path = File.join(@remote_scripts_base_path, directory)
@local_scripts_path = File.join(@local_scripts_base_path, directory)
register_action(:INIT, method("init"))
end
# Sends a message to the OpenNebula core through stdout
def send_message(action="-", result=RESULT[:failure], id="-", info="-")
@send_mutex.synchronize {
STDOUT.puts "#{action} #{result} #{id} #{info}"
STDOUT.flush
}
end
# Calls remotes or local action checking the action name and
# @local_actions. Optional arguments can be specified as a hash
#
# @param [String] parameters arguments passed to the script
# @param [Number, String] id action identifier
# @param [String] host hostname where the action is going to be executed
# @param [String, Symbol] aname name of the action
# @param [Hash] ops extra options for the command
# @option ops [String] :stdin text to be writen to stdin
# @option ops [String] :script_name default script name for the action,
# action name is used by defaults
def do_action(parameters, id, host, aname, ops={})
options={
:stdin => nil,
:script_name => nil
}.merge(ops)
params=parameters+" #{id} #{host}"
command=action_command_line(aname, params, options[:script_name])
if action_is_local? aname
local_action(command, id, aname)
else
remotes_action(command, id, host, aname, @remote_scripts_base_path,
options[:stdin])
end
end
# Given the action name and the parameter returns full path of the script
# and appends its parameters. It uses @local_actions hash to know if the
# actions is remote or local. If the local actions has defined an special
# script name this is used, otherwise the action name in downcase is
# used as the script name.
#
# @param [String, Symbol] action name of the action
# @param [String] parameters arguments for the script
# @param [String, nil] default_name alternative name for the script
# @return [String] command line needed to execute the action
def action_command_line(action, parameters, default_name=nil)
if action_is_local? action
script_path=@local_scripts_path
else
script_path=@remote_scripts_path
end
File.join(script_path, action_script_name(action, default_name))+
" "+parameters
end
# True if the action is meant to be executed locally
#
# @param [String, Symbol] action name of the action
def action_is_local?(action)
@local_actions.include? action.to_s.upcase
end
# Name of the script file for the given action
#
# @param [String, Symbol] action name of the action
# @param [String, nil] default_name alternative name for the script
def action_script_name(action, default_name=nil)
name=@local_actions[action.to_s.upcase]
if name
name
else
default_name || action.to_s.downcase
end
end
# Execute a command associated to an action and id in a remote host.
#
# @param [String] command command line to execute the script
# @param [Number, String] id action identifier
# @param [String] host hostname where the action is going to be executed
# @param [String, Symbol] aname name of the action
# @param [String] remote_dir path where the remotes reside
# @param [String, nil] std_in input of the string from the STDIN
def remotes_action(command, id, host, aname, remote_dir, std_in=nil)
command_exe = RemotesCommand.run(command,
host,
remote_dir,
log_method(id),
std_in,
@retries)
if command_exe.code == 0
result = RESULT[:success]
info = command_exe.stdout
else
result = RESULT[:failure]
info = command_exe.get_error_message
end
info = "-" if info == nil || info.empty?
send_message(aname,result,id,info)
end
# Execute a command associated to an action and id on localhost
#
# @param [String] command command line to execute the script
# @param [Number, String] id action identifier
# @param [String, Symbol] aname name of the action
def local_action(command, id, aname)
command_exe = LocalCommand.run(command, log_method(id))
if command_exe.code == 0
result = RESULT[:success]
info = command_exe.stdout
else
result = RESULT[:failure]
info = command_exe.get_error_message
end
info = "-" if info == nil || info.empty?
send_message(aname,result,id,info)
end
# Sends a log message to ONE. The +message+ can be multiline, it will
# be automatically splitted by lines.
def log(number, message)
in_error_message=false
msg=message.strip
msg.each_line {|line|
severity='I'
l=line.strip
if l=='ERROR MESSAGE --8<------'
in_error_message=true
next
elsif l=='ERROR MESSAGE ------>8--'
in_error_message=false
next
else
if in_error_message
severity='E'
elsif line.match(/^(ERROR|DEBUG|INFO):(.*)$/)
line=$2
case $1
when 'ERROR'
severity='E'
when 'DEBUG'
severity='D'
when 'INFO'
severity='I'
else
severity='I'
end
end
end
send_message("LOG", severity, number, line.strip)
}
end
# Generates a proc with that calls log with a hardcoded number. It will
# be used to add loging to command actions
def log_method(num)
lambda {|message|
log(num, message)
}
end
# Start the driver. Reads from STDIN and executes methods associated with
# the messages
def start_driver
loop_thread = Thread.new { loop }
start_listener
loop_thread.kill
end
private
def init
@ -333,40 +205,6 @@ private
end
end
end
def read_configuration
one_config=nil
if ENV['ONE_LOCATION']
one_config=ENV['ONE_LOCATION']+'/var/config'
else
one_config='/var/lib/one/config'
end
config=Hash.new
cfg=''
begin
open(one_config) do |file|
cfg=file.read
end
cfg.split(/\n/).each do |line|
m=line.match(/^([^=]+)=(.*)$/)
if m
name=m[1].strip.upcase
value=m[2].strip
config[name]=value
end
end
rescue Exception => e
STDERR.puts "Error reading config: #{e.inspect}"
STDERR.flush
end
config
end
end
################################################################

View File

@ -15,6 +15,8 @@
#--------------------------------------------------------------------------- #
require "OpenNebulaDriver"
require "CommandManager"
require 'base64'
require 'rexml/document'
# Author:: dsa-research.org
# Copyright:: (c) 2011 Universidad Computense de Madrid
@ -85,26 +87,15 @@ class VirtualMachineDriver < OpenNebulaDriver
register_action(ACTION[:poll].to_sym, method("poll"))
end
# Converts a deployment file from its remote path to the local (front-end)
# path
def get_local_deployment_file(rfile)
lfile = nil
# Decodes the encoded XML driver message received from the core
#
# @param [String] drv_message the driver message
# @return [REXML::Element] the root element of the decoded XML message
def decode(drv_message)
message = Base64.decode64(drv_message)
xml_doc = REXML::Document.new(message)
one_location = ENV["ONE_LOCATION"]
if one_location == nil
var_location = "/var/lib/one/"
else
var_location = one_location + "/var/"
end
m = rfile.match(/.*?\/(\d+)\/images\/(deployment.\d+)$/)
lfile = "#{var_location}#{m[1]}/#{m[2]}" if m
lfile = nil if lfile and !File.exists?(lfile)
return lfile
xml_doc.root
end
# Execute a command associated to an action and id in a remote host.
@ -118,37 +109,37 @@ class VirtualMachineDriver < OpenNebulaDriver
end
# Virtual Machine Manager Protocol Actions (generic implementation)
def deploy(id, host, remote_dfile, not_used)
def deploy(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:deploy],RESULT[:failure],id,error)
end
def shutdown(id, host, deploy_id, not_used)
def shutdown(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:shutdown],RESULT[:failure],id,error)
end
def cancel(id, host, deploy_id, not_used)
def cancel(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:cancel],RESULT[:failure],id,error)
end
def save(id, host, deploy_id, file)
def save(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:save],RESULT[:failure],id,error)
end
def restore(id, host, deploy_id, file)
def restore(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:restore],RESULT[:failure],id,error)
end
def migrate(id, host, deploy_id, dest_host)
def migrate(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:migrate],RESULT[:failure],id,error)
end
def poll(id, host, deploy_id, not_used)
def poll(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:poll],RESULT[:failure],id,error)
end

View File

@ -43,11 +43,18 @@ module OpenNebula
# This function is used to pass error message to the mad
def self.error_message(message)
STDERR.puts "ERROR MESSAGE --8<------"
STDERR.puts message
STDERR.puts "ERROR MESSAGE ------>8--"
STDERR.puts format_error_message(message)
end
#This function formats an error message for OpenNebula Copyright e
def self.format_error_message(message)
error_str = "ERROR MESSAGE --8<------\n"
error_str << message
error_str << "\nERROR MESSAGE ------>8--"
return error_str
end
# Executes a command, if it fails returns error message and exits
# If a second parameter is present it is used as the error message when
# the command fails

238
src/mad/ruby/ssh_stream.rb Normal file
View File

@ -0,0 +1,238 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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 'CommandManager'
require 'open3'
require 'scripts_common'
class SshStream
attr_reader :stream_out, :stream_err, :stdin
attr_reader :out, :err
#
#
EOF_ERR = "EOF_ERR"
EOF_OUT = "EOF_OUT"
RC_STR = "ExitCode: "
SSH_RC_STR = "ExitSSHCode: "
EOF_CMD = "echo \"#{RC_STR}$? #{EOF_ERR}\" 1>&2; echo \"#{EOF_OUT}\""
SSH_CMD = "ssh"
#
#
#
def initialize(host)
@host = host
end
def opened?
defined?(@stdin)
end
def alive?
@alive == true
end
def open
@stdin, @stdout, @stderr=Open3::popen3("#{SSH_CMD} #{@host} bash -s ; echo #{SSH_RC_STR} $? 1>&2")
@stream_out = ""
@stream_err = ""
@out = ""
@err = ""
@alive = true
end
def close
begin
@stdin.puts "\nexit"
rescue #rescue from EPIPE if ssh command exited already
end
@stdin.close if not @stdin.closed?
@stdout.close if not @stdout.closed?
@stderr.close if not @stderr.closed?
@alive = false
end
def exec(command)
return if ! @alive
@out = ""
@err = ""
begin
cmd="(#{command}); #{EOF_CMD}"
sliced=cmd.scan(/.{1,100}/)
sliced.each do |slice|
@stdin.write slice
@stdin.flush
end
@stdin.write "\n"
@stdin.flush
rescue
end
end
def wait_for_command
done_out = false
done_err = false
code = -1
while not (done_out and done_err ) and @alive
rc, rw, re= IO.select([@stdout, @stderr],[],[])
rc.each { |fd|
begin
c = fd.read_nonblock(100)
next if !c
rescue #rescue from EOF if ssh command finishes and closes fds
next
end
if fd == @stdout
@out << c
done_out = true if @out.slice!("#{EOF_OUT}\n")
else
@err << c
tmp = @err.scan(/^#{SSH_RC_STR}(\d+)$/)
if tmp[0]
message = "Error connecting to #{@host}"
code = tmp[0][0].to_i
@err << OpenNebula.format_error_message(message)
@alive = false
break
end
tmp = @err.scan(/^#{RC_STR}(\d*) #{EOF_ERR}\n/)
if tmp[0]
code = tmp[0][0].to_i
done_err = true
@err.slice!(" #{EOF_ERR}\n")
end
end
}
end
@stream_out << @out
@stream_err << @err
return code
end
def exec_and_wait(command)
exec(command)
wait_for_command
end
end
class SshStreamCommand < RemotesCommand
def initialize(host, remote_dir, logger=nil, stdin=nil)
super('true', host, logger, stdin)
@remote_dir = remote_dir
@stream = SshStream.new(host)
@stream.open
end
def run(command, stdin=nil, base_cmd = nil)
@stream.open unless @stream.opened?
if base_cmd #Check if base command is on remote host
chk_cmd = "if [ ! -x \"#{base_cmd.match(/\S*/)[0]}\" ]; \
then exit #{MAGIC_RC} 1>&2; \
fi"
if @stream.exec_and_wait(chk_cmd) == MAGIC_RC
RemotesCommand.update_remotes(@host, @remote_dir, @logger)
end
end
@stream.exec(command)
@stream.stdin.write(stdin) if stdin
@code = @stream.wait_for_command
@stdout = @stream.out
@stderr = @stream.err
if @code != 0
log("Command execution fail: #{command}")
end
log(@stderr)
return self
end
end
if $0 == __FILE__
ssh=SshStream.new('localhost')
ssh.open
ssh.exec("date | tee /tmp/test.javi")
code=ssh.wait_for_command
puts "Code: #{code}"
puts "output: #{ssh.out}"
ssh.exec "cat << EOT | cat"
ssh.stdin.puts "blah blah\nmas blah\nrequeteblah"
ssh.stdin.puts "EOT"
code=ssh.wait_for_command
puts "Code: #{code}"
puts "output: #{ssh.out}"
code=ssh.exec_and_wait("whoami")
puts "Code: #{code}"
puts "output: #{ssh.out}"
code=ssh.exec_and_wait("touch /etc/pepe.txt")
puts "Code: #{code}"
puts "output: #{ssh.out}"
puts "output err: #{ssh.err}"
ssh.close
cssh = SshStreamCommand.new('no_host',
'/tmp',
lambda { |e| STDOUT.puts "error: #{e}" },
nil)
cssh.run('whoami')
end

View File

@ -72,6 +72,9 @@ public class Host extends PoolElement{
* @param vmm The name of the virtual machine manager mad name
* (vmm_mad_name), this values are taken from the oned.conf with the
* tag name VM_MAD (name)
* @param vnm The name of the virtual network manager mad name
* (vnm_mad_name), this values are taken from the oned.conf with the
* tag name VN_MAD (name)
* @param tm The transfer manager mad name to be used with this host
* @return If successful the message contains the associated
* id generated for this host
@ -80,9 +83,10 @@ public class Host extends PoolElement{
String hostname,
String im,
String vmm,
String vnm,
String tm)
{
return client.call(ALLOCATE, hostname, im, vmm, tm);
return client.call(ALLOCATE, hostname, im, vmm, vnm, tm);
}
/**

View File

@ -63,7 +63,8 @@ public class HostTest
@Before
public void setUp() throws Exception
{
res = Host.allocate(client, name, "im_dummy", "vmm_dummy", "tm_dummy");
res = Host.allocate(client, name, "im_dummy", "vmm_dummy", "vnm_dummy",
"tm_dummy");
int hid = !res.isError() ? Integer.parseInt(res.getMessage()) : -1;
host = new Host(hid, client);
@ -83,7 +84,8 @@ public class HostTest
{
String name = "allocate_test";
res = Host.allocate(client, name, "im_dummy", "vmm_dummy", "tm_dummy");
res = Host.allocate(client, name, "im_dummy", "vmm_dummy", "vmm_dummy",
"tm_dummy");
assertTrue( !res.isError() );
// assertTrue( res.getMessage().equals("0") );

View File

@ -80,11 +80,11 @@ public class VirtualMachineTest
res = Host.allocate(client, "host_A",
"im_dummy", "vmm_dummy", "tm_dummy");
"im_dummy", "vmm_dummy", "vmm_dummy", "tm_dummy");
hid_A = Integer.parseInt( res.getMessage() );
res = Host.allocate(client, "host_B",
"im_dummy", "vmm_dummy", "tm_dummy");
"im_dummy", "vmm_dummy", "vmm_dummy", "tm_dummy");
hid_B = Integer.parseInt( res.getMessage() );
}

View File

@ -78,15 +78,15 @@ module OpenNebula
# Allocates a new Host in OpenNebula
#
# +hostname+ A string containing the name of the new Host.
# @param hostname [String] Name of the new Host.
# @param im [String] Name of the im_driver
# @param vmm [String] Name of the vmm_driver
# @param tm [String] Name of the tm_driver
#
# +im+ A string containing the name of the im_driver
#
# +vmm+ A string containing the name of the vmm_driver
#
# +tm+ A string containing the name of the tm_driver
def allocate(hostname,im,vmm,tm)
super(HOST_METHODS[:allocate],hostname,im,vmm,tm)
# @return [Integer, OpenNebula::Error] the new VM ID in case of
# success, error otherwise
def allocate(hostname,im,vmm,vnm,tm)
super(HOST_METHODS[:allocate],hostname,im,vmm,vnm,tm)
end
# Deletes the Host

View File

@ -212,11 +212,13 @@ int HostAllocate::pool_allocate(xmlrpc_c::paramList const& paramList,
string host = xmlrpc_c::value_string(paramList.getString(1));
string im_mad = xmlrpc_c::value_string(paramList.getString(2));
string vmm_mad = xmlrpc_c::value_string(paramList.getString(3));
string tm_mad = xmlrpc_c::value_string(paramList.getString(4));
string vnm_mad = xmlrpc_c::value_string(paramList.getString(4));
string tm_mad = xmlrpc_c::value_string(paramList.getString(5));
HostPool * hpool = static_cast<HostPool *>(pool);
return hpool->allocate(&id, host, im_mad, vmm_mad, tm_mad, error_str);
return hpool->allocate(&id, host, im_mad, vmm_mad, vnm_mad, tm_mad,
error_str);
}
/* -------------------------------------------------------------------------- */

View File

@ -86,9 +86,10 @@ bool RequestManagerVirtualMachine::vm_authorization(int oid,
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int RequestManagerVirtualMachine::get_host_information(int hid,
string& name,
int RequestManagerVirtualMachine::get_host_information(int hid,
string& name,
string& vmm,
string& vnm,
string& tm,
RequestAttributes& att)
{
@ -110,6 +111,7 @@ int RequestManagerVirtualMachine::get_host_information(int hid,
name = host->get_name();
vmm = host->get_vmm_mad();
vnm = host->get_vnm_mad();
tm = host->get_tm_mad();
host->unlock();
@ -142,6 +144,7 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm,
int hid,
const string& hostname,
const string& vmm_mad,
const string& vnm_mad,
const string& tm_mad,
RequestAttributes& att)
{
@ -154,7 +157,7 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm,
nd.get_configuration_attribute("VM_DIR",vmdir);
vm->add_history(hid,hostname,vmdir,vmm_mad,tm_mad);
vm->add_history(hid,hostname,vmdir,vmm_mad,vnm_mad,tm_mad);
rc = vmpool->update_history(vm);
@ -273,6 +276,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
string hostname;
string vmm_mad;
string vnm_mad;
string tm_mad;
int id = xmlrpc_c::value_int(paramList.getInt(1));
@ -283,7 +287,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
if (get_host_information(hid,hostname,vmm_mad,tm_mad, att) != 0)
if (get_host_information(hid,hostname,vmm_mad,vnm_mad,tm_mad, att) != 0)
{
return;
}
@ -303,7 +307,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
if ( add_history(vm,hid,hostname,vmm_mad,tm_mad,att) != 0)
if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,att) != 0)
{
vm->unlock();
return;
@ -329,6 +333,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
string hostname;
string vmm_mad;
string vnm_mad;
string tm_mad;
int id = xmlrpc_c::value_int(paramList.getInt(1));
@ -340,7 +345,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
if (get_host_information(hid,hostname,vmm_mad,tm_mad,att) != 0)
if (get_host_information(hid,hostname,vmm_mad,vnm_mad,tm_mad,att) != 0)
{
return;
}
@ -362,7 +367,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
if ( add_history(vm,hid,hostname,vmm_mad,tm_mad,att) != 0)
if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,att) != 0)
{
vm->unlock();
return;

View File

@ -27,9 +27,10 @@ module OpenNebulaJSON
end
self.allocate(host_hash['name'],
host_hash['im_mad'],
host_hash['vm_mad'],
host_hash['tm_mad'])
host_hash['im_mad'],
host_hash['vm_mad'],
host_hash['vnm_mad'],
host_hash['tm_mad'])
end
def delete

View File

@ -80,10 +80,19 @@ var create_host_tmpl =
<option value="im_dummy">Dummy</option>\
</select>\
</div>\
<div class="manager clear" id="vnm_mads">\
<label>Virtual Network Manager:</label>\
<select id="vnm_mad" name="vn">\
<option value="dummy">Dummy</option>\
<option value="etables">Etables</option>\
<option value="ovswitch">Open vSwitch</option>\
<option value="802.1Q">802.1Q</option>\
</select>\
</div>\
<div class="manager clear" id="tm_mads">\
<label>Transfer Manager:</label>\
<select id="tm_mad" name="tm">\
<option value="tm_shared">SHARED</option>\
<option value="tm_shared">Shared</option>\
<option value="tm_ssh">SSH</option>\
<option value="tm_dummy">Dummy</option>\
</select>\
@ -443,6 +452,10 @@ function updateHostInfo(request,host){
<td class="key_td">VM MAD</td>\
<td class="value_td">'+host_info.VM_MAD+'</td>\
</tr>\
<tr>\
<td class="key_td">VN MAD</td>\
<td class="value_td">'+host_info.VN_MAD+'</td>\
</tr>\
<tr>\
<td class="key_td">TM MAD</td>\
<td class="value_td">'+host_info.TM_MAD+'</td>\
@ -537,6 +550,7 @@ function setupCreateHostDialog(){
"name": $('#name',this).val(),
"tm_mad": $('#tm_mad :selected',this).val(),
"vm_mad": $('#vmm_mad :selected',this).val(),
"vnm_mad": $('#vnm_mad :selected',this).val(),
"im_mad": $('#im_mad :selected',this).val()
}
}

View File

@ -1,9 +1,8 @@
/* A Bison parser, made by GNU Bison 2.4.2. */
/* A Bison parser, made by GNU Bison 2.5. */
/* Skeleton implementation for Bison's Yacc-like parsers in C
/* Bison implementation for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -45,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
#define YYBISON_VERSION "2.4.2"
#define YYBISON_VERSION "2.5"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@ -74,7 +73,7 @@
/* Copy the first part of user declarations. */
/* Line 189 of yacc.c */
/* Line 268 of yacc.c */
#line 17 "template_syntax.y"
#include <iostream>
@ -127,8 +126,8 @@ extern "C"
/* Line 189 of yacc.c */
#line 132 "template_syntax.cc"
/* Line 268 of yacc.c */
#line 131 "template_syntax.cc"
/* Enabling traces. */
#ifndef YYDEBUG
@ -171,7 +170,7 @@ extern "C"
typedef union YYSTYPE
{
/* Line 214 of yacc.c */
/* Line 293 of yacc.c */
#line 74 "template_syntax.y"
char * val_str;
@ -179,8 +178,8 @@ typedef union YYSTYPE
/* Line 214 of yacc.c */
#line 184 "template_syntax.cc"
/* Line 293 of yacc.c */
#line 183 "template_syntax.cc"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@ -204,8 +203,8 @@ typedef struct YYLTYPE
/* Copy the second part of user declarations. */
/* Line 264 of yacc.c */
#line 209 "template_syntax.cc"
/* Line 343 of yacc.c */
#line 208 "template_syntax.cc"
#ifdef short
# undef short
@ -308,11 +307,11 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef _STDLIB_H
# define _STDLIB_H 1
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# endif
@ -335,24 +334,24 @@ YYID (yyi)
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
# if (defined __cplusplus && ! defined _STDLIB_H \
# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef _STDLIB_H
# define _STDLIB_H 1
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
@ -383,23 +382,7 @@ union yyalloc
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ 2 * YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
while (YYID (0))
# endif
# endif
# define YYCOPY_NEEDED 1
/* Relocate STACK from its old location to the new one. The
local variables YYSIZE and YYSTACKSIZE give the old and new number of
@ -419,6 +402,26 @@ union yyalloc
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
while (YYID (0))
# endif
# endif
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 6
/* YYLAST -- Last index in YYTABLE. */
@ -528,8 +531,8 @@ static const yytype_uint8 yyr2[] =
0, 2, 1, 2, 3, 5, 2, 3, 5
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
STATE-NUM when YYTABLE doesn't specify something else to do. Zero
/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
Performed when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
@ -560,8 +563,7 @@ static const yytype_int8 yypgoto[] =
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
number is the opposite. If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
@ -569,6 +571,12 @@ static const yytype_uint8 yytable[] =
12, 15, 17, 16, 18, 7
};
#define yypact_value_is_default(yystate) \
((yystate) == (-8))
#define yytable_value_is_error(yytable_value) \
YYID (0)
static const yytype_uint8 yycheck[] =
{
0, 3, 9, 9, 5, 7, 4, 8, 6, 9,
@ -616,7 +624,6 @@ do \
{ \
yychar = (Token); \
yylval = (Value); \
yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
@ -880,7 +887,6 @@ int yydebug;
# define YYMAXDEPTH 10000
#endif
#if YYERROR_VERBOSE
@ -983,115 +989,142 @@ yytnamerr (char *yyres, const char *yystr)
}
# endif
/* Copy into YYRESULT an error message about the unexpected token
YYCHAR while in state YYSTATE. Return the number of bytes copied,
including the terminating null byte. If YYRESULT is null, do not
copy anything; just return the number of bytes that would be
copied. As a special case, return 0 if an ordinary "syntax error"
message will do. Return YYSIZE_MAXIMUM if overflow occurs during
size calculation. */
static YYSIZE_T
yysyntax_error (char *yyresult, int yystate, int yychar)
/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
about the unexpected token YYTOKEN for the state stack whose top is
YYSSP.
Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
not large enough to hold the message. In that case, also set
*YYMSG_ALLOC to the required number of bytes. Return 2 if the
required number of bytes is too large to store. */
static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
int yyn = yypact[yystate];
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
YYSIZE_T yysize1;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
const char *yyformat = 0;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
"expected"). */
int yycount = 0;
if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
return 0;
else
/* There are many possibilities here to consider:
- Assume YYFAIL is not used. It's too flawed to consider. See
<http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
for details. YYERROR is fine as it does not invoke this
function.
- If this state is a consistent state with a default action, then
the only way this function was invoked is if the default action
is an error action. In that case, don't check for expected
tokens because there are none.
- The only way there can be no lookahead present (in yychar) is if
this state is a consistent state with a default action. Thus,
detecting the absence of a lookahead is sufficient to determine
that there is no unexpected or expected token to report. In that
case, just report a simple "syntax error".
- Don't assume there isn't a lookahead just because this state is a
consistent state with a default action. There might have been a
previous inconsistent state, consistent state with a non-default
action, or user semantic action that manipulated yychar.
- Of course, the expected token list depends on states to have
correct lookahead information, and it depends on the parser not
to perform extra reductions after fetching a lookahead from the
scanner and before detecting a syntax error. Thus, state merging
(from LALR or IELR) and default reductions corrupt the expected
token list. However, the list is correct for canonical LR with
one exception: it will still contain any token that will not be
accepted due to an error action in a later state.
*/
if (yytoken != YYEMPTY)
{
int yytype = YYTRANSLATE (yychar);
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
YYSIZE_T yysize = yysize0;
YYSIZE_T yysize1;
int yysize_overflow = 0;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
int yyx;
int yyn = yypact[*yyssp];
yyarg[yycount++] = yytname[yytoken];
if (!yypact_value_is_default (yyn))
{
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. In other words, skip the first -YYN actions for
this state because they are default actions. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yyx;
# if 0
/* This is so xgettext sees the translatable formats that are
constructed on the fly. */
YY_("syntax error, unexpected %s");
YY_("syntax error, unexpected %s, expecting %s");
YY_("syntax error, unexpected %s, expecting %s or %s");
YY_("syntax error, unexpected %s, expecting %s or %s or %s");
YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
# endif
char *yyfmt;
char const *yyf;
static char const yyunexpected[] = "syntax error, unexpected %s";
static char const yyexpecting[] = ", expecting %s";
static char const yyor[] = " or %s";
char yyformat[sizeof yyunexpected
+ sizeof yyexpecting - 1
+ ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
* (sizeof yyor - 1))];
char const *yyprefix = yyexpecting;
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yycount = 1;
yyarg[0] = yytname[yytype];
yyfmt = yystpcpy (yyformat, yyunexpected);
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
yycount = 1;
yysize = yysize0;
yyformat[sizeof yyunexpected - 1] = '\0';
break;
}
yyarg[yycount++] = yytname[yyx];
yysize1 = yysize + yytnamerr (0, yytname[yyx]);
yysize_overflow |= (yysize1 < yysize);
yysize = yysize1;
yyfmt = yystpcpy (yyfmt, yyprefix);
yyprefix = yyor;
}
yyf = YY_(yyformat);
yysize1 = yysize + yystrlen (yyf);
yysize_overflow |= (yysize1 < yysize);
yysize = yysize1;
if (yysize_overflow)
return YYSIZE_MAXIMUM;
if (yyresult)
{
/* Avoid sprintf, as that infringes on the user's name space.
Don't have undefined behavior even if the translation
produced a string with the wrong number of "%s"s. */
char *yyp = yyresult;
int yyi = 0;
while ((*yyp = *yyf) != '\0')
{
if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
{
yyp += yytnamerr (yyp, yyarg[yyi++]);
yyf += 2;
}
else
{
yyp++;
yyf++;
}
}
}
return yysize;
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
&& !yytable_value_is_error (yytable[yyx + yyn]))
{
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
yycount = 1;
yysize = yysize0;
break;
}
yyarg[yycount++] = yytname[yyx];
yysize1 = yysize + yytnamerr (0, yytname[yyx]);
if (! (yysize <= yysize1
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
yysize = yysize1;
}
}
}
switch (yycount)
{
# define YYCASE_(N, S) \
case N: \
yyformat = S; \
break
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
# undef YYCASE_
}
yysize1 = yysize + yystrlen (yyformat);
if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
yysize = yysize1;
if (*yymsg_alloc < yysize)
{
*yymsg_alloc = 2 * yysize;
if (! (yysize <= *yymsg_alloc
&& *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
*yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
return 1;
}
/* Avoid sprintf, as that infringes on the user's name space.
Don't have undefined behavior even if the translation
produced a string with the wrong number of "%s"s. */
{
char *yyp = *yymsg;
int yyi = 0;
while ((*yyp = *yyformat) != '\0')
if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
{
yyp += yytnamerr (yyp, yyarg[yyi++]);
yyformat += 2;
}
else
{
yyp++;
yyformat++;
}
}
return 0;
}
#endif /* YYERROR_VERBOSE */
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
@ -1132,6 +1165,7 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, mc, tmpl, error_msg)
}
}
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
@ -1148,12 +1182,9 @@ int yyparse ();
#endif /* ! YYPARSE_PARAM */
/*-------------------------.
| yyparse or yypush_parse. |
`-------------------------*/
/*----------.
| yyparse. |
`----------*/
#ifdef YYPARSE_PARAM
#if (defined __STDC__ || defined __C99__FUNC__ \
@ -1219,7 +1250,7 @@ YYLTYPE yylloc;
YYLTYPE *yylsp;
/* The locations where the error started and ended. */
YYLTYPE yyerror_range[2];
YYLTYPE yyerror_range[3];
YYSIZE_T yystacksize;
@ -1368,7 +1399,7 @@ yybackup:
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
if (yypact_value_is_default (yyn))
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
@ -1399,8 +1430,8 @@ yybackup:
yyn = yytable[yyn];
if (yyn <= 0)
{
if (yyn == 0 || yyn == YYTABLE_NINF)
goto yyerrlab;
if (yytable_value_is_error (yyn))
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
@ -1456,7 +1487,7 @@ yyreduce:
{
case 4:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 99 "template_syntax.y"
{
Attribute * pattr;
@ -1466,12 +1497,12 @@ yyreduce:
pattr = new SingleAttribute(name,unescape(value));
tmpl->set(pattr);
;}
}
break;
case 5:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 109 "template_syntax.y"
{
Attribute * pattr;
@ -1484,12 +1515,12 @@ yyreduce:
tmpl->set(pattr);
delete amap;
;}
}
break;
case 6:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 122 "template_syntax.y"
{
Attribute * pattr;
@ -1499,12 +1530,12 @@ yyreduce:
pattr = new SingleAttribute(name,value);
tmpl->set(pattr);
;}
}
break;
case 7:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 134 "template_syntax.y"
{
map<string,string>* vattr;
@ -1517,12 +1548,12 @@ yyreduce:
vattr->insert(make_pair(name,unescape(value)));
(yyval.val_attr) = static_cast<void *>(vattr);
;}
}
break;
case 8:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 147 "template_syntax.y"
{
string name((yyvsp[(3) - (5)].val_str));
@ -1535,15 +1566,26 @@ yyreduce:
attrmap->insert(make_pair(name,unescape(value)));
(yyval.val_attr) = (yyvsp[(1) - (5)].val_attr);
;}
}
break;
/* Line 1464 of yacc.c */
#line 1545 "template_syntax.cc"
/* Line 1806 of yacc.c */
#line 1576 "template_syntax.cc"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
that yytoken be updated with the new translation. We take the
approach of translating immediately before every use of yytoken.
One alternative is translating here after every semantic action,
but that translation would be missed if the semantic action invokes
YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
incorrect destructor might then be invoked immediately. In the
case of YYERROR or YYBACKUP, subsequent parser actions might lead
to an incorrect destructor call or verbose syntax error message
before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
@ -1572,6 +1614,10 @@ yyreduce:
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
@ -1579,41 +1625,40 @@ yyerrlab:
#if ! YYERROR_VERBOSE
yyerror (&yylloc, mc, tmpl, error_msg, YY_("syntax error"));
#else
# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
yyssp, yytoken)
{
YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
{
YYSIZE_T yyalloc = 2 * yysize;
if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
yyalloc = YYSTACK_ALLOC_MAXIMUM;
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yyalloc);
if (yymsg)
yymsg_alloc = yyalloc;
else
{
yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf;
}
}
if (0 < yysize && yysize <= yymsg_alloc)
{
(void) yysyntax_error (yymsg, yystate, yychar);
yyerror (&yylloc, mc, tmpl, error_msg, yymsg);
}
else
{
yyerror (&yylloc, mc, tmpl, error_msg, YY_("syntax error"));
if (yysize != 0)
goto yyexhaustedlab;
}
char const *yymsgp = YY_("syntax error");
int yysyntax_error_status;
yysyntax_error_status = YYSYNTAX_ERROR;
if (yysyntax_error_status == 0)
yymsgp = yymsg;
else if (yysyntax_error_status == 1)
{
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
if (!yymsg)
{
yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf;
yysyntax_error_status = 2;
}
else
{
yysyntax_error_status = YYSYNTAX_ERROR;
yymsgp = yymsg;
}
}
yyerror (&yylloc, mc, tmpl, error_msg, yymsgp);
if (yysyntax_error_status == 2)
goto yyexhaustedlab;
}
# undef YYSYNTAX_ERROR
#endif
}
yyerror_range[0] = yylloc;
yyerror_range[1] = yylloc;
if (yyerrstatus == 3)
{
@ -1650,7 +1695,7 @@ yyerrorlab:
if (/*CONSTCOND*/ 0)
goto yyerrorlab;
yyerror_range[0] = yylsp[1-yylen];
yyerror_range[1] = yylsp[1-yylen];
/* Do not reclaim the symbols of the rule which action triggered
this YYERROR. */
YYPOPSTACK (yylen);
@ -1669,7 +1714,7 @@ yyerrlab1:
for (;;)
{
yyn = yypact[yystate];
if (yyn != YYPACT_NINF)
if (!yypact_value_is_default (yyn))
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@ -1684,7 +1729,7 @@ yyerrlab1:
if (yyssp == yyss)
YYABORT;
yyerror_range[0] = *yylsp;
yyerror_range[1] = *yylsp;
yydestruct ("Error: popping",
yystos[yystate], yyvsp, yylsp, mc, tmpl, error_msg);
YYPOPSTACK (1);
@ -1694,10 +1739,10 @@ yyerrlab1:
*++yyvsp = yylval;
yyerror_range[1] = yylloc;
yyerror_range[2] = yylloc;
/* Using YYLLOC is tempting, but would change the location of
the lookahead. YYLOC is available though. */
YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
*++yylsp = yyloc;
/* Shift the error token. */
@ -1733,8 +1778,13 @@ yyexhaustedlab:
yyreturn:
if (yychar != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval, &yylloc, mc, tmpl, error_msg);
{
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = YYTRANSLATE (yychar);
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval, &yylloc, mc, tmpl, error_msg);
}
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
@ -1759,7 +1809,7 @@ yyreturn:
/* Line 1684 of yacc.c */
/* Line 2067 of yacc.c */
#line 160 "template_syntax.y"

View File

@ -1,9 +1,8 @@
/* A Bison parser, made by GNU Bison 2.4.2. */
/* A Bison parser, made by GNU Bison 2.5. */
/* Skeleton interface for Bison's Yacc-like parsers in C
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -54,7 +53,7 @@
typedef union YYSTYPE
{
/* Line 1685 of yacc.c */
/* Line 2068 of yacc.c */
#line 74 "template_syntax.y"
char * val_str;
@ -62,8 +61,8 @@ typedef union YYSTYPE
/* Line 1685 of yacc.c */
#line 67 "template_syntax.hh"
/* Line 2068 of yacc.c */
#line 66 "template_syntax.hh"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */

View File

@ -43,6 +43,7 @@ History::History(
vm_dir(""),
hid(-1),
vmm_mad_name(""),
vnm_mad_name(""),
tm_mad_name(""),
stime(0),
etime(0),
@ -63,6 +64,7 @@ History::History(
const string& _hostname,
const string& _vm_dir,
const string& _vmm,
const string& _vnm,
const string& _tm):
oid(_oid),
seq(_seq),
@ -70,6 +72,7 @@ History::History(
vm_dir(_vm_dir),
hid(_hid),
vmm_mad_name(_vmm),
vnm_mad_name(_vnm),
tm_mad_name(_tm),
stime(0),
etime(0),
@ -267,6 +270,7 @@ string& History::to_xml(string& xml) const
"<STIME>" << stime << "</STIME>" <<
"<ETIME>" << etime << "</ETIME>" <<
"<VMMMAD>" << vmm_mad_name << "</VMMMAD>"<<
"<VNMMAD>" << vnm_mad_name << "</VNMMAD>"<<
"<TMMAD>" << tm_mad_name << "</TMMAD>" <<
"<PSTIME>" << prolog_stime << "</PSTIME>"<<
"<PETIME>" << prolog_etime << "</PETIME>"<<
@ -297,6 +301,7 @@ int History::rebuild_attributes()
rc += xpath(stime , "/HISTORY/STIME", 0);
rc += xpath(etime , "/HISTORY/ETIME", 0);
rc += xpath(vmm_mad_name , "/HISTORY/VMMMAD", "not_found");
rc += xpath(vnm_mad_name , "/HISTORY/VNMMAD", "not_found");
rc += xpath(tm_mad_name , "/HISTORY/TMMAD", "not_found");
rc += xpath(prolog_stime , "/HISTORY/PSTIME", 0);
rc += xpath(prolog_etime , "/HISTORY/PETIME", 0);

View File

@ -581,6 +581,7 @@ void VirtualMachine::add_history(
const string& hostname,
const string& vm_dir,
const string& vmm_mad,
const string& vnm_mad,
const string& tm_mad)
{
ostringstream os;
@ -597,7 +598,7 @@ void VirtualMachine::add_history(
previous_history = history;
}
history = new History(oid,seq,hid,hostname,vm_dir,vmm_mad,tm_mad);
history = new History(oid,seq,hid,hostname,vm_dir,vmm_mad,vnm_mad,tm_mad);
history_records.push_back(history);
};
@ -620,6 +621,7 @@ void VirtualMachine::cp_history()
history->hostname,
history->vm_dir,
history->vmm_mad_name,
history->vnm_mad_name,
history->tm_mad_name);
@ -647,6 +649,7 @@ void VirtualMachine::cp_previous_history()
previous_history->hostname,
previous_history->vm_dir,
previous_history->vmm_mad_name,
previous_history->vnm_mad_name,
previous_history->tm_mad_name);
previous_history = history;

View File

@ -302,6 +302,7 @@ public:
string hostnames[] = {"A_hostname", "B_hostname", "C_hostname"};
string vm_dirs[] = {"A_vm_dir", "B_vm_dir", "C_vm_dir"};
string vmm_mads[] = {"A_vmm_mad", "B_vmm_mad", "C_vmm_mad"};
string vnm_mads[] = {"A_vnm_mad", "B_vnm_mad", "C_vnm_mad"};
string tm_mads[] = {"A_tm_mad", "B_tm_mad", "C_tm_mad"};
int oid, rc;
@ -324,7 +325,7 @@ public:
CPPUNIT_ASSERT( vm != 0 );
// Add a history item
vm->add_history(0, hostnames[0], vm_dirs[0], vmm_mads[0], tm_mads[0]);
vm->add_history(0, hostnames[0], vm_dirs[0], vmm_mads[0], vnm_mads[0], tm_mads[0]);
rc = vmp->update(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -342,7 +343,7 @@ public:
CPPUNIT_ASSERT( vm != 0 );
// Add a history item
vm->add_history(1, hostnames[1], vm_dirs[1], vmm_mads[1], tm_mads[1]);
vm->add_history(1, hostnames[1], vm_dirs[1], vmm_mads[1], vnm_mads[1], tm_mads[1]);
rc = vmp->update(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -351,7 +352,7 @@ public:
CPPUNIT_ASSERT( rc == 0 );
// Add another history item
vm->add_history(2, hostnames[2], vm_dirs[2], vmm_mads[2], tm_mads[2]);
vm->add_history(2, hostnames[2], vm_dirs[2], vmm_mads[2], vnm_mads[2], tm_mads[2]);
rc = vmp->update(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -408,6 +409,7 @@ public:
string new_hostname = "new_hostname";
string vm_dir = "vm_dir";
string vmm_mad = "vm_mad";
string vnm_mad = "vn_mad";
string tm_mad = "tm_mad";
// Allocate a VM
@ -418,7 +420,7 @@ public:
CPPUNIT_ASSERT( vm != 0 );
// Add a history item
vm->add_history(0, hostname, vm_dir, vmm_mad, tm_mad);
vm->add_history(0, hostname, vm_dir, vmm_mad, vnm_mad, tm_mad);
rc = vmp->update(vm);
CPPUNIT_ASSERT( rc == 0 );
@ -426,7 +428,7 @@ public:
rc = vmp->update_history(vm);
CPPUNIT_ASSERT( rc == 0 );
vm->add_history(0, new_hostname, vm_dir, vmm_mad, tm_mad);
vm->add_history(0, new_hostname, vm_dir, vmm_mad, vnm_mad, tm_mad);
rc = vmp->update(vm);
CPPUNIT_ASSERT( rc == 0 );

View File

@ -1,9 +1,8 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* A Bison parser, made by GNU Bison 2.5. */
/* Skeleton implementation for Bison's Yacc-like parsers in C
/* Bison implementation for Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2009, 2010 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -45,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
#define YYBISON_VERSION "2.4.3"
#define YYBISON_VERSION "2.5"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@ -74,7 +73,7 @@
/* Copy the first part of user declarations. */
/* Line 189 of yacc.c */
/* Line 268 of yacc.c */
#line 17 "vm_var_syntax.y"
#include <iostream>
@ -307,7 +306,7 @@ void get_network_attribute(VirtualMachine * vm,
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*
void get_user_attribute(VirtualMachine * vm,
const string& attr_name,
string& attr_value)
@ -337,7 +336,7 @@ void get_user_attribute(VirtualMachine * vm,
user->unlock();
}
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -408,6 +407,19 @@ void insert_vector(VirtualMachine * vm,
return;
}
else if (name == "USER")
{
string value;
get_user_attribute(vm, vname, value);
if (!value.empty())
{
parsed << value;
}
return;
}
else
{
if ( ( num = vm->get_template_attribute(name.c_str(),values) ) <= 0 )
@ -447,8 +459,8 @@ void insert_vector(VirtualMachine * vm,
/* Line 189 of yacc.c */
#line 452 "vm_var_syntax.cc"
/* Line 268 of yacc.c */
#line 464 "vm_var_syntax.cc"
/* Enabling traces. */
#ifndef YYDEBUG
@ -493,8 +505,8 @@ void insert_vector(VirtualMachine * vm,
typedef union YYSTYPE
{
/* Line 214 of yacc.c */
#line 395 "vm_var_syntax.y"
/* Line 293 of yacc.c */
#line 408 "vm_var_syntax.y"
char * val_str;
int val_int;
@ -502,8 +514,8 @@ typedef union YYSTYPE
/* Line 214 of yacc.c */
#line 507 "vm_var_syntax.cc"
/* Line 293 of yacc.c */
#line 519 "vm_var_syntax.cc"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@ -527,8 +539,8 @@ typedef struct YYLTYPE
/* Copy the second part of user declarations. */
/* Line 264 of yacc.c */
#line 532 "vm_var_syntax.cc"
/* Line 343 of yacc.c */
#line 544 "vm_var_syntax.cc"
#ifdef short
# undef short
@ -631,11 +643,11 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef _STDLIB_H
# define _STDLIB_H 1
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# endif
@ -658,24 +670,24 @@ YYID (yyi)
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
# if (defined __cplusplus && ! defined _STDLIB_H \
# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef _STDLIB_H
# define _STDLIB_H 1
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
@ -706,23 +718,7 @@ union yyalloc
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ 2 * YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
while (YYID (0))
# endif
# endif
# define YYCOPY_NEEDED 1
/* Relocate STACK from its old location to the new one. The
local variables YYSIZE and YYSTACKSIZE give the old and new number of
@ -742,6 +738,26 @@ union yyalloc
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
while (YYID (0))
# endif
# endif
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 7
/* YYLAST -- Last index in YYTABLE. */
@ -814,7 +830,7 @@ static const yytype_int8 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
0, 419, 419, 420, 423, 427, 440, 455
0, 432, 432, 433, 436, 440, 453, 468
};
#endif
@ -851,8 +867,8 @@ static const yytype_uint8 yyr2[] =
0, 2, 1, 2, 1, 2, 5, 9
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
STATE-NUM when YYTABLE doesn't specify something else to do. Zero
/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
Performed when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
@ -883,8 +899,7 @@ static const yytype_int8 yypgoto[] =
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
number is the opposite. If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
@ -892,6 +907,12 @@ static const yytype_uint8 yytable[] =
2, 12, 13, 14, 15, 16, 8, 0, 17
};
#define yypact_value_is_default(yystate) \
((yystate) == (-5))
#define yytable_value_is_error(yytable_value) \
YYID (0)
static const yytype_int8 yycheck[] =
{
0, 5, 4, 7, 6, -1, 9, 10, 9, 9,
@ -939,7 +960,6 @@ do \
{ \
yychar = (Token); \
yylval = (Value); \
yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
@ -1207,7 +1227,6 @@ int yydebug;
# define YYMAXDEPTH 10000
#endif
#if YYERROR_VERBOSE
@ -1310,115 +1329,142 @@ yytnamerr (char *yyres, const char *yystr)
}
# endif
/* Copy into YYRESULT an error message about the unexpected token
YYCHAR while in state YYSTATE. Return the number of bytes copied,
including the terminating null byte. If YYRESULT is null, do not
copy anything; just return the number of bytes that would be
copied. As a special case, return 0 if an ordinary "syntax error"
message will do. Return YYSIZE_MAXIMUM if overflow occurs during
size calculation. */
static YYSIZE_T
yysyntax_error (char *yyresult, int yystate, int yychar)
/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
about the unexpected token YYTOKEN for the state stack whose top is
YYSSP.
Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
not large enough to hold the message. In that case, also set
*YYMSG_ALLOC to the required number of bytes. Return 2 if the
required number of bytes is too large to store. */
static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
int yyn = yypact[yystate];
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
YYSIZE_T yysize1;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
const char *yyformat = 0;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
"expected"). */
int yycount = 0;
if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
return 0;
else
/* There are many possibilities here to consider:
- Assume YYFAIL is not used. It's too flawed to consider. See
<http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
for details. YYERROR is fine as it does not invoke this
function.
- If this state is a consistent state with a default action, then
the only way this function was invoked is if the default action
is an error action. In that case, don't check for expected
tokens because there are none.
- The only way there can be no lookahead present (in yychar) is if
this state is a consistent state with a default action. Thus,
detecting the absence of a lookahead is sufficient to determine
that there is no unexpected or expected token to report. In that
case, just report a simple "syntax error".
- Don't assume there isn't a lookahead just because this state is a
consistent state with a default action. There might have been a
previous inconsistent state, consistent state with a non-default
action, or user semantic action that manipulated yychar.
- Of course, the expected token list depends on states to have
correct lookahead information, and it depends on the parser not
to perform extra reductions after fetching a lookahead from the
scanner and before detecting a syntax error. Thus, state merging
(from LALR or IELR) and default reductions corrupt the expected
token list. However, the list is correct for canonical LR with
one exception: it will still contain any token that will not be
accepted due to an error action in a later state.
*/
if (yytoken != YYEMPTY)
{
int yytype = YYTRANSLATE (yychar);
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
YYSIZE_T yysize = yysize0;
YYSIZE_T yysize1;
int yysize_overflow = 0;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
int yyx;
int yyn = yypact[*yyssp];
yyarg[yycount++] = yytname[yytoken];
if (!yypact_value_is_default (yyn))
{
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. In other words, skip the first -YYN actions for
this state because they are default actions. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yyx;
# if 0
/* This is so xgettext sees the translatable formats that are
constructed on the fly. */
YY_("syntax error, unexpected %s");
YY_("syntax error, unexpected %s, expecting %s");
YY_("syntax error, unexpected %s, expecting %s or %s");
YY_("syntax error, unexpected %s, expecting %s or %s or %s");
YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
# endif
char *yyfmt;
char const *yyf;
static char const yyunexpected[] = "syntax error, unexpected %s";
static char const yyexpecting[] = ", expecting %s";
static char const yyor[] = " or %s";
char yyformat[sizeof yyunexpected
+ sizeof yyexpecting - 1
+ ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
* (sizeof yyor - 1))];
char const *yyprefix = yyexpecting;
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yycount = 1;
yyarg[0] = yytname[yytype];
yyfmt = yystpcpy (yyformat, yyunexpected);
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
yycount = 1;
yysize = yysize0;
yyformat[sizeof yyunexpected - 1] = '\0';
break;
}
yyarg[yycount++] = yytname[yyx];
yysize1 = yysize + yytnamerr (0, yytname[yyx]);
yysize_overflow |= (yysize1 < yysize);
yysize = yysize1;
yyfmt = yystpcpy (yyfmt, yyprefix);
yyprefix = yyor;
}
yyf = YY_(yyformat);
yysize1 = yysize + yystrlen (yyf);
yysize_overflow |= (yysize1 < yysize);
yysize = yysize1;
if (yysize_overflow)
return YYSIZE_MAXIMUM;
if (yyresult)
{
/* Avoid sprintf, as that infringes on the user's name space.
Don't have undefined behavior even if the translation
produced a string with the wrong number of "%s"s. */
char *yyp = yyresult;
int yyi = 0;
while ((*yyp = *yyf) != '\0')
{
if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
{
yyp += yytnamerr (yyp, yyarg[yyi++]);
yyf += 2;
}
else
{
yyp++;
yyf++;
}
}
}
return yysize;
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
&& !yytable_value_is_error (yytable[yyx + yyn]))
{
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
yycount = 1;
yysize = yysize0;
break;
}
yyarg[yycount++] = yytname[yyx];
yysize1 = yysize + yytnamerr (0, yytname[yyx]);
if (! (yysize <= yysize1
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
yysize = yysize1;
}
}
}
switch (yycount)
{
# define YYCASE_(N, S) \
case N: \
yyformat = S; \
break
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
# undef YYCASE_
}
yysize1 = yysize + yystrlen (yyformat);
if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
yysize = yysize1;
if (*yymsg_alloc < yysize)
{
*yymsg_alloc = 2 * yysize;
if (! (yysize <= *yymsg_alloc
&& *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
*yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
return 1;
}
/* Avoid sprintf, as that infringes on the user's name space.
Don't have undefined behavior even if the translation
produced a string with the wrong number of "%s"s. */
{
char *yyp = *yymsg;
int yyi = 0;
while ((*yyp = *yyformat) != '\0')
if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
{
yyp += yytnamerr (yyp, yyarg[yyi++]);
yyformat += 2;
}
else
{
yyp++;
yyformat++;
}
}
return 0;
}
#endif /* YYERROR_VERBOSE */
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
@ -1461,6 +1507,7 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, mc, vm, parsed, errmsg)
}
}
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
@ -1477,12 +1524,9 @@ int yyparse ();
#endif /* ! YYPARSE_PARAM */
/*-------------------------.
| yyparse or yypush_parse. |
`-------------------------*/
/*----------.
| yyparse. |
`----------*/
#ifdef YYPARSE_PARAM
#if (defined __STDC__ || defined __C99__FUNC__ \
@ -1698,7 +1742,7 @@ yybackup:
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
if (yypact_value_is_default (yyn))
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
@ -1729,8 +1773,8 @@ yybackup:
yyn = yytable[yyn];
if (yyn <= 0)
{
if (yyn == 0 || yyn == YYTABLE_NINF)
goto yyerrlab;
if (yytable_value_is_error (yyn))
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
@ -1786,17 +1830,17 @@ yyreduce:
{
case 4:
/* Line 1464 of yacc.c */
#line 424 "vm_var_syntax.y"
/* Line 1806 of yacc.c */
#line 437 "vm_var_syntax.y"
{
(*parsed) << (yyvsp[(1) - (1)].val_str);
;}
}
break;
case 5:
/* Line 1464 of yacc.c */
#line 428 "vm_var_syntax.y"
/* Line 1806 of yacc.c */
#line 441 "vm_var_syntax.y"
{
string name((yyvsp[(1) - (2)].val_str));
@ -1808,13 +1852,13 @@ yyreduce:
{
(*parsed) << (yyvsp[(2) - (2)].val_char);
}
;}
}
break;
case 6:
/* Line 1464 of yacc.c */
#line 441 "vm_var_syntax.y"
/* Line 1806 of yacc.c */
#line 454 "vm_var_syntax.y"
{
string name((yyvsp[(1) - (5)].val_str));
string vname((yyvsp[(3) - (5)].val_str));
@ -1828,13 +1872,13 @@ yyreduce:
{
(*parsed) << (yyvsp[(5) - (5)].val_char);
}
;}
}
break;
case 7:
/* Line 1464 of yacc.c */
#line 456 "vm_var_syntax.y"
/* Line 1806 of yacc.c */
#line 469 "vm_var_syntax.y"
{
string name((yyvsp[(1) - (9)].val_str));
string vname((yyvsp[(3) - (9)].val_str));
@ -1851,15 +1895,26 @@ yyreduce:
{
(*parsed) << (yyvsp[(9) - (9)].val_char);
}
;}
}
break;
/* Line 1464 of yacc.c */
#line 1861 "vm_var_syntax.cc"
/* Line 1806 of yacc.c */
#line 1905 "vm_var_syntax.cc"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
that yytoken be updated with the new translation. We take the
approach of translating immediately before every use of yytoken.
One alternative is translating here after every semantic action,
but that translation would be missed if the semantic action invokes
YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
incorrect destructor might then be invoked immediately. In the
case of YYERROR or YYBACKUP, subsequent parser actions might lead
to an incorrect destructor call or verbose syntax error message
before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
@ -1888,6 +1943,10 @@ yyreduce:
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
@ -1895,37 +1954,36 @@ yyerrlab:
#if ! YYERROR_VERBOSE
yyerror (&yylloc, mc, vm, parsed, errmsg, YY_("syntax error"));
#else
# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
yyssp, yytoken)
{
YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
{
YYSIZE_T yyalloc = 2 * yysize;
if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
yyalloc = YYSTACK_ALLOC_MAXIMUM;
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yyalloc);
if (yymsg)
yymsg_alloc = yyalloc;
else
{
yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf;
}
}
if (0 < yysize && yysize <= yymsg_alloc)
{
(void) yysyntax_error (yymsg, yystate, yychar);
yyerror (&yylloc, mc, vm, parsed, errmsg, yymsg);
}
else
{
yyerror (&yylloc, mc, vm, parsed, errmsg, YY_("syntax error"));
if (yysize != 0)
goto yyexhaustedlab;
}
char const *yymsgp = YY_("syntax error");
int yysyntax_error_status;
yysyntax_error_status = YYSYNTAX_ERROR;
if (yysyntax_error_status == 0)
yymsgp = yymsg;
else if (yysyntax_error_status == 1)
{
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
if (!yymsg)
{
yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf;
yysyntax_error_status = 2;
}
else
{
yysyntax_error_status = YYSYNTAX_ERROR;
yymsgp = yymsg;
}
}
yyerror (&yylloc, mc, vm, parsed, errmsg, yymsgp);
if (yysyntax_error_status == 2)
goto yyexhaustedlab;
}
# undef YYSYNTAX_ERROR
#endif
}
@ -1985,7 +2043,7 @@ yyerrlab1:
for (;;)
{
yyn = yypact[yystate];
if (yyn != YYPACT_NINF)
if (!yypact_value_is_default (yyn))
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@ -2049,8 +2107,13 @@ yyexhaustedlab:
yyreturn:
if (yychar != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval, &yylloc, mc, vm, parsed, errmsg);
{
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = YYTRANSLATE (yychar);
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval, &yylloc, mc, vm, parsed, errmsg);
}
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
@ -2075,8 +2138,8 @@ yyreturn:
/* Line 1684 of yacc.c */
#line 474 "vm_var_syntax.y"
/* Line 2067 of yacc.c */
#line 487 "vm_var_syntax.y"
extern "C" void vm_var__error(

View File

@ -1,9 +1,8 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* A Bison parser, made by GNU Bison 2.5. */
/* Skeleton interface for Bison's Yacc-like parsers in C
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2009, 2010 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -56,8 +55,8 @@
typedef union YYSTYPE
{
/* Line 1685 of yacc.c */
#line 395 "vm_var_syntax.y"
/* Line 2068 of yacc.c */
#line 408 "vm_var_syntax.y"
char * val_str;
int val_int;
@ -65,8 +64,8 @@ typedef union YYSTYPE
/* Line 1685 of yacc.c */
#line 70 "vm_var_syntax.hh"
/* Line 2068 of yacc.c */
#line 69 "vm_var_syntax.hh"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */

View File

@ -245,7 +245,7 @@ void get_network_attribute(VirtualMachine * vm,
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*
void get_user_attribute(VirtualMachine * vm,
const string& attr_name,
string& attr_value)
@ -275,7 +275,7 @@ void get_user_attribute(VirtualMachine * vm,
user->unlock();
}
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -346,6 +346,19 @@ void insert_vector(VirtualMachine * vm,
return;
}
else if (name == "USER")
{
string value;
get_user_attribute(vm, vname, value);
if (!value.empty())
{
parsed << value;
}
return;
}
else
{
if ( ( num = vm->get_template_attribute(name.c_str(),values) ) <= 0 )

View File

@ -245,12 +245,80 @@ void VirtualMachineManager::do_action(const string &action, void * arg)
/* Manager Actions */
/* ************************************************************************** */
string * VirtualMachineManager::format_message(
const string& hostname,
const string& net_drv,
const string& m_hostname,
const string& m_net_drv,
const string& domain,
const string& ldfile,
const string& rdfile,
const string& cfile,
const string& tmpl)
{
ostringstream oss;
oss << "<VMM_DRIVER_ACTION_DATA>"
<< "<HOST>" << hostname << "</HOST>"
<< "<NET_DRV>" << net_drv << "</NET_DRV>";
if (!m_hostname.empty())
{
oss << "<MIGR_HOST>" << m_hostname << "</MIGR_HOST>"
<< "<MIGR_NET_DRV>"<< m_net_drv << "</MIGR_NET_DRV>";
}
else
{
oss << "<MIGR_HOST/><MIGR_NET_DRV/>";
}
if (!domain.empty())
{
oss << "<DEPLOY_ID>" << domain << "</DEPLOY_ID>";
}
else
{
oss << "<DEPLOY_ID/>";
}
if (!ldfile.empty())
{
oss << "<LOCAL_DEPLOYMENT_FILE>" << ldfile << "</LOCAL_DEPLOYMENT_FILE>";
oss << "<REMOTE_DEPLOYMENT_FILE>" << rdfile << "</REMOTE_DEPLOYMENT_FILE>";
}
else
{
oss << "<LOCAL_DEPLOYMENT_FILE/>";
oss << "<REMOTE_DEPLOYMENT_FILE/>";
}
if (!cfile.empty())
{
oss << "<CHECKPOINT_FILE>" << cfile << "</CHECKPOINT_FILE>";
}
else
{
oss << "<CHECKPOINT_FILE/>";
}
oss << tmpl
<< "</VMM_DRIVER_ACTION_DATA>";
return SSLTools::base64_encode(oss.str());
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineManager::deploy_action(int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
int rc;
ostringstream os;
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
int rc;
ostringstream os;
string vm_tmpl;
string * drv_msg;
// Get the VM from the pool
vm = vmpool->get(vid,true);
@ -287,7 +355,20 @@ void VirtualMachineManager::deploy_action(int vid)
}
// Invoke driver method
vmd->deploy(vid,vm->get_hostname(),vm->get_remote_deployment_file());
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
"",
vm->get_deployment_file(),
vm->get_remote_deployment_file(),
"",
vm->to_xml(vm_tmpl));
vmd->deploy(vid, *drv_msg);
delete drv_msg;
vm->unlock();
@ -326,8 +407,11 @@ void VirtualMachineManager::save_action(
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
string hostname;
ostringstream os;
string hostname, vnm_mad;
string vm_tmpl;
string * drv_msg;
ostringstream os;
// Get the VM from the pool
vm = vmpool->get(vid,true);
@ -359,20 +443,32 @@ void VirtualMachineManager::save_action(
}
hostname = vm->get_previous_hostname();
vnm_mad = vm->get_previous_vnm_mad();
}
else
{
hostname=vm->get_hostname();
hostname = vm->get_hostname();
vnm_mad = vm->get_vnm_mad();
}
// Invoke driver method
vmd->save(
vid,
drv_msg = format_message(
hostname,
vnm_mad,
"",
"",
vm->get_deploy_id(),
vm->get_checkpoint_file());
"",
"",
vm->get_checkpoint_file(),
vm->to_xml(vm_tmpl));
vmd->save(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
@ -406,9 +502,12 @@ error_common:
void VirtualMachineManager::shutdown_action(
int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
string vm_tmpl;
string * drv_msg;
ostringstream os;
// Get the VM from the pool
vm = vmpool->get(vid,true);
@ -432,9 +531,23 @@ void VirtualMachineManager::shutdown_action(
}
// Invoke driver method
vmd->shutdown(vid,vm->get_hostname(),vm->get_deploy_id());
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->shutdown(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
@ -466,6 +579,9 @@ void VirtualMachineManager::cancel_action(
VirtualMachine * vm;
ostringstream os;
string vm_tmpl;
string * drv_msg;
const VirtualMachineManagerDriver * vmd;
// Get the VM from the pool
@ -490,9 +606,23 @@ void VirtualMachineManager::cancel_action(
}
// Invoke driver method
vmd->cancel(vid,vm->get_hostname(),vm->get_deploy_id());
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->cancel(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
@ -527,6 +657,9 @@ void VirtualMachineManager::cancel_previous_action(
VirtualMachine * vm;
ostringstream os;
string vm_tmpl;
string * drv_msg;
const VirtualMachineManagerDriver * vmd;
// Get the VM from the pool
@ -551,9 +684,23 @@ void VirtualMachineManager::cancel_previous_action(
}
// Invoke driver method
vmd->cancel(vid,vm->get_previous_hostname(),vm->get_deploy_id());
drv_msg = format_message(
vm->get_previous_hostname(),
vm->get_previous_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->cancel(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
@ -579,7 +726,10 @@ void VirtualMachineManager::migrate_action(
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
ostringstream os;
string vm_tmpl;
string * drv_msg;
// Get the VM from the pool
vm = vmpool->get(vid,true);
@ -608,10 +758,20 @@ void VirtualMachineManager::migrate_action(
}
// Invoke driver method
vmd->migrate(vid,
vm->get_previous_hostname(),
vm->get_deploy_id(),
vm->get_hostname());
drv_msg = format_message(
vm->get_previous_hostname(),
vm->get_previous_vnm_mad(),
vm->get_hostname(),
vm->get_vnm_mad(),
vm->get_deploy_id(),
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->migrate(vid, *drv_msg);
delete drv_msg;
vm->unlock();
@ -648,9 +808,13 @@ error_common:
void VirtualMachineManager::restore_action(
int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
string vm_tmpl;
string * drv_msg;
// Get the VM from the pool
vm = vmpool->get(vid,true);
@ -674,12 +838,23 @@ void VirtualMachineManager::restore_action(
}
// Invoke driver method
vmd->restore(vid,
vm->get_hostname(),
vm->get_deploy_id(),
vm->get_checkpoint_file());
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
vm->get_checkpoint_file(),
vm->to_xml(vm_tmpl));
vmd->restore(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
@ -708,9 +883,13 @@ error_common:
void VirtualMachineManager::poll_action(
int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
string vm_tmpl;
string * drv_msg;
// Get the VM from the pool
vm = vmpool->get(vid,true);
@ -734,9 +913,23 @@ void VirtualMachineManager::poll_action(
}
// Invoke driver method
vmd->poll(vid,vm->get_hostname(),vm->get_deploy_id());
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->poll(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
@ -824,6 +1017,9 @@ void VirtualMachineManager::timer_action()
const VirtualMachineManagerDriver * vmd;
string vm_tmpl;
string * drv_msg;
mark = mark + timer_period;
if ( mark >= 600 )
@ -874,7 +1070,20 @@ void VirtualMachineManager::timer_action()
continue;
}
vmd->poll(*it,vm->get_hostname(),vm->get_deploy_id());
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->poll(*it, *drv_msg);
delete drv_msg;
vmpool->update(vm);

View File

@ -104,13 +104,12 @@ void VirtualMachineManagerDriver::get_default(
void VirtualMachineManagerDriver::deploy (
const int oid,
const string& host,
const string& conf) const
const string& drv_msg) const
{
ostringstream os;
os << "DEPLOY " << oid << " " << host << " " << conf << " -" << endl;
os << "DEPLOY " << oid << " " << drv_msg << endl;
write(os);
};
@ -119,12 +118,11 @@ void VirtualMachineManagerDriver::deploy (
void VirtualMachineManagerDriver::shutdown (
const int oid,
const string& host,
const string& name) const
const string& drv_msg) const
{
ostringstream os;
os << "SHUTDOWN " << oid << " " << host << " " << name << " -" << endl;
os << "SHUTDOWN " << oid << " " << drv_msg << endl;
write(os);
};
@ -134,12 +132,11 @@ void VirtualMachineManagerDriver::shutdown (
void VirtualMachineManagerDriver::cancel (
const int oid,
const string& host,
const string& name) const
const string& drv_msg) const
{
ostringstream os;
os << "CANCEL " << oid << " " << host << " " << name << " -" << endl;
os << "CANCEL " << oid << " " << drv_msg << endl;
write(os);
};
@ -149,13 +146,11 @@ void VirtualMachineManagerDriver::cancel (
void VirtualMachineManagerDriver::checkpoint (
const int oid,
const string& host,
const string& name,
const string& file) const
const string& drv_msg) const
{
ostringstream os;
os<< "CHECKPOINT " << oid<< " "<< host<< " "<< name<< " "<< file<< endl;
os<< "CHECKPOINT " << oid << " " << drv_msg << endl;
write(os);
};
@ -165,13 +160,11 @@ void VirtualMachineManagerDriver::checkpoint (
void VirtualMachineManagerDriver::save (
const int oid,
const string& host,
const string& name,
const string& file) const
const string& drv_msg) const
{
ostringstream os;
os<< "SAVE " << oid << " " << host << " " << name << " "<< file << endl;
os<< "SAVE " << oid << " " << drv_msg << endl;
write(os);
};
@ -181,13 +174,11 @@ void VirtualMachineManagerDriver::save (
void VirtualMachineManagerDriver::restore (
const int oid,
const string& host,
const string& name,
const string& file) const
const string& drv_msg) const
{
ostringstream os;
os << "RESTORE " << oid << " " << host << " " << name << " " << file<< endl;
os << "RESTORE " << oid << " " << drv_msg << endl;
write(os);
};
@ -197,13 +188,11 @@ void VirtualMachineManagerDriver::restore (
void VirtualMachineManagerDriver::migrate (
const int oid,
const string& shost,
const string& name,
const string& dhost) const
const string& drv_msg) const
{
ostringstream os;
os<< "MIGRATE " << oid << " "<< shost<< " "<< name<< " "<< dhost<< endl;
os<< "MIGRATE " << oid << " " << drv_msg << endl;
write(os);
};
@ -213,12 +202,11 @@ void VirtualMachineManagerDriver::migrate (
void VirtualMachineManagerDriver::poll (
const int oid,
const string& host,
const string& name) const
const string& drv_msg) const
{
ostringstream os;
os << "POLL " << oid << " " << host << " " << name << " -" << endl;
os << "POLL " << oid << " " << drv_msg << endl;
write(os);
};

View File

@ -35,9 +35,7 @@ int XMLDriver::deployment_description(
return -1;
}
vm->template_to_xml(xml);
file << xml ;
file << vm->template_to_xml(xml);
file.close();

View File

@ -39,31 +39,36 @@ class DummyDriver < VirtualMachineDriver
)
end
def deploy(id, host, remote_dfile, not_used)
send_message(ACTION[:deploy],RESULT[:success],id,"dummy")
def deploy(id, drv_message)
msg = decode(drv_message)
host = msg.elements["HOST"].text
name = msg.elements["VM/NAME"].text
send_message(ACTION[:deploy],RESULT[:success],id,"#{host}:#{name}:dummy")
end
def shutdown(id, host, deploy_id, not_used)
def shutdown(id, drv_message)
send_message(ACTION[:shutdown],RESULT[:success],id)
end
def cancel(id, host, deploy_id, not_used)
def cancel(id, drv_message)
send_message(ACTION[:cancel],RESULT[:success],id)
end
def save(id, host, deploy_id, file)
def save(id, drv_message)
send_message(ACTION[:save],RESULT[:success],id)
end
def restore(id, host, deploy_id , file)
def restore(id, drv_message)
send_message(ACTION[:restore],RESULT[:success],id)
end
def migrate(id, host, deploy_id, dest_host)
def migrate(id, drv_message)
send_message(ACTION[:migrate],RESULT[:success],id)
end
def poll(id, host, deploy_id, not_used)
def poll(id, drv_message)
# monitor_info: string in the form "VAR=VAL VAR=VAL ... VAR=VAL"
# known VAR are in POLL_ATTRIBUTES. VM states VM_STATES
monitor_info = "#{POLL_ATTRIBUTE[:state]}=#{VM_STATE[:active]} " \

View File

@ -89,9 +89,12 @@ class EC2Driver < VirtualMachineDriver
end
# DEPLOY action, also sets ports and ip if needed
def deploy(id, host, remote_dfile, not_used)
def deploy(id, drv_message)
msg = decode(drv_message)
local_dfile = get_local_deployment_file(remote_dfile)
host = msg.elements["HOST"].text
local_dfile = msg.elements["LOCAL_DEPLOYMENT_FILE"].text
if !local_dfile
send_message(ACTION[:deploy],RESULT[:failure],id,
@ -175,17 +178,31 @@ class EC2Driver < VirtualMachineDriver
end
# Shutdown a EC2 instance
def shutdown(id, host, deploy_id, not_used)
def shutdown(id, drv_message)
msg = decode(drv_message)
host = msg.elements["HOST"].text
deploy_id = msg.elements["DEPLOY_ID"].text
ec2_terminate(ACTION[:shutdown], id, deploy_id)
end
# Cancel a EC2 instance
def cancel(id, host, deploy_id, not_used)
def cancel(id, drv_message)
msg = decode(drv_message)
host = msg.elements["HOST"].text
deploy_id = msg.elements["DEPLOY_ID"].text
ec2_terminate(ACTION[:cancel], id, deploy_id)
end
# Get info (IP, and state) for a EC2 instance
def poll(id, host, deploy_id, not_used)
def poll(id, drv_message)
msg = decode(drv_message)
host = msg.elements["HOST"].text
deploy_id = msg.elements["DEPLOY_ID"].text
info = "#{POLL_ATTRIBUTE[:usedmemory]}=0 " \
"#{POLL_ATTRIBUTE[:usedcpu]}=0 " \

View File

@ -16,7 +16,6 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
# Set up the environment for the driver
ONE_LOCATION = ENV["ONE_LOCATION"]
@ -32,12 +31,188 @@ end
$: << RUBY_LIB_LOCATION
require "VirtualMachineDriver"
require 'one_vnm'
require 'getoptlong'
require 'ssh_stream'
require 'pp'
class VmmAction
attr_reader :data
# Initialize a VmmAction object
# @param[OpenNebula::ExecDriver] Driver to be used for the actions
# @param[String] Id of the VM
# @param[String] name of the actions as described in the VMM protocol
# @param[xml_data] data sent from OpenNebula core
def initialize(driver, id, action, xml_data)
# Initialize object with xml data
@vmm = driver
@id = id
@main_action = action
@xml_data = @vmm.decode(xml_data)
@data = Hash.new
get_data(:host)
get_data(:net_drv)
get_data(:deploy_id)
get_data(:checkpoint_file)
get_data(:local_dfile, :LOCAL_DEPLOYMENT_FILE)
get_data(:remote_dfile, :REMOTE_DEPLOYMENT_FILE)
# For migration
get_data(:dest_host, :MIGR_HOST)
get_data(:dest_driver, :MIGR_NET_DRV)
# Initialize streams and vnm
@ssh_src = @vmm.get_ssh_stream(@data[:host], @id)
@vnm_src = VirtualNetworkDriver.new(@data[:net_drv],
:local_actions => @vmm.options[:local_actions],
:message => @xml_data,
:ssh_stream => @ssh_src)
if @data[:dest_host] and !@data[:dest_host].empty?
@ssh_dst = @vmm.get_ssh_stream(@data[:dest_host], @id)
@vnm_dst = VirtualNetworkDriver.new(@data[:dest_driver],
:local_actions => @vmm.options[:local_actions],
:message => @xml_data,
:ssh_stream => @ssh_dst)
end
end
#Execute a set of steps defined with
# - :driver :vmm or :vnm to execute the step
# - :action for the step
# - :parameters command line paremeters for the action
# - :destination use next host
# - :fail_action steps to be executed if steps fail
# - :stdin for the action
# @param [Array] of steps
def run(steps, info_on_success = nil)
result = execute_steps(steps)
#Prepare the info for the OpenNebula core
if DriverExecHelper.failed?(result)
info = @data[:failed_info]
else
info = @data["#{@main_action.to_s}_info".to_sym]
end
@vmm.send_message(VirtualMachineDriver::ACTION[@main_action],
result, @id, info)
end
private
DRIVER_NAMES = {
:vmm => "virtualization driver",
:vnm => "network driver"
}
# Executes a set of steps. If one step fails any recover action is performed
# and the step execution breaks.
# @param [Array] array of steps to be executed
# @return [String, Hash] "SUCCESS/FAILURE" for the step set, and
# information associated to each step (by :<action>_info). In case of
# failure information is also in [:failed_info]
def execute_steps(steps)
result = DriverExecHelper.const_get(:RESULT)[:failure]
steps.each do |step|
# Execute Step
case step[:driver]
when :vmm
if step[:destination]
host = @data[:dest_host]
ssh = @ssh_dst
else
host = @data[:host]
ssh = @ssh_src
end
result, info = @vmm.do_action(get_parameters(step[:parameters]),
@id,
host,
step[:action],
:ssh_stream => ssh,
:respond => false,
:stdin => step[:stdin])
when :vnm
if step[:destination]
vnm = @vnm_dst
else
vnm = @vnm_src
end
result, info = vnm.do_action(@id, step[:action])
else
result = DriverExecHelper.const_get(:RESULT)[:failure]
info = "No driver in #{step[:action]}"
end
# Save the step info
@data["#{step[:action]}_info".to_sym] = info
# Roll back steps, store failed info and break steps
if DriverExecHelper.failed?(result)
execute_steps(@data[:fail_actions]) if @data[:fail_actions]
@data[:failed_info] = info
@vmm.log(@id,
"Failed to execute #{DRIVER_NAMES[step[:driver]]} " \
"operation: #{step[:action]}.")
break
else
@vmm.log(@id,
"Sussecfully execute #{DRIVER_NAMES[step[:driver]]} " \
"operation: #{step[:action]}.")
end
end
return result
end
# Prepare the parameters for the action step generating a blanck separated
# list of command arguments
# @param [Hash] an action step
def get_parameters(step_params)
parameters = step_params || []
parameters.map do |param|
if Symbol===param
@data[param].to_s
else
param
end
end.join(' ')
end
# Extracts data from the XML argument of the VMM action
# @param [Symbol] corresponding to a XML element
# @param [String] an xpath for the XML element
# @return [String] the element value
def get_data(name, xml_path=nil)
if xml_path
path=xml_path.to_s
else
path=name.to_s.upcase
end
@data[name]=@xml_data.elements[path].text
end
end
# The main class for the Sh driver
class ExecDriver < VirtualMachineDriver
attr_reader :options
# SshDriver constructor
# Initializes the VMM driver
# @param [String] hypervisor name identifies the plugin
# @param [OpenNebulaDriver::options]
def initialize(hypervisor, options={})
@options={
:threaded => true
@ -48,9 +223,29 @@ class ExecDriver < VirtualMachineDriver
@hypervisor = hypervisor
end
# Creates an SshStream to execute commands on the target host
# @param[String] the hostname of the host
# @param[String] id of the VM to log messages
# @return [SshStreamCommand]
def get_ssh_stream(host, id)
SshStreamCommand.new(host,
@remote_scripts_base_path,
log_method(id))
end
#---------------------------------------------------------------------------
# Virtual Machine Manager Protocol Actions
#---------------------------------------------------------------------------
#
# DEPLOY action, sends the deployment file to remote host
def deploy(id, host, remote_dfile, not_used)
local_dfile = get_local_deployment_file(remote_dfile)
#
def deploy(id, drv_message)
action = VmmAction.new(self, id, :deploy, drv_message)
# ----------------------------------------------------------------------
# Initialization of deployment data
# ----------------------------------------------------------------------
local_dfile=action.data[:local_dfile]
if !local_dfile || File.zero?(local_dfile)
send_message(ACTION[:deploy],RESULT[:failure],id,
@ -58,48 +253,207 @@ class ExecDriver < VirtualMachineDriver
return
end
tmp = File.new(local_dfile)
domain = tmp.read
tmp.close()
domain = File.read(local_dfile)
if action_is_local?(:deploy)
dfile=local_dfile
dfile = action.data[:local_dfile]
else
dfile=remote_dfile
dfile = action.data[:remote_dfile]
end
do_action("#{dfile} #{host}", id, host, :deploy,
:stdin => domain)
# ----------------------------------------------------------------------
# Deployment Steps
# ----------------------------------------------------------------------
steps=[
# Execute pre-boot networking setup
{
:driver => :vnm,
:action => :pre
},
# Boot the Virtual Machine
{
:driver => :vmm,
:action => :deploy,
:parameters => [dfile, :host],
:stdin => domain
},
# Execute post-boot networking setup
{
:driver => :vnm,
:action => :post,
:fail_actions => [
{
:driver => :vmm,
:action => :cancel,
:parameters => [:deploy_info, :host]
}
]
}
]
action.run(steps)
end
# Basic Domain Management Operations
#
# SHUTDOWN action, graceful shutdown and network clean up
#
def shutdown(id, drv_message)
def shutdown(id, host, deploy_id, not_used)
do_action("#{deploy_id} #{host}", id, host, :shutdown)
action = VmmAction.new(self, id, :shutdown, drv_message)
steps=[
# Shutdown the Virtual Machine
{
:driver => :vmm,
:action => :shutdown,
:parameters => [:deploy_id, :host]
},
# Execute networking clean up operations
{
:driver => :vnm,
:action => :clean
}
]
action.run(steps)
end
def cancel(id, host, deploy_id, not_used)
do_action("#{deploy_id} #{host}", id, host, :cancel)
#
# CANCEL action, destroys a VM and network clean up
#
def cancel(id, drv_message)
action = VmmAction.new(self, id, :cancel, drv_message)
steps=[
# Cancel the Virtual Machine
{
:driver => :vmm,
:action => :cancel,
:parameters => [:deploy_id, :host]
},
# Execute networking clean up operations
{
:driver => :vnm,
:action => :clean
}
]
action.run(steps)
end
def save(id, host, deploy_id, file)
do_action("#{deploy_id} #{file} #{host}", id, host, :save)
#
# SAVE action, stops the VM and saves its state, network is cleaned up
#
def save(id, drv_message)
action = VmmAction.new(self, id, :save, drv_message)
steps=[
# Save the Virtual Machine state
{
:driver => :vmm,
:action => :save,
:parameters => [:deploy_id, :checkpoint_file, :host]
},
# Execute networking clean up operations
{
:driver => :vnm,
:action => :clean
}
]
action.run(steps)
end
def restore(id, host, deploy_id, file)
do_action("#{file} #{host}", id, host, :restore)
#
# RESTORE action, restore a VM from a previous state, and restores network
#
def restore(id, drv_message)
action=VmmAction.new(self, id, :restore, drv_message)
steps=[
# Execute pre-boot networking setup
{
:driver => :vnm,
:action => :pre
},
# Restore the Virtual Machine from checkpoint
{
:driver => :vmm,
:action => :restore,
:parameters => [:checkpoint_file, :host]
},
# Execute post-boot networking setup
{
:driver => :vnm,
:action => :post,
:fail_actions => [
{
:driver => :vmm,
:action => :cancel,
:parameters => [:deploy_id, :host]
}
],
}
]
action.run(steps)
end
def migrate(id, host, deploy_id, dest_host)
do_action("#{deploy_id} #{dest_host} #{host}", id, host, :migrate)
#
# MIGRATE (live) action, migrates a VM to another host creating network
#
def migrate(id, drv_message)
action=VmmAction.new(self, id, :migrate, drv_message)
steps=[
# Execute pre-boot networking setup on migrating host
{
:driver => :vnm,
:action => :pre,
:destination => true
},
# Migrate the Virtual Machine
{
:driver => :vmm,
:action => :migrate,
:parameters => [:deploy_id, :dest_host, :host]
},
# Execute networking clean up operations
{
:driver => :vnm,
:action => :clean
},
# Execute post-boot networking setup on migrating host
{
:driver => :vnm,
:action => :post,
:destination => :true
#TODO :fail_action what to do here? cancel VM?
},
]
action.run(steps)
end
def poll(id, host, deploy_id, not_used)
#
# POLL action, gets information of a VM
#
def poll(id, drv_message)
data = decode(drv_message)
host = data.elements['HOST'].text
deploy_id = data.elements['DEPLOY_ID'].text
do_action("#{deploy_id} #{host}", id, host, :poll)
end
end
# SshDriver Main program
################################################################################
#
# Virtual Machine Manager Execution Driver - Main Program
#
################################################################################
opts = GetoptLong.new(
[ '--retries', '-r', GetoptLong::OPTIONAL_ARGUMENT ],
[ '--threads', '-t', GetoptLong::OPTIONAL_ARGUMENT ],
@ -138,3 +492,5 @@ exec_driver = ExecDriver.new(hypervisor,
:local_actions => local_actions)
exec_driver.start_driver

View File

@ -25,6 +25,8 @@
#include "AuthManager.h"
#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper)
/* ************************************************************************** */
/* Virtual Network :: Constructor/Destructor */
/* ************************************************************************** */
@ -207,6 +209,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
int rc;
string pub;
string vlan_attr;
string s_type;
unsigned int default_size = VirtualNetworkPool::default_size();
@ -219,7 +222,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
// ------------ TYPE ----------------------
erase_template_attribute("TYPE",s_type);
transform(s_type.begin(),s_type.end(),s_type.begin(),(int(*)(int))toupper);
TO_UPPER(s_type);
if (s_type == "RANGED")
{
@ -255,6 +258,14 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
erase_template_attribute("VLAN_ID",vlan_id);
// ------------ VLAN ----------------------
erase_template_attribute("VLAN", vlan_attr);
TO_UPPER(vlan_attr);
vlan = (vlan_attr == "YES");
// ------------ BRIDGE --------------------
erase_template_attribute("BRIDGE",bridge);
@ -272,7 +283,6 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
oss << "onebr" << oid;
bridge = oss.str();
replace_template_attribute("BRIDGE",bridge);
}
}
@ -280,7 +290,7 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
erase_template_attribute("PUBLIC", pub);
transform (pub.begin(), pub.end(), pub.begin(), (int(*)(int))toupper);
TO_UPPER(pub);
public_obj = (pub == "YES");
@ -515,7 +525,8 @@ string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const
"<GNAME>" << gname << "</GNAME>" <<
"<NAME>" << name << "</NAME>" <<
"<TYPE>" << type << "</TYPE>" <<
"<BRIDGE>" << bridge << "</BRIDGE>";
"<BRIDGE>" << bridge << "</BRIDGE>"<<
"<VLAN>" << vlan << "</VLAN>";
if (!phydev.empty())
{
@ -583,6 +594,7 @@ int VirtualNetwork::from_xml(const string &xml_str)
rc += xpath(int_type, "/VNET/TYPE", -1);
rc += xpath(bridge, "/VNET/BRIDGE", "not_found");
rc += xpath(public_obj, "/VNET/PUBLIC", 0);
rc += xpath(vlan, "/VNET/VLAN", 0);
xpath(phydev, "/VNET/PHYDEV", "");
xpath(vlan_id, "/VNET/VLAN_ID","");
@ -653,6 +665,15 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid)
nic->replace("MAC" ,mac);
nic->replace("IP" ,ip);
if ( vlan == 1 )
{
nic->replace("VLAN", "YES");
}
else
{
nic->replace("VLAN", "NO");
}
if (!phydev.empty())
{
nic->replace("PHYDEV", phydev);

View File

@ -71,18 +71,18 @@ const string templates[] =
const string xmls[] =
{
"<VNET><ID>0</ID><UID>123</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>",
"<VNET><ID>0</ID><UID>123</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><VLAN>0</VLAN><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>",
"<VNET><ID>1</ID><UID>261</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_ADDRESS><![CDATA[192.168.0.0]]></NETWORK_ADDRESS><NETWORK_SIZE><![CDATA[C]]></NETWORK_SIZE></TEMPLATE><LEASES></LEASES></VNET>",
"<VNET><ID>1</ID><UID>261</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><VLAN>0</VLAN><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_ADDRESS><![CDATA[192.168.0.0]]></NETWORK_ADDRESS><NETWORK_SIZE><![CDATA[C]]></NETWORK_SIZE></TEMPLATE><LEASES></LEASES></VNET>",
"<VNET><ID>0</ID><UID>133</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number two</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.2.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>",
"<VNET><ID>0</ID><UID>133</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number two</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><VLAN>0</VLAN><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.2.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>",
};
const string xml_dump =
"<VNET_POOL><VNET><ID>0</ID><UID>1</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE></VNET><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_ADDRESS><![CDATA[192.168.0.0]]></NETWORK_ADDRESS><NETWORK_SIZE><![CDATA[C]]></NETWORK_SIZE></TEMPLATE></VNET></VNET_POOL>";
"<VNET_POOL><VNET><ID>0</ID><UID>1</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>Net number one</NAME><TYPE>1</TYPE><BRIDGE>br1</BRIDGE><VLAN>0</VLAN><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE></VNET><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><VLAN>0</VLAN><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_ADDRESS><![CDATA[192.168.0.0]]></NETWORK_ADDRESS><NETWORK_SIZE><![CDATA[C]]></NETWORK_SIZE></TEMPLATE></VNET></VNET_POOL>";
const string xml_dump_where =
"<VNET_POOL><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_ADDRESS><![CDATA[192.168.0.0]]></NETWORK_ADDRESS><NETWORK_SIZE><![CDATA[C]]></NETWORK_SIZE></TEMPLATE></VNET></VNET_POOL>";
"<VNET_POOL><VNET><ID>1</ID><UID>2</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>A virtual network</NAME><TYPE>0</TYPE><BRIDGE>br0</BRIDGE><VLAN>0</VLAN><PUBLIC>1</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><NETWORK_ADDRESS><![CDATA[192.168.0.0]]></NETWORK_ADDRESS><NETWORK_SIZE><![CDATA[C]]></NETWORK_SIZE></TEMPLATE></VNET></VNET_POOL>";
/* ************************************************************************* */
/* ************************************************************************* */
@ -310,8 +310,8 @@ public:
};
string phydev_xml[] = {
"<VNET><ID>0</ID><UID>0</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>BRIDGE and PHYDEV</NAME><TYPE>1</TYPE><BRIDGE>br0</BRIDGE><PHYDEV>eth0</PHYDEV><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>",
"<VNET><ID>1</ID><UID>0</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>No BRIDGE only PHYDEV</NAME><TYPE>1</TYPE><BRIDGE>onebr1</BRIDGE><PHYDEV>eth0</PHYDEV><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE><BRIDGE><![CDATA[onebr1]]></BRIDGE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>"
"<VNET><ID>0</ID><UID>0</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>BRIDGE and PHYDEV</NAME><TYPE>1</TYPE><BRIDGE>br0</BRIDGE><VLAN>0</VLAN><PHYDEV>eth0</PHYDEV><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>",
"<VNET><ID>1</ID><UID>0</UID><GID>0</GID><UNAME>the_user</UNAME><GNAME>oneadmin</GNAME><NAME>No BRIDGE only PHYDEV</NAME><TYPE>1</TYPE><BRIDGE>onebr1</BRIDGE><VLAN>0</VLAN><PHYDEV>eth0</PHYDEV><PUBLIC>0</PUBLIC><TOTAL_LEASES>0</TOTAL_LEASES><TEMPLATE></TEMPLATE><LEASES><LEASE><IP>130.10.0.1</IP><MAC>50:20:20:20:20:20</MAC><USED>0</USED><VID>-1</VID></LEASE></LEASES></VNET>"
};
// test vm with bridge and phydev

70
src/vnm_mad/one_vnm.rb Normal file
View File

@ -0,0 +1,70 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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 "DriverExecHelper"
# This module provides an abstraction to generate an execution context for
# OpenNebula Drivers
class VirtualNetworkDriver
include DriverExecHelper
# Inits the VNET Driver
# @param [String] name of the vnet driver to use, as listed in remotes/vnet
# @option ops [String] :ssh_stream to be used for command execution
# @option ops [String] :message from ONE
def initialize(directory, options={})
@options = options
@ssh_stream = options[:ssh_stream]
@message = options[:message]
@vm_encoded = Base64.encode64(@message.elements['VM'].to_s).delete("\n")
initialize_helper("vnm/#{directory}", options)
end
# Calls remotes or local action checking the action name and
# @local_actions. Optional arguments can be specified as a hash
#
# @param [Number, String] id action identifier
# @param [String, Symbol] aname name of the action
# @param [Hash] ops extra options for the command
# @option ops [String] :stdin text to be writen to stdin
def do_action(id, aname, ops = {})
options={
:stdin => nil,
}.merge(ops)
cmd = action_command_line(aname, @vm_encoded)
if action_is_local?(aname)
execution = LocalCommand.run(cmd, log_method(id))
else
if options[:stdin]
cmdin = "cat << EOT | #{cmd}"
stdin = "#{options[:stdin]}\nEOT\n"
else
cmdin = cmd
stdin = nil
end
execution = @ssh_stream.run(cmdin, stdin, cmd)
end
result, info = get_info_from_execution(execution)
end
end

View File

@ -14,6 +14,8 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'OpenNebulaNetwork'
class OpenNebulaHM < OpenNebulaNetwork
def initialize(vm, hypervisor = nil)
super(vm,hypervisor)
@ -48,12 +50,8 @@ class OpenNebulaHM < OpenNebulaNetwork
end
end
end
end
def deactivate
vm_id = @vm['ID']
process do |nic|
end
return 0
end
def bridge_exists?(bridge)
@ -61,16 +59,16 @@ class OpenNebulaHM < OpenNebulaNetwork
end
def create_bridge(bridge)
system("#{COMMANDS[:brctl]} addbr #{bridge}")
OpenNebula.exec_and_log("#{COMMANDS[:brctl]} addbr #{bridge}")
end
def device_exists?(dev, vlan=nil)
dev = "#{dev}.#{vlan}" if vlan
system("#{COMMANDS[:ip]} link show #{dev}")
OpenNebula.exec_and_log("#{COMMANDS[:ip]} link show #{dev}")
end
def create_dev_vlan(dev, vlan)
system("#{COMMANDS[:vconfig]} add #{dev} #{vlan}")
OpenNebula.exec_and_log("#{COMMANDS[:vconfig]} add #{dev} #{vlan}")
end
def attached_bridge_dev?(bridge, dev, vlan=nil)
@ -81,11 +79,11 @@ class OpenNebulaHM < OpenNebulaNetwork
def attach_brigde_dev(bridge, dev, vlan=nil)
dev = "#{dev}.#{vlan}" if vlan
system("#{COMMANDS[:brctl]} addif #{bridge} #{dev}")
OpenNebula.exec_and_log("#{COMMANDS[:brctl]} addif #{bridge} #{dev}")
end
def ifup(dev, vlan=nil)
dev = "#{dev}.#{vlan}" if vlan
system("#{COMMANDS[:ip]} link set #{dev} up")
OpenNebula.exec_and_log("#{COMMANDS[:ip]} link set #{dev} up")
end
end

View File

@ -0,0 +1,19 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
exit 0

19
src/vnm_mad/remotes/802.1Q/post Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
exit 0

25
src/vnm_mad/remotes/802.1Q/pre Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
$: << File.dirname(__FILE__)
$: << File.join(File.dirname(__FILE__), "..")
require 'HostManaged'
hm = OpenNebulaHM.from_base64(ARGV[0])
exit hm.activate

View File

@ -104,7 +104,7 @@ class OpenNebulaFirewall < OpenNebulaNetwork
def run_rules(rules)
rules.flatten.each do |rule|
system(rule)
OpenNebula.exec_and_log(rule)
end
end

View File

@ -17,9 +17,14 @@
#--------------------------------------------------------------------------- #
$: << File.dirname(__FILE__)
$: << File.join(File.dirname(__FILE__), '..')
require 'rexml/document'
require 'OpenNebulaNic'
require 'base64'
require 'scripts_common'
include OpenNebula
CONF = {
:start_vlan => 2
@ -28,7 +33,7 @@ CONF = {
COMMANDS = {
:ebtables => "sudo /sbin/ebtables",
:iptables => "sudo /sbin/iptables",
:brctl => "sudo /usr/sbin/brctl",
:brctl => "sudo /sbin/brctl",
:ip => "sudo /sbin/ip",
:vconfig => "sudo /sbin/vconfig",
:virsh => "virsh -c qemu:///system",
@ -37,11 +42,8 @@ COMMANDS = {
:lsmod => "/sbin/lsmod"
}
#
#
#
class VM
attr_accessor :nics, :filtered_nics, :vm_info
attr_accessor :nics, :vm_info
def initialize(vm_root, hypervisor)
@vm_root = vm_root
@ -50,7 +52,7 @@ class VM
nics = Nics.new(@hypervisor)
@vm_root.elements.each("TEMPLATE/NIC") do |nic_element|
@vm_root.elements.each("TEMPLATE/NIC[VLAN='YES']") do |nic_element|
nic = nics.new_nic
nic_element.elements.each('*') do |nic_attribute|
@ -64,21 +66,12 @@ class VM
nics << nic
end
@nics = nics
@filtered_nics = nics
end
def filter(*filter)
@filtered_nics = @nics.get(*filter)
end
def unfilter
@filtered_nics = @nics
@nics = nics
end
def each_nic(block)
if @filtered_nics != nil
@filtered_nics.each do |the_nic|
if @nics != nil
@nics.each do |the_nic|
block.call(the_nic)
end
end
@ -98,9 +91,14 @@ end
class OpenNebulaNetwork
attr_reader :hypervisor, :vm
def self.from_base64(vm_64, hypervisor=nil)
vm_xml = Base64::decode64(vm_64)
self.new(vm_xml, hypervisor)
end
def initialize(vm_tpl, hypervisor=nil)
if !hypervisor
@hypervisor = detect_hypervisor
@hypervisor = detect_hypervisor
else
@hypervisor = hypervisor
end
@ -108,16 +106,6 @@ class OpenNebulaNetwork
@vm = VM.new(REXML::Document.new(vm_tpl).root, @hypervisor)
end
def filter(*filter)
@vm.filter(*filter)
self
end
def unfilter
@vm.unfilter
self
end
def process(&block)
@vm.each_nic(block)
end

View File

@ -28,59 +28,11 @@ class Nics < Array
def new_nic
@nicClass.new
end
# finds nics that match 'args'
# 'args' can be a Hash, or an array
# args example:
# {:mac => "02:00:C0:A8:01:01", :bridge => "br0"}
# :mac, "02:00:C0:A8:01:01"
# key values may also be an array:
# {:mac => "02:00:C0:A8:01:01", :bridge => ["br0","br1"]}
def get(*args)
if args.length == 2
dict = Hash.new
dict[args[0]] = args[1]
elsif args.length == 1
dict = args[0]
else
return nil
end
matching = Array.new
self.each do |e|
e_filter = Hash.new
dict.each_key{|k| e_filter[k] = e[k]}
if compare(e_filter,dict)
matching << e
end
end
if matching.empty?
nil
else
matching
end
end
def compare(hash1, hash2)
#hash1 has a single value per key
#hash2 may contain an array of values
hash1.each do |k,v|
return false if !hash2[k]
v2 = hash2[k]
if hash2[k].kind_of?(Array)
return false if !v2.include? v
else
return false if v != v2
end
end
true
end
end
# A NIC using KVM. This class implements functions to get the physical interface
# that the NIC is using
# A NIC using KVM. This class implements functions to get the physical interface
# that the NIC is using
class NicKVM < Hash
def initialize
super(nil)
@ -118,8 +70,8 @@ class NicKVM < Hash
end
# A NIC using Xen. This class implements functions to get the physical interface
# that the NIC is using
# A NIC using Xen. This class implements functions to get the physical interface
# that the NIC is using
class NicXen < Hash
def initialize
super(nil)

19
src/vnm_mad/remotes/dummy/clean Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
exit 0

19
src/vnm_mad/remotes/dummy/post Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
exit 0

19
src/vnm_mad/remotes/dummy/pre Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
exit 0

View File

@ -14,15 +14,19 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'OpenNebulaNetwork'
class EbtablesVLAN < OpenNebulaNetwork
def initialize(vm, hypervisor = nil)
super(vm,hypervisor)
end
def ebtables(rule)
system("#{COMMANDS[:ebtables]} -A #{rule}")
OpenNebula.exec_and_log("#{COMMANDS[:ebtables]} -A #{rule}")
end
# Activates ebtables rules
#
def activate
process do |nic|
tap = nic[:tap]
@ -42,6 +46,8 @@ class EbtablesVLAN < OpenNebulaNetwork
ebtables(out_rule)
end
end
return 0
end
def deactivate
@ -59,6 +65,8 @@ class EbtablesVLAN < OpenNebulaNetwork
end
remove_rules(tap)
end
return 0
end
def rules
@ -74,6 +82,6 @@ class EbtablesVLAN < OpenNebulaNetwork
end
def remove_rule(rule)
system("#{COMMANDS[:ebtables]} -D FORWARD #{rule}")
OpenNebula.exec_and_log("#{COMMANDS[:ebtables]} -D FORWARD #{rule}")
end
end

View File

@ -17,21 +17,12 @@
#--------------------------------------------------------------------------- #
$: << File.dirname(__FILE__)
$: << File.join(File.dirname(__FILE__), "..")
require 'base64'
require 'OpenNebulaNetwork'
require 'Firewall'
require 'Ebtables'
action = ARGV[0]
template = ARGV[1]
template = ARGV[0]
vm_xml = Base64::decode64(template)
onevlan = EbtablesVLAN.from_base64(template)
fw = OpenNebulaFirewall.new(vm_xml)
case action
when "on"
fw.activate
when "off"
fw.deactivate
end
exit onevlan.deactivate

View File

@ -17,24 +17,9 @@
#--------------------------------------------------------------------------- #
$: << File.dirname(__FILE__)
$: << File.join(File.dirname(__FILE__), "..")
require 'base64'
require 'OpenNebulaNetwork'
require 'Ebtables'
action = ARGV[0]
template = ARGV[1]
# Uncomment to act only on the listed bridges.
#FILTERED_BRIDGES = ['br0']
vm_xml = Base64::decode64(template)
onevlan = EbtablesVLAN.new(vm_xml)
case action
when "on"
onevlan.filter(:bridge => FILTERED_BRIDGES) if defined? FILTERED_BRIDGES
onevlan.activate
when "off"
onevlan.deactivate
end
onevlan = EbtablesVLAN.from_base64(ARGV[0])
exit onevlan.activate

View File

@ -0,0 +1,19 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
exit 0

View File

@ -17,13 +17,11 @@
#--------------------------------------------------------------------------- #
$: << File.dirname(__FILE__)
$: << File.join(File.dirname(__FILE__), "..")
require 'base64'
require 'OpenNebulaNetwork'
require 'HostManaged'
require 'Firewall'
template = ARGV[0]
vm_xml = Base64::decode64(template)
fw = OpenNebulaFirewall.from_base64(ARGV[0])
hm = OpenNebulaHM.new(vm_xml)
hm.activate
fw.deactivate

View File

@ -17,13 +17,11 @@
#--------------------------------------------------------------------------- #
$: << File.dirname(__FILE__)
$: << File.join(File.dirname(__FILE__), "..")
require 'base64'
require 'OpenNebulaNetwork'
require 'OpenvSwitch'
require 'Firewall'
template = ARGV[0]
vm_xml = Base64::decode64(template)
fw = OpenNebulaFirewall.from_base64(ARGV[0])
onevlan = OpenvSwitchVLAN.new(vm_xml)
onevlan.activate
fw.activate

19
src/vnm_mad/remotes/fw/pre Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
exit 0

View File

@ -14,6 +14,8 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
require 'OpenNebulaNetwork'
class OpenvSwitchVLAN < OpenNebulaNetwork
def initialize(vm, hypervisor = nil)
super(vm,hypervisor)
@ -30,7 +32,9 @@ class OpenvSwitchVLAN < OpenNebulaNetwork
cmd = "#{COMMANDS[:ovs_vsctl]} set Port #{nic[:tap]} "
cmd << "tag=#{vlan}"
system(cmd)
OpenNebula.exec_and_log(cmd)
end
return 0
end
end

View File

@ -0,0 +1,19 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
exit 0

View File

@ -0,0 +1,25 @@
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
$: << File.dirname(__FILE__)
$: << File.join(File.dirname(__FILE__), "..")
require 'OpenvSwitch'
onevlan = OpenvSwitchVLAN.from_base64(ARGV[0])
exit onevlan.activate()

View File

@ -0,0 +1,19 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2011, 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. #
#--------------------------------------------------------------------------- #
exit 0

View File

@ -1,18 +1,24 @@
#!/usr/bin/env ruby
$: << File.dirname(__FILE__) + '/..' \
<< './'
$: << File.dirname(__FILE__) + '/..'
$: << File.dirname(__FILE__) + '/../ebtables'
$: << File.dirname(__FILE__) + '/../802.1Q'
$: << File.dirname(__FILE__) + '/../ovswitch'
$: << File.dirname(__FILE__) + '/../../../mad/ruby'
$: << './'
$: << File.dirname(__FILE__)
$: << File.join(File.dirname(__FILE__), '..')
$: << File.join(File.dirname(__FILE__),'../../../mad/ruby/')
require 'rubygems'
require 'rspec'
require 'SystemMock'
require 'pp'
require 'OpenNebulaNetwork'
require 'Ebtables'
require 'ebtables/Ebtables'
require 'Firewall'
require 'HostManaged'
require 'OpenvSwitch'
require '802.1Q/HostManaged'
require 'ovswitch/OpenvSwitch'
OUTPUT = Hash.new
Dir[File.dirname(__FILE__) + "/output/**"].each do |f|
@ -20,6 +26,9 @@ Dir[File.dirname(__FILE__) + "/output/**"].each do |f|
OUTPUT[key] = File.read(f)
end
require 'scripts_common'
require 'SystemMock'
include OpenNebula
include SystemMock
RSpec.configure do |config|
@ -36,40 +45,28 @@ describe 'networking' do
}
onevlan = OpenNebulaNetwork.new(OUTPUT[:onevm_show],"kvm")
nics_expected = [{:bridge=>"br0",
:ip=>"172.16.0.100",
:mac=>"02:00:ac:10:00:64",
:network=>"Small network",
:network_id=>"0",
:tap=>"vnet0"},
{:bridge=>"br1",
:ip=>"10.1.1.1",
:mac=>"02:00:0a:01:01:01",
:network=>"r1",
:network_id=>"1",
:tap=>"vnet1"},
{:bridge=>"br2",
:ip=>"10.1.2.1",
:mac=>"02:00:0a:01:02:01",
:network=>"r2",
:network_id=>"2",
:tap=>"vnet2"}]
onevlan.vm.nics.should == nics_expected
end
it "filter nics in kvm" do
$capture_commands = {
/virsh.*dumpxml/ => OUTPUT[:virsh_dumpxml]
}
onevlan = OpenNebulaNetwork.new(OUTPUT[:onevm_show],"kvm")
onevlan.filter(:bridge => "br1")
nics_expected = [{:bridge=>"br1",
:ip=>"172.16.0.100",
:mac=>"02:00:ac:10:00:64",
:network=>"Small network",
:network_id=>"0",
:vlan=>"YES",
:tap=>"vnet0"},
{:bridge=>"br1",
:ip=>"10.1.1.1",
:mac=>"02:00:0a:01:01:01",
:network=>"r1",
:network_id=>"1",
:tap=>"vnet1"}]
onevlan.vm.filtered_nics.should == nics_expected
:vlan=>"YES",
:tap=>"vnet1"},
{:bridge=>"br2",
:ip=>"10.1.2.1",
:mac=>"02:00:0a:01:02:01",
:network=>"r2",
:network_id=>"2",
:vlan=>"YES",
:tap=>"vnet2"}]
onevlan.vm.nics.should == nics_expected
end
end
@ -88,7 +85,10 @@ describe 'ebtables' do
"sudo /sbin/ebtables -A FORWARD -s ! 02:00:0a:01:01:01 -i vnet1 -j DROP",
"sudo /sbin/ebtables -A FORWARD -s ! 02:00:0a:01:02:00/ff:ff:ff:ff:ff:00 -o vnet2 -j DROP",
"sudo /sbin/ebtables -A FORWARD -s ! 02:00:0a:01:02:01 -i vnet2 -j DROP"]
$collector[:system].should == ebtables_cmds
ebtables_cmds.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd|
$collector[:backtick].include?(cmd).should == true
end
end
end
@ -106,7 +106,9 @@ describe 'openvswitch' do
"sudo /usr/local/bin/ovs-vsctl set Port vnet2 tag=4"
]
$collector[:system].should == openvswitch_tags
openvswitch_tags.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd|
$collector[:backtick].include?(cmd).should == true
end
end
it "force VLAN_ID for Open vSwitch vlans in kvm" do
@ -117,12 +119,14 @@ describe 'openvswitch' do
}
onevlan = OpenvSwitchVLAN.new(OUTPUT[:onevm_show_vlan_id_kvm],"kvm")
onevlan.activate
onevlan_rules = ["sudo /usr/local/bin/ovs-vsctl set Port vnet0 tag=6",
"sudo /usr/local/bin/ovs-vsctl set Port vnet1 tag=50",
"sudo /usr/local/bin/ovs-vsctl set Port vnet1 tag=51"]
$collector[:system].should == onevlan_rules
onevlan_rules.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd|
$collector[:backtick].include?(cmd).should == true
end
end
end
@ -146,7 +150,9 @@ describe 'firewall' do
"sudo /sbin/iptables -A one-36-3 -p icmp -m state --state ESTABLISHED -j ACCEPT",
"sudo /sbin/iptables -A one-36-3 -p icmp -j DROP"]
$collector[:system].should == fw_activate_rules
fw_activate_rules.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd|
$collector[:backtick].include?(cmd).should == true
end
end
end
@ -155,20 +161,23 @@ describe 'host-managed' do
$capture_commands = {
/virsh.*dumpxml/ => OUTPUT[:virsh_dumpxml_phydev],
/brctl show/ => OUTPUT[:brctl_show],
/brctl add/ => nil,
/vconfig/ => nil,
/ip link/ => nil
/brctl add/ => nil,
/vconfig/ => nil,
/ip link/ => nil
}
hm = OpenNebulaHM.new(OUTPUT[:onevm_show_phydev_kvm],"kvm")
hm.activate
hm_activate_rules = ["sudo /usr/sbin/brctl addbr onebr6",
hm_activate_rules = ["sudo /sbin/brctl addbr onebr6",
"sudo /sbin/ip link set onebr6 up",
"sudo /sbin/ip link show eth0.8",
"sudo /sbin/vconfig add eth0 8",
"sudo /sbin/ip link set eth0.8 up",
"sudo /usr/sbin/brctl addif onebr6 eth0.8"]
$collector[:system].should == hm_activate_rules
"sudo /sbin/brctl addif onebr6 eth0.8"]
hm_activate_rules.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd|
$collector[:backtick].include?(cmd).should == true
end
end
it "force VLAN_ID for vlans in kvm" do
@ -182,19 +191,21 @@ describe 'host-managed' do
hm = OpenNebulaHM.new(OUTPUT[:onevm_show_vlan_id_kvm],"kvm")
hm.activate
hm_vlan_id = ["sudo /usr/sbin/brctl addbr onebr10",
hm_vlan_id = ["sudo /sbin/brctl addbr onebr10",
"sudo /sbin/ip link set onebr10 up",
"sudo /sbin/ip link show eth0.50",
"sudo /sbin/vconfig add eth0 50",
"sudo /sbin/ip link set eth0.50 up",
"sudo /usr/sbin/brctl addif onebr10 eth0.50",
"sudo /usr/sbin/brctl addbr specialbr",
"sudo /sbin/brctl addif onebr10 eth0.50",
"sudo /sbin/brctl addbr specialbr",
"sudo /sbin/ip link set specialbr up",
"sudo /sbin/ip link show eth0.51",
"sudo /sbin/vconfig add eth0 51",
"sudo /sbin/ip link set eth0.51 up",
"sudo /usr/sbin/brctl addif specialbr eth0.51"]
"sudo /sbin/brctl addif specialbr eth0.51"]
$collector[:system].should == hm_vlan_id
hm_vlan_id.map{|c| c + " 2>&1 1>/dev/null"}.each do |cmd|
$collector[:backtick].include?(cmd).should == true
end
end
end

View File

@ -1,14 +1,15 @@
module SystemMock
require 'open3'
def execute_cmd(cmd)
if $capture_commands
$capture_commands.each do |regex, output|
if cmd.match(regex)
Kernel.send(:`,":;exit 0")
return output
end
end
end
Open3.popen3(cmd){|stdin, stdout, stderr| stdout.read}
Kernel.send(:`,cmd)
end
def `(cmd)

View File

@ -37,6 +37,7 @@
<MAC><![CDATA[02:00:ac:10:00:64]]></MAC>
<NETWORK><![CDATA[Small network]]></NETWORK>
<NETWORK_ID><![CDATA[0]]></NETWORK_ID>
<VLAN><![CDATA[YES]]></VLAN>
</NIC>
<NIC>
<BRIDGE><![CDATA[br1]]></BRIDGE>
@ -44,6 +45,7 @@
<MAC><![CDATA[02:00:0a:01:01:01]]></MAC>
<NETWORK><![CDATA[r1]]></NETWORK>
<NETWORK_ID><![CDATA[1]]></NETWORK_ID>
<VLAN><![CDATA[YES]]></VLAN>
</NIC>
<NIC>
<BRIDGE><![CDATA[br2]]></BRIDGE>
@ -51,6 +53,7 @@
<MAC><![CDATA[02:00:0a:01:02:01]]></MAC>
<NETWORK><![CDATA[r2]]></NETWORK>
<NETWORK_ID><![CDATA[2]]></NETWORK_ID>
<VLAN><![CDATA[YES]]></VLAN>
</NIC>
<VMID><![CDATA[2]]></VMID>
</TEMPLATE>

View File

@ -37,6 +37,7 @@
<MAC><![CDATA[02:00:c0:a8:00:65]]></MAC>
<NETWORK><![CDATA[ursa-dev]]></NETWORK>
<NETWORK_ID><![CDATA[4]]></NETWORK_ID>
<VLAN><![CDATA[YES]]></VLAN>
</NIC>
<NIC>
<BRIDGE><![CDATA[onebr6]]></BRIDGE>
@ -45,6 +46,7 @@
<NETWORK><![CDATA[vlan-dev]]></NETWORK>
<NETWORK_ID><![CDATA[6]]></NETWORK_ID>
<PHYDEV><![CDATA[eth0]]></PHYDEV>
<VLAN><![CDATA[YES]]></VLAN>
</NIC>
<VMID><![CDATA[9]]></VMID>
</TEMPLATE>

View File

@ -37,6 +37,7 @@
<MAC><![CDATA[02:00:c0:a8:00:67]]></MAC>
<NETWORK><![CDATA[ursa-dev]]></NETWORK>
<NETWORK_ID><![CDATA[4]]></NETWORK_ID>
<VLAN><![CDATA[YES]]></VLAN>
</NIC>
<NIC>
<BRIDGE><![CDATA[onebr10]]></BRIDGE>
@ -45,6 +46,7 @@
<NETWORK><![CDATA[vlan50]]></NETWORK>
<NETWORK_ID><![CDATA[10]]></NETWORK_ID>
<PHYDEV><![CDATA[eth0]]></PHYDEV>
<VLAN><![CDATA[YES]]></VLAN>
<VLAN_ID><![CDATA[50]]></VLAN_ID>
</NIC>
<NIC>
@ -54,6 +56,7 @@
<NETWORK><![CDATA[vlan51]]></NETWORK>
<NETWORK_ID><![CDATA[11]]></NETWORK_ID>
<PHYDEV><![CDATA[eth0]]></PHYDEV>
<VLAN><![CDATA[YES]]></VLAN>
<VLAN_ID><![CDATA[51]]></VLAN_ID>
</NIC>
<VMID><![CDATA[22]]></VMID>

View File

@ -33,6 +33,7 @@
<MAC><![CDATA[02:00:ac:10:00:cb]]></MAC>
<NETWORK><![CDATA[virt-net]]></NETWORK>
<NETWORK_ID><![CDATA[3]]></NETWORK_ID>
<VLAN><![CDATA[YES]]></VLAN>
<WHITE_PORTS_TCP><![CDATA[22,80]]></WHITE_PORTS_TCP>
</NIC>
<NIC>
@ -42,6 +43,7 @@
<NETWORK><![CDATA[phy]]></NETWORK>
<NETWORK_ID><![CDATA[2]]></NETWORK_ID>
<PHYDEV><![CDATA[eth0]]></PHYDEV>
<VLAN><![CDATA[YES]]></VLAN>
</NIC>
<OS>
<INITRD><![CDATA[/srv/cloud/one/ttylinux-xen/initrd.gz]]></INITRD>

View File

@ -1,9 +1,8 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* A Bison parser, made by GNU Bison 2.5. */
/* Skeleton implementation for Bison's Yacc-like parsers in C
/* Bison implementation for Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2009, 2010 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -45,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
#define YYBISON_VERSION "2.4.3"
#define YYBISON_VERSION "2.5"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@ -74,7 +73,7 @@
/* Copy the first part of user declarations. */
/* Line 189 of yacc.c */
/* Line 268 of yacc.c */
#line 17 "expr_arith.y"
#include <iostream>
@ -130,8 +129,8 @@ extern "C"
/* Line 189 of yacc.c */
#line 135 "expr_arith.cc"
/* Line 268 of yacc.c */
#line 134 "expr_arith.cc"
/* Enabling traces. */
#ifndef YYDEBUG
@ -170,7 +169,7 @@ extern "C"
typedef union YYSTYPE
{
/* Line 214 of yacc.c */
/* Line 293 of yacc.c */
#line 78 "expr_arith.y"
char * val_str;
@ -179,8 +178,8 @@ typedef union YYSTYPE
/* Line 214 of yacc.c */
#line 184 "expr_arith.cc"
/* Line 293 of yacc.c */
#line 183 "expr_arith.cc"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@ -204,8 +203,8 @@ typedef struct YYLTYPE
/* Copy the second part of user declarations. */
/* Line 264 of yacc.c */
#line 209 "expr_arith.cc"
/* Line 343 of yacc.c */
#line 208 "expr_arith.cc"
#ifdef short
# undef short
@ -308,11 +307,11 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef _STDLIB_H
# define _STDLIB_H 1
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# endif
@ -335,24 +334,24 @@ YYID (yyi)
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
# if (defined __cplusplus && ! defined _STDLIB_H \
# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef _STDLIB_H
# define _STDLIB_H 1
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
@ -383,23 +382,7 @@ union yyalloc
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ 2 * YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
while (YYID (0))
# endif
# endif
# define YYCOPY_NEEDED 1
/* Relocate STACK from its old location to the new one. The
local variables YYSIZE and YYSTACKSIZE give the old and new number of
@ -419,6 +402,26 @@ union yyalloc
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
while (YYID (0))
# endif
# endif
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 10
/* YYLAST -- Last index in YYTABLE. */
@ -532,8 +535,8 @@ static const yytype_uint8 yyr2[] =
3, 2, 3
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
STATE-NUM when YYTABLE doesn't specify something else to do. Zero
/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
Performed when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
@ -564,8 +567,7 @@ static const yytype_int8 yypgoto[] =
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
number is the opposite. If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
@ -574,6 +576,12 @@ static const yytype_uint8 yytable[] =
4, 5, 11, 12, 13, 14
};
#define yypact_value_is_default(yystate) \
((yystate) == (-5))
#define yytable_value_is_error(yytable_value) \
YYID (0)
static const yytype_int8 yycheck[] =
{
1, 5, 6, -1, 5, 0, 3, 4, 5, 6,
@ -622,7 +630,6 @@ do \
{ \
yychar = (Token); \
yylval = (Value); \
yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
@ -890,7 +897,6 @@ int yydebug;
# define YYMAXDEPTH 10000
#endif
#if YYERROR_VERBOSE
@ -993,115 +999,142 @@ yytnamerr (char *yyres, const char *yystr)
}
# endif
/* Copy into YYRESULT an error message about the unexpected token
YYCHAR while in state YYSTATE. Return the number of bytes copied,
including the terminating null byte. If YYRESULT is null, do not
copy anything; just return the number of bytes that would be
copied. As a special case, return 0 if an ordinary "syntax error"
message will do. Return YYSIZE_MAXIMUM if overflow occurs during
size calculation. */
static YYSIZE_T
yysyntax_error (char *yyresult, int yystate, int yychar)
/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
about the unexpected token YYTOKEN for the state stack whose top is
YYSSP.
Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
not large enough to hold the message. In that case, also set
*YYMSG_ALLOC to the required number of bytes. Return 2 if the
required number of bytes is too large to store. */
static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
int yyn = yypact[yystate];
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
YYSIZE_T yysize1;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
const char *yyformat = 0;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
"expected"). */
int yycount = 0;
if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
return 0;
else
/* There are many possibilities here to consider:
- Assume YYFAIL is not used. It's too flawed to consider. See
<http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
for details. YYERROR is fine as it does not invoke this
function.
- If this state is a consistent state with a default action, then
the only way this function was invoked is if the default action
is an error action. In that case, don't check for expected
tokens because there are none.
- The only way there can be no lookahead present (in yychar) is if
this state is a consistent state with a default action. Thus,
detecting the absence of a lookahead is sufficient to determine
that there is no unexpected or expected token to report. In that
case, just report a simple "syntax error".
- Don't assume there isn't a lookahead just because this state is a
consistent state with a default action. There might have been a
previous inconsistent state, consistent state with a non-default
action, or user semantic action that manipulated yychar.
- Of course, the expected token list depends on states to have
correct lookahead information, and it depends on the parser not
to perform extra reductions after fetching a lookahead from the
scanner and before detecting a syntax error. Thus, state merging
(from LALR or IELR) and default reductions corrupt the expected
token list. However, the list is correct for canonical LR with
one exception: it will still contain any token that will not be
accepted due to an error action in a later state.
*/
if (yytoken != YYEMPTY)
{
int yytype = YYTRANSLATE (yychar);
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
YYSIZE_T yysize = yysize0;
YYSIZE_T yysize1;
int yysize_overflow = 0;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
int yyx;
int yyn = yypact[*yyssp];
yyarg[yycount++] = yytname[yytoken];
if (!yypact_value_is_default (yyn))
{
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. In other words, skip the first -YYN actions for
this state because they are default actions. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yyx;
# if 0
/* This is so xgettext sees the translatable formats that are
constructed on the fly. */
YY_("syntax error, unexpected %s");
YY_("syntax error, unexpected %s, expecting %s");
YY_("syntax error, unexpected %s, expecting %s or %s");
YY_("syntax error, unexpected %s, expecting %s or %s or %s");
YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
# endif
char *yyfmt;
char const *yyf;
static char const yyunexpected[] = "syntax error, unexpected %s";
static char const yyexpecting[] = ", expecting %s";
static char const yyor[] = " or %s";
char yyformat[sizeof yyunexpected
+ sizeof yyexpecting - 1
+ ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
* (sizeof yyor - 1))];
char const *yyprefix = yyexpecting;
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yycount = 1;
yyarg[0] = yytname[yytype];
yyfmt = yystpcpy (yyformat, yyunexpected);
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
yycount = 1;
yysize = yysize0;
yyformat[sizeof yyunexpected - 1] = '\0';
break;
}
yyarg[yycount++] = yytname[yyx];
yysize1 = yysize + yytnamerr (0, yytname[yyx]);
yysize_overflow |= (yysize1 < yysize);
yysize = yysize1;
yyfmt = yystpcpy (yyfmt, yyprefix);
yyprefix = yyor;
}
yyf = YY_(yyformat);
yysize1 = yysize + yystrlen (yyf);
yysize_overflow |= (yysize1 < yysize);
yysize = yysize1;
if (yysize_overflow)
return YYSIZE_MAXIMUM;
if (yyresult)
{
/* Avoid sprintf, as that infringes on the user's name space.
Don't have undefined behavior even if the translation
produced a string with the wrong number of "%s"s. */
char *yyp = yyresult;
int yyi = 0;
while ((*yyp = *yyf) != '\0')
{
if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
{
yyp += yytnamerr (yyp, yyarg[yyi++]);
yyf += 2;
}
else
{
yyp++;
yyf++;
}
}
}
return yysize;
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
&& !yytable_value_is_error (yytable[yyx + yyn]))
{
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
yycount = 1;
yysize = yysize0;
break;
}
yyarg[yycount++] = yytname[yyx];
yysize1 = yysize + yytnamerr (0, yytname[yyx]);
if (! (yysize <= yysize1
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
yysize = yysize1;
}
}
}
switch (yycount)
{
# define YYCASE_(N, S) \
case N: \
yyformat = S; \
break
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
# undef YYCASE_
}
yysize1 = yysize + yystrlen (yyformat);
if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
yysize = yysize1;
if (*yymsg_alloc < yysize)
{
*yymsg_alloc = 2 * yysize;
if (! (yysize <= *yymsg_alloc
&& *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
*yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
return 1;
}
/* Avoid sprintf, as that infringes on the user's name space.
Don't have undefined behavior even if the translation
produced a string with the wrong number of "%s"s. */
{
char *yyp = *yymsg;
int yyi = 0;
while ((*yyp = *yyformat) != '\0')
if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
{
yyp += yytnamerr (yyp, yyarg[yyi++]);
yyformat += 2;
}
else
{
yyp++;
yyformat++;
}
}
return 0;
}
#endif /* YYERROR_VERBOSE */
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
@ -1144,6 +1177,7 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, mc, oxml, result, error_msg)
}
}
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
@ -1160,12 +1194,9 @@ int yyparse ();
#endif /* ! YYPARSE_PARAM */
/*-------------------------.
| yyparse or yypush_parse. |
`-------------------------*/
/*----------.
| yyparse. |
`----------*/
#ifdef YYPARSE_PARAM
#if (defined __STDC__ || defined __C99__FUNC__ \
@ -1381,7 +1412,7 @@ yybackup:
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
if (yypact_value_is_default (yyn))
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
@ -1412,8 +1443,8 @@ yybackup:
yyn = yytable[yyn];
if (yyn <= 0)
{
if (yyn == 0 || yyn == YYTABLE_NINF)
goto yyerrlab;
if (yytable_value_is_error (yyn))
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
@ -1469,21 +1500,21 @@ yyreduce:
{
case 2:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 100 "expr_arith.y"
{ result = static_cast<int>((yyvsp[(1) - (1)].val_float));;}
{ result = static_cast<int>((yyvsp[(1) - (1)].val_float));}
break;
case 3:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 101 "expr_arith.y"
{ result = 0; ;}
{ result = 0; }
break;
case 4:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 104 "expr_arith.y"
{ float val = 0.0;
@ -1509,71 +1540,82 @@ yyreduce:
}
(yyval.val_float) = val;
;}
}
break;
case 5:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 129 "expr_arith.y"
{ (yyval.val_float) = (yyvsp[(1) - (1)].val_float); ;}
{ (yyval.val_float) = (yyvsp[(1) - (1)].val_float); }
break;
case 6:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 130 "expr_arith.y"
{ (yyval.val_float) = static_cast<float>((yyvsp[(1) - (1)].val_int)); ;}
{ (yyval.val_float) = static_cast<float>((yyvsp[(1) - (1)].val_int)); }
break;
case 7:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 131 "expr_arith.y"
{ (yyval.val_float) = (yyvsp[(1) - (3)].val_float) + (yyvsp[(3) - (3)].val_float);;}
{ (yyval.val_float) = (yyvsp[(1) - (3)].val_float) + (yyvsp[(3) - (3)].val_float);}
break;
case 8:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 132 "expr_arith.y"
{ (yyval.val_float) = (yyvsp[(1) - (3)].val_float) - (yyvsp[(3) - (3)].val_float);;}
{ (yyval.val_float) = (yyvsp[(1) - (3)].val_float) - (yyvsp[(3) - (3)].val_float);}
break;
case 9:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 133 "expr_arith.y"
{ (yyval.val_float) = (yyvsp[(1) - (3)].val_float) * (yyvsp[(3) - (3)].val_float);;}
{ (yyval.val_float) = (yyvsp[(1) - (3)].val_float) * (yyvsp[(3) - (3)].val_float);}
break;
case 10:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 134 "expr_arith.y"
{ (yyval.val_float) = (yyvsp[(1) - (3)].val_float) / (yyvsp[(3) - (3)].val_float);;}
{ (yyval.val_float) = (yyvsp[(1) - (3)].val_float) / (yyvsp[(3) - (3)].val_float);}
break;
case 11:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 135 "expr_arith.y"
{ (yyval.val_float) = - (yyvsp[(2) - (2)].val_float);;}
{ (yyval.val_float) = - (yyvsp[(2) - (2)].val_float);}
break;
case 12:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 136 "expr_arith.y"
{ (yyval.val_float) = (yyvsp[(2) - (3)].val_float);;}
{ (yyval.val_float) = (yyvsp[(2) - (3)].val_float);}
break;
/* Line 1464 of yacc.c */
#line 1575 "expr_arith.cc"
/* Line 1806 of yacc.c */
#line 1606 "expr_arith.cc"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
that yytoken be updated with the new translation. We take the
approach of translating immediately before every use of yytoken.
One alternative is translating here after every semantic action,
but that translation would be missed if the semantic action invokes
YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
incorrect destructor might then be invoked immediately. In the
case of YYERROR or YYBACKUP, subsequent parser actions might lead
to an incorrect destructor call or verbose syntax error message
before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
@ -1602,6 +1644,10 @@ yyreduce:
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
@ -1609,37 +1655,36 @@ yyerrlab:
#if ! YYERROR_VERBOSE
yyerror (&yylloc, mc, oxml, result, error_msg, YY_("syntax error"));
#else
# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
yyssp, yytoken)
{
YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
{
YYSIZE_T yyalloc = 2 * yysize;
if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
yyalloc = YYSTACK_ALLOC_MAXIMUM;
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yyalloc);
if (yymsg)
yymsg_alloc = yyalloc;
else
{
yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf;
}
}
if (0 < yysize && yysize <= yymsg_alloc)
{
(void) yysyntax_error (yymsg, yystate, yychar);
yyerror (&yylloc, mc, oxml, result, error_msg, yymsg);
}
else
{
yyerror (&yylloc, mc, oxml, result, error_msg, YY_("syntax error"));
if (yysize != 0)
goto yyexhaustedlab;
}
char const *yymsgp = YY_("syntax error");
int yysyntax_error_status;
yysyntax_error_status = YYSYNTAX_ERROR;
if (yysyntax_error_status == 0)
yymsgp = yymsg;
else if (yysyntax_error_status == 1)
{
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
if (!yymsg)
{
yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf;
yysyntax_error_status = 2;
}
else
{
yysyntax_error_status = YYSYNTAX_ERROR;
yymsgp = yymsg;
}
}
yyerror (&yylloc, mc, oxml, result, error_msg, yymsgp);
if (yysyntax_error_status == 2)
goto yyexhaustedlab;
}
# undef YYSYNTAX_ERROR
#endif
}
@ -1699,7 +1744,7 @@ yyerrlab1:
for (;;)
{
yyn = yypact[yystate];
if (yyn != YYPACT_NINF)
if (!yypact_value_is_default (yyn))
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@ -1763,8 +1808,13 @@ yyexhaustedlab:
yyreturn:
if (yychar != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval, &yylloc, mc, oxml, result, error_msg);
{
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = YYTRANSLATE (yychar);
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval, &yylloc, mc, oxml, result, error_msg);
}
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
@ -1789,7 +1839,7 @@ yyreturn:
/* Line 1684 of yacc.c */
/* Line 2067 of yacc.c */
#line 139 "expr_arith.y"

View File

@ -1,9 +1,8 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* A Bison parser, made by GNU Bison 2.5. */
/* Skeleton interface for Bison's Yacc-like parsers in C
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2009, 2010 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -50,7 +49,7 @@
typedef union YYSTYPE
{
/* Line 1685 of yacc.c */
/* Line 2068 of yacc.c */
#line 78 "expr_arith.y"
char * val_str;
@ -59,8 +58,8 @@ typedef union YYSTYPE
/* Line 1685 of yacc.c */
#line 64 "expr_arith.hh"
/* Line 2068 of yacc.c */
#line 63 "expr_arith.hh"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */

View File

@ -1,9 +1,8 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* A Bison parser, made by GNU Bison 2.5. */
/* Skeleton implementation for Bison's Yacc-like parsers in C
/* Bison implementation for Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2009, 2010 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -45,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
#define YYBISON_VERSION "2.4.3"
#define YYBISON_VERSION "2.5"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@ -74,7 +73,7 @@
/* Copy the first part of user declarations. */
/* Line 189 of yacc.c */
/* Line 268 of yacc.c */
#line 17 "expr_bool.y"
#include <iostream>
@ -135,8 +134,8 @@ void get_xml_attribute(ObjectXML * oxml, const char* attr, string& val);
/* Line 189 of yacc.c */
#line 140 "expr_bool.cc"
/* Line 268 of yacc.c */
#line 139 "expr_bool.cc"
/* Enabling traces. */
#ifndef YYDEBUG
@ -175,7 +174,7 @@ void get_xml_attribute(ObjectXML * oxml, const char* attr, string& val);
typedef union YYSTYPE
{
/* Line 214 of yacc.c */
/* Line 293 of yacc.c */
#line 83 "expr_bool.y"
char * val_str;
@ -184,8 +183,8 @@ typedef union YYSTYPE
/* Line 214 of yacc.c */
#line 189 "expr_bool.cc"
/* Line 293 of yacc.c */
#line 188 "expr_bool.cc"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@ -209,8 +208,8 @@ typedef struct YYLTYPE
/* Copy the second part of user declarations. */
/* Line 264 of yacc.c */
#line 214 "expr_bool.cc"
/* Line 343 of yacc.c */
#line 213 "expr_bool.cc"
#ifdef short
# undef short
@ -313,11 +312,11 @@ YYID (yyi)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef _STDLIB_H
# define _STDLIB_H 1
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# endif
@ -340,24 +339,24 @@ YYID (yyi)
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
# if (defined __cplusplus && ! defined _STDLIB_H \
# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
# ifndef _STDLIB_H
# define _STDLIB_H 1
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
@ -388,23 +387,7 @@ union yyalloc
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ 2 * YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
while (YYID (0))
# endif
# endif
# define YYCOPY_NEEDED 1
/* Relocate STACK from its old location to the new one. The
local variables YYSIZE and YYSTACKSIZE give the old and new number of
@ -424,6 +407,26 @@ union yyalloc
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
/* Copy COUNT objects from FROM to TO. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(To, From, Count) \
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
# else
# define YYCOPY(To, From, Count) \
do \
{ \
YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
while (YYID (0))
# endif
# endif
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 12
/* YYLAST -- Last index in YYTABLE. */
@ -540,8 +543,8 @@ static const yytype_uint8 yyr2[] =
3, 3, 3, 4, 3, 3, 2, 3
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
STATE-NUM when YYTABLE doesn't specify something else to do. Zero
/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
Performed when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
@ -574,8 +577,7 @@ static const yytype_int8 yypgoto[] =
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
number is the opposite. If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
@ -584,6 +586,12 @@ static const yytype_uint8 yytable[] =
16, 17, 18, 26, 27, 28, 19, 21, 20, 22
};
#define yypact_value_is_default(yystate) \
((yystate) == (-6))
#define yytable_value_is_error(yytable_value) \
YYID (0)
static const yytype_int8 yycheck[] =
{
1, 3, 3, 0, 9, 7, 4, 5, 4, 5,
@ -633,7 +641,6 @@ do \
{ \
yychar = (Token); \
yylval = (Value); \
yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
@ -901,7 +908,6 @@ int yydebug;
# define YYMAXDEPTH 10000
#endif
#if YYERROR_VERBOSE
@ -1004,115 +1010,142 @@ yytnamerr (char *yyres, const char *yystr)
}
# endif
/* Copy into YYRESULT an error message about the unexpected token
YYCHAR while in state YYSTATE. Return the number of bytes copied,
including the terminating null byte. If YYRESULT is null, do not
copy anything; just return the number of bytes that would be
copied. As a special case, return 0 if an ordinary "syntax error"
message will do. Return YYSIZE_MAXIMUM if overflow occurs during
size calculation. */
static YYSIZE_T
yysyntax_error (char *yyresult, int yystate, int yychar)
/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
about the unexpected token YYTOKEN for the state stack whose top is
YYSSP.
Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
not large enough to hold the message. In that case, also set
*YYMSG_ALLOC to the required number of bytes. Return 2 if the
required number of bytes is too large to store. */
static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
int yyn = yypact[yystate];
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
YYSIZE_T yysize1;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
const char *yyformat = 0;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
"expected"). */
int yycount = 0;
if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
return 0;
else
/* There are many possibilities here to consider:
- Assume YYFAIL is not used. It's too flawed to consider. See
<http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
for details. YYERROR is fine as it does not invoke this
function.
- If this state is a consistent state with a default action, then
the only way this function was invoked is if the default action
is an error action. In that case, don't check for expected
tokens because there are none.
- The only way there can be no lookahead present (in yychar) is if
this state is a consistent state with a default action. Thus,
detecting the absence of a lookahead is sufficient to determine
that there is no unexpected or expected token to report. In that
case, just report a simple "syntax error".
- Don't assume there isn't a lookahead just because this state is a
consistent state with a default action. There might have been a
previous inconsistent state, consistent state with a non-default
action, or user semantic action that manipulated yychar.
- Of course, the expected token list depends on states to have
correct lookahead information, and it depends on the parser not
to perform extra reductions after fetching a lookahead from the
scanner and before detecting a syntax error. Thus, state merging
(from LALR or IELR) and default reductions corrupt the expected
token list. However, the list is correct for canonical LR with
one exception: it will still contain any token that will not be
accepted due to an error action in a later state.
*/
if (yytoken != YYEMPTY)
{
int yytype = YYTRANSLATE (yychar);
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
YYSIZE_T yysize = yysize0;
YYSIZE_T yysize1;
int yysize_overflow = 0;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
int yyx;
int yyn = yypact[*yyssp];
yyarg[yycount++] = yytname[yytoken];
if (!yypact_value_is_default (yyn))
{
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. In other words, skip the first -YYN actions for
this state because they are default actions. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yyx;
# if 0
/* This is so xgettext sees the translatable formats that are
constructed on the fly. */
YY_("syntax error, unexpected %s");
YY_("syntax error, unexpected %s, expecting %s");
YY_("syntax error, unexpected %s, expecting %s or %s");
YY_("syntax error, unexpected %s, expecting %s or %s or %s");
YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
# endif
char *yyfmt;
char const *yyf;
static char const yyunexpected[] = "syntax error, unexpected %s";
static char const yyexpecting[] = ", expecting %s";
static char const yyor[] = " or %s";
char yyformat[sizeof yyunexpected
+ sizeof yyexpecting - 1
+ ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
* (sizeof yyor - 1))];
char const *yyprefix = yyexpecting;
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yycount = 1;
yyarg[0] = yytname[yytype];
yyfmt = yystpcpy (yyformat, yyunexpected);
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
yycount = 1;
yysize = yysize0;
yyformat[sizeof yyunexpected - 1] = '\0';
break;
}
yyarg[yycount++] = yytname[yyx];
yysize1 = yysize + yytnamerr (0, yytname[yyx]);
yysize_overflow |= (yysize1 < yysize);
yysize = yysize1;
yyfmt = yystpcpy (yyfmt, yyprefix);
yyprefix = yyor;
}
yyf = YY_(yyformat);
yysize1 = yysize + yystrlen (yyf);
yysize_overflow |= (yysize1 < yysize);
yysize = yysize1;
if (yysize_overflow)
return YYSIZE_MAXIMUM;
if (yyresult)
{
/* Avoid sprintf, as that infringes on the user's name space.
Don't have undefined behavior even if the translation
produced a string with the wrong number of "%s"s. */
char *yyp = yyresult;
int yyi = 0;
while ((*yyp = *yyf) != '\0')
{
if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
{
yyp += yytnamerr (yyp, yyarg[yyi++]);
yyf += 2;
}
else
{
yyp++;
yyf++;
}
}
}
return yysize;
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
&& !yytable_value_is_error (yytable[yyx + yyn]))
{
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
yycount = 1;
yysize = yysize0;
break;
}
yyarg[yycount++] = yytname[yyx];
yysize1 = yysize + yytnamerr (0, yytname[yyx]);
if (! (yysize <= yysize1
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
yysize = yysize1;
}
}
}
switch (yycount)
{
# define YYCASE_(N, S) \
case N: \
yyformat = S; \
break
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
# undef YYCASE_
}
yysize1 = yysize + yystrlen (yyformat);
if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
yysize = yysize1;
if (*yymsg_alloc < yysize)
{
*yymsg_alloc = 2 * yysize;
if (! (yysize <= *yymsg_alloc
&& *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
*yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
return 1;
}
/* Avoid sprintf, as that infringes on the user's name space.
Don't have undefined behavior even if the translation
produced a string with the wrong number of "%s"s. */
{
char *yyp = *yymsg;
int yyi = 0;
while ((*yyp = *yyformat) != '\0')
if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
{
yyp += yytnamerr (yyp, yyarg[yyi++]);
yyformat += 2;
}
else
{
yyp++;
yyformat++;
}
}
return 0;
}
#endif /* YYERROR_VERBOSE */
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
@ -1155,6 +1188,7 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp, mc, oxml, result, error_msg)
}
}
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
@ -1171,12 +1205,9 @@ int yyparse ();
#endif /* ! YYPARSE_PARAM */
/*-------------------------.
| yyparse or yypush_parse. |
`-------------------------*/
/*----------.
| yyparse. |
`----------*/
#ifdef YYPARSE_PARAM
#if (defined __STDC__ || defined __C99__FUNC__ \
@ -1392,7 +1423,7 @@ yybackup:
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
if (yypact_value_is_default (yyn))
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
@ -1423,8 +1454,8 @@ yybackup:
yyn = yytable[yyn];
if (yyn <= 0)
{
if (yyn == 0 || yyn == YYTABLE_NINF)
goto yyerrlab;
if (yytable_value_is_error (yyn))
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
@ -1480,152 +1511,163 @@ yyreduce:
{
case 2:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 103 "expr_bool.y"
{ result=(yyvsp[(1) - (1)].val_int); ;}
{ result=(yyvsp[(1) - (1)].val_int); }
break;
case 3:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 104 "expr_bool.y"
{ result=true; ;}
{ result=true; }
break;
case 4:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 107 "expr_bool.y"
{ int val;
get_xml_attribute(oxml,(yyvsp[(1) - (3)].val_str),val);
(yyval.val_int) = val == (yyvsp[(3) - (3)].val_int);;}
(yyval.val_int) = val == (yyvsp[(3) - (3)].val_int);}
break;
case 5:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 112 "expr_bool.y"
{ int val;
get_xml_attribute(oxml,(yyvsp[(1) - (4)].val_str),val);
(yyval.val_int) = val != (yyvsp[(4) - (4)].val_int);;}
(yyval.val_int) = val != (yyvsp[(4) - (4)].val_int);}
break;
case 6:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 117 "expr_bool.y"
{ int val;
get_xml_attribute(oxml,(yyvsp[(1) - (3)].val_str),val);
(yyval.val_int) = val > (yyvsp[(3) - (3)].val_int);;}
(yyval.val_int) = val > (yyvsp[(3) - (3)].val_int);}
break;
case 7:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 122 "expr_bool.y"
{ int val;
get_xml_attribute(oxml,(yyvsp[(1) - (3)].val_str),val);
(yyval.val_int) = val < (yyvsp[(3) - (3)].val_int);;}
(yyval.val_int) = val < (yyvsp[(3) - (3)].val_int);}
break;
case 8:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 127 "expr_bool.y"
{ float val;
get_xml_attribute(oxml,(yyvsp[(1) - (3)].val_str),val);
(yyval.val_int) = val == (yyvsp[(3) - (3)].val_float);;}
(yyval.val_int) = val == (yyvsp[(3) - (3)].val_float);}
break;
case 9:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 132 "expr_bool.y"
{ float val;
get_xml_attribute(oxml,(yyvsp[(1) - (4)].val_str),val);
(yyval.val_int) = val != (yyvsp[(4) - (4)].val_float);;}
(yyval.val_int) = val != (yyvsp[(4) - (4)].val_float);}
break;
case 10:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 137 "expr_bool.y"
{ float val;
get_xml_attribute(oxml,(yyvsp[(1) - (3)].val_str),val);
(yyval.val_int) = val > (yyvsp[(3) - (3)].val_float);;}
(yyval.val_int) = val > (yyvsp[(3) - (3)].val_float);}
break;
case 11:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 142 "expr_bool.y"
{ float val;
get_xml_attribute(oxml,(yyvsp[(1) - (3)].val_str),val);
(yyval.val_int) = val < (yyvsp[(3) - (3)].val_float);;}
(yyval.val_int) = val < (yyvsp[(3) - (3)].val_float);}
break;
case 12:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 147 "expr_bool.y"
{ string val;
get_xml_attribute(oxml,(yyvsp[(1) - (3)].val_str),val);
(yyval.val_int) = (val.empty() || (yyvsp[(3) - (3)].val_str)==0) ? false : fnmatch((yyvsp[(3) - (3)].val_str),val.c_str(),0)==0;;}
(yyval.val_int) = (val.empty() || (yyvsp[(3) - (3)].val_str)==0) ? false : fnmatch((yyvsp[(3) - (3)].val_str),val.c_str(),0)==0;}
break;
case 13:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 152 "expr_bool.y"
{ string val;
get_xml_attribute(oxml,(yyvsp[(1) - (4)].val_str),val);
(yyval.val_int) = (val.empty() || (yyvsp[(4) - (4)].val_str)==0) ? false : fnmatch((yyvsp[(4) - (4)].val_str),val.c_str(),0)!=0;;}
(yyval.val_int) = (val.empty() || (yyvsp[(4) - (4)].val_str)==0) ? false : fnmatch((yyvsp[(4) - (4)].val_str),val.c_str(),0)!=0;}
break;
case 14:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 157 "expr_bool.y"
{ (yyval.val_int) = (yyvsp[(1) - (3)].val_int) && (yyvsp[(3) - (3)].val_int); ;}
{ (yyval.val_int) = (yyvsp[(1) - (3)].val_int) && (yyvsp[(3) - (3)].val_int); }
break;
case 15:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 158 "expr_bool.y"
{ (yyval.val_int) = (yyvsp[(1) - (3)].val_int) || (yyvsp[(3) - (3)].val_int); ;}
{ (yyval.val_int) = (yyvsp[(1) - (3)].val_int) || (yyvsp[(3) - (3)].val_int); }
break;
case 16:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 159 "expr_bool.y"
{ (yyval.val_int) = ! (yyvsp[(2) - (2)].val_int); ;}
{ (yyval.val_int) = ! (yyvsp[(2) - (2)].val_int); }
break;
case 17:
/* Line 1464 of yacc.c */
/* Line 1806 of yacc.c */
#line 160 "expr_bool.y"
{ (yyval.val_int) = (yyvsp[(2) - (3)].val_int); ;}
{ (yyval.val_int) = (yyvsp[(2) - (3)].val_int); }
break;
/* Line 1464 of yacc.c */
#line 1627 "expr_bool.cc"
/* Line 1806 of yacc.c */
#line 1658 "expr_bool.cc"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
that yytoken be updated with the new translation. We take the
approach of translating immediately before every use of yytoken.
One alternative is translating here after every semantic action,
but that translation would be missed if the semantic action invokes
YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
incorrect destructor might then be invoked immediately. In the
case of YYERROR or YYBACKUP, subsequent parser actions might lead
to an incorrect destructor call or verbose syntax error message
before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
@ -1654,6 +1696,10 @@ yyreduce:
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
@ -1661,37 +1707,36 @@ yyerrlab:
#if ! YYERROR_VERBOSE
yyerror (&yylloc, mc, oxml, result, error_msg, YY_("syntax error"));
#else
# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
yyssp, yytoken)
{
YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
{
YYSIZE_T yyalloc = 2 * yysize;
if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
yyalloc = YYSTACK_ALLOC_MAXIMUM;
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yyalloc);
if (yymsg)
yymsg_alloc = yyalloc;
else
{
yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf;
}
}
if (0 < yysize && yysize <= yymsg_alloc)
{
(void) yysyntax_error (yymsg, yystate, yychar);
yyerror (&yylloc, mc, oxml, result, error_msg, yymsg);
}
else
{
yyerror (&yylloc, mc, oxml, result, error_msg, YY_("syntax error"));
if (yysize != 0)
goto yyexhaustedlab;
}
char const *yymsgp = YY_("syntax error");
int yysyntax_error_status;
yysyntax_error_status = YYSYNTAX_ERROR;
if (yysyntax_error_status == 0)
yymsgp = yymsg;
else if (yysyntax_error_status == 1)
{
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
if (!yymsg)
{
yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf;
yysyntax_error_status = 2;
}
else
{
yysyntax_error_status = YYSYNTAX_ERROR;
yymsgp = yymsg;
}
}
yyerror (&yylloc, mc, oxml, result, error_msg, yymsgp);
if (yysyntax_error_status == 2)
goto yyexhaustedlab;
}
# undef YYSYNTAX_ERROR
#endif
}
@ -1751,7 +1796,7 @@ yyerrlab1:
for (;;)
{
yyn = yypact[yystate];
if (yyn != YYPACT_NINF)
if (!yypact_value_is_default (yyn))
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@ -1815,8 +1860,13 @@ yyexhaustedlab:
yyreturn:
if (yychar != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval, &yylloc, mc, oxml, result, error_msg);
{
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = YYTRANSLATE (yychar);
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval, &yylloc, mc, oxml, result, error_msg);
}
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
@ -1841,7 +1891,7 @@ yyreturn:
/* Line 1684 of yacc.c */
/* Line 2067 of yacc.c */
#line 163 "expr_bool.y"

View File

@ -1,9 +1,8 @@
/* A Bison parser, made by GNU Bison 2.4.3. */
/* A Bison parser, made by GNU Bison 2.5. */
/* Skeleton interface for Bison's Yacc-like parsers in C
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2009, 2010 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -50,7 +49,7 @@
typedef union YYSTYPE
{
/* Line 1685 of yacc.c */
/* Line 2068 of yacc.c */
#line 83 "expr_bool.y"
char * val_str;
@ -59,8 +58,8 @@ typedef union YYSTYPE
/* Line 1685 of yacc.c */
#line 64 "expr_bool.hh"
/* Line 2068 of yacc.c */
#line 63 "expr_bool.hh"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */