1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-11 05:17:41 +03:00

Merge branch 'master' into feature-1791

Conflicts:
	include/LifeCycleManager.h
	include/VirtualMachine.h
	src/lcm/LifeCycleActions.cc
	src/lcm/LifeCycleManager.cc
	src/lcm/LifeCycleStates.cc
This commit is contained in:
Ruben S. Montero 2013-03-07 23:40:01 +01:00
commit 0e2849b645
76 changed files with 4455 additions and 458 deletions

View File

@ -259,8 +259,8 @@ public:
* @return 0 on success, -1 otherwise
*/
int attach(
int vid,
VirtualMachineTemplate * tmpl,
int vid,
VirtualMachineTemplate * tmpl,
string& error_str);
/**
@ -276,6 +276,75 @@ public:
int disk_id,
string& error_str);
/**
* Starts the attach NIC action.
* @param vid VirtualMachine identification
* @param tmpl Template containing the new NIC attribute.
* @param error_str Error reason, if any
*
* @return 0 on success, -1 otherwise
*/
int attach_nic(
int vid,
VirtualMachineTemplate * tmpl,
string& error_str);
/**
* Starts the detach NIC action.
* @param vid VirtualMachine identification
* @param nic_id NIC to detach
* @param error_str Error reason, if any
*
* @return 0 on success, -1 otherwise
*/
int detach_nic(
int id,
int nic_id,
string& error_str);
/**
* Starts the snapshot create action
*
* @param vid VirtualMachine identification
* @param name Name for the new snapshot
* @param snap_id Will contain the new snapshot ID
* @param error_str Error reason, if any
*
* @return 0 on success, -1 otherwise
*/
int snapshot_create(
int vid,
string& name,
int& snap_id,
string& error_str);
/**
* Starts the snapshot revert action
*
* @param vid VirtualMachine identification
* @param snap_id Snapshot to be restored
* @param error_str Error reason, if any
*
* @return 0 on success, -1 otherwise
*/
int snapshot_revert(
int vid,
int snap_id,
string& error_str);
/**
* Starts the snapshot delete action
*
* @param vid VirtualMachine identification
* @param snap_id Snapshot to be deleted
* @param error_str Error reason, if any
*
* @return 0 on success, -1 otherwise
*/
int snapshot_delete(
int vid,
int snap_id,
string& error_str);
private:
/**
* Thread id for the Dispatch Manager

View File

@ -36,6 +36,8 @@ public:
FixedLeases(SqlDB * db,
int _oid,
unsigned int _mac_prefix,
unsigned int _global[],
unsigned int _site[],
vector<const Attribute*>& vector_leases);
/**
* Create a plain FixedLeases, you can populate the lease pool using
@ -43,8 +45,10 @@ public:
*/
FixedLeases(SqlDB * db,
int _oid,
unsigned int _mac_prefix):
Leases(db,_oid,0,_mac_prefix),
unsigned int _mac_prefix,
unsigned int _global[],
unsigned int _site[]):
Leases(db,_oid,0,_mac_prefix,_global,_site),
current(leases.begin()){};
~FixedLeases(){};
@ -56,7 +60,7 @@ public:
* @param mac mac of the returned lease
* @return 0 if success
*/
int get(int vid, string& ip, string& mac);
int get(int vid, string& ip, string& mac, unsigned int eui64[]);
/**
* Ask for a specific lease in the network
@ -65,7 +69,7 @@ public:
* @param mac mac of the lease
* @return 0 if success
*/
int set(int vid, const string& ip, string& mac);
int set(int vid, const string& ip, string& mac, unsigned int eui64[]);
/**
* Release an used lease, which becomes unused
@ -110,7 +114,6 @@ public:
}
private:
/**
* Current lease pointer
*/

View File

@ -40,9 +40,17 @@ public:
* @param _oid the virtual network unique identifier
* @param _size the max number of leases
*/
Leases(SqlDB * _db, int _oid, unsigned long _size, unsigned int _mac_prefix):
ObjectSQL(),
oid(_oid), size(_size), n_used(0), mac_prefix(_mac_prefix), db(_db){};
Leases(SqlDB * _db, int _oid, unsigned long _size, unsigned int _mac_prefix,
unsigned int _global[], unsigned int _site[]):
ObjectSQL(), oid(_oid), size(_size), n_used(0), mac_prefix(_mac_prefix)
, db(_db)
{
global[1] = _global[1];
global[0] = _global[0];
site[1] = _site[1];
site[0] = _site[0];
};
virtual ~Leases()
{
@ -61,18 +69,20 @@ public:
* @param vid identifier of the VM getting this lease
* @param ip ip of the returned lease
* @param mac mac of the returned lease
* @param eui64 extended unique identifier
* @return 0 if success
*/
virtual int get(int vid, string& ip,string& mac) = 0;
virtual int get(int vid, string& ip, string& mac, unsigned int *eui64) = 0;
/**
* Ask for a specific lease in the network
* @param vid identifier of the VM getting this lease
* @param ip ip of lease requested
* @param mac mac of the lease
* @param eui64 extended unique identifier
* @return 0 if success
*/
virtual int set(int vid, const string& ip, string& mac) = 0;
virtual int set(int vid, const string& ip, string& mac, unsigned int *eui64) = 0;
/**
* Release an used lease, which becomes unused
@ -122,9 +132,6 @@ public:
*/
int free_leases(vector<const Attribute*>& vector_leases, string& error_msg);
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
protected:
/**
* The Lease class, it represents a pair of IP and MAC assigned to
@ -133,16 +140,6 @@ protected:
class Lease : public ObjectXML
{
public:
/**
* Creates a new lease, string form. This constructor throws a runtime
* exception if the IP or MAC format is wrong.
* @param _ip, the Lease IP in string format
* @param _mac, the Lease MAC in string format
* @param _vid, the ID of the VM owning the lease
* @param _used, the lease is in use
*/
//Lease(const string& _ip, const string& _mac,int _vid, bool _used=true);
/**
* Creates a new lease, numeric form.
* @param _ip, the Lease IP in numeric format
@ -150,12 +147,16 @@ protected:
* @param _vid, the ID of the VM owning the lease
* @param _used, the lease is in use
*/
Lease(unsigned int _ip, unsigned int _mac[], int _vid, bool _used=true)
:ObjectXML(),ip(_ip), vid(_vid), used(_used)
Lease(unsigned int _ip,
unsigned int _mac[],
int _vid,
bool _used)
:ObjectXML(),ip(_ip), vid(_vid), used(_used)
{
// TODO check size
mac[PREFIX]=_mac[PREFIX];
mac[SUFFIX]=_mac[SUFFIX];
mac[1]=_mac[1];
mac[0]=_mac[0];
mac_to_eui64(mac, eui64);
};
/**
@ -166,13 +167,6 @@ protected:
~Lease(){};
/**
* Converts this lease's IP and MAC to string
* @param ip ip of the lease in string
* @param mac mac of the lease in string
*/
void to_string(string& _ip, string& _mac) const;
/**
* Conversion from string IP to unsigned int IP
* @return 0 if success
@ -184,21 +178,35 @@ protected:
*/
static void ip_to_string(const unsigned int i_ip, string& ip);
/**
* Generates IPv6 strings based on the modified EUI64 and global and
* site network prefixes.
*/
static void ip6_to_string(const unsigned int eui64[],
const unsigned int prefix[],
string& ip6s);
/**
* Conversion from string MAC to unsigned int[] MAC
* @return 0 if success
*/
static int mac_to_number(const string& mac, unsigned int i_mac[]);
/**
* Generates the modified extended unique identifier based on MAC
* @param i_mac the MAC address
* @param i_meui64 the modified EUI64
*/
static void mac_to_eui64(const unsigned int mac[], unsigned int eui64[]);
/**
* Conversion from string IP to unsigned int IP
*/
static void mac_to_string(const unsigned int i_mac[], string& mac);
/**
* Prints a Lease in a single line
* Conversion from string IP to unsigned int IP
*/
friend ostream& operator<<(ostream& os, Lease& _lease);
static int prefix6_to_number(const string& prefix, unsigned int ip[]);
/**
* Function to print the Lease object into a string in
@ -206,8 +214,9 @@ protected:
* @param xml the resulting XML string
* @return a reference to the generated string
*/
string& to_xml(string& xml) const;
string& to_xml(string& xml,
const unsigned int global[],
const unsigned int site[]) const;
/**
* Function to print the Lease object into a string in
* XML format. The output contains all the internal attributes,
@ -225,22 +234,15 @@ protected:
*/
int from_xml(const string &xml_str);
/**
* Constants to access the array storing the MAC address
*/
enum MACIndex
{
SUFFIX = 0,/**< Lower significant 4 bytes */
PREFIX = 1 /**< Higher significant 2 bytes */
};
unsigned int ip;
unsigned int ip;
unsigned int mac[2];
unsigned int mac [2];
unsigned int eui64[2];
int vid;
int vid;
bool used;
bool used;
};
friend class VirtualNetwork;
@ -252,12 +254,12 @@ protected:
/**
* Leases identifier. Connects it to a Virtual Network
*/
int oid;
int oid;
/**
* Number of possible leases (free + assigned)
*/
unsigned int size;
unsigned int size;
/**
* Hash of leases, indexed by lease.ip
@ -274,6 +276,16 @@ protected:
*/
unsigned int mac_prefix;
/**
* Global prefix for IPv6 addresses (64 upper bits)
*/
unsigned int global[2];
/**
* Global prefix for IPv6 addresses (64 upper bits)
*/
unsigned int site[2];
// -------------------------------------------------------------------------
// DataBase implementation variables
// -------------------------------------------------------------------------
@ -307,7 +319,7 @@ protected:
bool check(unsigned int ip);
/**
* Check if a VM is the owner of the ip
* Check if a VM is the owner of the ip
* @param ip of the lease to be checked
* @param vid the ID of the VM
* @return true if the ip was already assigned

View File

@ -62,10 +62,20 @@ public:
ATTACH_FAILURE, /**< Sent by the VMM when an attach action fails */
DETACH_SUCCESS, /**< Sent by the VMM when a detach action succeeds */
DETACH_FAILURE, /**< Sent by the VMM when a detach action fails */
ATTACH_NIC_SUCCESS,/**< Sent by the VMM when an attach nic action succeeds */
ATTACH_NIC_FAILURE,/**< Sent by the VMM when an attach nic action fails */
DETACH_NIC_SUCCESS,/**< Sent by the VMM when a detach nic action succeeds */
DETACH_NIC_FAILURE,/**< Sent by the VMM when a detach nic action fails */
CLEANUP_SUCCESS, /**< Sent by the VMM when a cleanup action succeeds */
CLEANUP_FAILURE, /**< Sent by the VMM when a cleanup action fails */
SAVEAS_HOT_SUCCESS,/**< Sent by the VMM when hot saveas succeeds */
SAVEAS_HOT_FAILURE,/**< Sent by the VMM when hot saveas fails */
SNAPSHOT_CREATE_SUCCESS, /**< Sent by the VMM on snap. create success */
SNAPSHOT_CREATE_FAILURE, /**< Sent by the VMM on snap. create failure */
SNAPSHOT_REVERT_SUCCESS, /**< Sent by the VMM on snap. revert success */
SNAPSHOT_REVERT_FAILURE, /**< Sent by the VMM on snap. revert failure */
SNAPSHOT_DELETE_SUCCESS, /**< Sent by the VMM on snap. revert success */
SNAPSHOT_DELETE_FAILURE, /**< Sent by the VMM on snap. revert failure */
DEPLOY, /**< Sent by the DM to deploy a VM on a host */
SUSPEND, /**< Sent by the DM to suspend an running VM */
RESTORE, /**< Sent by the DM to restore a suspended VM */
@ -193,8 +203,28 @@ private:
void saveas_hot_failure_action(int vid);
void attach_nic_success_action(int vid);
void attach_nic_failure_action(int vid);
void detach_nic_success_action(int vid);
void detach_nic_failure_action(int vid);
void cleanup_callback_action(int vid);
void snapshot_create_success(int vid);
void snapshot_create_failure(int vid);
void snapshot_revert_success(int vid);
void snapshot_revert_failure(int vid);
void snapshot_delete_success(int vid);
void snapshot_delete_failure(int vid);
void deploy_action(int vid);
void suspend_action(int vid);

View File

@ -32,6 +32,8 @@ public:
RangedLeases(SqlDB * db,
int _oid,
unsigned int _mac_prefix,
unsigned int _global[],
unsigned int _site[],
unsigned int _ip_start,
unsigned int _ip_end);
@ -55,7 +57,7 @@ public:
* @param mac mac of the returned lease
* @return 0 if success
*/
int get(int vid, string& ip, string& mac);
int get(int vid, string& ip, string& mac, unsigned int eui64[]);
/**
* Ask for a specific lease in the network
@ -64,7 +66,7 @@ public:
* @param mac mac of the lease
* @return 0 if success
*/
int set(int vid, const string& ip, string& mac);
int set(int vid, const string& ip, string& mac, unsigned int eui64[]);
/**
* Release an used lease, which becomes unused

View File

@ -177,8 +177,6 @@ public:
~VirtualMachineMonitoring(){};
/* -------------------------------------------------------------------- */
void request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att);
};
@ -220,6 +218,40 @@ public:
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachineAttachNic : public RequestManagerVirtualMachine
{
public:
VirtualMachineAttachNic():
RequestManagerVirtualMachine("VirtualMachineAttachNic",
"Attaches a new NIC to the virtual machine",
"A:sis"){};
~VirtualMachineAttachNic(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class VirtualMachineDetachNic : public RequestManagerVirtualMachine
{
public:
VirtualMachineDetachNic():
RequestManagerVirtualMachine("VirtualMachineDetachNic",
"Detaches a NIC from a virtual machine",
"A:sii"){};
~VirtualMachineDetachNic(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class VirtualMachineResize : public RequestManagerVirtualMachine
{
public:
@ -232,7 +264,58 @@ public:
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachineSnapshotCreate: public RequestManagerVirtualMachine
{
public:
VirtualMachineSnapshotCreate():
RequestManagerVirtualMachine("VirtualMachineSnapshotCreate",
"Creates a new virtual machine snapshot",
"A:sis"){};
~VirtualMachineSnapshotCreate(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachineSnapshotRevert: public RequestManagerVirtualMachine
{
public:
VirtualMachineSnapshotRevert():
RequestManagerVirtualMachine("VirtualMachineSnapshotRevert",
"Reverts a virtual machine to a snapshot",
"A:sii"){};
~VirtualMachineSnapshotRevert(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachineSnapshotDelete: public RequestManagerVirtualMachine
{
public:
VirtualMachineSnapshotDelete():
RequestManagerVirtualMachine("VirtualMachineSnapshotDelete",
"Deletes a virtual machine snapshot",
"A:sii"){};
~VirtualMachineSnapshotDelete(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -66,33 +66,35 @@ public:
*/
enum LcmState
{
LCM_INIT = 0,
PROLOG = 1,
BOOT = 2,
RUNNING = 3,
MIGRATE = 4,
SAVE_STOP = 5,
SAVE_SUSPEND = 6,
SAVE_MIGRATE = 7,
PROLOG_MIGRATE = 8,
PROLOG_RESUME = 9,
EPILOG_STOP = 10,
EPILOG = 11,
SHUTDOWN = 12,
CANCEL = 13,
FAILURE = 14,
CLEANUP_RESUBMIT = 15,
UNKNOWN = 16,
HOTPLUG = 17,
SHUTDOWN_POWEROFF = 18,
BOOT_UNKNOWN = 19,
BOOT_POWEROFF = 20,
BOOT_SUSPENDED = 21,
BOOT_STOPPED = 22,
CLEANUP_DELETE = 23,
HOTPLUG_SAVEAS = 24,
HOTPLUG_SAVEAS_POWEROFF = 25,
HOTPLUG_SAVEAS_SUSPENDED = 26
LCM_INIT = 0,
PROLOG = 1,
BOOT = 2,
RUNNING = 3,
MIGRATE = 4,
SAVE_STOP = 5,
SAVE_SUSPEND = 6,
SAVE_MIGRATE = 7,
PROLOG_MIGRATE = 8,
PROLOG_RESUME = 9,
EPILOG_STOP = 10,
EPILOG = 11,
SHUTDOWN = 12,
CANCEL = 13,
FAILURE = 14,
CLEANUP_RESUBMIT = 15,
UNKNOWN = 16,
HOTPLUG = 17,
SHUTDOWN_POWEROFF = 18,
BOOT_UNKNOWN = 19,
BOOT_POWEROFF = 20,
BOOT_SUSPENDED = 21,
BOOT_STOPPED = 22,
CLEANUP_DELETE = 23,
HOTPLUG_SNAPSHOT = 24,
HOTPLUG_NIC = 25,
HOTPLUG_SAVEAS = 26,
HOTPLUG_SAVEAS_POWEROFF = 27,
HOTPLUG_SAVEAS_SUSPENDED = 28
};
// -------------------------------------------------------------------------
@ -812,6 +814,16 @@ public:
*/
void release_network_leases();
/**
* Releases the network lease taken by this NIC
*
* @param nic NIC to be released
* @param vmid Virtual Machine oid
*
* @return 0 on success, -1 otherwise
*/
static int release_network_leases(VectorAttribute const * nic, int vmid);
/**
* Get all disk images for this Virtual Machine
* @param error_str Returns the error reason, if any
@ -910,7 +922,6 @@ public:
// -------------------------------------------------------------------------
// Hotplug related functions
// -------------------------------------------------------------------------
/**
* Collects information about VM DISKS
* @param max_disk_id of the VM
@ -927,15 +938,15 @@ public:
int get_disk_hot_info(int& image_id, int& disk_id, string& source);
/**
* Generate a DISK attributed to be attached to the VM.
* Generate a DISK attribute to be attached to the VM.
* @param tmpl Template containing a single DISK vector attribute.
* @param used_targets targets in use by current DISKS
* @param max_disk_id Max DISK/DISK_ID of the VM
* @param uid of the VM owner
* @param image_id returns the id of the aquired image
* @param image_id returns the id of the acquired image
* @param error_str describes the error
*
* @return a new vectorattribute with the DISK (should be freed if not
* @return a new VectorAttribute with the DISK (should be freed if not
* added to the template), 0 in case of error;
*/
static VectorAttribute * set_up_attach_disk(
@ -984,19 +995,113 @@ public:
*/
int set_attach_disk(int disk_id);
/**
* Cleans the ATTACH = YES attribute from the disks
*
* @return 0 on success, -1 otherwise
*/
int detach_success();
// ------------------------------------------------------------------------
// NIC Hotplug related functions
// ------------------------------------------------------------------------
/**
* Cleans the ATTACH = YES attribute from the disks
*
* @return 0 on success, -1 otherwise
* Collects information about VM DISKS
* @param max_disk_id of the VM
*/
int detach_failure();
void get_nic_info(int& max_nic_id);
/**
* Generates a NIC attribute to be attached to the VM.
* @param tmpl Template containing a single NIC vector attribute.
* @param max_nic_id Max NIC/NIC_ID of the VM
* @param uid of the VM owner
* @param network_id returns the id of the acquired network
* @param error_str describes the error
*
* @return a new VectorAttribute with the DISK (should be freed if not
* added to the template), 0 in case of error
*/
static VectorAttribute * set_up_attach_nic(
int vm_id,
VirtualMachineTemplate * tmpl,
int max_nic_id,
int uid,
int& network_id,
string& error_str);
/**
* Cleans the ATTACH = YES attribute from the NICs
*/
void clear_attach_nic();
/**
* Deletes the NIC that was in the process of being attached
*
* @return the deleted NIC or 0 if none was deleted
*/
VectorAttribute * delete_attach_nic();
/**
* Adds a new NIC to the virtual machine template. The NIC should be
* generated by the build_attach_nic
* @param new_nic must be allocated in the heap
*/
void set_attach_nic(VectorAttribute * new_nic)
{
new_nic->replace("ATTACH", "YES");
obj_template->set(new_nic);
}
/**
* Sets the attach attribute to the given NIC
* @param nic_id of the NIC
* @return 0 if the nic_id was found, -1 otherwise
*/
int set_attach_nic(int nic_id);
// ------------------------------------------------------------------------
// Snapshot related functions
// ------------------------------------------------------------------------
/**
* Creates a new Snapshot attribute, and sets it to ACTIVE=YES
*
* @param name for the new Snapshot. If it is empty, the generated name
* will be placed in this param
* @param snap_id Id of the new snapshot
*
* @return 0 on success
*/
int new_snapshot(string& name, int& snap_id);
/**
* Sets the given Snapshot as ACTIVE=YES
*
* @param snap_id the snapshow ID
*
* @return 0 on success
*/
int set_active_snapshot(int snap_id);
/**
* Replaces HYPERVISOR_ID for the active SNAPSHOT
*
* @param hypervisor_id Id returned by the hypervisor for the newly
* created snapshot
*/
void update_snapshot_id(string& hypervisor_id);
/**
* Cleans the ACTIVE = YES attribute from the snapshots
*/
void clear_active_snapshot();
/**
* Deletes the SNAPSHOT that was in the process of being created
*/
void delete_active_snapshot();
/**
* Deletes all SNAPSHOT attributes
*/
void delete_snapshots();
private:

View File

@ -61,7 +61,12 @@ public:
DRIVER_CANCEL,
FINALIZE,
ATTACH,
DETACH
DETACH,
ATTACH_NIC,
DETACH_NIC,
SNAPSHOT_CREATE,
SNAPSHOT_REVERT,
SNAPSHOT_DELETE
};
/**
@ -332,6 +337,46 @@ private:
void detach_action(
int vid);
/**
* Attaches a new NIC to a VM. The VM must have a NIC with the
* attribute ATTACH = YES
* @param vid the id of the VM.
*/
void attach_nic_action(
int vid);
/**
* Detaches a NIC from a VM. The VM must have a NIC with the
* attribute ATTACH = YES
* @param vid the id of the VM.
*/
void detach_nic_action(
int vid);
/**
* Creates a new system snapshot. The VM must have a snapshot with the
* attribute ACTIVE = YES
*
* @param vid the id of the VM.
*/
void snapshot_create_action(int vid);
/**
* Reverts to a snapshot. The VM must have a snapshot with the
* attribute ACTIVE = YES
*
* @param vid the id of the VM.
*/
void snapshot_revert_action(int vid);
/**
* Deletes a snapshot. The VM must have a snapshot with the
* attribute ACTIVE = YES
*
* @param vid the id of the VM.
*/
void snapshot_delete_action(int vid);
/**
* This function cancels the current driver operation
*/

View File

@ -275,7 +275,7 @@ private:
}
/**
* Sends an attach request to the MAD: "ATTACH ID XML_DRV_MSG"
* Sends an attach request to the MAD: "ATTACHDISK ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
@ -287,7 +287,7 @@ private:
}
/**
* Sends a detach request to the MAD: "DETACH ID XML_DRV_MSG"
* Sends a detach request to the MAD: "DETACHDISK ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
@ -298,13 +298,67 @@ private:
write_drv("DETACHDISK", oid, drv_msg);
}
void write_drv(const char * aname, const int oid, const string& msg) const
/**
* Sends an attach NIC request to the MAD: "ATTACHNIC ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
void attach_nic (
const int oid,
const string& drv_msg) const
{
ostringstream os;
write_drv("ATTACHNIC", oid, drv_msg);
}
os << aname << " " << oid << " " << msg << endl;
/**
* Sends a detach request to the MAD: "DETACHNIC ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
void detach_nic (
const int oid,
const string& drv_msg) const
{
write_drv("DETACHNIC", oid, drv_msg);
}
write(os);
/**
* Sends a snapshot create request to the MAD:
* "SNAPSHOTCREATE ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
void snapshot_create (
const int oid,
const string& drv_msg) const
{
write_drv("SNAPSHOTCREATE", oid, drv_msg);
}
/**
* Sends a snapshot revert request to the MAD:
* "SNAPSHOTREVERT ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
void snapshot_revert (
const int oid,
const string& drv_msg) const
{
write_drv("SNAPSHOTREVERT", oid, drv_msg);
}
/**
* Sends a snapshot delete request to the MAD:
* "SNAPSHOTDELETE ID XML_DRV_MSG"
* @param oid the virtual machine id.
* @param drv_msg xml data for the mad operation
*/
void snapshot_delete (
const int oid,
const string& drv_msg) const
{
write_drv("SNAPSHOTDELETE", oid, drv_msg);
}
/**
@ -325,10 +379,21 @@ private:
long long &net_rx,
char &state,
map<string,string> &custom);
/**
*
*/
void write_drv(const char * aname, const int oid, const string& msg) const
{
ostringstream os;
os << aname << " " << oid << " " << msg << endl;
write(os);
}
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#endif /*VIRTUAL_MACHINE_MANAGER_DRIVER_H_*/

View File

@ -117,8 +117,10 @@ public:
*/
int get_lease(int vid, string& _ip, string& _mac, string& _bridge)
{
unsigned int eui64[2];
_bridge = bridge;
return leases->get(vid,_ip,_mac);
return leases->get(vid, _ip, _mac, eui64);
};
/**
@ -131,8 +133,10 @@ public:
*/
int set_lease(int vid, const string& _ip, string& _mac, string& _bridge)
{
unsigned int eui64[2];
_bridge = bridge;
return leases->set(vid,_ip,_mac);
return leases->set(vid, _ip, _mac, eui64);
};
/**
@ -227,6 +231,26 @@ private:
*/
int vlan;
/**
* IPv6 address global unicast prefix
*/
string global;
/**
* Binary representation of the IPv6 address global unicast prefix
*/
unsigned int global_bin[2];
/**
* IPv6 address site unicast prefix
*/
string site;
/**
* Binary representation of the IPv6 address site unicast prefix
*/
unsigned int site_bin[2];
// -------------------------------------------------------------------------
// Virtual Network Description
// -------------------------------------------------------------------------

View File

@ -101,13 +101,20 @@ public:
* Generates a NIC attribute for VM templates using the VirtualNetwork
* metadata
* @param nic the nic attribute to be generated
* @param nic_id the id for this NIC
* @param uid of the VM owner
* @param vid of the VM requesting the lease
* @param error_str string describing the error
* @return 0 on success,
* -1 error,
* -2 not using the pool
*/
int nic_attribute(VectorAttribute * nic, int uid, int vid, string& error_str);
int nic_attribute(
VectorAttribute* nic,
int nic_id,
int uid,
int vid,
string& error_str);
/**
* Generates an Authorization token for a NIC attribute

View File

@ -49,7 +49,13 @@ usage() {
}
#-------------------------------------------------------------------------------
TEMP_OPT=`getopt -o hkrlcsou:g:d: -n 'install.sh' -- "$@"`
PARAMETERS="hkrlcsou:g:d:"
if [ $(getopt --version | tr -d " ") = "--" ]; then
TEMP_OPT=`getopt $PARAMETERS "$@"`
else
TEMP_OPT=`getopt -o $PARAMETERS -n 'install.sh' -- "$@"`
fi
if [ $? != 0 ] ; then
usage
@ -685,7 +691,8 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \
src/vnm_mad/one_vnm.rb \
src/mad/ruby/Ganglia.rb \
src/oca/ruby/deprecated/OpenNebula.rb \
src/oca/ruby/opennebula.rb"
src/oca/ruby/opennebula.rb \
src/sunstone/OpenNebulaVNC.rb"
#-------------------------------------------------------------------------------
# Ruby auth library files, to be installed under $LIB_LOCATION/ruby/opennebula
@ -752,6 +759,11 @@ VMM_EXEC_KVM_SCRIPTS="src/vmm_mad/remotes/kvm/cancel \
src/vmm_mad/remotes/kvm/poll_ganglia \
src/vmm_mad/remotes/kvm/attach_disk \
src/vmm_mad/remotes/kvm/detach_disk \
src/vmm_mad/remotes/kvm/attach_nic \
src/vmm_mad/remotes/kvm/detach_nic \
src/vmm_mad/remotes/kvm/snapshot_create \
src/vmm_mad/remotes/kvm/snapshot_revert \
src/vmm_mad/remotes/kvm/snapshot_delete \
src/vmm_mad/remotes/kvm/shutdown"
#-------------------------------------------------------------------------------
@ -770,6 +782,11 @@ VMM_EXEC_XEN3_SCRIPTS="src/vmm_mad/remotes/xen/cancel \
src/vmm_mad/remotes/xen/poll_ganglia \
src/vmm_mad/remotes/xen/attach_disk \
src/vmm_mad/remotes/xen/detach_disk \
src/vmm_mad/remotes/xen/attach_nic \
src/vmm_mad/remotes/xen/detach_nic \
src/vmm_mad/remotes/xen/snapshot_create \
src/vmm_mad/remotes/xen/snapshot_revert \
src/vmm_mad/remotes/xen/snapshot_delete \
src/vmm_mad/remotes/xen/shutdown"
VMM_EXEC_XEN4_SCRIPTS="src/vmm_mad/remotes/xen/cancel \
@ -784,6 +801,11 @@ VMM_EXEC_XEN4_SCRIPTS="src/vmm_mad/remotes/xen/cancel \
src/vmm_mad/remotes/xen/poll_ganglia \
src/vmm_mad/remotes/xen/attach_disk \
src/vmm_mad/remotes/xen/detach_disk \
src/vmm_mad/remotes/xen/attach_nic \
src/vmm_mad/remotes/xen/detach_nic \
src/vmm_mad/remotes/xen/snapshot_create \
src/vmm_mad/remotes/xen/snapshot_revert \
src/vmm_mad/remotes/xen/snapshot_delete \
src/vmm_mad/remotes/xen/shutdown"
#-------------------------------------------------------------------------------
# VMM Driver VMWARE scripts, to be installed under $REMOTES_LOCATION/vmm/vmware
@ -792,6 +814,11 @@ VMM_EXEC_XEN4_SCRIPTS="src/vmm_mad/remotes/xen/cancel \
VMM_EXEC_VMWARE_SCRIPTS="src/vmm_mad/remotes/vmware/cancel \
src/vmm_mad/remotes/vmware/attach_disk \
src/vmm_mad/remotes/vmware/detach_disk \
src/vmm_mad/remotes/vmware/attach_nic \
src/vmm_mad/remotes/vmware/detach_nic \
src/vmm_mad/remotes/vmware/snapshot_create \
src/vmm_mad/remotes/vmware/snapshot_revert \
src/vmm_mad/remotes/vmware/snapshot_delete \
src/vmm_mad/remotes/vmware/scripts_common_sh.sh \
src/vmm_mad/remotes/vmware/deploy \
src/vmm_mad/remotes/vmware/migrate \
@ -1384,9 +1411,10 @@ ETC_CLIENT_FILES="src/cli/etc/group.default"
#-----------------------------------------------------------------------------
SUNSTONE_FILES="src/sunstone/sunstone-server.rb \
src/sunstone/OpenNebulaVNC.rb"
src/sunstone/config.ru"
SUNSTONE_BIN_FILES="src/sunstone/bin/sunstone-server"
SUNSTONE_BIN_FILES="src/sunstone/bin/sunstone-server \
src/sunstone/bin/novnc-server"
SUNSTONE_ETC_FILES="src/sunstone/etc/sunstone-server.conf \
src/sunstone/etc/sunstone-plugins.yaml"

View File

@ -106,7 +106,9 @@
BOOT_POWEROFF = 20,
BOOT_SUSPENDED = 21,
BOOT_STOPPED = 22,
CLEANUP_DELETE = 23
CLEANUP_DELETE = 23,
HOTPLUG_SNAPSHOT = 24,
HOTPLUG_NIC = 25
-->
<xs:element name="LCM_STATE" type="xs:integer"/>
<xs:element name="RESCHED" type="xs:integer"/>

View File

@ -68,7 +68,9 @@
BOOT_POWEROFF = 20,
BOOT_SUSPENDED = 21,
BOOT_STOPPED = 22,
CLEANUP_DELETE = 23
CLEANUP_DELETE = 23,
HOTPLUG_SNAPSHOT = 24,
HOTPLUG_NIC = 25
-->
<xs:element name="LCM_STATE" type="xs:integer"/>
<xs:element name="RESCHED" type="xs:integer"/>

View File

@ -32,6 +32,8 @@
<xs:element name="VLAN" type="xs:integer"/>
<xs:element name="PHYDEV" type="xs:string"/>
<xs:element name="VLAN_ID" type="xs:string"/>
<xs:element name="GLOBAL_PREFIX" type="xs:string"/>
<xs:element name="SITE_PREFIX" type="xs:string"/>
<xs:element name="RANGE" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>

View File

@ -2,3 +2,6 @@
# the server, each CA certificate shoud be name CA_hash.0
#:ca_dir: "/etc/one/auth/certificates"
# Uncoment this line if you want to force crl checking
#:check_crl: true

View File

@ -199,7 +199,6 @@ private
###########################################################################
def validate
now = Time.now
failed = "Could not validate user credentials: "
# Check start time and end time of certificates
@cert_chain.each do |cert|
@ -213,6 +212,8 @@ private
# Validate the proxy certifcates
signee = @cert_chain[0]
check_crl(signee)
@cert_chain[1..-1].each do |cert|
if !((signee.issuer.to_s == cert.subject.to_s) &&
(signee.verify(cert.public_key)))
@ -247,4 +248,41 @@ private
raise
end
end
def check_crl(signee)
failed = "Could not validate user credentials: "
ca_hash = signee.issuer.hash.to_s(16)
ca_path = @options[:ca_dir] + '/' + ca_hash + '.0'
crl_path = @options[:ca_dir] + '/' + ca_hash + '.r0'
if !File.exist?(crl_path)
if @options[:check_crl]
raise failed + "CRL file #{crl_path} does not exist"
else
return
end
end
ca_cert = OpenSSL::X509::Certificate.new( File.read(ca_path) )
crl_cert = OpenSSL::X509::CRL.new( File.read(crl_path) )
# First verify the CRL itself with its signer
unless crl_cert.verify( ca_cert.public_key ) then
raise failed + "CRL is not verified by its Signer"
end
# Extract the list of revoked certificates from the CRL
rc_array = crl_cert.revoked
# Loop over the list and compare with the target personal
# certificate
rc_array.each do |e|
if e.serial.eql?(signee.serial) then
raise failed + "#{signee.subject.to_s} is found in the "<<
"CRL, i.e. it is revoked"
end
end
end
end

View File

@ -37,6 +37,17 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
}
}
NETWORK = {
:name => "network",
:short => "-n id|name",
:large => "--network id|name" ,
:description => "Selects the virtual network",
:format => String,
:proc => lambda { |o, options|
OpenNebulaHelper.rname_to_id(o, "VNET")
}
}
FILE = {
:name => "file",
:short => "-f file",
@ -258,35 +269,6 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
}
puts
if vm.has_elements?("/VM/USER_TEMPLATE/SCHED_ACTION")
CLIHelper.print_header(str_h1 % "SCHEDULED ACTIONS",false)
CLIHelper::ShowTable.new(nil, self) do
column :"ID", "", :size=>2 do |d|
d["ID"] if !d.nil?
end
column :"ACTION", "", :left, :size=>10 do |d|
d["ACTION"] if !d.nil?
end
column :"SCHEDULED", "", :size=>12 do |d|
OpenNebulaHelper.time_to_str(d["TIME"], false) if !d.nil?
end
column :"DONE", "", :size=>12 do |d|
OpenNebulaHelper.time_to_str(d["DONE"], false) if !d.nil?
end
column :"MESSAGE", "", :left, :donottruncate, :size=>40 do |d|
d["MESSAGE"] if !d.nil?
end
end.show([vm.to_hash['VM']['USER_TEMPLATE']['SCHED_ACTION']].flatten, {})
puts
end
if vm.has_elements?("/VM/TEMPLATE/DISK")
CLIHelper.print_header(str_h1 % "VM DISKS",false)
CLIHelper::ShowTable.new(nil, self) do
@ -352,40 +334,99 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
end
if vm.has_elements?("/VM/TEMPLATE/NIC")
CLIHelper.print_header(str_h1 % "VM NICS",false)
CLIHelper.print_header(str_h1 % "VM NICS",false)
vm_nics = [vm.to_hash['VM']['TEMPLATE']['NIC']].flatten
nic_default = {"NETWORK" => "-",
"IP" => "-",
"MAC"=> "-",
"VLAN"=>"no",
"BRIDGE"=>"-"}
array_id = 0
vm_nics.each {|nic|
next if nic.has_key?("CLI_DONE")
if nic.has_key?("IP6_LINK")
ip6_link = {"IP" => nic.delete("IP6_LINK"),
"CLI_DONE" => true,
"DOUBLE_ENTRY" => true}
vm_nics.insert(array_id+1,ip6_link)
array_id += 1
end
if nic.has_key?("IP6_SITE")
ip6_link = {"IP" => nic.delete("IP6_SITE"),
"CLI_DONE" => true,
"DOUBLE_ENTRY" => true}
vm_nics.insert(array_id+1,ip6_link)
array_id += 1
end
if nic.has_key?("IP6_GLOBAL")
ip6_link = {"IP" => nic.delete("IP6_GLOBAL"),
"CLI_DONE" => true,
"DOUBLE_ENTRY" => true}
vm_nics.insert(array_id+1,ip6_link)
array_id += 1
end
nic.merge!(nic_default) {|k,v1,v2| v1}
array_id += 1
}
nic_id=0
CLIHelper::ShowTable.new(nil, self) do
column :ID, "", :size=>3 do |d|
nic_id+=1
nic_id-1
column :ID, "", :size=>2 do |d|
if d["DOUBLE_ENTRY"]
""
else
d["NIC_ID"]
end
end
column :NETWORK, "", :left, :size=>25 do |d|
d["NETWORK"] || "-"
end
column :IP, "", :size=>15 do |d|
d["IP"] || "-"
end
column :MAC, "", :size=>17 do |d|
d["MAC"] || "-"
column :NETWORK, "", :left, :size=>12 do |d|
if d["DOUBLE_ENTRY"]
""
else
d["NETWORK"]
end
end
column :VLAN, "", :size=>4 do |d|
if !d["VLAN"]
"no"
if d["DOUBLE_ENTRY"]
""
else
d["VLAN"].downcase
end
end
column :BRIDGE, "", :left, :size=>11 do |d|
d["BRIDGE"] || "-"
column :BRIDGE, "", :left, :size=>8 do |d|
if d["DOUBLE_ENTRY"]
""
else
d["BRIDGE"]
end
end
end.show([vm.to_hash['VM']['TEMPLATE']['NIC']].flatten, {})
column :IP, "",:left, :donottruncate, :size=>15 do |d|
d["IP"]
end
column :MAC, "", :left, :size=>17 do |d|
if d["DOUBLE_ENTRY"]
""
else
d["MAC"]
end
end
end.show(vm_nics,{})
while vm.has_elements?("/VM/TEMPLATE/NIC")
vm.delete_element("/VM/TEMPLATE/NIC")
@ -394,8 +435,69 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
puts
end
CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE TEMPLATE",false)
puts vm.template_str
if vm.has_elements?("/VM/TEMPLATE/SNAPSHOT")
CLIHelper.print_header(str_h1 % "SNAPSHOTS",false)
CLIHelper::ShowTable.new(nil, self) do
column :"ID", "", :size=>4 do |d|
d["SNAPSHOT_ID"] if !d.nil?
end
column :"TIME", "", :size=>12 do |d|
OpenNebulaHelper.time_to_str(d["TIME"], false) if !d.nil?
end
column :"NAME", "", :left, :size=>46 do |d|
d["NAME"] if !d.nil?
end
column :"HYPERVISOR_ID", "", :left, :size=>15 do |d|
d["HYPERVISOR_ID"] if !d.nil?
end
end.show([vm.to_hash['VM']['TEMPLATE']['SNAPSHOT']].flatten, {})
vm.delete_element("/VM/TEMPLATE/SNAPSHOT")
puts
end
if vm.has_elements?("/VM/HISTORY_RECORDS")
puts
CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE HISTORY",false)
format_history(vm)
end
if vm.has_elements?("/VM/USER_TEMPLATE/SCHED_ACTION")
CLIHelper.print_header(str_h1 % "SCHEDULED ACTIONS",false)
CLIHelper::ShowTable.new(nil, self) do
column :"ID", "", :size=>2 do |d|
d["ID"] if !d.nil?
end
column :"ACTION", "", :left, :size=>10 do |d|
d["ACTION"] if !d.nil?
end
column :"SCHEDULED", "", :size=>12 do |d|
OpenNebulaHelper.time_to_str(d["TIME"], false) if !d.nil?
end
column :"DONE", "", :size=>12 do |d|
OpenNebulaHelper.time_to_str(d["DONE"], false) if !d.nil?
end
column :"MESSAGE", "", :left, :donottruncate, :size=>40 do |d|
d["MESSAGE"] if !d.nil?
end
end.show([vm.to_hash['VM']['USER_TEMPLATE']['SCHED_ACTION']].flatten, {})
puts
end
if vm.has_elements?("/VM/USER_TEMPLATE")
puts
@ -408,12 +510,8 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
puts vm.template_like_str('USER_TEMPLATE')
end
if vm.has_elements?("/VM/HISTORY_RECORDS")
puts
CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE HISTORY",false)
format_history(vm)
end
CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE TEMPLATE",false)
puts vm.template_str
end
def format_history(vm)

View File

@ -112,8 +112,10 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
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 % ["PHYSICAL DEVICE", vn["PHYDEV"]] if !vn["PHYDEV"].empty?
puts str % ["VLAN ID", vn["VLAN_ID"]] if !vn["VLAN_ID"].empty?
puts str % ["GLOBAL PREFIX", vn["GLOBAL_PREFIX"]] if !vn["GLOBAL_PREFIX"].empty?
puts str % ["SITE PREFIX", vn["SITE_PREFIX"]] if !vn["SITE_PREFIX"].empty?
puts str % ["USED LEASES", vn['TOTAL_LEASES']]
puts

View File

@ -56,6 +56,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do
:description => "Device where the image will be attached"
}
IP={
:name => "ip",
:short => "-i ip",
:large => "--ip ip",
:format => String,
:description => "IP address for the new NIC"
}
CACHE={
:name => "cache",
:large => "--cache cache_mode",
@ -575,6 +583,53 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
attachnic_desc = <<-EOT.unindent
Attaches a NIC to a running VM
States: RUNNING
EOT
command :attachnic, attachnic_desc, :vmid,
:options => [OneVMHelper::FILE, OneVMHelper::NETWORK, IP] do
if options[:file].nil? and options[:network].nil?
STDERR.puts "Provide a template file or a network:"
STDERR.puts "\t--file <file>"
STDERR.puts "\t--network <network>"
exit -1
end
if options[:file]
template = File.read(options[:file])
else
network_id = options[:network]
ip = options[:ip]
if ip
template = "NIC = [ NETWORK_ID = #{network_id}, IP = #{ip} ]"
else
template = "NIC = [ NETWORK_ID = #{network_id} ]"
end
end
helper.perform_action(args[0],options,"Attach NIC") do |vm|
vm.attachnic(template)
end
end
detachnic_desc = <<-EOT.unindent
Detaches a NIC from a running VM
States: RUNNING
EOT
command :detachnic, detachnic_desc, :vmid, :nicid do
nicid = args[1].to_i
helper.perform_action(args[0],options,"Detach NIC") do |vm|
vm.detachnic(nicid)
end
end
chgrp_desc = <<-EOT.unindent
Changes the VM group
EOT
@ -631,10 +686,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
list_desc = <<-EOT.unindent
Lists VMs in the pool
EOT
rename_desc = <<-EOT.unindent
Renames the VM
EOT
@ -645,6 +696,52 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
# TODO: Write a more complete description:
# what is a snapshot (system snapshot)
# how to revert to a snapshot
snapshot_create_desc = <<-EOT.unindent
Creates a new VM snapshot
EOT
command :"snapshot-create", snapshot_create_desc, [:range,:vmid_list],
[:name, nil], :options => [OneVMHelper::SCHEDULE] do
if (!options[:schedule].nil?)
helper.schedule_actions(args[0], options, @comm_name)
else
helper.perform_actions(args[0],options,"snapshot created") do |o|
o.snapshot_create(args[1])
end
end
end
# TODO: Write a more complete description:
snapshot_revert_desc = <<-EOT.unindent
Reverts a VM to a saved snapshot
EOT
command :"snapshot-revert", snapshot_revert_desc, :vmid, :snapshot_id do
helper.perform_action(args[0],options,"snapshot reverted") do |o|
o.snapshot_revert(args[1].to_i)
end
end
# TODO: Write a more complete description:
snapshot_delete_desc = <<-EOT.unindent
Delets a snapshot of a VM
EOT
command :"snapshot-delete", snapshot_delete_desc, :vmid, :snapshot_id do
helper.perform_action(args[0],options,"snapshot deleted") do |o|
o.snapshot_delete(args[1].to_i)
end
end
list_desc = <<-EOT.unindent
Lists VMs in the pool
EOT
command :list, list_desc, [:filterflag, nil],
:options=>CLIHelper::OPTIONS+OpenNebulaHelper::OPTIONS+
[OpenNebulaHelper::DESCRIBE] do

View File

@ -124,6 +124,24 @@ function set_downloader_args {
echo "$HASHES $5 $6"
}
#------------------------------------------------------------------------------
# Gets the size in bytes of a file
# @param $1 - Path to the image
# @return size of the image in bytes
#------------------------------------------------------------------------------
function file_size {
stat --version &> /dev/null
if [ $? = 0 ]; then
STAT_CMD="stat -c %s"
else
STAT_CMD="stat -f %z"
fi
$STAT_CMD "$*"
}
#-------------------------------------------------------------------------------
# Computes the size of an image
# @param $1 - Path to the image
@ -156,7 +174,7 @@ function fs_size {
SIZE=`du -sb "$1" | cut -f1`
error=$?
else
SIZE=`stat -c %s "$1"`
SIZE=$(file_size "$1")
error=$?
fi
;;

View File

@ -133,7 +133,7 @@ esac
# Rename the disk filename to disk.vmdk (warning: it does so in SRC)
if [ ! -f $SRC/disk.vmdk ]; then
BASE_DISK_FILE=`ls $SRC | grep -v '\-\(flat\|delta\|s[0-9]*\)\.vmdk$'`
BASE_DISK_FILE=`ls $SRC | grep '\.vmdk$' | grep -v '\-\(flat\|delta\|s[0-9]*\)\.vmdk$'`
exec_and_log "mv -f $SRC/$BASE_DISK_FILE $SRC/disk.vmdk" \
"Error renaming disk file $SRC/$BASE_DISK_FILE to $SRC/disk.vmdk"

View File

@ -103,7 +103,7 @@ http://*|https://* )
esac
if [ -d "$DST" -a ! -f "$DST/disk.vmdk" ]; then
BASE_DISK_FILE=`ls $DST | grep -v '\-\(flat\|delta\|s[0-9]*\)\.vmdk$'`
BASE_DISK_FILE=`ls $SRC | grep '\.vmdk$' | grep -v '\-\(flat\|delta\|s[0-9]*\)\.vmdk$'`
exec_and_log "mv -f $DST/$BASE_DISK_FILE $DST/disk.vmdk" \

View File

@ -905,7 +905,6 @@ int DispatchManager::resubmit(int vid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::attach(int vid,
VirtualMachineTemplate * tmpl,
string & error_str)
@ -1022,7 +1021,6 @@ int DispatchManager::detach(
int disk_id,
string& error_str)
{
ostringstream oss;
Nebula& nd = Nebula::instance();
@ -1075,3 +1073,363 @@ int DispatchManager::detach(
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::snapshot_create(
int vid,
string& name,
int& snap_id,
string& error_str)
{
ostringstream oss;
Nebula& nd = Nebula::instance();
VirtualMachineManager* vmm = nd.get_vmm();
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "Could not create a new snapshot for VM " << vid
<< ", VM does not exist" ;
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
if ( vm->get_state() != VirtualMachine::ACTIVE ||
vm->get_lcm_state() != VirtualMachine::RUNNING )
{
oss << "Could not create a new snapshot for VM " << vid
<< ", wrong state.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
vm->set_state(VirtualMachine::HOTPLUG_SNAPSHOT);
vm->set_resched(false);
vm->new_snapshot(name, snap_id);
vmpool->update(vm);
vm->unlock();
vmm->trigger(VirtualMachineManager::SNAPSHOT_CREATE,vid);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::snapshot_revert(
int vid,
int snap_id,
string& error_str)
{
ostringstream oss;
int rc;
Nebula& nd = Nebula::instance();
VirtualMachineManager* vmm = nd.get_vmm();
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "Could not revert VM " << vid << " to snapshot " << snap_id
<< ", VM does not exist" ;
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
if ( vm->get_state() != VirtualMachine::ACTIVE ||
vm->get_lcm_state() != VirtualMachine::RUNNING )
{
oss << "Could not revert VM " << vid << " to snapshot " << snap_id
<< ", wrong state.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
rc = vm->set_active_snapshot(snap_id);
if ( rc == -1 )
{
oss << "Could not revert VM " << vid << " to snapshot " << snap_id
<< ", it does not exist.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
vm->set_state(VirtualMachine::HOTPLUG_SNAPSHOT);
vm->set_resched(false);
vmpool->update(vm);
vm->unlock();
vmm->trigger(VirtualMachineManager::SNAPSHOT_REVERT,vid);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::snapshot_delete(
int vid,
int snap_id,
string& error_str)
{
ostringstream oss;
int rc;
Nebula& nd = Nebula::instance();
VirtualMachineManager* vmm = nd.get_vmm();
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "Could not delete snapshot " << snap_id << " for VM " << vid
<< ", VM does not exist" ;
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
if ( vm->get_state() != VirtualMachine::ACTIVE ||
vm->get_lcm_state() != VirtualMachine::RUNNING )
{
oss << "Could not delete snapshot " << snap_id << " for VM " << vid
<< ", wrong state.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
rc = vm->set_active_snapshot(snap_id);
if ( rc == -1 )
{
oss << "Could not delete snapshot " << snap_id << " for VM " << vid
<< ", it does not exist.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
vm->set_state(VirtualMachine::HOTPLUG_SNAPSHOT);
vm->set_resched(false);
vmpool->update(vm);
vm->unlock();
vmm->trigger(VirtualMachineManager::SNAPSHOT_DELETE,vid);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::attach_nic(
int vid,
VirtualMachineTemplate* tmpl,
string & error_str)
{
ostringstream oss;
int max_nic_id;
int uid;
int oid;
int network_id;
VectorAttribute * nic;
Nebula& nd = Nebula::instance();
VirtualMachineManager* vmm = nd.get_vmm();
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "Could not add a new NIC to VM " << vid
<< ", VM does not exist" ;
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
if ( vm->get_state() != VirtualMachine::ACTIVE ||
vm->get_lcm_state() != VirtualMachine::RUNNING )
{
oss << "Could not add a new NIC to VM " << vid << ", wrong state.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
vm->get_nic_info(max_nic_id);
vm->set_state(VirtualMachine::HOTPLUG_NIC);
vm->set_resched(false);
uid = vm->get_uid();
oid = vm->get_oid();
vmpool->update(vm);
vm->unlock();
nic = VirtualMachine::set_up_attach_nic(oid,
tmpl,
max_nic_id,
uid,
network_id,
error_str);
vm = vmpool->get(vid, true);
if ( vm == 0 )
{
VirtualMachine::release_network_leases(nic, vid);
oss << "Could not attach a new NIC to VM " << vid
<< ", VM does not exist after setting its state to HOTPLUG." ;
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
if ( nic == 0 )
{
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->unlock();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
else
{
vm->set_attach_nic(nic);
}
vmpool->update(vm);
vm->unlock();
vmm->trigger(VirtualMachineManager::ATTACH_NIC,vid);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::detach_nic(
int vid,
int nic_id,
string& error_str)
{
ostringstream oss;
Nebula& nd = Nebula::instance();
VirtualMachineManager* vmm = nd.get_vmm();
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "VirtualMachine " << vid << " no longer exists";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
if ( vm->get_state() != VirtualMachine::ACTIVE ||
vm->get_lcm_state() != VirtualMachine::RUNNING )
{
oss << "Could not detach NIC from VM " << vid << ", wrong state.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
if ( vm->set_attach_nic(nic_id) == -1 )
{
oss << "Could not detach NIC with NIC_ID " << nic_id
<< ", it does not exist.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
vm->set_state(VirtualMachine::HOTPLUG_NIC);
vm->set_resched(false);
vmpool->update(vm);
vm->unlock();
vmm->trigger(VirtualMachineManager::DETACH_NIC,vid);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -702,6 +702,9 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose)
}
vm->set_resched(false);
vm->delete_snapshots();
vmpool->update(vm);
vm->set_etime(the_time);
@ -736,6 +739,8 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose)
case VirtualMachine::HOTPLUG_SAVEAS:
case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF:
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
case VirtualMachine::HOTPLUG_SNAPSHOT:
case VirtualMachine::HOTPLUG_NIC:
vm->set_running_etime(the_time);
vmpool->update_history(vm);

View File

@ -153,6 +153,21 @@ void LifeCycleManager::trigger(Actions action, int _vid)
aname = "SAVEAS_HOT_FAILURE";
break;
case ATTACH_NIC_SUCCESS:
aname = "ATTACH_NIC_SUCCESS";
break;
case ATTACH_NIC_FAILURE:
aname = "ATTACH_NIC_FAILURE";
break;
case DETACH_NIC_SUCCESS:
aname = "DETACH_NIC_SUCCESS";
break;
case DETACH_NIC_FAILURE:
aname = "DETACH_NIC_FAILURE";
case CLEANUP_SUCCESS:
aname = "CLEANUP_SUCCESS";
break;
@ -161,6 +176,30 @@ void LifeCycleManager::trigger(Actions action, int _vid)
aname = "CLEANUP_FAILURE";
break;
case SNAPSHOT_CREATE_SUCCESS:
aname = "SNAPSHOT_CREATE_SUCCESS";
break;
case SNAPSHOT_CREATE_FAILURE:
aname = "SNAPSHOT_CREATE_FAILURE";
break;
case SNAPSHOT_REVERT_SUCCESS:
aname = "SNAPSHOT_REVERT_SUCCESS";
break;
case SNAPSHOT_REVERT_FAILURE:
aname = "SNAPSHOT_REVERT_FAILURE";
break;
case SNAPSHOT_DELETE_SUCCESS:
aname = "SNAPSHOT_DELETE_SUCCESS";
break;
case SNAPSHOT_DELETE_FAILURE:
aname = "SNAPSHOT_DELETE_FAILURE";
break;
case DEPLOY:
aname = "DEPLOY";
break;
@ -322,6 +361,22 @@ void LifeCycleManager::do_action(const string &action, void * arg)
{
saveas_hot_failure_action(vid);
}
else if (action == "ATTACH_NIC_SUCCESS")
{
attach_nic_success_action(vid);
}
else if (action == "ATTACH_NIC_FAILURE")
{
attach_nic_failure_action(vid);
}
else if (action == "DETACH_NIC_SUCCESS")
{
detach_nic_success_action(vid);
}
else if (action == "DETACH_NIC_FAILURE")
{
detach_nic_failure_action(vid);
}
else if (action == "CLEANUP_SUCCESS")
{
cleanup_callback_action(vid);
@ -330,6 +385,30 @@ void LifeCycleManager::do_action(const string &action, void * arg)
{
cleanup_callback_action(vid);
}
else if (action == "SNAPSHOT_CREATE_SUCCESS")
{
snapshot_create_success(vid);
}
else if (action == "SNAPSHOT_CREATE_FAILURE")
{
snapshot_create_failure(vid);
}
else if (action == "SNAPSHOT_REVERT_SUCCESS")
{
snapshot_revert_success(vid);
}
else if (action == "SNAPSHOT_REVERT_FAILURE")
{
snapshot_revert_failure(vid);
}
else if (action == "SNAPSHOT_DELETE_SUCCESS")
{
snapshot_delete_success(vid);
}
else if (action == "SNAPSHOT_DELETE_FAILURE")
{
snapshot_delete_failure(vid);
}
else if (action == "DEPLOY")
{
deploy_action(vid);

View File

@ -45,6 +45,8 @@ void LifeCycleManager::save_success_action(int vid)
vm->set_state(VirtualMachine::PROLOG_MIGRATE);
vm->delete_snapshots();
vmpool->update(vm);
vm->set_previous_etime(the_time);
@ -81,6 +83,10 @@ void LifeCycleManager::save_success_action(int vid)
// SUSPENDED STATE
//----------------------------------------------------
vm->delete_snapshots();
vmpool->update(vm);
vm->set_running_etime(the_time);
vm->set_etime(the_time);
@ -107,6 +113,8 @@ void LifeCycleManager::save_success_action(int vid)
vm->set_state(VirtualMachine::EPILOG_STOP);
vm->delete_snapshots();
vmpool->update(vm);
vm->set_epilog_stime(the_time);
@ -272,6 +280,8 @@ void LifeCycleManager::deploy_success_action(int vid)
vm->set_state(VirtualMachine::RUNNING);
vm->delete_snapshots();
vmpool->update(vm);
vm->log("LCM", Log::INFO, "New VM state is RUNNING");
@ -464,6 +474,8 @@ void LifeCycleManager::shutdown_success_action(int vid)
vm->set_state(VirtualMachine::EPILOG);
vm->delete_snapshots();
vmpool->update(vm);
vm->set_epilog_stime(the_time);
@ -484,6 +496,10 @@ void LifeCycleManager::shutdown_success_action(int vid)
// POWEROFF STATE
//----------------------------------------------------
vm->delete_snapshots();
vmpool->update(vm);
vm->set_running_etime(the_time);
vm->set_etime(the_time);
@ -859,6 +875,8 @@ void LifeCycleManager::cancel_success_action(int vid)
vm->set_state(VirtualMachine::EPILOG);
vm->delete_snapshots();
vmpool->update(vm);
vm->set_reason(History::CANCEL);
@ -987,6 +1005,8 @@ void LifeCycleManager::monitor_suspend_action(int vid)
vm->set_resched(false);
vm->delete_snapshots();
vmpool->update(vm);
vm->set_running_etime(the_time);
@ -1073,6 +1093,8 @@ void LifeCycleManager::failure_action(VirtualMachine * vm)
vm->set_resched(false);
vm->delete_snapshots();
vmpool->update(vm);
vm->set_etime(the_time);
@ -1198,6 +1220,265 @@ void LifeCycleManager::detach_failure_action(int vid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::snapshot_create_success(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_SNAPSHOT )
{
vm->clear_active_snapshot();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
}
else
{
vm->log("LCM",Log::ERROR,"snapshot_create_success, VM in a wrong state");
}
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::snapshot_create_failure(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_SNAPSHOT )
{
vm->delete_active_snapshot();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
}
else
{
vm->log("LCM",Log::ERROR,"snapshot_create_failure, VM in a wrong state");
}
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::snapshot_revert_success(int vid)
{
// TODO: snapshot list may be inconsistent with hypervisor info
// after a revert operation
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_SNAPSHOT )
{
vm->clear_active_snapshot();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
}
else
{
vm->log("LCM",Log::ERROR,"snapshot_revert_success, VM in a wrong state");
}
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::snapshot_revert_failure(int vid)
{
// TODO: for now, it is the same code
snapshot_revert_success(vid);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::snapshot_delete_success(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_SNAPSHOT )
{
vm->delete_active_snapshot();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
}
else
{
vm->log("LCM",Log::ERROR,"snapshot_delete_success, VM in a wrong state");
}
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::snapshot_delete_failure(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_SNAPSHOT )
{
vm->clear_active_snapshot();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
}
else
{
vm->log("LCM",Log::ERROR,"snapshot_delete_failure, VM in a wrong state");
}
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::attach_nic_success_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC )
{
vm->clear_attach_nic();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
}
else
{
vm->log("LCM",Log::ERROR,"attach_nic_success_action, VM in a wrong state");
}
vm->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::attach_nic_failure_action(int vid)
{
VirtualMachine * vm;
VectorAttribute * nic;
int uid;
int gid;
int oid;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC )
{
nic = vm->delete_attach_nic();
uid = vm->get_uid();
gid = vm->get_gid();
oid = vm->get_oid();
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->unlock();
if ( nic != 0 )
{
Template tmpl;
tmpl.set(nic);
Quotas::quota_del(Quotas::NETWORK, uid, gid, &tmpl);
VirtualMachine::release_network_leases(nic, oid);
}
}
else
{
vm->log("LCM",Log::ERROR,"attach_nic_failure_action, VM in a wrong state");
vm->unlock();
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::detach_nic_success_action(int vid)
{
attach_nic_failure_action(vid);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::detach_nic_failure_action(int vid)
{
attach_nic_success_action(vid);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::saveas_hot_success_action(int vid)
{
Nebula& nd = Nebula::instance();
@ -1308,3 +1589,6 @@ void LifeCycleManager::saveas_hot_failure_action(int vid)
image->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -42,7 +42,12 @@ class VirtualMachineDriver < OpenNebulaDriver
:log => "LOG",
:attach_disk => "ATTACHDISK",
:detach_disk => "DETACHDISK",
:cleanup => "CLEANUP"
:snapshot_create => "SNAPSHOTCREATE",
:snapshot_revert => "SNAPSHOTREVERT",
:snapshot_delete => "SNAPSHOTDELETE",
:cleanup => "CLEANUP",
:attach_nic => "ATTACHNIC",
:detach_nic => "DETACHNIC"
}
POLL_ATTRIBUTE = {
@ -79,18 +84,26 @@ class VirtualMachineDriver < OpenNebulaDriver
@hosts = Array.new
register_action(ACTION[:deploy].to_sym, method("deploy"))
register_action(ACTION[:shutdown].to_sym, method("shutdown"))
register_action(ACTION[:reboot].to_sym, method("reboot"))
register_action(ACTION[:reset].to_sym, method("reset"))
register_action(ACTION[:cancel].to_sym, method("cancel"))
register_action(ACTION[:save].to_sym, method("save"))
register_action(ACTION[:restore].to_sym, method("restore"))
register_action(ACTION[:migrate].to_sym, method("migrate"))
register_action(ACTION[:poll].to_sym, method("poll"))
register_action(ACTION[:attach_disk].to_sym, method("attach_disk"))
register_action(ACTION[:detach_disk].to_sym, method("detach_disk"))
register_action(ACTION[:cleanup].to_sym, method("cleanup"))
register_action(ACTION[:deploy].to_sym, method("deploy"))
register_action(ACTION[:shutdown].to_sym, method("shutdown"))
register_action(ACTION[:reboot].to_sym, method("reboot"))
register_action(ACTION[:reset].to_sym, method("reset"))
register_action(ACTION[:cancel].to_sym, method("cancel"))
register_action(ACTION[:save].to_sym, method("save"))
register_action(ACTION[:restore].to_sym, method("restore"))
register_action(ACTION[:migrate].to_sym, method("migrate"))
register_action(ACTION[:poll].to_sym, method("poll"))
register_action(ACTION[:attach_disk].to_sym, method("attach_disk"))
register_action(ACTION[:detach_disk].to_sym, method("detach_disk"))
register_action(ACTION[:snapshot_create].to_sym,
method("snapshot_create"))
register_action(ACTION[:snapshot_revert].to_sym,
method("snapshot_revert"))
register_action(ACTION[:snapshot_delete].to_sym,
method("snapshot_delete"))
register_action(ACTION[:cleanup].to_sym, method("cleanup"))
register_action(ACTION[:attach_nic].to_sym, method("attach_nic"))
register_action(ACTION[:detach_nic].to_sym, method("detach_nic"))
end
# Decodes the encoded XML driver message received from the core
@ -170,6 +183,31 @@ class VirtualMachineDriver < OpenNebulaDriver
send_message(ACTION[:detach_disk],RESULT[:failure],id,error)
end
def attach_nic(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:attach_nic],RESULT[:failure],id,error)
end
def detach_nic(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:detach_nic],RESULT[:failure],id,error)
end
def snapshot_create(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:snapshot_create],RESULT[:failure],id,error)
end
def snapshot_revert(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:snapshot_revert],RESULT[:failure],id,error)
end
def snapshot_delete(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:snapshot_delete],RESULT[:failure],id,error)
end
def cleanup(id, drv_message)
error = "Action not implemented by driver #{self.class}"
send_message(ACTION[:cleanup],RESULT[:failure],id,error)

View File

@ -26,8 +26,8 @@ import org.w3c.dom.Node;
* It also offers static XML-RPC call wrappers.
*/
public class VirtualMachine extends PoolElement{
private static final String METHOD_PREFIX = "vm.";
private static final String ALLOCATE = METHOD_PREFIX + "allocate";
private static final String INFO = METHOD_PREFIX + "info";
private static final String DEPLOY = METHOD_PREFIX + "deploy";
@ -42,6 +42,8 @@ public class VirtualMachine extends PoolElement{
private static final String RENAME = METHOD_PREFIX + "rename";
private static final String UPDATE = METHOD_PREFIX + "update";
private static final String RESIZE = METHOD_PREFIX + "resize";
private static final String ATTACHNIC = METHOD_PREFIX + "attachnic";
private static final String DETACHNIC = METHOD_PREFIX + "detachnic";
private static final String[] VM_STATES =
{
@ -92,7 +94,9 @@ public class VirtualMachine extends PoolElement{
"BOOT_POWEROFF",
"BOOT_SUSPENDED",
"BOOT_STOPPED",
"CLEANUP_DELETE" };
"CLEANUP_DELETE",
"HOTPLUG_SNAPSHOT",
"HOTPLUG_NIC" };
private static final String[] SHORT_LCM_STATES =
{
@ -119,7 +123,8 @@ public class VirtualMachine extends PoolElement{
"boot",
"boot",
"boot",
"clea" };
"clea",
"snap" };
/**
* Creates a new VM representation.
@ -312,7 +317,7 @@ public class VirtualMachine extends PoolElement{
}
/**
* Detaches a disk to a running VM
* Detaches a disk from a running VM
*
* @param client XML-RPC Client.
* @param id The virtual machine id (vid) of the target instance.
@ -325,6 +330,34 @@ public class VirtualMachine extends PoolElement{
return client.call(DETACH, id, diskId);
}
/**
* Attaches a NIC to a running VM
*
* @param client XML-RPC Client.
* @param id The virtual machine id (vid) of the target instance.
* @param nicTemplate Template containing the new NIC definition
* @return If an error occurs the error message contains the reason.
*/
public static OneResponse attachnic(Client client, int id,
String nicTemplate)
{
return client.call(ATTACHNIC, id, nicTemplate);
}
/**
* Detaches a NIC from a running VM
*
* @param client XML-RPC Client.
* @param id The virtual machine id (vid) of the target instance.
* @param nicId The NIC_ID of the NIC to detach
* @return If an error occurs the error message contains the reason.
*/
public static OneResponse detachnic(Client client, int id,
int nicId)
{
return client.call(DETACHNIC, id, nicId);
}
/**
* Renames this VM
*
@ -559,7 +592,7 @@ public class VirtualMachine extends PoolElement{
}
/**
* Detaches a disk to a running VM
* Detaches a disk from a running VM
*
* @param diskId The DISK_ID of the disk to detach
* @return If an error occurs the error message contains the reason.
@ -569,6 +602,28 @@ public class VirtualMachine extends PoolElement{
return detachdisk(client, id, diskId);
}
/**
* Attaches a NIC to a running VM
*
* @param nicTemplate Template containing the new NIC definition
* @return If an error occurs the error message contains the reason.
*/
public OneResponse attachnic(String nicTemplate)
{
return attachnic(client, id, nicTemplate);
}
/**
* Detaches a NIC from a running VM
*
* @param nicId The NIC_ID of the NIC to detach
* @return If an error occurs the error message contains the reason.
*/
public OneResponse detachnic(int nicId)
{
return detachnic(client, id, nicId);
}
/**
* Renames this VM
*

View File

@ -23,7 +23,6 @@ module OpenNebula
# Constants and Class Methods
#######################################################################
VM_METHODS = {
:info => "vm.info",
:allocate => "vm.allocate",
@ -38,7 +37,12 @@ module OpenNebula
:detach => "vm.detach",
:rename => "vm.rename",
:update => "vm.update",
:resize => "vm.resize"
:resize => "vm.resize",
:snapshotcreate => "vm.snapshotcreate",
:snapshotrevert => "vm.snapshotrevert",
:snapshotdelete => "vm.snapshotdelete",
:attachnic => "vm.attachnic",
:detachnic => "vm.detachnic"
}
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED
@ -47,7 +51,8 @@ module OpenNebula
LCM_STATE=%w{LCM_INIT PROLOG BOOT RUNNING MIGRATE SAVE_STOP SAVE_SUSPEND
SAVE_MIGRATE PROLOG_MIGRATE PROLOG_RESUME EPILOG_STOP EPILOG
SHUTDOWN CANCEL FAILURE CLEANUP_RESUBMIT UNKNOWN HOTPLUG SHUTDOWN_POWEROFF
BOOT_UNKNOWN BOOT_POWEROFF BOOT_SUSPENDED BOOT_STOPPED CLEANUP_DELETE}
BOOT_UNKNOWN BOOT_POWEROFF BOOT_SUSPENDED BOOT_STOPPED CLEANUP_DELETE
HOTPLUG_SNAPSHOT HOTPLUG_NIC}
SHORT_VM_STATES={
"INIT" => "init",
@ -84,7 +89,9 @@ module OpenNebula
"BOOT_POWEROFF" => "boot",
"BOOT_SUSPENDED" => "boot",
"BOOT_STOPPED" => "boot",
"CLEANUP_DELETE" => "clea"
"CLEANUP_DELETE" => "clea",
"HOTPLUG_SNAPSHOT" => "snap",
"HOTPLUG_NIC" => "hotp"
}
MIGRATE_REASON=%w{NONE ERROR STOP_RESUME USER CANCEL}
@ -244,23 +251,39 @@ module OpenNebula
end
# Attaches a disk to a running VM
def attachdisk(disk)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(VM_METHODS[:attach], @pe_id, disk)
rc = nil if !OpenNebula.is_error?(rc)
return rc
#
# @param disk_template [String] Template containing a DISK element
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def attachdisk(disk_template)
return call(VM_METHODS[:attach], @pe_id, disk_template)
end
# Detaches a disk from a running VM
def detachdisk(disk)
return Error.new('ID not defined') if !@pe_id
#
# @param disk_id [Integer] Id of the disk to be detached
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def detachdisk(disk_id)
return call(VM_METHODS[:detach], @pe_id, disk_id)
end
rc = @client.call(VM_METHODS[:detach], @pe_id, disk)
rc = nil if !OpenNebula.is_error?(rc)
# Attaches a NIC to a running VM
#
# @param nic_template [String] Template containing a NIC element
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def attachnic(nic_template)
return call(VM_METHODS[:attachnic], @pe_id, nic_template)
end
return rc
# Detaches a NIC from a running VM
#
# @param disk_id [Integer] Id of the NIC to be detached
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def detachnic(nic_id)
return call(VM_METHODS[:detachnic], @pe_id, nic_id)
end
# Deletes a VM from the pool
@ -427,6 +450,39 @@ module OpenNebula
return call(VM_METHODS[:rename], @pe_id, name)
end
# Creates a new VM snapshot
#
# @param name [String] Name for the snapshot.
#
# @return [Integer, OpenNebula::Error] The new snaphost ID in case
# of success, Error otherwise
def snapshot_create(name="")
return Error.new('ID not defined') if !@pe_id
name ||= ""
return @client.call(VM_METHODS[:snapshotcreate], @pe_id, name)
end
# Reverts to a snapshot
#
# @param snap_id [Integer] Id of the snapshot
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def snapshot_revert(snap_id)
return call(VM_METHODS[:snapshotrevert], @pe_id, snap_id)
end
# Deletes a VM snapshot
#
# @param snap_id [Integer] Id of the snapshot
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def snapshot_delete(snap_id)
return call(VM_METHODS[:snapshotdelete], @pe_id, snap_id)
end
#######################################################################
# Helpers to get VirtualMachine information
#######################################################################

View File

@ -140,6 +140,11 @@ module Migrator
@db.run "DROP TABLE old_host_pool;"
########################################################################
# Feature #1565: New cid column
# Feature #471: IPv6 addresses
########################################################################
@db.run "ALTER TABLE network_pool RENAME TO old_network_pool;"
@db.run "CREATE TABLE network_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, cid INTEGER, UNIQUE(name,uid));"
@ -148,10 +153,13 @@ module Migrator
cluster_id = doc.root.get_text('CLUSTER_ID').to_s
doc.root.add_element("GLOBAL_PREFIX")
doc.root.add_element("SITE_PREFIX")
@db[:network_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => row[:body],
:body => doc.root.to_s,
:uid => row[:uid],
:gid => row[:gid],
:owner_u => row[:owner_u],
@ -313,7 +321,6 @@ module Migrator
@db.run "DROP TABLE old_group_pool;"
########################################################################
# Bug #1694: SYSTEM_DS is now set with the method adddatastore
########################################################################
@ -493,6 +500,44 @@ module Migrator
@db.run "DROP TABLE old_template_pool;"
########################################################################
# Feature #1691 Add new attribute NIC/NIC_ID
########################################################################
@db.run "ALTER TABLE vm_pool RENAME TO old_vm_pool;"
@db.run "CREATE TABLE vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER);"
@db.fetch("SELECT * FROM old_vm_pool") do |row|
if ( row[:state] != 6 ) # DONE
doc = Document.new(row[:body])
nic_id = 0
doc.root.each_element("TEMPLATE/NIC") { |e|
e.delete_element("NIC_ID")
e.add_element("NIC_ID").text = (nic_id).to_s
nic_id += 1
}
row[:body] = doc.root.to_s
end
@db[:vm_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => row[:body],
:uid => row[:uid],
:gid => row[:gid],
:last_poll => row[:last_poll],
:state => row[:state],
:lcm_state => row[:lcm_state],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u])
end
@db.run "DROP TABLE old_vm_pool;"
########################################################################
#

View File

@ -102,7 +102,9 @@ var oZones = {
"BOOT_POWEROFF",
"BOOT_SUSPENDED",
"BOOT_STOPPED",
"CLEANUP_DELETE"][value]);
"CLEANUP_DELETE",
"HOTPLUG_SNAPSHOT",
"HOTPLUG_NIC"][value]);
break;
case "IMAGE":
case "image":

View File

@ -254,7 +254,13 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr vm_monitoring(new VirtualMachineMonitoring());
xmlrpc_c::methodPtr vm_attach(new VirtualMachineAttach());
xmlrpc_c::methodPtr vm_detach(new VirtualMachineDetach());
xmlrpc_c::methodPtr vm_attachnic(new VirtualMachineAttachNic());
xmlrpc_c::methodPtr vm_detachnic(new VirtualMachineDetachNic());
xmlrpc_c::methodPtr vm_resize(new VirtualMachineResize());
xmlrpc_c::methodPtr vm_snap_create(new VirtualMachineSnapshotCreate());
xmlrpc_c::methodPtr vm_snap_revert(new VirtualMachineSnapshotRevert());
xmlrpc_c::methodPtr vm_snap_delete(new VirtualMachineSnapshotDelete());
xmlrpc_c::methodPtr vm_pool_acct(new VirtualMachinePoolAccounting());
xmlrpc_c::methodPtr vm_pool_monitoring(new VirtualMachinePoolMonitoring());
@ -396,9 +402,14 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vm.monitoring", vm_monitoring);
RequestManagerRegistry.addMethod("one.vm.attach", vm_attach);
RequestManagerRegistry.addMethod("one.vm.detach", vm_detach);
RequestManagerRegistry.addMethod("one.vm.attachnic", vm_attachnic);
RequestManagerRegistry.addMethod("one.vm.detachnic", vm_detachnic);
RequestManagerRegistry.addMethod("one.vm.rename", vm_rename);
RequestManagerRegistry.addMethod("one.vm.resize", vm_resize);
RequestManagerRegistry.addMethod("one.vm.update", vm_update);
RequestManagerRegistry.addMethod("one.vm.snapshotcreate", vm_snap_create);
RequestManagerRegistry.addMethod("one.vm.snapshotrevert", vm_snap_revert);
RequestManagerRegistry.addMethod("one.vm.snapshotdelete", vm_snap_delete);
RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info);
RequestManagerRegistry.addMethod("one.vmpool.accounting", vm_pool_acct);

View File

@ -1421,3 +1421,251 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
success_response(id, att);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineSnapshotCreate::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
int rc;
int snap_id;
string error_str;
int id = xmlrpc_c::value_int(paramList.getInt(1));
string name = xmlrpc_c::value_string(paramList.getString(2));
// -------------------------------------------------------------------------
// Authorize the operation
// -------------------------------------------------------------------------
if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
{
return;
}
rc = dm->snapshot_create(id, name, snap_id, error_str);
if ( rc != 0 )
{
failure_response(ACTION,
request_error(error_str, ""),
att);
}
else
{
success_response(snap_id, att);
}
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineSnapshotRevert::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
int rc;
string error_str;
int id = xmlrpc_c::value_int(paramList.getInt(1));
int snap_id = xmlrpc_c::value_int(paramList.getInt(2));
// -------------------------------------------------------------------------
// Authorize the operation
// -------------------------------------------------------------------------
if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
{
return;
}
rc = dm->snapshot_revert(id, snap_id, error_str);
if ( rc != 0 )
{
failure_response(ACTION,
request_error(error_str, ""),
att);
}
else
{
success_response(id, att);
}
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineSnapshotDelete::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
int rc;
string error_str;
int id = xmlrpc_c::value_int(paramList.getInt(1));
int snap_id = xmlrpc_c::value_int(paramList.getInt(2));
// -------------------------------------------------------------------------
// Authorize the operation
// -------------------------------------------------------------------------
if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
{
return;
}
rc = dm->snapshot_delete(id, snap_id, error_str);
if ( rc != 0 )
{
failure_response(ACTION,
request_error(error_str, ""),
att);
}
else
{
success_response(id, att);
}
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineAttachNic::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
VirtualMachineTemplate tmpl;
PoolObjectAuth host_perms;
int rc;
string error_str;
int id = xmlrpc_c::value_int(paramList.getInt(1));
string str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
// -------------------------------------------------------------------------
// Parse NIC template
// -------------------------------------------------------------------------
rc = tmpl.parse_str_or_xml(str_tmpl, error_str);
if ( rc != 0 )
{
failure_response(INTERNAL, error_str, att);
return;
}
// -------------------------------------------------------------------------
// Authorize the operation, restricted attributes & check quotas
// -------------------------------------------------------------------------
if ( vm_authorization(id, 0, &tmpl, att, 0, 0, auth_op) == false )
{
return;
}
if (att.uid != UserPool::ONEADMIN_ID && att.gid!=GroupPool::ONEADMIN_ID)
{
string aname;
if (tmpl.check(aname))
{
ostringstream oss;
oss << "NIC includes a restricted attribute " << aname;
failure_response(AUTHORIZATION,
authorization_error(oss.str(), att),
att);
return;
}
}
if ( quota_authorization(&tmpl, Quotas::NETWORK, att) == false )
{
return;
}
rc = dm->attach_nic(id, &tmpl, error_str);
if ( rc != 0 )
{
quota_rollback(&tmpl, Quotas::NETWORK, att);
failure_response(ACTION,
request_error(error_str, ""),
att);
}
else
{
success_response(id, att);
}
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineDetachNic::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
int rc;
string error_str;
int id = xmlrpc_c::value_int(paramList.getInt(1));
int nic_id = xmlrpc_c::value_int(paramList.getInt(2));
// -------------------------------------------------------------------------
// Authorize the operation
// -------------------------------------------------------------------------
if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
{
return;
}
rc = dm->detach_nic(id, nic_id, error_str);
if ( rc != 0 )
{
failure_response(ACTION,
request_error(error_str, ""),
att);
}
else
{
success_response(id, att);
}
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -254,14 +254,28 @@ int VirtualMachineActionsPoolXML::action(
try
{
client->call( client->get_endpoint(), // serverUrl
if (action == "snapshot-create")
{
client->call( client->get_endpoint(), // serverUrl
"one.vm.snapshotcreate", // methodName
"sis", // arguments format
&result, // resultP
client->get_oneauth().c_str(), // session
vid, // VM ID
string("").c_str() // snapshot name
);
}
else
{
client->call( client->get_endpoint(), // serverUrl
"one.vm.action", // methodName
"ssi", // arguments format
&result, // resultP
client->get_oneauth().c_str(), // session
action.c_str(), // action
vid // VM ID
);
);
}
}
catch (exception const& e)
{

View File

@ -312,7 +312,8 @@ int VirtualMachineXML::parse_action_name(string& action_st)
&& action_st != "reboot"
&& action_st != "reset"
&& action_st != "poweroff"
&& action_st != "finalize")
&& action_st != "finalize"
&& action_st != "snapshot-create")
{
return -1;
}

View File

@ -27,9 +27,10 @@ class OpenNebulaVNC
attr_reader :proxy_port
def initialize(config, logger, opts={
:json_errors => true,
:token_folder_name => 'sunstone_vnc_tokens'})
def initialize(config, logger, options = {})
opts={ :json_errors => true,
:token_folder_name => 'sunstone_vnc_tokens'}.merge(options)
@pipe = nil
@token_folder = File.join(VAR_LOCATION, opts[:token_folder_name])
@proxy_path = config[:vnc_proxy_path]
@ -38,6 +39,8 @@ class OpenNebulaVNC
@wss = config[:vnc_proxy_support_wss]
@lock_file = config[:lock_file] || '/tmp/novnc.lock'
if (@wss == "yes") || (@wss == "only") || (@wss == true)
@enable_wss = true
@cert = config[:vnc_proxy_cert]
@ -48,21 +51,24 @@ class OpenNebulaVNC
@options = opts
@logger = logger
begin
Dir.mkdir(@token_folder)
rescue Exception => e
@logger.error "Cannot create token folder"
@logger.error e.message
end
end
def start
if @proxy_path == nil || @proxy_path.empty?
@logger.info "VNC proxy not configured"
return
if is_running?
message="VNC server already running"
STDERR.puts message
@logger.info message
return false
end
if @proxy_path == nil || @proxy_path.empty?
@logger.error "VNC proxy not configured"
return false
end
create_token_dir
proxy_options = "--target-config=#{@token_folder} "
if @enable_wss
@ -75,16 +81,31 @@ class OpenNebulaVNC
begin
@logger.info { "Starting VNC proxy: #{cmd}" }
@pipe = IO.popen(cmd,'r')
pid=start_daemon(cmd, 'VNC_LOG')
rescue Exception => e
@logger.error e.message
return
return false
end
File.write(@lock_file, pid)
sleep 1
if !is_running?
message="Error starting VNC proxy"
STDERR.puts message
@logger.error message
File.delete(@lock_file) if File.exist?(@lock_file)
return false
end
true
end
def proxy(vm_resource)
# Check configurations and VM attributes
if !@pipe
if !is_running?
return error(400, "VNC Proxy is not running")
end
@ -121,12 +142,6 @@ class OpenNebulaVNC
:token => random_str,
}
# Delete token soon after
Thread.new do
sleep TOKEN_EXPIRE_SECONDS
delete_token(token_file)
end
return [200, info.to_json]
end
@ -140,16 +155,40 @@ class OpenNebulaVNC
end
end
def stop
if !@pipe then return end
@logger.info "Killing VNC proxy"
Process.kill('TERM',@pipe.pid)
@pipe.close
begin
Dir.rmdir(@token_folder)
rescue => e
@logger.error "Error deleting token folder"
@logger.error e.message
def stop(force=false)
pid=get_pid
if pid
@logger.info "Killing VNC proxy"
signal=(force ? 'KILL' : 'TERM')
Process.kill(signal ,pid)
sleep 1
if is_running?
message="VNC server is still running"
STDERR.puts message
logger.error message
return false
end
delete_token_dir
else
message="VNC server is not running"
@logger.info message
STDERR.puts message
end
true
end
def status
if is_running?
STDOUT.puts "VNC is running"
true
else
STDOUT.puts "VNC is NOT running"
false
end
end
@ -163,4 +202,56 @@ class OpenNebulaVNC
end
end
def create_token_dir
delete_token_dir
begin
Dir.mkdir(@token_folder) if !File.exist?(@token_folder)
rescue Exception => e
@logger.error "Cannot create token folder"
@logger.error e.message
end
end
def delete_token_dir
if File.exist?(@token_folder)
begin
Dir.glob("#{@token_folder}/*").each do |file|
File.delete(file)
end
Dir.rmdir(@token_folder)
rescue => e
@logger.error "Error deleting token folder"
@logger.error e.message
end
end
end
def is_running?
if File.exist?(@lock_file)
pid=File.read(@lock_file).strip
if system("ps #{pid} 1> /dev/null")
return pid.to_i
end
@logger.info "Deleting stale lock file"
File.delete(@lock_file)
end
false
end
alias_method :get_pid, :is_running?
def start_daemon(cmd, log)
pid=spawn(*cmd.split(" "),
:pgroup => true,
:in => :close,
[:out, :err] => [log, "a"],
:close_others => true )
Process.detach(pid)
pid
end
end

87
src/sunstone/bin/novnc-server Executable file
View File

@ -0,0 +1,87 @@
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
ONE_LOCATION = ENV["ONE_LOCATION"]
if !ONE_LOCATION
LOG_LOCATION = "/var/log/one"
LOCK_LOCATION = "/var/lock/one"
VAR_LOCATION = "/var/lib/one"
ETC_LOCATION = "/etc/one"
RUBY_LIB_LOCATION = "/usr/lib/one/ruby"
else
VAR_LOCATION = ONE_LOCATION + "/var"
LOCK_LOCATION = ONE_LOCATION + "/var"
LOG_LOCATION = ONE_LOCATION + "/var"
ETC_LOCATION = ONE_LOCATION + "/etc"
RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby"
end
VNC_LOCK = LOCK_LOCATION + "/novnc.lock"
VNC_LOG = LOG_LOCATION + "/novnc.log"
CONFIGURATION_FILE = ETC_LOCATION + "/sunstone-server.conf"
PLUGIN_CONFIGURATION_FILE = ETC_LOCATION + "/sunstone-plugins.yaml"
SUNSTONE_ROOT_DIR = File.dirname(__FILE__)
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+'/cloud'
$: << SUNSTONE_ROOT_DIR
$: << SUNSTONE_ROOT_DIR+'/models'
require 'logger'
require 'yaml'
require 'OpenNebulaVNC'
$log=Logger.new(VNC_LOG)
begin
conf = YAML.load_file(CONFIGURATION_FILE)
rescue Exception => e
STDERR.puts "Error parsing config file #{CONFIGURATION_FILE}: #{e.message}"
exit 1
end
vnc=OpenNebulaVNC.new(conf, $log)
if ARGV[0]
res=case ARGV[0].downcase.to_sym
when :start
vnc.start
when :stop
vnc.stop(ARGV[1]=='--force')
when :restart
vnc.stop
sleep 1
vnc.start
when :status
vnc.status
end
if !res
STDERR.puts "Error, check #{VNC_LOG}"
exit(-1)
end
else
exit(-1)
end

View File

@ -24,6 +24,7 @@ if [ -z "$ONE_LOCATION" ]; then
SUNSTONE_LOG=/var/log/one/sunstone.log
SUNSTONE_LOG_ERROR=/var/log/one/sunstone.error
SUNSTONE_CONF=/etc/one/sunstone-server.conf
NOVNC_SERVER=/usr/bin/novnc-server
else
SUNSTONE_PID=$ONE_LOCATION/var/sunstone.pid
SUNSTONE_SERVER=$ONE_LOCATION/lib/sunstone/sunstone-server.rb
@ -31,6 +32,7 @@ else
SUNSTONE_LOG=$ONE_LOCATION/var/sunstone.log
SUNSTONE_LOG_ERROR=$ONE_LOCATION/var/sunstone.error
SUNSTONE_CONF=$ONE_LOCATION/etc/sunstone-server.conf
NOVNC_SERVER=$ONE_LOCATION/bin/novnc-server
fi
setup()
@ -65,6 +67,13 @@ start()
exit 1
fi
# Start novnc server
$NOVNC_SERVER start
if [ "$?" != "0" ]; then
echo "Could not start novnc server" 1>&2
fi
# Start the sunstone daemon
touch $SUNSTONE_LOCK_FILE
ruby $SUNSTONE_SERVER > $SUNSTONE_LOG 2>$SUNSTONE_LOG_ERROR &
@ -95,6 +104,9 @@ start()
#
stop()
{
# Stop novnc server
$NOVNC_SERVER stop
if [ ! -f $SUNSTONE_PID ]; then
echo "Couldn't find sunstone-server process pid."
exit 1

12
src/sunstone/config.ru Executable file
View File

@ -0,0 +1,12 @@
# If you are using self contained installation set this variable to the
# install location
#ENV['ONE_LOCATION']='/path/to/OpenNebula/install'
WITH_RACKUP=true
$: << '.'
require 'sunstone-server'
run Sinatra::Application

View File

@ -31,6 +31,16 @@
:host: 127.0.0.1
:port: 9869
# Place where to store sessions, this value can be memory or memcache
# Use memcache when starting multiple server processes, for example,
# with passenger
:sessions: memory
# Memcache configuration
:memcache_host: localhost
:memcache_port: 11211
:memcache_namespace: opennebula.sunstone
################################################################################
# Log
################################################################################

View File

@ -110,7 +110,9 @@ var OpenNebula = {
"BOOT_POWEROFF",
"BOOT_SUSPENDED",
"BOOT_STOPPED",
"CLEANUP_DELETE"][value]);
"CLEANUP_DELETE",
"HOTPLUG_SNAPSHOT",
"HOTPLUG_NIC"][value]);
break;
case "IMAGE":
case "image":

View File

@ -50,7 +50,7 @@ var vm_graphs = [
];
var VNCstates=["RUNNING","SHUTDOWN","SHUTDOWN_POWEROFF","UNKNOWN","HOTPLUG","CANCEL","MIGRATE"];
var VNCstates=["RUNNING","SHUTDOWN","SHUTDOWN_POWEROFF","UNKNOWN","HOTPLUG","CANCEL","MIGRATE", "HOTPLUG_SNAPSHOT", "HOTPLUG_NIC"];
//Permanent storage for last value of aggregated network usage
//Used to calculate bandwidth
@ -1649,4 +1649,4 @@ $(document).ready(function(){
infoListener(dataTable_vMachines,'VM.showinfo');
$('div#vms_tab div.legend_div').hide();
})
})

View File

@ -80,7 +80,23 @@ set :config, conf
set :bind, settings.config[:host]
set :port, settings.config[:port]
use Rack::Session::Pool, :key => 'sunstone'
case settings.config[:sessions]
when 'memory'
use Rack::Session::Pool, :key => 'sunstone'
when 'memcache'
memcache_server=settings.config[:memcache_host]+':'<<
settings.config[:memcache_port].to_s
STDERR.puts memcache_server
use Rack::Session::Memcache,
:memcache_server => memcache_server,
:namespace => settings.config[:memcache_namespace]
else
STDERR.puts "Wrong value for :sessions in configuration file"
exit(-1)
end
# Enable logger
@ -104,10 +120,6 @@ set :cloud_auth, cloud_auth
configure do
set :run, false
set :vnc, OpenNebulaVNC.new(conf, settings.logger)
settings.vnc.start()
Kernel.at_exit do
settings.vnc.stop
end
end
##############################################################################
@ -396,4 +408,5 @@ post '/:resource/:id/action' do
request.body.read)
end
Sinatra::Application.run!
Sinatra::Application.run! if(!defined?(WITH_RACKUP))

View File

@ -1597,7 +1597,7 @@ void VirtualMachine::get_disk_info(int& max_disk_id,
int disk_id;
int num_disks;
max_disk_id = 0;
max_disk_id = -1;
num_disks = obj_template->get("DISK", disks);
@ -1740,7 +1740,6 @@ VectorAttribute * VirtualMachine::set_up_attach_disk(
int VirtualMachine::set_attach_disk(int disk_id)
{
int num_disks;
int d_id;
@ -1858,6 +1857,175 @@ VectorAttribute * VirtualMachine::delete_attach_disk()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::get_nic_info(int& max_nic_id)
{
vector<Attribute *> nics;
VectorAttribute * nic;
int nic_id;
int num_nics;
max_nic_id = -1;
num_nics = obj_template->get("NIC", nics);
for(int i=0; i<num_nics; i++)
{
nic = dynamic_cast<VectorAttribute * >(nics[i]);
if ( nic == 0 )
{
continue;
}
nic->vector_value("NIC_ID", nic_id);
if ( nic_id > max_nic_id )
{
max_nic_id = nic_id;
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
VectorAttribute * VirtualMachine::set_up_attach_nic(
int vm_id,
VirtualMachineTemplate * tmpl,
int max_nic_id,
int uid,
int& network_id,
string& error_str)
{
vector<Attribute *> nics;
VectorAttribute * new_nic;
Nebula& nd = Nebula::instance();
VirtualNetworkPool* vnpool = nd.get_vnpool();
network_id = -1;
// -------------------------------------------------------------------------
// Get the NIC attribute from the template
// -------------------------------------------------------------------------
if ( tmpl->get("NIC", nics) != 1 )
{
error_str = "The template must contain one NIC attribute";
return 0;
}
new_nic = new VectorAttribute(*(dynamic_cast<VectorAttribute * >(nics[0])));
// -------------------------------------------------------------------------
// Acquire the new network lease
// -------------------------------------------------------------------------
int rc = vnpool->nic_attribute(new_nic, max_nic_id+1, uid, vm_id, error_str);
if ( rc == -1 ) //-2 is not using a pre-defined network
{
delete new_nic;
return 0;
}
return new_nic;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::clear_attach_nic()
{
int num_nics;
vector<Attribute *> nics;
VectorAttribute * nic;
num_nics = obj_template->get("NIC", nics);
for(int i=0; i<num_nics; i++)
{
nic = dynamic_cast<VectorAttribute * >(nics[i]);
if ( nic == 0 )
{
continue;
}
if ( nic->vector_value("ATTACH") == "YES" )
{
nic->remove("ATTACH");
return;
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
VectorAttribute * VirtualMachine::delete_attach_nic()
{
vector<Attribute *> nics;
VectorAttribute * nic;
int num_nics = obj_template->get("NIC", nics);
for(int i=0; i<num_nics; i++)
{
nic = dynamic_cast<VectorAttribute * >(nics[i]);
if ( nic == 0 )
{
continue;
}
if ( nic->vector_value("ATTACH") == "YES" )
{
return static_cast<VectorAttribute * >(obj_template->remove(nic));
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::set_attach_nic(int nic_id)
{
int num_nics;
int n_id;
vector<Attribute *> nics;
VectorAttribute * nic;
num_nics = obj_template->get("NIC", nics);
for(int i=0; i<num_nics; i++)
{
nic = dynamic_cast<VectorAttribute * >(nics[i]);
if ( nic == 0 )
{
continue;
}
nic->vector_value("NIC_ID", n_id);
if ( n_id == nic_id )
{
nic->replace("ATTACH", "YES");
return 0;
}
}
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::release_disk_images()
{
int iid;
@ -1904,6 +2072,190 @@ void VirtualMachine::release_disk_images()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::new_snapshot(string& name, int& snap_id)
{
int num_snaps;
int id;
int max_id = -1;
vector<Attribute *> snaps;
VectorAttribute * snap;
num_snaps = obj_template->get("SNAPSHOT", snaps);
for(int i=0; i<num_snaps; i++)
{
snap = dynamic_cast<VectorAttribute * >(snaps[i]);
if ( snap == 0 )
{
continue;
}
snap->vector_value("SNAPSHOT_ID", id);
if (id > max_id)
{
max_id = id;
}
}
snap_id = max_id + 1;
if (name.empty())
{
ostringstream oss;
oss << "snapshot-" << snap_id;
name = oss.str();
}
snap = new VectorAttribute("SNAPSHOT");
snap->replace("SNAPSHOT_ID", snap_id);
snap->replace("NAME", name);
snap->replace("TIME", (int)time(0));
snap->replace("HYPERVISOR_ID", "");
snap->replace("ACTIVE", "YES");
obj_template->set(snap);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::set_active_snapshot(int snap_id)
{
int num_snaps;
int s_id;
vector<Attribute *> snaps;
VectorAttribute * snap;
num_snaps = obj_template->get("SNAPSHOT", snaps);
for(int i=0; i<num_snaps; i++)
{
snap = dynamic_cast<VectorAttribute * >(snaps[i]);
if ( snap == 0 )
{
continue;
}
snap->vector_value("SNAPSHOT_ID", s_id);
if ( s_id == snap_id )
{
snap->replace("ACTIVE", "YES");
return 0;
}
}
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::update_snapshot_id(string& hypervisor_id)
{
int num_snaps;
vector<Attribute *> snaps;
VectorAttribute * snap;
num_snaps = obj_template->get("SNAPSHOT", snaps);
for(int i=0; i<num_snaps; i++)
{
snap = dynamic_cast<VectorAttribute * >(snaps[i]);
if ( snap == 0 )
{
continue;
}
if ( snap->vector_value("ACTIVE") == "YES" )
{
snap->replace("HYPERVISOR_ID", hypervisor_id);
break;
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::clear_active_snapshot()
{
int num_snaps;
vector<Attribute *> snaps;
VectorAttribute * snap;
num_snaps = obj_template->get("SNAPSHOT", snaps);
for(int i=0; i<num_snaps; i++)
{
snap = dynamic_cast<VectorAttribute * >(snaps[i]);
if ( snap == 0 )
{
continue;
}
if ( snap->vector_value("ACTIVE") == "YES" )
{
snap->remove("ACTIVE");
return;
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::delete_active_snapshot()
{
vector<Attribute *> snaps;
VectorAttribute * snap;
int num_snaps = obj_template->get("SNAPSHOT", snaps);
for(int i=0; i<num_snaps; i++)
{
snap = dynamic_cast<VectorAttribute * >(snaps[i]);
if ( snap == 0 )
{
continue;
}
if ( snap->vector_value("ACTIVE") == "YES" )
{
if (obj_template->remove(snap) != 0)
{
delete snap;
}
return;
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::delete_snapshots()
{
obj_template->erase("SNAPSHOT");
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::get_network_leases(string& estr)
{
int num_nics, rc;
@ -1930,7 +2282,7 @@ int VirtualMachine::get_network_leases(string& estr)
continue;
}
rc = vnpool->nic_attribute(nic, uid, oid, estr);
rc = vnpool->nic_attribute(nic, i, uid, oid, estr);
if (rc == -1)
{
@ -1946,63 +2298,71 @@ int VirtualMachine::get_network_leases(string& estr)
void VirtualMachine::release_network_leases()
{
Nebula& nd = Nebula::instance();
VirtualNetworkPool * vnpool = nd.get_vnpool();
string vnid;
string ip;
int num_nics;
vector<Attribute const * > nics;
VirtualNetwork * vn;
num_nics = get_template_attribute("NIC",nics);
num_nics = get_template_attribute("NIC",nics);
for(int i=0; i<num_nics; i++)
{
VectorAttribute const * nic =
dynamic_cast<VectorAttribute const * >(nics[i]);
if ( nic == 0 )
{
continue;
}
vnid = nic->vector_value("NETWORK_ID");
if ( vnid.empty() )
{
continue;
}
ip = nic->vector_value("IP");
if ( ip.empty() )
{
continue;
}
vn = vnpool->get(atoi(vnid.c_str()),true);
if ( vn == 0 )
{
continue;
}
if (vn->is_owner(ip,oid))
{
vn->release_lease(ip);
vnpool->update(vn);
}
vn->unlock();
release_network_leases(nic, oid);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::release_network_leases(VectorAttribute const * nic, int vmid)
{
VirtualNetworkPool* vnpool = Nebula::instance().get_vnpool();
VirtualNetwork* vn;
int vnid;
string ip;
if ( nic == 0 )
{
return -1;
}
if ( nic->vector_value("NETWORK_ID", vnid) != 0 )
{
return -1;
}
ip = nic->vector_value("IP");
if ( ip.empty() )
{
return -1;
}
vn = vnpool->get(vnid, true);
if ( vn == 0 )
{
return -1;
}
if (vn->is_owner(ip,vmid))
{
vn->release_lease(ip);
vnpool->update(vn);
}
vn->unlock();
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::generate_context(string &files, int &disk_id)
{
ofstream file;

View File

@ -362,6 +362,11 @@ void insert_single(VirtualMachine * vm,
else
{
vm->get_template_attribute(name.c_str(),value);
if (value.empty())
{
vm->get_user_template_attribute(name.c_str(),value);
}
}
if (!value.empty())
@ -464,7 +469,7 @@ void insert_vector(VirtualMachine * vm,
/* Line 371 of yacc.c */
#line 468 "vm_var_syntax.cc"
#line 473 "vm_var_syntax.cc"
# ifndef YY_NULL
# if defined __cplusplus && 201103L <= __cplusplus
@ -517,7 +522,7 @@ extern int vm_var__debug;
typedef union YYSTYPE
{
/* Line 387 of yacc.c */
#line 416 "vm_var_syntax.y"
#line 421 "vm_var_syntax.y"
char * val_str;
int val_int;
@ -525,7 +530,7 @@ typedef union YYSTYPE
/* Line 387 of yacc.c */
#line 529 "vm_var_syntax.cc"
#line 534 "vm_var_syntax.cc"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@ -565,7 +570,7 @@ int vm_var__parse ();
/* Copy the second part of user declarations. */
/* Line 390 of yacc.c */
#line 569 "vm_var_syntax.cc"
#line 574 "vm_var_syntax.cc"
#ifdef short
# undef short
@ -856,7 +861,7 @@ static const yytype_int8 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
0, 440, 440, 441, 444, 448, 461, 476
0, 445, 445, 446, 449, 453, 466, 481
};
#endif
@ -1900,7 +1905,7 @@ yyreduce:
{
case 4:
/* Line 1792 of yacc.c */
#line 445 "vm_var_syntax.y"
#line 450 "vm_var_syntax.y"
{
(*parsed) << (yyvsp[(1) - (1)].val_str);
}
@ -1908,7 +1913,7 @@ yyreduce:
case 5:
/* Line 1792 of yacc.c */
#line 449 "vm_var_syntax.y"
#line 454 "vm_var_syntax.y"
{
string name((yyvsp[(1) - (2)].val_str));
@ -1925,7 +1930,7 @@ yyreduce:
case 6:
/* Line 1792 of yacc.c */
#line 462 "vm_var_syntax.y"
#line 467 "vm_var_syntax.y"
{
string name((yyvsp[(1) - (5)].val_str));
string vname((yyvsp[(3) - (5)].val_str));
@ -1944,7 +1949,7 @@ yyreduce:
case 7:
/* Line 1792 of yacc.c */
#line 477 "vm_var_syntax.y"
#line 482 "vm_var_syntax.y"
{
string name((yyvsp[(1) - (9)].val_str));
string vname((yyvsp[(3) - (9)].val_str));
@ -1966,7 +1971,7 @@ yyreduce:
/* Line 1792 of yacc.c */
#line 1970 "vm_var_syntax.cc"
#line 1975 "vm_var_syntax.cc"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@ -2205,7 +2210,7 @@ yyreturn:
/* Line 2055 of yacc.c */
#line 495 "vm_var_syntax.y"
#line 500 "vm_var_syntax.y"
extern "C" void vm_var__error(

View File

@ -63,7 +63,7 @@ extern int vm_var__debug;
typedef union YYSTYPE
{
/* Line 2058 of yacc.c */
#line 416 "vm_var_syntax.y"
#line 421 "vm_var_syntax.y"
char * val_str;
int val_int;

View File

@ -92,8 +92,8 @@ int LibVirtDriver::deployment_description_kvm(
bool pae = false;
bool acpi = false;
int pae_found;
int acpi_found;
int pae_found = -1;
int acpi_found = -1;
const VectorAttribute * raw;
string default_raw;

View File

@ -183,6 +183,26 @@ void VirtualMachineManager::trigger(Actions action, int _vid)
aname = "DETACH";
break;
case ATTACH_NIC:
aname = "ATTACH_NIC";
break;
case DETACH_NIC:
aname = "DETACH_NIC";
break;
case SNAPSHOT_CREATE:
aname = "SNAPSHOT_CREATE";
break;
case SNAPSHOT_REVERT:
aname = "SNAPSHOT_REVERT";
break;
case SNAPSHOT_DELETE:
aname = "SNAPSHOT_DELETE";
break;
default:
delete vid;
return;
@ -279,6 +299,26 @@ void VirtualMachineManager::do_action(const string &action, void * arg)
{
detach_action(vid);
}
else if (action == "ATTACH_NIC")
{
attach_nic_action(vid);
}
else if (action == "DETACH_NIC")
{
detach_nic_action(vid);
}
else if (action == "SNAPSHOT_CREATE")
{
snapshot_create_action(vid);
}
else if (action == "SNAPSHOT_REVERT")
{
snapshot_revert_action(vid);
}
else if (action == "SNAPSHOT_DELETE")
{
snapshot_delete_action(vid);
}
else if (action == ACTION_TIMER)
{
timer_action();
@ -1761,6 +1801,394 @@ error_common:
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineManager::snapshot_create_action(int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
string vm_tmpl;
string* drv_msg;
// Get the VM from the pool
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory())
{
goto error_history;
}
// Get the driver for this VM
vmd = get(vm->get_vmm_mad());
if ( vmd == 0 )
{
goto error_driver;
}
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->snapshot_create(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
os.str("");
os << "snapshot_create_action, VM has no history";
goto error_common;
error_driver:
os.str("");
os << "snapshot_create_action, error getting driver " << vm->get_vmm_mad();
goto error_common;
error_common:
Nebula &ne = Nebula::instance();
LifeCycleManager * lcm = ne.get_lcm();
lcm->trigger(LifeCycleManager::SNAPSHOT_CREATE_FAILURE, vid);
vm->log("VMM", Log::ERROR, os);
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineManager::snapshot_revert_action(int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
string vm_tmpl;
string* drv_msg;
// Get the VM from the pool
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory())
{
goto error_history;
}
// Get the driver for this VM
vmd = get(vm->get_vmm_mad());
if ( vmd == 0 )
{
goto error_driver;
}
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->snapshot_revert(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
os.str("");
os << "snapshot_revert_action, VM has no history";
goto error_common;
error_driver:
os.str("");
os << "snapshot_revert_action, error getting driver " << vm->get_vmm_mad();
goto error_common;
error_common:
Nebula &ne = Nebula::instance();
LifeCycleManager * lcm = ne.get_lcm();
lcm->trigger(LifeCycleManager::SNAPSHOT_REVERT_FAILURE, vid);
vm->log("VMM", Log::ERROR, os);
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineManager::snapshot_delete_action(int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
string vm_tmpl;
string* drv_msg;
// Get the VM from the pool
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory())
{
goto error_history;
}
// Get the driver for this VM
vmd = get(vm->get_vmm_mad());
if ( vmd == 0 )
{
goto error_driver;
}
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->snapshot_delete(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
os.str("");
os << "snapshot_delete_action, VM has no history";
goto error_common;
error_driver:
os.str("");
os << "snapshot_delete_action, error getting driver " << vm->get_vmm_mad();
goto error_common;
error_common:
Nebula &ne = Nebula::instance();
LifeCycleManager * lcm = ne.get_lcm();
lcm->trigger(LifeCycleManager::SNAPSHOT_DELETE_FAILURE, vid);
vm->log("VMM", Log::ERROR, os);
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineManager::attach_nic_action(
int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os, error_os;
string vm_tmpl;
string* drv_msg;
// Get the VM from the pool
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory())
{
goto error_history;
}
// Get the driver for this VM
vmd = get(vm->get_vmm_mad());
if ( vmd == 0 )
{
goto error_driver;
}
// Invoke driver method
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->attach_nic(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
os.str("");
os << "attach_nic_action, VM has no history";
goto error_common;
error_driver:
os.str("");
os << "attach_nic_action, error getting driver " << vm->get_vmm_mad();
goto error_common;
error_common:
Nebula &ne = Nebula::instance();
LifeCycleManager * lcm = ne.get_lcm();
lcm->trigger(LifeCycleManager::ATTACH_NIC_FAILURE, vid);
vm->log("VMM", Log::ERROR, os);
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineManager::detach_nic_action(
int vid)
{
VirtualMachine * vm;
const VirtualMachineManagerDriver * vmd;
ostringstream os;
string vm_tmpl;
string * drv_msg;
string opennebula_hostname;
string error_str;
// Get the VM from the pool
vm = vmpool->get(vid,true);
if (vm == 0)
{
return;
}
if (!vm->hasHistory())
{
goto error_history;
}
// Get the driver for this VM
vmd = get(vm->get_vmm_mad());
if ( vmd == 0 )
{
goto error_driver;
}
// Invoke driver method
drv_msg = format_message(
vm->get_hostname(),
vm->get_vnm_mad(),
"",
"",
vm->get_deploy_id(),
"",
"",
"",
"",
"",
vm->to_xml(vm_tmpl));
vmd->detach_nic(vid, *drv_msg);
delete drv_msg;
vm->unlock();
return;
error_history:
os.str("");
os << "detach_nic_action, VM has no history";
goto error_common;
error_driver:
os.str("");
os << "detach_nic_action, error getting driver " << vm->get_vmm_mad();
goto error_common;
error_common:
Nebula &ne = Nebula::instance();
LifeCycleManager * lcm = ne.get_lcm();
lcm->trigger(LifeCycleManager::DETACH_NIC_FAILURE, vid);
vm->log("VMM", Log::ERROR, os);
vm->unlock();
return;
}
/* ************************************************************************** */
/* MAD Loading */
/* ************************************************************************** */

View File

@ -364,7 +364,7 @@ void VirtualMachineManagerDriver::protocol(
LifeCycleManager *lcm = ne.get_lcm();
if ( result == "SUCCESS" )
{
{
vm->log("VMM", Log::INFO, "VM Disk successfully attached.");
lcm->trigger(LifeCycleManager::ATTACH_SUCCESS, id);
@ -396,6 +396,109 @@ void VirtualMachineManagerDriver::protocol(
lcm->trigger(LifeCycleManager::DETACH_FAILURE, id);
}
}
else if ( action == "ATTACHNIC" )
{
Nebula &ne = Nebula::instance();
LifeCycleManager *lcm = ne.get_lcm();
if ( result == "SUCCESS" )
{
vm->log("VMM", Log::ERROR, "VM NIC Successfully attached.");
lcm->trigger(LifeCycleManager::ATTACH_NIC_SUCCESS, id);
}
else
{
log_error(vm, os, is, "Error attaching new VM NIC");
vmpool->update(vm);
lcm->trigger(LifeCycleManager::ATTACH_NIC_FAILURE, id);
}
}
else if ( action == "DETACHNIC" )
{
Nebula &ne = Nebula::instance();
LifeCycleManager *lcm = ne.get_lcm();
if ( result == "SUCCESS" )
{
vm->log("VMM",Log::ERROR,"VM NIC Successfully detached.");
lcm->trigger(LifeCycleManager::DETACH_NIC_SUCCESS, id);
}
else
{
log_error(vm,os,is,"Error detaching VM NIC");
vmpool->update(vm);
lcm->trigger(LifeCycleManager::DETACH_NIC_FAILURE, id);
}
}
else if ( action == "SNAPSHOTCREATE" )
{
Nebula &ne = Nebula::instance();
LifeCycleManager *lcm = ne.get_lcm();
if ( result == "SUCCESS" )
{
string hypervisor_id;
is >> hypervisor_id;
vm->update_snapshot_id(hypervisor_id);
vmpool->update(vm);
vm->log("VMM", Log::INFO, "VM Snapshot successfully created.");
lcm->trigger(LifeCycleManager::SNAPSHOT_CREATE_SUCCESS, id);
}
else
{
log_error(vm, os, is, "Error creating new VM Snapshot");
vmpool->update(vm);
lcm->trigger(LifeCycleManager::SNAPSHOT_CREATE_FAILURE, id);
}
}
else if ( action == "SNAPSHOTREVERT" )
{
Nebula &ne = Nebula::instance();
LifeCycleManager *lcm = ne.get_lcm();
if ( result == "SUCCESS" )
{
vm->log("VMM",Log::INFO,"VM Snapshot successfully reverted.");
lcm->trigger(LifeCycleManager::SNAPSHOT_REVERT_SUCCESS, id);
}
else
{
log_error(vm,os,is,"Error reverting VM Snapshot");
vmpool->update(vm);
lcm->trigger(LifeCycleManager::SNAPSHOT_REVERT_FAILURE, id);
}
}
else if ( action == "SNAPSHOTDELETE" )
{
Nebula &ne = Nebula::instance();
LifeCycleManager *lcm = ne.get_lcm();
if ( result == "SUCCESS" )
{
vm->log("VMM",Log::INFO,"VM Snapshot successfully deleted.");
lcm->trigger(LifeCycleManager::SNAPSHOT_DELETE_SUCCESS, id);
}
else
{
log_error(vm,os,is,"Error deleting VM Snapshot");
vmpool->update(vm);
lcm->trigger(LifeCycleManager::SNAPSHOT_DELETE_FAILURE, id);
}
}
else if ( action == "CLEANUP" )
{
Nebula &ne = Nebula::instance();

View File

@ -128,6 +128,36 @@ class DummyDriver < VirtualMachineDriver
send_message(ACTION[:detach_disk],result,id)
end
def attach_nic(id, drv_message)
result = retrieve_result("attach_nic")
send_message(ACTION[:attach_nic],result,id)
end
def detach_nic(id, drv_message)
result = retrieve_result("detach_nic")
send_message(ACTION[:detach_nic],result,id)
end
def snapshot_create(id, drv_message)
result = retrieve_result("snapshot_create")
send_message(ACTION[:snapshot_create], result, id, "dummy-snap")
end
def snapshot_revert(id, drv_message)
result = retrieve_result("snapshot_revert")
send_message(ACTION[:snapshot_revert], result, id)
end
def snapshot_delete(id, drv_message)
result = retrieve_result("snapshot_delete")
send_message(ACTION[:snapshot_delete], result, id)
end
def cleanup(id, drv_message)
result = retrieve_result("cleanup")

View File

@ -608,6 +608,66 @@ class ExecDriver < VirtualMachineDriver
action.run(steps)
end
#
# SNAPSHOTCREATE action, creates a new system snapshot
#
def snapshot_create(id, drv_message)
action = ACTION[:snapshot_create]
xml_data = decode(drv_message)
host = xml_data.elements['HOST'].text
deploy_id = xml_data.elements['DEPLOY_ID'].text
snap_id_xpath = "VM/TEMPLATE/SNAPSHOT[ACTIVE='YES']/SNAPSHOT_ID"
snap_id = xml_data.elements[snap_id_xpath].text.to_i
do_action("#{deploy_id} #{snap_id}",
id,
host,
ACTION[:snapshot_create],
:script_name => "snapshot_create")
end
#
# SNAPSHOTREVERT action, reverts to a system snapshot
#
def snapshot_revert(id, drv_message)
action = ACTION[:snapshot_revert]
xml_data = decode(drv_message)
host = xml_data.elements['HOST'].text
deploy_id = xml_data.elements['DEPLOY_ID'].text
snap_id_xpath = "VM/TEMPLATE/SNAPSHOT[ACTIVE='YES']/HYPERVISOR_ID"
snapshot_name = xml_data.elements[snap_id_xpath].text
do_action("#{deploy_id} #{snapshot_name}",
id,
host,
ACTION[:snapshot_revert],
:script_name => "snapshot_revert")
end
#
# SNAPSHOTDELETE action, deletes a system snapshot
#
def snapshot_delete(id, drv_message)
action = ACTION[:snapshot_delete]
xml_data = decode(drv_message)
host = xml_data.elements['HOST'].text
deploy_id = xml_data.elements['DEPLOY_ID'].text
snap_id_xpath = "VM/TEMPLATE/SNAPSHOT[ACTIVE='YES']/HYPERVISOR_ID"
snapshot_name = xml_data.elements[snap_id_xpath].text
do_action("#{deploy_id} #{snapshot_name}",
id,
host,
ACTION[:snapshot_delete],
:script_name => "snapshot_delete")
end
#
# CLEANUP action, frees resources allocated in a host: VM and disk images
#
@ -674,6 +734,96 @@ class ExecDriver < VirtualMachineDriver
action.run(steps)
end
#
# ATTACHNIC action to attach a new nic interface
#
def attach_nic(id, drv_message)
xml_data = decode(drv_message)
begin
source = xml_data.elements["VM/TEMPLATE/NIC[ATTACH='YES']/BRIDGE"]
mac = xml_data.elements["VM/TEMPLATE/NIC[ATTACH='YES']/MAC"]
source = source.text.strip
mac = mac.text.strip
rescue
send_message(action, RESULT[:failure], id,
"Error in #{ACTION[:attach_nic]}, BRIDGE and MAC needed in NIC")
return
end
model = xml_data.elements["VM/TEMPLATE/NIC[ATTACH='YES']/MODEL"]
model = model.text if !model.nil?
model = model.strip if !model.nil?
model = "-" if model.nil?
action = VmmAction.new(self, id, :attach_nic, drv_message)
steps=[
# Execute pre-attach networking setup
{
:driver => :vnm,
:action => :pre
},
# Attach the new NIC
{
:driver => :vmm,
:action => :attach_nic,
:parameters => [:deploy_id, mac, source, model]
},
# Execute post-boot networking setup
{
:driver => :vnm,
:action => :post,
:parameters => [:deploy_info],
:fail_actions => [
{
:driver => :vmm,
:action => :detach_nic,
:parameters => [:deploy_id, mac]
}
]
}
]
action.run(steps)
end
#
# DETACHNIC action to detach a nic interface
#
def detach_nic(id, drv_message)
xml_data = decode(drv_message)
begin
mac = xml_data.elements["VM/TEMPLATE/NIC[ATTACH='YES']/MAC"]
mac = mac.text.strip
rescue
send_message(action, RESULT[:failure], id,
"Error in #{ACTION[:detach_nic]}, MAC needed in NIC")
return
end
action = VmmAction.new(self, id, :detach_nic, drv_message)
steps=[
# Detach the NIC
{
:driver => :vmm,
:action => :detach_nic,
:parameters => [:deploy_id, mac]
},
# Clean networking setup
{
:driver => :vnm,
:action => :clean
}
]
action.run(steps)
end
private
def ensure_xpath(xml_data, id, action, xpath)

View File

@ -22,4 +22,8 @@ else
MAD_LOCATION=$ONE_LOCATION/lib/mads
fi
exec $MAD_LOCATION/one_vmm_exec -l deploy,shutdown,reboot,cancel,save,restore,migrate,poll,pre,post,clean $*
LOCAL_ACTIONS="deploy,shutdown,reboot,cancel,save,restore,migrate,poll,pre"
LOCAL_ACTIONS="${LOCAL_ACTIONS},post,clean"
LOCAL_ACTIONS="${LOCAL_ACTIONS},snapshotcreate,snapshotrevert,snapshotdelete"
exec $MAD_LOCATION/one_vmm_exec -l $LOCAL_ACTIONS $*

View File

@ -0,0 +1,34 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/kvmrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN=$1
MAC=$2
SOURCE=$3
MODEL=$4
ATTACH_ARGS="--domain $DOMAIN --type bridge --source $SOURCE --mac $MAC"
if [ "$MODEL" != "-" ]; then
ATTACH_ARGS="$ATTACH_ARGS --model $MODEL"
fi
exec_and_log "virsh --connect $LIBVIRT_URI attach-interface $ATTACH_ARGS" \
"Could not attach NIC ($MAC) to $DOMAIN"

View File

@ -0,0 +1,28 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/kvmrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN=$1
MAC=$2
DETACH_ARGS="--domain $DOMAIN --type bridge --mac $MAC"
exec_and_log "virsh --connect $LIBVIRT_URI detach-interface $DETACH_ARGS" \
"Could not detach NIC ($MAC) to $DOMAIN"

View File

@ -0,0 +1,34 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/kvmrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN="$1"
SNAP_ID="$2"
data=`virsh --connect $LIBVIRT_URI snapshot-create-as $DOMAIN`
if [ "$?" = "0" ]; then
echo "$data" | awk '{print $3}'
else
error_message "Could not create snapshot $NAME for domain $DOMAIN."
exit -1
fi
exit 0

View File

@ -0,0 +1,29 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/kvmrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN="$1"
NAME="$2"
exec_and_log \
"virsh --connect $LIBVIRT_URI snapshot-delete $DOMAIN $NAME" \
"Could not delete snapshot $NAME for domain $DOMAIN."
exit 0

View File

@ -0,0 +1,29 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/kvmrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN="$1"
NAME="$2"
exec_and_log \
"virsh --connect $LIBVIRT_URI snapshot-revert --force $DOMAIN $NAME" \
"Could not revert to snapshot $NAME for domain $DOMAIN."
exit 0

View File

@ -0,0 +1,21 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/../../scripts_common.sh
log_error "Attach network interface is not yet supported for VMware."
exit 1

View File

@ -0,0 +1,21 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/../../scripts_common.sh
log_error "Detach network interface is not yet supported for VMware."
exit 1

View File

@ -0,0 +1,40 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2013, C12G Labs S.L #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
# ---------------------------------------------------------------------------- #
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vmware_driver'
deploy_id = ARGV[0]
host = ARGV[3]
vmware_drv = VMwareDriver.new(host)
hypervisor_id = vmware_drv.snapshot_create(deploy_id)
puts hypervisor_id
exit 0

View File

@ -0,0 +1,38 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2013, C12G Labs S.L #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
# ---------------------------------------------------------------------------- #
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vmware_driver'
deploy_id = ARGV[0]
snapshot_id = ARGV[1]
host = ARGV[3]
vmware_drv = VMwareDriver.new(host)
vmware_drv.snapshot_delete(deploy_id, snapshot_id)

View File

@ -0,0 +1,38 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# Copyright 2010-2013, C12G Labs S.L #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
# ---------------------------------------------------------------------------- #
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vmware_driver'
deploy_id = ARGV[0]
snapshot_id = ARGV[1]
host = ARGV[3]
vmware_drv = VMwareDriver.new(host)
vmware_drv.snapshot_revert(deploy_id, snapshot_id)

View File

@ -262,6 +262,42 @@ class VMwareDriver
undefine_domain(deploy_id)
end
# ------------------------------------------------------------------------ #
# Creates a new system snapshot #
# ------------------------------------------------------------------------ #
def snapshot_create(deploy_id)
rc, info = do_action(
"virsh -c #{@uri} snapshot-create-as #{deploy_id}")
exit info if rc == false
hypervisor_id = info.split[2]
return hypervisor_id
end
# ------------------------------------------------------------------------ #
# Delete a system snapshot #
# ------------------------------------------------------------------------ #
def snapshot_delete(deploy_id, snapshot_id)
rc, info = do_action(
"virsh -c #{@uri} snapshot-delete #{deploy_id} #{snapshot_id}")
exit info if rc == false
end
# ------------------------------------------------------------------------ #
# Revert to a system snapshot #
# ------------------------------------------------------------------------ #
def snapshot_revert(deploy_id, snapshot_id)
action = "virsh -c #{@uri} snapshot-revert " <<
"--force #{deploy_id} #{snapshot_id}"
rc, info = do_action(action)
exit info if rc == false
end
# ######################################################################## #
# DRIVER HELPER FUNCTIONS #
# ######################################################################## #

View File

@ -0,0 +1,28 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/xenrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN=$1
MAC=$2
SOURCE=$3
MODEL=$4
exec_and_log "$XM_ATTACH_NIC $DOMAIN bridge=$SOURCE mac=$MAC" \
"Could not attach NIC ($MAC) to $DOMAIN"

View File

@ -0,0 +1,28 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/xenrc
source $(dirname $0)/../../scripts_common.sh
DOMAIN=$1
MAC=$2
ID=`$XM_NETWORK_LIST $DOMAIN | grep -i $MAC | cut -d' ' -f1`
exec_and_log "$XM_DETACH_NIC $DOMAIN $ID" \
"Could not detach NIC ($MAC) to $DOMAIN"

View File

@ -0,0 +1,21 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/../../scripts_common.sh
log_error "Snapshotting is not yet supported for Xen."
exit 1

View File

@ -0,0 +1,22 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/../../scripts_common.sh
log_error "Snapshotting is not yet supported for Xen."
exit 1

View File

@ -0,0 +1,22 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2013, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
source $(dirname $0)/../../scripts_common.sh
log_error "Snapshotting is not yet supported for Xen."
exit 1

View File

@ -30,6 +30,9 @@ export XM_SHUTDOWN="sudo $XM_PATH shutdown"
export XM_POLL="sudo /usr/sbin/xentop -bi2"
export XM_ATTACH_DISK="sudo $XM_PATH block-attach"
export XM_DETACH_DISK="sudo $XM_PATH block-detach"
export XM_ATTACH_NIC="sudo $XM_PATH network-attach"
export XM_DETACH_NIC="sudo $XM_PATH network-detach"
export XM_NETWORK_LIST="sudo $XM_PATH network-list"
# In xen 4.1 the credit scheduler command is called sched-credit,
# uncomment this line if you are using this version

View File

@ -30,6 +30,9 @@ export XM_SHUTDOWN="sudo $XM_PATH shutdown"
export XM_POLL="sudo /usr/sbin/xentop -bi2"
export XM_ATTACH_DISK="sudo $XM_PATH block-attach"
export XM_DETACH_DISK="sudo $XM_PATH block-detach"
export XM_ATTACH_NIC="sudo $XM_PATH network-attach"
export XM_DETACH_NIC="sudo $XM_PATH network-detach"
export XM_NETWORK_LIST="sudo $XM_PATH network-list"
# In xen 4.1 the credit scheduler command is called sched-credit,
# uncomment this line if you are using this version

View File

@ -24,8 +24,10 @@ FixedLeases::FixedLeases(
SqlDB * db,
int _oid,
unsigned int _mac_prefix,
unsigned int _global[],
unsigned int _site[],
vector<const Attribute*>& vector_leases):
Leases(db,_oid,0,_mac_prefix),current(leases.begin())
Leases(db,_oid,0,_mac_prefix, _global, _site), current(leases.begin())
{
const VectorAttribute * single_attr_lease;
string _mac;
@ -68,24 +70,44 @@ int FixedLeases::add(const string& ip, const string& mac, int vid,
int rc;
if ( Leases::Lease::ip_to_number(ip,_ip) )
if (ip.empty() && mac.empty())
{
goto error_ip;
goto error_no_ip_mac;
}
if ( leases.count(_ip) > 0 )
//Set IP & MAC addresses if provided
if (!ip.empty())
{
goto error_duplicate;
if ( Leases::Lease::ip_to_number(ip,_ip) )
{
goto error_ip;
}
}
if (!mac.empty())
{
if (Leases::Lease::mac_to_number(mac,_mac))
{
goto error_mac;
}
}
//Generate IP from MAC (or viceversa)
if (ip.empty())
{
_ip = _mac[0];
}
if (mac.empty())
{
_mac[Lease::PREFIX] = mac_prefix;
_mac[Lease::SUFFIX] = _ip;
_mac[1] = mac_prefix;
_mac[0] = _ip;
}
else if (Leases::Lease::mac_to_number(mac,_mac))
//Check for duplicates
if ( leases.count(_ip) > 0 )
{
goto error_mac;
goto error_duplicate;
}
lease = new Lease(_ip,_mac,vid,used);
@ -120,23 +142,23 @@ int FixedLeases::add(const string& ip, const string& mac, int vid,
return rc;
error_no_ip_mac:
oss << "Both IP and MAC cannot be empty";
goto error_common;
error_ip:
oss.str("");
oss << "Error inserting lease, malformed IP = " << ip;
goto error_common;
error_mac:
oss.str("");
oss << "Error inserting lease, malformed MAC = " << mac;
goto error_common;
error_duplicate:
oss.str("");
oss << "Error inserting lease, IP " << ip << " already exists";
goto error_common;
error_body:
oss.str("");
oss << "Error inserting lease, marshall error";
delete lease;
goto error_common;
@ -192,7 +214,7 @@ int FixedLeases::remove(const string& ip, string& error_msg)
}
delete it->second;
leases.erase(it);
return rc;
@ -255,7 +277,7 @@ int FixedLeases::unset(const string& ip)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int FixedLeases::get(int vid, string& ip, string& mac)
int FixedLeases::get(int vid, string& ip, string& mac, unsigned int eui64[])
{
int rc = -1;
@ -280,7 +302,11 @@ int FixedLeases::get(int vid, string& ip, string& mac)
rc = update_lease(current->second);
current->second->to_string(ip,mac);
Leases::Lease::mac_to_string(current->second->mac, mac);
Leases::Lease::ip_to_string(current->second->ip, ip);
eui64[0] = current->second->eui64[0];
eui64[1] = current->second->eui64[1];
current++;
break;
@ -293,7 +319,7 @@ int FixedLeases::get(int vid, string& ip, string& mac)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int FixedLeases::set(int vid, const string& ip, string& mac)
int FixedLeases::set(int vid, const string& ip, string& mac, unsigned int eui64[])
{
map<unsigned int,Lease *>::iterator it;
@ -323,6 +349,9 @@ int FixedLeases::set(int vid, const string& ip, string& mac)
Leases::Lease::mac_to_string(it->second->mac,mac);
eui64[0] = it->second->eui64[0];
eui64[1] = it->second->eui64[1];
return update_lease(it->second);
}
@ -394,7 +423,6 @@ int FixedLeases::add_leases(vector<const Attribute*>& vector_leases,
error_msg = "Empty lease description.";
}
return rc;
}

View File

@ -14,10 +14,11 @@
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "Leases.h"
#include "NebulaLog.h"
#include <arpa/inet.h>
/* ************************************************************************** */
/* ************************************************************************** */
/* Lease class */
@ -27,17 +28,6 @@
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Leases::Lease::to_string(string &_ip,
string &_mac) const
{
mac_to_string(mac, _mac);
ip_to_string(ip, _ip);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Leases::Lease::ip_to_number(const string& _ip, unsigned int& i_ip)
{
istringstream iss;
@ -108,6 +98,38 @@ void Leases::Lease::ip_to_string(const unsigned int i_ip, string& ip)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Leases::Lease::ip6_to_string(const unsigned int eui64[],
const unsigned int prefix[],
string& ip6s)
{
struct in6_addr ip6;
char dst[INET6_ADDRSTRLEN];
ip6.s6_addr32[2] = htonl(eui64[1]);
ip6.s6_addr32[3] = htonl(eui64[0]);
// global or site unicast address
if (prefix[1] != 0 && prefix[0] != 0 )
{
ip6.s6_addr32[0] = htonl(prefix[1]);
ip6.s6_addr32[1] = htonl(prefix[0]);
}
else // link local address
{
ip6.s6_addr32[0] = htonl(0xfe800000);
ip6.s6_addr32[1] = 0;
}
if ( inet_ntop(AF_INET6, &ip6, dst, INET6_ADDRSTRLEN) != 0 )
{
ip6s = dst;
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Leases::Lease::mac_to_number(const string& _mac, unsigned int i_mac[])
{
istringstream iss;
@ -130,22 +152,61 @@ int Leases::Lease::mac_to_number(const string& _mac, unsigned int i_mac[])
iss.str(mac);
i_mac[PREFIX] = 0;
i_mac[SUFFIX] = 0;
i_mac[1] = 0;
i_mac[0] = 0;
iss >> hex >> i_mac[PREFIX] >> ws >> hex >> tmp >> ws;
i_mac[PREFIX] <<= 8;
i_mac[PREFIX] += tmp;
iss >> hex >> i_mac[1] >> ws >> hex >> tmp >> ws;
i_mac[1] <<= 8;
i_mac[1] += tmp;
for (int i=0;i<4;i++)
{
iss >> hex >> tmp >> ws;
i_mac[SUFFIX] <<= 8;
i_mac[SUFFIX] += tmp;
i_mac[0] <<= 8;
i_mac[0] += tmp;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Leases::Lease::prefix6_to_number(const string& prefix, unsigned int ip[])
{
struct in6_addr s6;
ostringstream oss;
if (prefix.empty())
{
ip[1] = ip[0] = 0;
return 0;
}
oss << prefix << ":0:0:0:1";
int rc = inet_pton(AF_INET6, oss.str().c_str(), &s6);
if ( rc != 1 )
{
return -1;
}
ip[1] = ntohl(s6.s6_addr32[0]);
ip[0] = ntohl(s6.s6_addr32[1]);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Leases::Lease::mac_to_eui64(const unsigned int i_mac[], unsigned int eui64[])
{
eui64[1] = ((i_mac[1]+512)<<16) + ((i_mac[0] & 0xFF000000)>>16) + 0x000000FF;
eui64[0] = 4261412864 + (i_mac[0] & 0x00FFFFFF);
}
/* -------------------------------------------------------------------------- */
@ -162,12 +223,12 @@ void Leases::Lease::mac_to_string(const unsigned int i_mac[], string& mac)
{
if ( i < 4 )
{
temp_byte = i_mac[SUFFIX];
temp_byte = i_mac[0];
temp_byte >>= i*8;
}
else
{
temp_byte = i_mac[PREFIX];
temp_byte = i_mac[1];
temp_byte >>= (i%4)*8;
}
@ -189,33 +250,44 @@ void Leases::Lease::mac_to_string(const unsigned int i_mac[], string& mac)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
ostream& operator<<(ostream& os, Leases::Lease& _lease)
string& Leases::Lease::to_xml(string& str,
const unsigned int global[],
const unsigned int site[]) const
{
string xml;
string ip_s;
string ipl_s, ips_s, ipg_s;
string mac_s;
os << _lease.to_xml(xml);
return os;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& Leases::Lease::to_xml(string& str) const
{
string ip;
string mac;
unsigned int tmp_prefix[2] = {0, 0};
ostringstream os;
to_string(ip,mac);
mac_to_string(mac, mac_s);
ip_to_string(ip, ip_s);
ip6_to_string(eui64, tmp_prefix, ipl_s);
os <<
"<LEASE>" <<
"<IP>" << ip << "</IP>" <<
"<MAC>" << mac << "</MAC>" <<
"<USED>"<< used << "</USED>"<<
"<VID>" << vid << "</VID>" <<
"<MAC>" << mac_s << "</MAC>" <<
"<IP>" << ip_s << "</IP>" <<
"<IP6_LINK>" << ipl_s << "</IP6_LINK>";
if (site[1] != 0 || site[0] != 0 )
{
ip6_to_string(eui64, site, ips_s);
os << "<IP6_SITE>" << ips_s << "</IP6_SITE>";
}
if (global[1] != 0 || global[0] != 0 )
{
ip6_to_string(eui64, global, ipg_s);
os << "<IP6_GLOBAL>" << ipg_s << "</IP6_GLOBAL>";
}
os << "<USED>"<< used << "</USED>"<<
"<VID>" << vid << "</VID>" <<
"</LEASE>";
str = os.str();
@ -232,11 +304,11 @@ string& Leases::Lease::to_xml_db(string& str) const
os <<
"<LEASE>" <<
"<IP>" << ip << "</IP>" <<
"<MAC_PREFIX>" << mac[Lease::PREFIX] << "</MAC_PREFIX>" <<
"<MAC_SUFFIX>" << mac[Lease::SUFFIX] << "</MAC_SUFFIX>" <<
"<USED>" << used << "</USED>"<<
"<VID>" << vid << "</VID>" <<
"<IP>" << ip << "</IP>" <<
"<MAC_PREFIX>" << mac[1] << "</MAC_PREFIX>" <<
"<MAC_SUFFIX>" << mac[0] << "</MAC_SUFFIX>" <<
"<USED>" << used << "</USED>"<<
"<VID>" << vid << "</VID>" <<
"</LEASE>";
str = os.str();
@ -255,11 +327,13 @@ int Leases::Lease::from_xml(const string &xml_str)
// Initialize the internal XML object
update_from_str(xml_str);
rc += xpath(ip , "/LEASE/IP" , 0);
rc += xpath(mac[Lease::PREFIX], "/LEASE/MAC_PREFIX" , 0);
rc += xpath(mac[Lease::SUFFIX], "/LEASE/MAC_SUFFIX" , 0);
rc += xpath(int_used , "/LEASE/USED" , 0);
rc += xpath(vid , "/LEASE/VID" , 0);
rc += xpath(ip, "/LEASE/IP", 0);
rc += xpath(mac[1], "/LEASE/MAC_PREFIX", 0);
rc += xpath(mac[0], "/LEASE/MAC_SUFFIX", 0);
rc += xpath(int_used, "/LEASE/USED", 0);
rc += xpath(vid, "/LEASE/VID", 0);
used = static_cast<bool>(int_used);
@ -268,6 +342,8 @@ int Leases::Lease::from_xml(const string &xml_str)
return -1;
}
mac_to_eui64(mac, eui64);
return 0;
}
@ -446,6 +522,8 @@ int Leases::hold_leases(vector<const Attribute*>& vector_leases,
string ip;
string mac;
unsigned int tmp[2];
if ( vector_leases.size() > 0 )
{
single_attr_lease =
@ -466,7 +544,7 @@ int Leases::hold_leases(vector<const Attribute*>& vector_leases,
return -1;
}
rc = set(-1, ip, mac);
rc = set(-1, ip, mac, tmp);
if ( rc != 0 )
{
@ -535,7 +613,7 @@ string& Leases::to_xml(string& xml) const
for(it=leases.begin();it!=leases.end();it++)
{
os << it->second->to_xml(lease_xml);
os << it->second->to_xml(lease_xml, global, site);
}
xml = os.str();

View File

@ -28,9 +28,11 @@ RangedLeases::RangedLeases(
SqlDB * db,
int _oid,
unsigned int _mac_prefix,
unsigned int _global[],
unsigned int _site[],
unsigned int _ip_start,
unsigned int _ip_end):
Leases(db,_oid,0,_mac_prefix),
Leases(db, _oid, 0, _mac_prefix, _global, _site),
ip_start(_ip_start),ip_end(_ip_end),current(0)
{
size = ip_end - ip_start + 1;
@ -39,31 +41,123 @@ RangedLeases::RangedLeases(
/* ************************************************************************** */
/* Ranged Leases :: Methods */
/* ************************************************************************** */
static int get_template_size(VirtualNetwork* vn,
unsigned int& host_bits,
unsigned int& size)
{
string st_size = "";
vn->erase_template_attribute("NETWORK_SIZE", st_size);
if ( st_size == "C" || st_size == "c" )
{
host_bits = 8;
size = 256;
}
else if ( st_size == "B" || st_size == "b" )
{
host_bits = 16;
size = 65536;
}
else if ( st_size == "A" || st_size == "a" )
{
host_bits = 24;
size = 16777216;
}
else
{
if (!st_size.empty())//Assume it's a number
{
istringstream iss(st_size);
iss >> size;
if (iss.fail())
{
return -1;
}
}
else
{
size = VirtualNetworkPool::default_size();
}
host_bits = (int) ceil(log(size+2)/log(2));
}
return 0;
}
/* -------------------------------------------------------------------------- */
int RangedLeases::process_template(VirtualNetwork* vn,
unsigned int& ip_start, unsigned int& ip_end, string& error_str)
{
ostringstream oss;
string st_size = "";
string st_addr = "";
string st_mask = "";
string st_ip_start = "";
string st_ip_end = "";
string st_mac_start = "";
unsigned int host_bits;
unsigned int host_bits = 0;
unsigned int network_bits;
unsigned int size;
unsigned int net_addr;
unsigned int net_mask;
size_t pos;
unsigned int mac[2];
// -------------------------------------------------------------------------
// Pure IPv6 network definition based on MAC_START and NETWORK_SIZE
// -------------------------------------------------------------------------
vn->erase_template_attribute("MAC_START", st_mac_start);
if (!st_mac_start.empty())
{
if ( Leases::Lease::mac_to_number(st_mac_start, mac) != 0 )
{
goto error_mac_start;
}
ip_start = mac[0];
if (get_template_size(vn, host_bits, size) != 0)
{
goto error_size;
}
ip_end = ip_start + size;
if ( ip_end < ip_start )
{
goto error_greater_mac;
}
vn->remove_template_attribute("IP_START");
vn->remove_template_attribute("IP_END");
vn->remove_template_attribute("NETWORK_ADDRESS");
vn->remove_template_attribute("NETWORK_MASK");
vn->remove_template_attribute("NETWORK_SIZE");
return 0;
}
// -------------------------------------------------------------------------
// Initialize IP_START and IP_END to limit the IP range
// -------------------------------------------------------------------------
ip_start = 0;
ip_end = 0;
// retrieve specific information from template
vn->erase_template_attribute("IP_START", st_ip_start);
vn->erase_template_attribute("IP_END", st_ip_end);
vn->erase_template_attribute("IP_END", st_ip_end);
if ( !st_ip_start.empty() )
{
@ -81,11 +175,15 @@ int RangedLeases::process_template(VirtualNetwork* vn,
}
}
// -------------------------------------------------------------------------
// Check for NETWORK_ADDRESS
// -------------------------------------------------------------------------
vn->erase_template_attribute("NETWORK_ADDRESS", st_addr);
if (st_addr.empty())
{
if ( ip_start != 0 && ip_end != 0 )
if ( ip_start != 0 && ip_end != 0 ) //Manually range, exit
{
if ( ip_end < ip_start )
{
@ -100,10 +198,13 @@ int RangedLeases::process_template(VirtualNetwork* vn,
}
}
// Check if the IP has a network prefix
// -------------------------------------------------------------------------
// Check for NETWORK_SIZE or NETWORK_ADDRESS
// -------------------------------------------------------------------------
pos = st_addr.find("/");
if ( pos != string::npos )
if ( pos != string::npos ) // Check for CIDR network address
{
string st_network_bits;
@ -120,7 +221,7 @@ int RangedLeases::process_template(VirtualNetwork* vn,
host_bits = 32 - network_bits;
}
else
else // Check for network mask in decimal-dot notation
{
vn->erase_template_attribute("NETWORK_MASK", st_mask);
@ -142,50 +243,29 @@ int RangedLeases::process_template(VirtualNetwork* vn,
host_bits++;
}
}
else
else //No network mask, get NETWORK_SIZE
{
vn->erase_template_attribute("NETWORK_SIZE",st_size);
if ( st_size == "C" || st_size == "c" )
if (get_template_size(vn, host_bits, size) != 0)
{
host_bits = 8;
}
else if ( st_size == "B" || st_size == "b" )
{
host_bits = 16;
}
else if ( st_size == "A" || st_size == "a" )
{
host_bits = 24;
}
else
{
unsigned int size;
if (!st_size.empty())//Assume it's a number
{
istringstream iss(st_size);
iss >> size;
}
else
{
size = VirtualNetworkPool::default_size();
}
host_bits = (int) ceil(log(size+2)/log(2));
goto error_size;
}
}
}
vn->remove_template_attribute("NETWORK_SIZE");
// Set the network mask
// -------------------------------------------------------------------------
// Generate NETWORK_MASK
// -------------------------------------------------------------------------
net_mask = 0xFFFFFFFF << host_bits;
Lease::ip_to_string(net_mask, st_mask);
vn->replace_template_attribute("NETWORK_MASK", st_mask);
// -------------------------------------------------------------------------
// Consistency Checks based on the network address, and range
// -------------------------------------------------------------------------
if ( Leases::Lease::ip_to_number(st_addr,net_addr) != 0 )
{
goto error_net_addr;
@ -225,6 +305,9 @@ int RangedLeases::process_template(VirtualNetwork* vn,
return 0;
error_mac_start:
oss << "MAC_START " << st_mac_start << " is not a valid MAC.";
goto error_common;
error_ip_start:
oss << "IP_START " << st_ip_start << " is not a valid IP.";
@ -260,6 +343,10 @@ error_range_ip_start:
<< st_addr << "/" << 32-host_bits << ".";
goto error_common;
error_size:
oss << "NETWORK_SIZE is not an integer number.";
goto error_common;
error_range_ip_end:
oss << "IP_END " << st_ip_end << " is not part of the network "
<< st_addr << "/" << 32-host_bits << ".";
@ -273,6 +360,9 @@ error_greater:
<< st_ip_end << ".";
goto error_common;
error_greater_mac:
oss << "Size too big, it will overflow MAC address space.";
goto error_common;
error_common:
error_str = oss.str();
@ -282,7 +372,7 @@ error_common:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int RangedLeases::get(int vid, string& ip, string& mac)
int RangedLeases::get(int vid, string& ip, string& mac, unsigned int eui64[])
{
unsigned int num_ip;
int rc = -1;
@ -295,8 +385,10 @@ int RangedLeases::get(int vid, string& ip, string& mac)
{
unsigned int num_mac[2];
num_mac[Lease::PREFIX] = mac_prefix;
num_mac[Lease::SUFFIX] = num_ip;
num_mac[1] = mac_prefix;
num_mac[0] = num_ip;
Leases::Lease::mac_to_eui64(num_mac, eui64);
rc = add(num_ip,num_mac,vid);
@ -316,7 +408,7 @@ int RangedLeases::get(int vid, string& ip, string& mac)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int RangedLeases::set(int vid, const string& ip, string& mac)
int RangedLeases::set(int vid, const string& ip, string& mac, unsigned int eui64[])
{
unsigned int num_ip;
unsigned int num_mac[2];
@ -339,8 +431,10 @@ int RangedLeases::set(int vid, const string& ip, string& mac)
return -1;
}
num_mac[Lease::PREFIX] = mac_prefix;
num_mac[Lease::SUFFIX] = num_ip;
num_mac[1] = mac_prefix;
num_mac[0] = num_ip;
Leases::Lease::mac_to_eui64(num_mac, eui64);
rc = add(num_ip,num_mac,vid);

View File

@ -56,6 +56,9 @@ VirtualNetwork::VirtualNetwork(int _uid,
}
set_umask(_umask);
global_bin[0] = global_bin[1] = 0;
site_bin[0] = site_bin[1] = 0;
};
/* -------------------------------------------------------------------------- */
@ -131,7 +134,7 @@ int VirtualNetwork::select_leases(SqlDB * db)
string network_address;
unsigned int mac_prefix = VirtualNetworkPool::mac_prefix();
unsigned int mac_prefix = VirtualNetworkPool::mac_prefix();
//Get the leases
if (type == RANGED)
@ -139,6 +142,8 @@ int VirtualNetwork::select_leases(SqlDB * db)
leases = new RangedLeases(db,
oid,
mac_prefix,
global_bin,
site_bin,
ip_start,
ip_end);
}
@ -146,7 +151,9 @@ int VirtualNetwork::select_leases(SqlDB * db)
{
leases = new FixedLeases(db,
oid,
mac_prefix);
mac_prefix,
global_bin,
site_bin);
}
else
{
@ -182,11 +189,11 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
ostringstream ose;
int rc;
string vlan_attr;
string s_type;
string ranged_error_str;
string vlan_attr;
string s_type;
string ranged_error_str;
unsigned int mac_prefix = VirtualNetworkPool::mac_prefix();
unsigned int mac_prefix = VirtualNetworkPool::mac_prefix();
//--------------------------------------------------------------------------
// VirtualNetwork Attributes from the template
@ -254,11 +261,27 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
ostringstream oss;
oss << "onebr" << oid;
bridge = oss.str();
}
}
// ------------ IP6 PREFIX ---------------
erase_template_attribute("GLOBAL_PREFIX", global);
if (Leases::Lease::prefix6_to_number(global, global_bin) != 0)
{
goto error_global;
}
erase_template_attribute("SITE_PREFIX", site);
if (Leases::Lease::prefix6_to_number(site, site_bin) != 0)
{
goto error_site;
}
//--------------------------------------------------------------------------
// Get the leases
//--------------------------------------------------------------------------
@ -278,6 +301,8 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
leases = new RangedLeases(db,
oid,
mac_prefix,
global_bin,
site_bin,
ip_start,
ip_end);
}
@ -290,6 +315,8 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str)
leases = new FixedLeases(db,
oid,
mac_prefix,
global_bin,
site_bin,
vector_leases);
remove_template_attribute("LEASES");
@ -336,6 +363,16 @@ error_ranged:
ose << ranged_error_str;
goto error_common;
error_global:
ose << global
<< " does not contain a character string representing a valid prefix";
goto error_common;
error_site:
ose << site
<< " does not contain a character string representing a valid prefix";
goto error_common;
error_null_leases:
ose << "Error getting Virtual Network leases.";
@ -514,6 +551,24 @@ string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const
os << "<VLAN_ID/>";
}
if (!global.empty())
{
os << "<GLOBAL_PREFIX>" << global << "</GLOBAL_PREFIX>";
}
else
{
os << "<GLOBAL_PREFIX/>";
}
if (!site.empty())
{
os << "<SITE_PREFIX>" << site << "</SITE_PREFIX>";
}
else
{
os << "<SITE_PREFIX/>";
}
if ( type == RANGED )
{
string st_ip_start;
@ -586,6 +641,12 @@ int VirtualNetwork::from_xml(const string &xml_str)
xpath(phydev, "/VNET/PHYDEV", "");
xpath(vlan_id, "/VNET/VLAN_ID","");
xpath(global, "/VNET/GLOBAL_PREFIX", "");
xpath(site, "/VNET/SITE_PREFIX","");
Leases::Lease::prefix6_to_number(site, site_bin);
Leases::Lease::prefix6_to_number(global, global_bin);
type = static_cast<NetworkType>(int_type);
// Get associated classes
@ -632,7 +693,10 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid)
string ip;
string mac;
ostringstream oss;
unsigned int eui64[2];
unsigned int prefix[2] = {0, 0};
ostringstream oss;
ip = nic->vector_value("IP");
oss << oid;
@ -643,11 +707,11 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid)
if (ip.empty())
{
rc = leases->get(vid,ip,mac);
rc = leases->get(vid, ip, mac, eui64);
}
else
{
rc = leases->set(vid,ip,mac);
rc = leases->set(vid,ip,mac, eui64);
}
if ( rc != 0 )
@ -659,11 +723,27 @@ int VirtualNetwork::nic_attribute(VectorAttribute *nic, int vid)
// NEW NIC ATTRIBUTES
//--------------------------------------------------------------------------
nic->replace("NETWORK" ,name);
nic->replace("NETWORK", name);
nic->replace("NETWORK_ID",oss.str());
nic->replace("BRIDGE" ,bridge);
nic->replace("MAC" ,mac);
nic->replace("IP" ,ip);
nic->replace("BRIDGE", bridge);
nic->replace("MAC", mac);
nic->replace("IP", ip);
Leases::Lease::ip6_to_string(eui64, prefix, ip);
nic->replace("IP6_LINK", ip);
if (!global.empty())
{
Leases::Lease::ip6_to_string(eui64, global_bin, ip);
nic->replace("IP6_GLOBAL", ip);
}
if (!site.empty())
{
Leases::Lease::ip6_to_string(eui64, site_bin, ip);
nic->replace("IP6_SITE", ip);
}
if ( vlan == 1 )
{

View File

@ -237,6 +237,7 @@ VirtualNetwork * VirtualNetworkPool::get_nic_by_id(const string& id_s,
}
int VirtualNetworkPool::nic_attribute(VectorAttribute * nic,
int nic_id,
int uid,
int vid,
string& error)
@ -267,6 +268,8 @@ int VirtualNetworkPool::nic_attribute(VectorAttribute * nic,
if ( rc == 0 )
{
update(vnet);
nic->replace("NIC_ID", nic_id);
}
else
{
@ -275,6 +278,7 @@ int VirtualNetworkPool::nic_attribute(VectorAttribute * nic,
vnet->unlock();
return rc;
}