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

Merge remote-tracking branch 'origin/master' into feature-3748

This commit is contained in:
Carlos Martín 2015-06-19 16:26:51 +02:00
commit 5a637828e1
150 changed files with 5396 additions and 1679 deletions

View File

@ -363,6 +363,56 @@ public:
int snap_id,
string& error_str);
/**
* Starts the disk snapshot create action
*
* @param vid VirtualMachine identification
* @param did DISK identification
* @param tag Description 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 disk_snapshot_create(
int vid,
int did,
const string& tag,
int& snap_id,
string& error_str);
/**
* Reverts the disk state to a previous snapshot
*
* @param vid VirtualMachine identification
* @param did DISK identification
* @param snap_id Snapshot to be restored
* @param error_str Error reason, if any
*
* @return 0 on success, -1 otherwise
*/
int disk_snapshot_revert(
int vid,
int did,
int snap_id,
string& error_str);
/**
* Deletes a disk snapshot
*
* @param vid VirtualMachine identification
* @param did DISK identification
* @param snap_id Snapshot to be restored
* @param error_str Error reason, if any
*
* @return 0 on success, -1 otherwise
*/
int disk_snapshot_delete(
int vid,
int did,
int snap_id,
string& error_str);
private:
/**
* Thread id for the Dispatch Manager

View File

@ -21,6 +21,7 @@
#include "ImageTemplate.h"
#include "NebulaLog.h"
#include "ObjectCollection.h"
#include "Snapshots.h"
using namespace std;
@ -96,16 +97,16 @@ public:
{
switch (ob)
{
case FILE: return "FILE" ; break;
case CD_ROM: return "CDROM" ; break;
case BLOCK: return "BLOCK" ; break;
case RBD: return "RBD" ; break;
case RBD_CDROM: return "RBD_CDROM" ; break;
case GLUSTER: return "GLUSTER" ; break;
case GLUSTER_CDROM: return "GLUSTER_CDROM" ; break;
case SHEEPDOG: return "SHEEPDOG" ; break;
case SHEEPDOG_CDROM: return "SHEEPDOG_CDROM" ; break;
default: return "";
case FILE: return "FILE" ; break;
case CD_ROM: return "CDROM" ; break;
case BLOCK: return "BLOCK" ; break;
case RBD: return "RBD" ; break;
case RBD_CDROM: return "RBD_CDROM" ; break;
case GLUSTER: return "GLUSTER" ; break;
case GLUSTER_CDROM: return "GLUSTER_CDROM" ; break;
case SHEEPDOG: return "SHEEPDOG" ; break;
case SHEEPDOG_CDROM: return "SHEEPDOG_CDROM" ; break;
default: return "";
}
};
@ -177,7 +178,7 @@ public:
* Returns true if the image is persistent
* @return true if the image is persistent
*/
bool isPersistent() const
bool is_persistent() const
{
return (persistent_img == 1);
};
@ -218,6 +219,7 @@ public:
return size_mb;
}
/**
* Sets the source path of the image
*/
@ -344,37 +346,15 @@ public:
* @param _type the new type. It will be transformed to upper case
* @return 0 on success, -1 otherwise
*/
int set_type(string& _type);
/**
* Check if the image can be used by other users
* @return true if group or others can access the image
*/
bool isPublic()
{
return (group_u == 1 || other_u == 1);
}
int set_type(string& _type, string& error);
/**
* Check if the image is used for saving_as a current one
* @return true if the image will be used to save an existing image.
*/
bool isSaving()
bool is_saving()
{
ImageTemplate * it = static_cast<ImageTemplate *>(obj_template);
return it->is_saving();
}
/**
* Check if the image is a hot snapshot
* @return true if image is a hot snapshot
*/
bool isHot()
{
ImageTemplate * it = static_cast<ImageTemplate *>(obj_template);
return it->is_saving_hot();
return (static_cast<ImageTemplate *>(obj_template))->is_saving();
}
/**
@ -388,13 +368,20 @@ public:
{
ostringstream oss;
if ((snapshots.size() > 0) && !persis)
{
error_str = "Image has snapshots.";
return -1;
}
switch(state)
{
case USED:
case CLONE:
case USED_PERS:
goto error_state;
break;
oss << "Image cannot be in state " << state_to_str(state) <<".";
error_str = oss.str();
return -1;
case INIT:
case READY:
@ -415,16 +402,6 @@ public:
}
return 0;
error_state:
oss << "Image cannot be in state " << state_to_str(state) << ".";
error_str = oss.str();
goto error_common;
error_common:
return -1;
}
/**
@ -486,6 +463,60 @@ public:
*/
ImageTemplate * clone_template(const string& new_name) const;
/* ---------------------------------------------------------------------- */
/* Snapshots functions */
/* ---------------------------------------------------------------------- */
/**
* Return the snapshot list of this image
*/
const Snapshots& get_snapshots() const
{
return snapshots;
};
/**
* Clear all the snapshots in the list
*/
void clear_snapshots()
{
snapshots.clear();
}
/**
* Set the snapshots for this image
* @param snapshot list
*/
void set_snapshots(const Snapshots& s)
{
snapshots = s;
snapshots.clear_disk_id();
};
void delete_snapshot(int snap_id)
{
snapshots.delete_snapshot(snap_id);
};
void revert_snapshot(int snap_id)
{
snapshots.active_snapshot(snap_id);
};
void set_target_snapshot(int snap_id)
{
target_snapshot = snap_id;
};
int get_target_snapshot()
{
return target_snapshot;
};
void clear_target_snapshot()
{
target_snapshot = -1;
};
private:
// -------------------------------------------------------------------------
@ -579,6 +610,16 @@ private:
*/
ObjectCollection img_clone_collection;
/**
* Snapshot list for this image
*/
Snapshots snapshots;
/**
* ID of the snapshot being processed (if any)
*/
int target_snapshot;
// *************************************************************************
// DataBase implementation (Private)
// *************************************************************************

View File

@ -26,6 +26,7 @@ using namespace std;
extern "C" void * image_action_loop(void *arg);
class Image;
class Snapshots;
class Template;
class ImageManager : public MadManager, public ActionListener
@ -189,6 +190,42 @@ public:
*/
void monitor_datastore(int ds_id);
/**
* Set the snapshots for the given image. The image MUST be persistent
* and of type OS or DATABLOCK.
* @param iid id of image
* @param s snapshot list
* @param failed the associated VM releasing the images is FAILED
*/
void set_image_snapshots(int iid, const Snapshots& s, bool failed);
/**
* Deletes the snapshot of an image
* @param iid id of image
* @param sid id of the snapshot
* @param error_str Error reason, if any
* @return 0 on success
*/
int delete_snapshot(int iid, int sid, string& error);
/**
* Reverts image state to a previous snapshot
* @param iid id of image
* @param sid id of the snapshot
* @param error_str Error reason, if any
* @return 0 on success
*/
int revert_snapshot(int iid, int sid, string& error);
/**
* Flattens ths snapshot by commiting changes to base image.
* @param iid id of image
* @param sid id of the snapshot
* @param error_str Error reason, if any
* @return 0 on success
*/
int flatten_snapshot(int iid, int sid, string& error);
private:
/**
* Generic name for the Image driver

View File

@ -114,6 +114,27 @@ private:
* @param drv_msg xml data for the mad operation.
*/
void monitor(int oid, const string& drv_msg) const;
/**
* Sends a delete snapshot command: "SNAP_DELETE DS_ID DS_XML"
* @param oid the datastore id.
* @param drv_msg xml data for the mad operation.
*/
void snapshot_delete(int oid, const string& drv_msg) const;
/**
* Sends a revert snapshot command: "SNAP_REVERT DS_ID DS_XML"
* @param oid the datastore id.
* @param drv_msg xml data for the mad operation.
*/
void snapshot_revert(int oid, const string& drv_msg) const;
/**
* Sends a flatten snapshot command: "SNAP_FLATTEN DS_ID DS_XML"
* @param oid the datastore id.
* @param drv_msg xml data for the mad operation.
*/
void snapshot_flatten(int oid, const string& drv_msg) const;
};
/* -------------------------------------------------------------------------- */

View File

@ -29,6 +29,7 @@
#include <vector>
class AuthRequest;
class Snapshots;
using namespace std;
@ -158,6 +159,7 @@ public:
* or the default one
* @param uid of VM owner (to look for the image id within its images)
* @param image_id on success returns the acquired image id
* @param snaps list of snapshots associated to this image
* @param error_str string describing the error
*
* @return 0 on success, -1 otherwise
@ -169,6 +171,7 @@ public:
string& dev_prefix,
int uid,
int& image_id,
Snapshots ** snaps,
string& error_str);
/**
* Generates an Authorization token for the DISK attribute

View File

@ -61,43 +61,16 @@ public:
bool is_saving()
{
string saving;
bool save_as_hot;
get(saving_attribute, saving);
get("SAVE_AS_HOT", save_as_hot);
return (saving.empty() == false);
}
bool is_saving_hot()
{
string save_as_hot;
get(saving_hot_attribute, save_as_hot);
return (save_as_hot.empty() == false);
return save_as_hot;
}
void set_saving()
{
SingleAttribute * attr= new SingleAttribute(saving_attribute, "YES");
erase(saving_attribute);
set(attr);
}
void set_saving_hot()
{
SingleAttribute * attr = new SingleAttribute(saving_hot_attribute,"YES");
erase(saving_hot_attribute);
set(attr);
}
void unset_saving()
{
erase(saving_attribute);
replace("SAVE_AS_HOT", "YES");
}
private:
@ -105,9 +78,6 @@ private:
static vector<string> restricted_attributes;
static string saving_attribute;
static string saving_hot_attribute;
bool has_restricted()
{
return restricted_attributes.size() > 0;

View File

@ -75,14 +75,16 @@ public:
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 */
SAVEAS_SUCCESS, /**< Sent by the VMM when saveas succeeds */
SAVEAS_FAILURE, /**< Sent by the VMM when 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 */
DISK_SNAPSHOT_SUCCESS, /**<Sent by TM when a snap. succeeds */
DISK_SNAPSHOT_FAILURE, /**<Sent by TM when a snap. fails */
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 */
@ -250,9 +252,9 @@ private:
void detach_failure_action(int vid);
void saveas_hot_success_action(int vid);
void saveas_success_action(int vid);
void saveas_hot_failure_action(int vid);
void saveas_failure_action(int vid);
void attach_nic_success_action(int vid);
@ -276,6 +278,10 @@ private:
void snapshot_delete_failure(int vid);
void disk_snapshot_success(int vid);
void disk_snapshot_failure(int vid);
void deploy_action(int vid);
void suspend_action(int vid);

View File

@ -119,7 +119,57 @@ public:
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class ImageSnapshotRevert : public RequestManagerImage
{
public:
ImageSnapshotRevert():
RequestManagerImage("ImageSnapshotRevert",
"Reverts image state to a previous snapshot",
"A:sii"){};
~ImageSnapshotRevert(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class ImageSnapshotFlatten : public RequestManagerImage
{
public:
ImageSnapshotFlatten():
RequestManagerImage("ImageSnapshotFlatten",
"Flattens the selected image snapshot",
"A:sii"){};
~ImageSnapshotFlatten(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class ImageSnapshotDelete : public RequestManagerImage
{
public:
ImageSnapshotDelete():
RequestManagerImage("ImageSnapshotDelete",
"Deletes a snapshot from image",
"A:sii"){};
~ImageSnapshotDelete(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -170,32 +170,15 @@ public:
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachineSaveDisk : public RequestManagerVirtualMachine
class VirtualMachineDiskSaveas : public RequestManagerVirtualMachine
{
public:
VirtualMachineSaveDisk():
RequestManagerVirtualMachine("VirtualMachineSaveDisk",
"Saves a disk from virtual machine as a new image",
"A:siissb"){};
VirtualMachineDiskSaveas():
RequestManagerVirtualMachine("VirtualMachineDiskSaveas",
"Save a disk from virtual machine as a new image",
"A:siissi"){};
~VirtualMachineSaveDisk(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class VirtualMachineSaveDiskCancel : public RequestManagerVirtualMachine
{
public:
VirtualMachineSaveDiskCancel():
RequestManagerVirtualMachine("VirtualMachineSaveDiskCancel",
"Cancels a disk snapshot set by VirtualMachineSaveDisk",
"A:sii"){};
~VirtualMachineSaveDiskCancel(){};
~VirtualMachineDiskSaveas(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
@ -405,4 +388,52 @@ public:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class VirtualMachineDiskSnapshotCreate: public RequestManagerVirtualMachine
{
public:
VirtualMachineDiskSnapshotCreate():
RequestManagerVirtualMachine("VirtualMachineDiskSnapshotCreate",
"Creates a new virtual machine disk snapshot",
"A:siis"){};
~VirtualMachineDiskSnapshotCreate(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class VirtualMachineDiskSnapshotRevert: public RequestManagerVirtualMachine
{
public:
VirtualMachineDiskSnapshotRevert():
RequestManagerVirtualMachine("VirtualMachineDiskSnapshotRevert",
"Reverts disk state to a snapshot",
"A:siii"){};
~VirtualMachineDiskSnapshotRevert(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class VirtualMachineDiskSnapshotDelete: public RequestManagerVirtualMachine
{
public:
VirtualMachineDiskSnapshotDelete():
RequestManagerVirtualMachine("VirtualMachineDiskSnapshotDelete",
"Deletes a disk snapshot",
"A:siii"){};
~VirtualMachineDiskSnapshotDelete(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
#endif

228
include/Snapshots.h Normal file
View File

@ -0,0 +1,228 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2015, 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. */
/* -------------------------------------------------------------------------- */
#ifndef SNAPSHOTS_H_
#define SNAPSHOTS_H_
#include <iostream>
#include <string>
#include <map>
#include <libxml/parser.h>
#include "Template.h"
using namespace std;
class VectorAttribute;
/**
* This class represents a list of Snapshots associated to an image or Virtual
* Machine Disk. The list is in the form:
* <SNAPSHOTS>
* <DISK_ID>: of the disk the snapshots are taken from (the initial backing)
* <ACTIVE>: the current snapshot in use by the VM. 0 for the original DISK
* <SNAPSHOT>
* <ID>
* <TAG>: Description
* <DATE>: the snapshot was taken
* <PARENT>: backing for this snapshot, -1 for the original image
* <CHILDREN>: comma separated list of children snapshots
*/
class Snapshots
{
public:
Snapshots(int _disk_id);
Snapshots(const Snapshots& s);
Snapshots& operator= (const Snapshots& s);
virtual ~Snapshots();
// *************************************************************************
// Inititalization functions
// *************************************************************************
/**
* Builds the snapshot list from its XML representation. This function
* is used when importing it from the DB.
* @param node xmlNode for the template
* @return 0 on success
*/
int from_xml_node(const xmlNodePtr node);
/**
* XML Representation of the Snapshots
*/
string& to_xml(string& xml) const
{
return snapshot_template.to_xml(xml);
};
/**
* Creates a new (empty) snapshot of the active disk
* @param tag description of this snapshot (optional)
* @return id of the new snapshot
*/
int create_snapshot(const string& tag);
/**
* Check if an snapshot can be deleted (no children, no active)
* @param id of the snapshot
* @param error if any
* @return true if can be deleted, false otherwise
*/
bool test_delete(unsigned int id, string& error) const;
/**
* Removes the snapshot from the list
* @param id of the snapshot
*/
void delete_snapshot(unsigned int id);
/**
* Set the given snapshot as active. Updates the values of the current
* snapshot
*/
int active_snapshot(unsigned int id);
/**
* Clear all the snapshots in the list
*/
void clear()
{
next_snapshot = 0;
active = -1;
disk_id = -1;
snapshot_template.clear();
snapshot_pool.clear();
}
/**
* Return the disk_id of the snapshot list
*/
int get_disk_id() const
{
return disk_id;
}
/**
* Return the active snapshot id
*/
int get_active_id() const
{
return active;
}
/**
* Removes the DISK_ID attribute to link the list to an Image
*/
void clear_disk_id()
{
disk_id = -1;
snapshot_template.erase("DISK_ID");
};
/**
* Sets the disk id for this snapshot list
* @param did the id
*/
void set_disk_id(int did)
{
disk_id = did;
snapshot_template.replace("DISK_ID", did);
};
/**
* @return number of snapshots in the list
*/
unsigned int size() const
{
return snapshot_pool.size();
};
/**
* Check if snapshot exists
* @param snap_id of the snapshot
* @return true if the snapshot with snap_id exisits
*/
bool exists(int snap_id) const
{
const VectorAttribute * snap = get_snapshot(snap_id);
return (snap != 0);
}
/**
* Get Attribute from the given snapshot
* @param id of the snapshot
* @param name of the attribute
*
* @return value or empty if not found
*/
string get_snapshot_attribute(unsigned int id, const char* name);
private:
/**
* Get a snapshot from the pool
* @param id of the snapshot
* @return pointer to the snapshot (VectorAttribute) or null
*/
const VectorAttribute * get_snapshot(unsigned int id) const;
VectorAttribute * get_snapshot(unsigned int id)
{
return const_cast<VectorAttribute *>(
static_cast<const Snapshots&>(*this).get_snapshot(id));
};
/**
* Build the object internal representation from an initialized
* template
*/
void init();
/**
* Text representation of the snapshot pool. To be stored as part of the
* VM or Image Templates
*/
Template snapshot_template;
/**
* Next id
*/
unsigned int next_snapshot;
/**
* Id of the active (current) snapshot, 0 represents the base image
*/
int active;
/**
* Id of the disk associated with this snapshot list
*/
unsigned int disk_id;
/**
* Snapshot pointer map
*/
map<unsigned int, VectorAttribute *> snapshot_pool;
};
#endif /*SNAPSHOTS_H_*/

View File

@ -55,12 +55,35 @@ public:
separator = t.separator;
xml_root = t.xml_root;
attributes.clear();
for (it = t.attributes.begin() ; it != t.attributes.end() ; it++)
{
attributes.insert(make_pair(it->first,(it->second)->clone()));
}
}
Template& operator=(const Template& t)
{
multimap<string,Attribute *>::const_iterator it;
if (this != &t)
{
replace_mode = t.replace_mode;
separator = t.separator;
xml_root = t.xml_root;
attributes.clear();
for (it = t.attributes.begin() ; it != t.attributes.end() ; it++)
{
attributes.insert(make_pair(it->first,(it->second)->clone()));
}
}
return *this;
}
/**
* The class destructor frees all the attributes conforming the template
*/
@ -127,6 +150,11 @@ public:
*/
string& to_str(string& str) const;
/**
* Clears all the attributes from the template
*/
void clear();
/**
* Sets a new attribute, the attribute MUST BE ALLOCATED IN THE HEAP, and
* will be freed when the template destructor is called.

View File

@ -60,6 +60,9 @@ public:
CHECKPOINT,
DRIVER_CANCEL,
SAVEAS_HOT,
SNAPSHOT_CREATE,
SNAPSHOT_REVERT,
SNAPSHOT_DELETE,
FINALIZE
};
@ -325,6 +328,26 @@ private:
* This function starts the saveas of the given disk
*/
void saveas_hot_action(int vid);
/**
* This function performs a generic snapshot action
*/
void do_snapshot_action(int vid, const char * action);
/**
* This function takes an snapshot of a disk
*/
void snapshot_create_action(int vid);
/**
* This function takes an snapshot of a disk
*/
void snapshot_revert_action(int vid);
/**
* This function deletes an snapshot of a disk
*/
void snapshot_delete_action(int vid);
};
#endif /*TRANSFER_MANAGER_H*/

View File

@ -187,11 +187,6 @@ public:
*/
static const char * PUBLIC_AUTH;
/**
* Name for the default auth driver to be used for not registered users
*/
static const char * DEFAULT_AUTH;
/**
* Name for the default Sunstone server user
*/

View File

@ -32,6 +32,7 @@
using namespace std;
class AuthRequest;
class Snapshots;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -154,7 +155,10 @@ public:
BOOT_UNDEPLOY_FAILURE = 47,
BOOT_STOPPED_FAILURE = 48,
PROLOG_RESUME_FAILURE = 49,
PROLOG_UNDEPLOY_FAILURE = 50
PROLOG_UNDEPLOY_FAILURE = 50,
DISK_SNAPSHOT_POWEROFF = 51,
DISK_SNAPSHOT_REVERT_POWEROFF = 52,
DISK_SNAPSHOT_DELETE_POWEROFF = 53
};
static int lcm_state_from_str(string& st, LcmState& state)
@ -210,6 +214,9 @@ public:
else if ( st == "BOOT_UNDEPLOY_FAILURE") { state = BOOT_UNDEPLOY_FAILURE; }
else if ( st == "PROLOG_RESUME_FAILURE") { state = PROLOG_RESUME_FAILURE; }
else if ( st == "PROLOG_UNDEPLOY_FAILURE") { state = PROLOG_UNDEPLOY_FAILURE; }
else if ( st == "DISK_SNAPSHOT_POWEROFF") { state = DISK_SNAPSHOT_POWEROFF; }
else if ( st == "DISK_SNAPSHOT_REVERT_POWEROFF") { state = DISK_SNAPSHOT_REVERT_POWEROFF; }
else if ( st == "DISK_SNAPSHOT_DELETE_POWEROFF") { state = DISK_SNAPSHOT_DELETE_POWEROFF; }
else {return -1;}
return 0;
@ -268,6 +275,9 @@ public:
case BOOT_UNDEPLOY_FAILURE: st = "BOOT_UNDEPLOY_FAILURE"; break;
case PROLOG_RESUME_FAILURE: st = "PROLOG_RESUME_FAILURE"; break;
case PROLOG_UNDEPLOY_FAILURE: st = "PROLOG_UNDEPLOY_FAILURE"; break;
case DISK_SNAPSHOT_POWEROFF: st = "DISK_SNAPSHOT_POWEROFF"; break;
case DISK_SNAPSHOT_REVERT_POWEROFF: st = "DISK_SNAPSHOT_REVERT_POWEROFF"; break;
case DISK_SNAPSHOT_DELETE_POWEROFF: st = "DISK_SNAPSHOT_DELETE_POWEROFF"; break;
}
return st;
@ -1260,82 +1270,56 @@ public:
int generate_context(string &files, int &disk_id, string& token_password);
// -------------------------------------------------------------------------
// Datastore related functions
// "Save as" Disk related functions (save_as hot)
// -------------------------------------------------------------------------
/**
* Gest the associated image to the given disk_id
* Mark the disk that is going to be "save as"
* @param disk_id of the VM
* @param hot is this a save_as hot operation
* @param snap_id of the disk to save, -1 to select the active snapshot
* @param err_str describing the error
* @return -1 if the image cannot saveas
* @return -1 if the image cannot saveas or image_id of current disk
*/
int get_image_from_disk(int disk_id, bool hot, string& err_str);
int set_saveas_disk(int disk_id, int snap_id, string& err_str);
/**
* Sets the corresponding SAVE_AS state.
* Set save attributes for the disk
* @param disk_id Index of the disk to save
* @param hot is this a save_as hot operation
* @return 0 if the VM can be saved as
* @param source to save the disk
* @param img_id ID of the image this disk will be saved to
*/
int set_saveas_state(int disk_id, bool hot);
int set_saveas_disk(int disk_id, const string& source, int img_id);
/**
* Clears the SAVE_AS state, moving the VM to the original state.
* @param disk_id Index of the disk to save
* @param hot is this a save_as hot operation
* @return 0 if the VM was in a SAVE_AS state
* Sets the corresponding state to save the disk.
* @return 0 if the VM can be saved
*/
int clear_saveas_state(int disk_id, bool hot);
int set_saveas_state();
/**
* Set the SAVE_AS attribute for the "disk_id"th disk.
* @param disk_id Index of the disk to save
* @param source to save the disk (SAVE_AS_SOURCE)
* @param img_id ID of the image this disk will be saved to (SAVE_AS).
* Clears the save state, moving the VM to the original state.
* @return 0 if the VM was in an saveas state
*/
int save_disk(int disk_id,
const string& source,
int img_id);
/**
* Clears the SAVE_AS attribute for the "disk_id"th disk.
* @param disk_id Index of the disk to save
* @return 0 on success, -1 if the disk does not exist
*/
int clear_save_disk(int disk_id);
int clear_saveas_state();
/**
* Returns the image ID to be saved-as.
* @param disk_id Index of the disk to save
* @return The image ID, or -1 if the disk is not going to be saved-as
* Clears the SAVE_AS_* attributes of the disk being saved as
* @return the ID of the image this disk will be saved to or -1 if it
* is not found.
*/
int get_save_disk_image(int disk_id);
int clear_saveas_disk();
/**
* Set the SAVE_AS attribute for the "disk_id"th disk.
* @param disk_id Index of the disk to save
* @param source to save the disk (SAVE_AS_SOURCE)
* @param img_id ID of the image this disk will be saved to (SAVE_AS).
*/
int save_disk_hot(int disk_id,
const string& source,
int img_id);
/**
* Get the original image id of the disk. It also checks that the disk can
* be saved_as.
* @param disk_id Index of the disk to save
* @param error_str describes the error
* @param source of the image to save the disk to
* @param image_id of the image to save the disk to
* @param tm_mad in use by the disk
* @param ds_id of the datastore in use by the disk
* @return -1 if failure
*/
int get_saveas_disk_hot(int& disk_id, string& source, int& image_id);
/**
* Clears the save_as attributes of the disk being (hot) saved as
*
* @param img_id ID of the image this disk will be saved to. Can be
* -1 if it is not found
* @return 0 if a disk with (HOTPLUG_)SAVE_AS was cleaned
*/
int cancel_saveas_disk(int& image_id);
int get_saveas_disk(int& disk_id, string& source, int& image_id,
string& snap_id, string& tm_mad, string& ds_id);
// ------------------------------------------------------------------------
// Authorization related functions
@ -1388,6 +1372,7 @@ public:
int max_disk_id,
int uid,
int& image_id,
Snapshots ** snap,
string& error_str);
/**
* Returns the disk that is waiting for an attachment action
@ -1406,18 +1391,27 @@ public:
*
* @return the DISK or 0 if no disk was deleted
*/
VectorAttribute * delete_attach_disk();
VectorAttribute * delete_attach_disk(Snapshots **snap);
/**
* Adds a new disk to the virtual machine template. The disk should be
* generated by the build_attach_disk
* @param new_disk must be allocated in the heap
* @param snap list of snapshots associated to the disk
*/
void set_attach_disk(VectorAttribute * new_disk)
void set_attach_disk(VectorAttribute * new_disk, Snapshots * snap)
{
new_disk->replace("ATTACH", "YES");
obj_template->set(new_disk);
if (snap != 0)
{
int disk_id;
new_disk->vector_value("DISK_ID", disk_id);
snapshots.insert(pair<int, Snapshots *>(disk_id, snap));
}
}
/**
@ -1495,6 +1489,64 @@ public:
*/
int set_attach_nic(int nic_id);
// ------------------------------------------------------------------------
// Snapshot related functions
// ------------------------------------------------------------------------
/**
* Return the snapshot list for the disk
* @param disk_id of the disk
* @param error if any
* @return pointer to Snapshots or 0 if not found
*/
const Snapshots * get_disk_snapshots(int did, string& err) const;
/**
* Creates a new snapshot of the given disk
* @param disk_id of the disk
* @param tag a description for this snapshot
* @param error if any
* @return the id of the new snapshot or -1 if error
*/
int new_disk_snapshot(int disk_id, const string& tag, string& error);
/**
* Sets the snap_id as active, the VM will boot from it next time
* @param disk_id of the disk
* @param snap_id of the snapshot
* @param error if any
* @return -1 if error
*/
int revert_disk_snapshot(int disk_id, int snap_id);
/**
* Deletes the snap_id from the list, test_delete_disk_snapshot *MUST* be
* called before actually deleting the snapshot.
* @param disk_id of the disk
* @param snap_id of the snapshot
*/
void delete_disk_snapshot(int disk_id, int snap_id);
/**
* Get information about the disk to take the snapshot from
* @param ds_id id of the datastore
* @param tm_mad used by the datastore
* @param disk_id of the disk
* @param snap_id of the snapshot
*/
int get_snapshot_disk(string& ds_id, string& tm_mad, string& disk_id,
string& snap_id);
/**
* Unset the current disk being snapshotted (reverted...)
*/
void clear_snapshot_disk();
/**
* Set the disk as being snapshotted (reverted...)
* @param disk_id of the disk
* @param snap_id of the target snap_id
*/
int set_snapshot_disk(int disk_id, int snap_id);
// ------------------------------------------------------------------------
// Snapshot related functions
@ -1651,6 +1703,11 @@ private:
*/
vector<History *> history_records;
/**
* Snapshots for each disk
*/
map<int, Snapshots *> snapshots;
// -------------------------------------------------------------------------
// Logging & Dirs
// -------------------------------------------------------------------------
@ -1797,12 +1854,12 @@ private:
*/
int parse_defaults(string& error_str);
/**
/**
* Known attributes for network contextualization rendered as:
* ETH_<nicid>_<context[0]> = $NETWORK[context[1], vnet_name]
*
* The context[1] values in the map are searched in the NIC and
* if not found in the AR and VNET. They can be also set in the
* The context[1] values in the map are searched in the NIC and
* if not found in the AR and VNET. They can be also set in the
* CONTEXT section it self using full name (ETH_).
*
* IPv4 context variables:
@ -1924,6 +1981,19 @@ private:
*/
int get_disk_images(string &error_str);
/**
* Return the VectorAttribute representation of a disk
* @param disk_id of the disk
* @return pointer to the VectorAttribute
*/
VectorAttribute* get_disk(int disk_id)
{
return const_cast<VectorAttribute *>(
static_cast<const VirtualMachine&>(*this).get_disk(disk_id));
};
const VectorAttribute* get_disk(int disk_id) const;
protected:
//**************************************************************************
@ -1998,11 +2068,6 @@ protected:
return -1;
}
// *************************************************************************
// Helpers
// *************************************************************************
VectorAttribute* get_disk(int disk_id);
};
#endif /*VIRTUAL_MACHINE_H_*/

View File

@ -344,10 +344,8 @@ public:
* Images and updates usage quotas
*
* @param vid VM id
* @param release_save_as true to release non-persistent images
* in the detach event
*/
void delete_attach_disk(int vid, bool release_save_as);
void delete_attach_disk(int vid);
/**
* Deletes the NIC that was in the process of being attached

View File

@ -1018,7 +1018,11 @@ TM_SHARED_FILES="src/tm_mad/shared/clone \
src/tm_mad/shared/context \
src/tm_mad/shared/premigrate \
src/tm_mad/shared/postmigrate \
src/tm_mad/shared/failmigrate \
src/tm_mad/shared/mvds \
src/tm_mad/shared/snap_create \
src/tm_mad/shared/snap_delete \
src/tm_mad/shared/snap_revert \
src/tm_mad/shared/cpds"
TM_FS_LVM_FILES="src/tm_mad/fs_lvm/clone \
@ -1028,6 +1032,10 @@ TM_FS_LVM_FILES="src/tm_mad/fs_lvm/clone \
src/tm_mad/fs_lvm/cpds \
src/tm_mad/fs_lvm/premigrate \
src/tm_mad/fs_lvm/postmigrate \
src/tm_mad/fs_lvm/snap_create \
src/tm_mad/fs_lvm/snap_delete \
src/tm_mad/fs_lvm/snap_revert \
src/tm_mad/fs_lvm/failmigrate \
src/tm_mad/fs_lvm/delete"
TM_QCOW2_FILES="src/tm_mad/qcow2/clone \
@ -1039,7 +1047,11 @@ TM_QCOW2_FILES="src/tm_mad/qcow2/clone \
src/tm_mad/qcow2/context \
src/tm_mad/qcow2/premigrate \
src/tm_mad/qcow2/postmigrate \
src/tm_mad/qcow2/failmigrate \
src/tm_mad/qcow2/mvds \
src/tm_mad/qcow2/snap_create \
src/tm_mad/qcow2/snap_delete \
src/tm_mad/qcow2/snap_revert \
src/tm_mad/qcow2/cpds"
TM_SSH_FILES="src/tm_mad/ssh/clone \
@ -1051,7 +1063,11 @@ TM_SSH_FILES="src/tm_mad/ssh/clone \
src/tm_mad/ssh/context \
src/tm_mad/ssh/premigrate \
src/tm_mad/ssh/postmigrate \
src/tm_mad/ssh/failmigrate \
src/tm_mad/ssh/mvds \
src/tm_mad/ssh/snap_create \
src/tm_mad/ssh/snap_delete \
src/tm_mad/ssh/snap_revert \
src/tm_mad/ssh/cpds"
TM_DUMMY_FILES="src/tm_mad/dummy/clone \
@ -1063,7 +1079,11 @@ TM_DUMMY_FILES="src/tm_mad/dummy/clone \
src/tm_mad/dummy/context \
src/tm_mad/dummy/premigrate \
src/tm_mad/dummy/postmigrate \
src/tm_mad/dummy/failmigrate \
src/tm_mad/dummy/mvds \
src/tm_mad/dummy/snap_create \
src/tm_mad/dummy/snap_delete \
src/tm_mad/dummy/snap_revert \
src/tm_mad/dummy/cpds"
TM_VMFS_FILES="src/tm_mad/vmfs/clone \
@ -1076,6 +1096,10 @@ TM_VMFS_FILES="src/tm_mad/vmfs/clone \
src/tm_mad/vmfs/mvds \
src/tm_mad/vmfs/cpds \
src/tm_mad/vmfs/postmigrate \
src/tm_mad/vmfs/snap_create \
src/tm_mad/vmfs/snap_delete \
src/tm_mad/vmfs/snap_revert \
src/tm_mad/vmfs/failmigrate \
src/tm_mad/vmfs/premigrate"
TM_LVM_FILES="src/tm_mad/lvm/clone \
@ -1085,6 +1109,10 @@ TM_LVM_FILES="src/tm_mad/lvm/clone \
src/tm_mad/lvm/cpds \
src/tm_mad/lvm/premigrate \
src/tm_mad/lvm/postmigrate \
src/tm_mad/lvm/snap_create \
src/tm_mad/lvm/snap_delete \
src/tm_mad/lvm/snap_revert \
src/tm_mad/lvm/failmigrate \
src/tm_mad/lvm/delete"
TM_CEPH_FILES="src/tm_mad/ceph/clone \
@ -1094,6 +1122,10 @@ TM_CEPH_FILES="src/tm_mad/ceph/clone \
src/tm_mad/ceph/cpds \
src/tm_mad/ceph/premigrate \
src/tm_mad/ceph/postmigrate \
src/tm_mad/ceph/snap_create \
src/tm_mad/ceph/snap_delete \
src/tm_mad/ceph/snap_revert \
src/tm_mad/ceph/failmigrate \
src/tm_mad/ceph/delete"
TM_DEV_FILES="src/tm_mad/dev/clone \
@ -1103,6 +1135,10 @@ TM_DEV_FILES="src/tm_mad/dev/clone \
src/tm_mad/dev/cpds \
src/tm_mad/dev/premigrate \
src/tm_mad/dev/postmigrate \
src/tm_mad/dev/snap_create \
src/tm_mad/dev/snap_delete \
src/tm_mad/dev/snap_revert \
src/tm_mad/dev/failmigrate \
src/tm_mad/dev/delete"
#-------------------------------------------------------------------------------
@ -1122,6 +1158,9 @@ DATASTORE_DRIVER_DUMMY_SCRIPTS="src/datastore_mad/remotes/dummy/cp \
src/datastore_mad/remotes/dummy/stat \
src/datastore_mad/remotes/dummy/clone \
src/datastore_mad/remotes/dummy/monitor \
src/datastore_mad/remotes/dummy/snap_delete \
src/datastore_mad/remotes/dummy/snap_revert \
src/datastore_mad/remotes/dummy/snap_flatten \
src/datastore_mad/remotes/dummy/rm"
DATASTORE_DRIVER_FS_SCRIPTS="src/datastore_mad/remotes/fs/cp \
@ -1129,6 +1168,9 @@ DATASTORE_DRIVER_FS_SCRIPTS="src/datastore_mad/remotes/fs/cp \
src/datastore_mad/remotes/fs/stat \
src/datastore_mad/remotes/fs/clone \
src/datastore_mad/remotes/fs/monitor \
src/datastore_mad/remotes/fs/snap_delete \
src/datastore_mad/remotes/fs/snap_revert \
src/datastore_mad/remotes/fs/snap_flatten \
src/datastore_mad/remotes/fs/rm"
DATASTORE_DRIVER_VMFS_SCRIPTS="src/datastore_mad/remotes/vmfs/cp \
@ -1137,6 +1179,9 @@ DATASTORE_DRIVER_VMFS_SCRIPTS="src/datastore_mad/remotes/vmfs/cp \
src/datastore_mad/remotes/vmfs/clone \
src/datastore_mad/remotes/vmfs/monitor \
src/datastore_mad/remotes/vmfs/rm \
src/datastore_mad/remotes/vmfs/snap_delete \
src/datastore_mad/remotes/vmfs/snap_revert \
src/datastore_mad/remotes/vmfs/snap_flatten \
src/datastore_mad/remotes/vmfs/vmfs.conf"
DATASTORE_DRIVER_LVM_SCRIPTS="src/datastore_mad/remotes/lvm/cp \
@ -1145,6 +1190,9 @@ DATASTORE_DRIVER_LVM_SCRIPTS="src/datastore_mad/remotes/lvm/cp \
src/datastore_mad/remotes/lvm/rm \
src/datastore_mad/remotes/lvm/monitor \
src/datastore_mad/remotes/lvm/clone \
src/datastore_mad/remotes/lvm/snap_delete \
src/datastore_mad/remotes/lvm/snap_revert \
src/datastore_mad/remotes/lvm/snap_flatten \
src/datastore_mad/remotes/lvm/lvm.conf"
DATASTORE_DRIVER_CEPH_SCRIPTS="src/datastore_mad/remotes/ceph/cp \
@ -1153,6 +1201,9 @@ DATASTORE_DRIVER_CEPH_SCRIPTS="src/datastore_mad/remotes/ceph/cp \
src/datastore_mad/remotes/ceph/rm \
src/datastore_mad/remotes/ceph/monitor \
src/datastore_mad/remotes/ceph/clone \
src/datastore_mad/remotes/ceph/snap_delete \
src/datastore_mad/remotes/ceph/snap_revert \
src/datastore_mad/remotes/ceph/snap_flatten \
src/datastore_mad/remotes/ceph/ceph.conf"
DATASTORE_DRIVER_DEV_SCRIPTS="src/datastore_mad/remotes/dev/cp \
@ -1160,6 +1211,9 @@ DATASTORE_DRIVER_DEV_SCRIPTS="src/datastore_mad/remotes/dev/cp \
src/datastore_mad/remotes/dev/stat \
src/datastore_mad/remotes/dev/rm \
src/datastore_mad/remotes/dev/monitor \
src/datastore_mad/remotes/dev/snap_delete \
src/datastore_mad/remotes/dev/snap_revert \
src/datastore_mad/remotes/dev/snap_flatten \
src/datastore_mad/remotes/dev/clone"
#-------------------------------------------------------------------------------

View File

@ -163,7 +163,10 @@
BOOT_UNDEPLOY_FAILURE = 47,
BOOT_STOPPED_FAILURE = 48,
PROLOG_RESUME_FAILURE = 49,
PROLOG_UNDEPLOY_FAILURE = 50
PROLOG_UNDEPLOY_FAILURE = 50,
DISK_SNAPSHOT_POWEROFF = 51,
DISK_SNAPSHOT_REVERT_POWEROFF = 52,
DISK_SNAPSHOT_DELETE_POWEROFF = 53
-->
<xs:element name="LCM_STATE" type="xs:integer"/>
<xs:element name="PREV_STATE" type="xs:integer"/>

View File

@ -96,7 +96,10 @@
BOOT_UNDEPLOY_FAILURE = 47,
BOOT_STOPPED_FAILURE = 48,
PROLOG_RESUME_FAILURE = 49,
PROLOG_UNDEPLOY_FAILURE = 50
PROLOG_UNDEPLOY_FAILURE = 50,
DISK_SNAPSHOT_POWEROFF = 51,
DISK_SNAPSHOT_REVERT_POWEROFF = 52,
DISK_SNAPSHOT_DELETE_POWEROFF = 53
-->
<xs:element name="LCM_STATE" type="xs:integer"/>
<xs:element name="PREV_STATE" type="xs:integer"/>

View File

@ -703,6 +703,13 @@ HM_MAD = [
# defined all the modules available will be enabled
# authz : list of authentication modules separated by commas
#
# DEFAULT_AUTH: The default authentication driver to use when OpenNebula does
# not know the user and needs to authenticate it externally. If you want to
# use "default" (not recommended, but supported for backwards compatibility
# reasons) make sure you create a symlink pointing to the actual authentication
# driver in /var/lib/one/remotes/auth, and add "default" to the 'auth'
# parameter in the 'AUTH_MAD' section.
#
# SESSION_EXPIRATION_TIME: Time in seconds to keep an authenticated token as
# valid. During this time, the driver is not used. Use 0 to disable session
# caching
@ -721,6 +728,8 @@ AUTH_MAD = [
authn = "ssh,x509,ldap,server_cipher,server_x509"
]
#DEFAULT_AUTH = "default"
SESSION_EXPIRATION_TIME = 900
#ENABLE_OTHER_PERMISSIONS = "YES"

View File

@ -0,0 +1,11 @@
Defaults:oneadmin !requiretty
Defaults:oneadmin secure_path = /sbin:/bin:/usr/sbin:/usr/bin
Cmnd_Alias ONE_MISC = /bin/dd, /sbin/mkfs, /bin/sync
Cmnd_Alias ONE_NET = /sbin/brctl, /sbin/ebtables, /sbin/iptables, /sbin/ip, /usr/sbin/ipset
Cmnd_Alias ONE_LVM = /sbin/lvcreate, /sbin/lvremove, /sbin/lvrename, /sbin/lvs, /sbin/vgdisplay
Cmnd_Alias ONE_ISCSI = /usr/bin/iscsiadm, /usr/sbin/tgt-admin, /usr/sbin/tgtadm
Cmnd_Alias ONE_OVS = /usr/bin/ovs-ofctl, /usr/bin/ovs-vsctl
Cmnd_Alias ONE_XEN = /usr/sbin/xentop, /usr/sbin/xl, /usr/sbin/xm
oneadmin ALL=(ALL) NOPASSWD: ONE_MISC, ONE_NET, ONE_LVM, ONE_ISCSI, ONE_OVS, ONE_XEN

128
share/pkgs/Debian8/opennebula Executable file
View File

@ -0,0 +1,128 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: opennebula
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: mysql
# Should-Stop: mysql
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: OpenNebula init script
# Description: OpenNebula cloud initialisation script
### END INIT INFO
# Author: Soren Hansen <soren@canonical.com>
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="OpenNebula cloud"
NAME=one
DAEMON=/usr/bin/$NAME
DAEMON_ARGS=""
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
mkdir -p /var/run/one /var/lock/one
chown oneadmin /var/run/one /var/lock/one
su oneadmin -s /bin/sh -c 'one start'
}
#
# Function that stops the daemon/service
#
do_stop()
{
su oneadmin -s /bin/sh -c 'one stop'
}
do_start_sched()
{
su oneadmin -s /bin/sh -c 'one start-sched'
}
do_stop_sched()
{
su oneadmin -s /bin/sh -c 'one stop-sched'
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "oned" "$NAME" && exit 0 || exit $?
;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
restart-sched)
log_daemon_msg "Restarting scheduler"
do_stop_sched
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}" >&2
exit 3
;;
esac
:

View File

@ -0,0 +1,106 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: opennebula-econe
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: ECONE Server init script
# Description: OpenNebula ECONE service initialisation script
### END INIT INFO
# Author: Tino Vázquez <tinova@opennebula.org>
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="ECONE Service"
NAME=econe-server
DAEMON=/usr/bin/$NAME
DAEMON_ARGS=""
SCRIPTNAME=/etc/init.d/$NAME
PID_FILE=/var/run/one/econe-server.pid
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
mkdir -p /var/run/one /var/lock/one /var/log/one
chown oneadmin /var/run/one /var/lock/one /var/log/one
su oneadmin -s /bin/sh -c "$DAEMON start"
}
#
# Function that stops the daemon/service
#
do_stop()
{
su oneadmin -s /bin/sh -c "$DAEMON stop"
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
ECONE_PID=`cat $PID_FILE`
kill -0 $ECONE_PID > /dev/null 2>&1
if [ "$?" -eq "0" ]; then
log_daemon_msg "$NAME is running"
log_end_msg 0
else
log_daemon_msg "$NAME is not running"
log_end_msg 1
fi
;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
:

View File

@ -0,0 +1,94 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: opennebula-flow
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: OneFlow init script
# Description: OpenNebula OneFlow service initialisation script
### END INIT INFO
# Author: Tino Vázquez <tinova@opennebula.org>
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="OneFlow Service"
NAME=oneflow-server
DAEMON=/usr/bin/$NAME
DAEMON_ARGS=""
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
mkdir -p /var/run/one /var/lock/one /var/log/one
chown oneadmin /var/run/one /var/lock/one /var/log/one
su oneadmin -s /bin/sh -c "$DAEMON start"
}
#
# Function that stops the daemon/service
#
do_stop()
{
su oneadmin -s /bin/sh -c "$DAEMON stop"
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 3
;;
esac
:

View File

@ -0,0 +1,94 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: opennebula-gate
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: OneGate init script
# Description: OpenNebula OneGate service initialisation script
### END INIT INFO
# Author: Tino Vázquez <tinova@opennebula.org>
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="OneGate Service"
NAME=onegate-server
DAEMON=/usr/bin/$NAME
DAEMON_ARGS=""
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
mkdir -p /var/run/one /var/lock/one /var/log/one
chown oneadmin /var/run/one /var/lock/one /var/log/one
su oneadmin -s /bin/sh -c "$DAEMON start"
}
#
# Function that stops the daemon/service
#
do_stop()
{
su oneadmin -s /bin/sh -c "$DAEMON stop"
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 3
;;
esac
:

View File

@ -0,0 +1,105 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: opennebula-novnc
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: novnc init script
# Description: OpenNebula novnc server
### END INIT INFO
# Author: Arnold Bechtoldt <mail@arnoldbechtoldt.com>
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="OpenNebula novnc server"
NAME=novnc-server
DAEMON=/usr/bin/$NAME
DAEMON_ARGS=""
SCRIPTNAME=/etc/init.d/opennebula-novnc
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
mkdir -p /var/lock/one /var/log/one
chown oneadmin /var/lock/one /var/log/one
su oneadmin -s /bin/sh -c "$DAEMON start"
}
#
# Function that retrives the status of the daemon/service
#
do_status()
{
su oneadmin -s /bin/sh -c "$DAEMON status"
}
#
# Function that stops the daemon/service
#
do_stop()
{
su oneadmin -s /bin/sh -c "$DAEMON stop"
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
do_status && exit 0 || exit $?
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
:

View File

@ -0,0 +1,108 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: opennebula-sunstone
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Sunstone init script
# Description: OpenNebula Sunstone web interface cloud initialisation script
### END INIT INFO
# Author: Jaime Melis <jmelis@opennebula.org>
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Sunstone Web interface"
NAME=sunstone-server
DAEMON=/usr/bin/$NAME
DAEMON_ARGS=""
SCRIPTNAME=/etc/init.d/opennebula-sunstone
PID_FILE=/var/run/one/sunstone.pid
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
service opennebula-novnc start
mkdir -p /var/run/one /var/lock/one /var/log/one
chown oneadmin /var/run/one /var/lock/one /var/log/one
su oneadmin -s /bin/sh -c "$DAEMON start-sunstone"
}
#
# Function that stops the daemon/service
#
do_stop()
{
su oneadmin -s /bin/sh -c "$DAEMON stop-sunstone"
service opennebula-novnc stop
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
SUNSTONE_PID=`cat $PID_FILE`
kill -0 $SUNSTONE_PID > /dev/null 2>&1
if [ "$?" -eq "0" ]; then
log_daemon_msg "$NAME is running"
log_end_msg 0
else
log_daemon_msg "$NAME is not running"
log_end_msg 1
fi
;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
:

View File

@ -167,6 +167,11 @@ class OneHostHelper < OpenNebulaHelper::OneHelper
NUM_THREADS = 15
def sync(host_ids, options)
if `id -u`.to_i == 0 || `id -G`.split.collect{|e| e.to_i}.include?(0)
STDERR.puts("Cannot run 'onehost sync' as root")
exit -1
end
begin
current_version = File.read(REMOTES_LOCATION+'/VERSION').strip
rescue

View File

@ -292,6 +292,13 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
puts str % [e, mask]
}
if image.has_elements?("/IMAGE/SNAPSHOTS")
puts
CLIHelper.print_header(str_h1 % "IMAGE SNAPSHOTS",false)
format_snapshots(image)
end
puts
CLIHelper.print_header(str_h1 % "IMAGE TEMPLATE",false)
@ -311,6 +318,44 @@ class OneImageHelper < OpenNebulaHelper::OneHelper
end
end
def format_snapshots(image)
table=CLIHelper::ShowTable.new(nil, self) do
column :AC , "Is active", :left, :size => 2 do |d|
if d["ACTIVE"] == "YES"
"=>"
else
""
end
end
column :ID, "Snapshot ID", :size=>3 do |d|
d["ID"]
end
column :PARENT, "Snapshot Parent ID", :size=>6 do |d|
d["PARENT"]
end
column :CHILDREN, "Snapshot Children IDs", :size=>10 do |d|
d["CHILDREN"]
end
column :TAG, "Snapshot Tag", :left, :size=>45 do |d|
d["TAG"]
end
column :DATE, "Snapshot creation date", :size=>15 do |d|
OpenNebulaHelper.time_to_str(d["DATE"])
end
default :AC, :ID, :PARENT, :DATE, :CHILDREN, :TAG
end
# Convert snapshot data to an array
image_hash = image.to_hash
image_snapshots = [image_hash['IMAGE']['SNAPSHOTS']].flatten.first
table.show(image_snapshots)
end
def self.create_image_variables(options, name)
if Array===name
names=name

View File

@ -601,13 +601,8 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
d["CLONE"]
end
column :"SAVE_AS", "", :size=>7 do |d|
d["SAVE_AS"] || "-"
end
default :ID, :TARGET, :IMAGE, :TYPE,
:SAVE, :SAVE_AS
:SAVE
end.show(vm_disks, {})
while vm.has_elements?("/VM/TEMPLATE/DISK")
@ -615,6 +610,12 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
end if !options[:all]
end
if vm.has_elements?("/VM/SNAPSHOTS")
puts
CLIHelper.print_header(str_h1 % "VM DISK SNAPSHOTS",false)
format_snapshots(vm)
end
sg_nics = []
if (vm.has_elements?("/VM/TEMPLATE/NIC/SECURITY_GROUPS"))
@ -941,4 +942,59 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
table.show(history)
end
def format_snapshots(vm)
table=CLIHelper::ShowTable.new(nil, self) do
column :AC , "Is active", :left, :size => 2 do |d|
if d["ACTIVE"] == "YES"
"=>"
else
""
end
end
column :ID, "Snapshot ID", :size=>3 do |d|
d["ID"]
end
column :DISK, "Disk ID", :size=>4 do |d|
d["DISK_ID"]
end
column :PARENT, "Snapshot Parent ID", :size=>6 do |d|
d["PARENT"]
end
column :CHILDREN, "Snapshot Children IDs", :size=>10 do |d|
d["CHILDREN"]
end
column :TAG, "Snapshot Tag", :left, :size=>45 do |d|
d["TAG"]
end
column :DATE, "Snapshot creation date", :size=>15 do |d|
OpenNebulaHelper.time_to_str(d["DATE"])
end
default :AC, :ID, :DISK, :PARENT, :DATE, :CHILDREN, :TAG
end
# Convert snapshot data to an array
vm_hash = vm.to_hash
vm_snapshots = [vm_hash['VM']['SNAPSHOTS']].flatten
snapshots = []
vm_snapshots.each do |disk|
disk_id = disk['DISK_ID']
sshots = [disk['SNAPSHOT']].flatten
sshots.each do |snapshot|
data = snapshot.merge({ 'DISK_ID' => disk_id })
snapshots << data
end
end
table.show(snapshots)
end
end

View File

@ -301,6 +301,36 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
snapshot_delete_desc = <<-EOT.unindent
Deletes a snapshot from the image
EOT
command :"snapshot-delete", snapshot_delete_desc, :imageid, :snapshot_id do
helper.perform_action(args[0], options, "snapshot deleted") do |o|
o.snapshot_delete(args[1].to_i)
end
end
snapshot_revert_desc = <<-EOT.unindent
Reverts image state to a snapshot
EOT
command :"snapshot-revert", snapshot_revert_desc, :imageid, :snapshot_id do
helper.perform_action(args[0], options, "image state reverted") do |o|
o.snapshot_revert(args[1].to_i)
end
end
snapshot_flatten_desc = <<-EOT.unindent
Flattens the snapshot and removes all other snapshots in the image
EOT
command :"snapshot-flatten", snapshot_flatten_desc, :imageid, :snapshot_id do
helper.perform_action(args[0], options, "snapshot flattened") do |o|
o.snapshot_flatten(args[1].to_i)
end
end
list_desc = <<-EOT.unindent
Lists Images in the pool
EOT

View File

@ -216,84 +216,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
vms_desc = <<-EOT.unindent
Import vCenter running Virtual Machines into OpenNebula
Deprecated action in onevcenter, please use onehost importvm instead
EOT
command :vms, vms_desc, :options=>[ VCENTER, USER, PASS ] do
if options[:vuser].nil? ||
options[:vpass].nil? ||
options[:vcenter].nil?
STDERR.puts "vCenter connection parameters are mandatory to import"\
" VM templates:\n"\
"\t --vcenter vCenter hostname\n"\
"\t --vuser username to login in vcenter\n"\
"\t --vpass password for the user"
exit -1
end
STDERR.puts "Deprecated action in onevcenter, please use onehost "\
"importvm instead"
begin
STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
vc = VCenterDriver::VIClient.new_connection(
:user => options[:vuser],
:password => options[:vpass],
:host => options[:vcenter])
STDOUT.print "done!\n\n"
STDOUT.print "Looking for running Virtual Machines..."
rs = vc.running_vms
STDOUT.print "done!\n"
rs.each {|dc, tmps|
STDOUT.print "\nDo you want to process datacenter #{dc} [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
if tmps.empty?
STDOUT.print " No new running Virtual Machines found in"\
" #{dc}...\n\n"
next
end
tmps.each{ |v|
STDOUT.print "\n * Running Virtual Machine found:\n"\
" - Name : #{v[:name]}\n"\
" - UUID : #{v[:uuid]}\n"\
" - Cluster: #{v[:host]}\n"\
" Import this Virtual Machine [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
one_v = ::OpenNebula::VirtualMachine.new(
::OpenNebula::VirtualMachine.build_xml, vc.one)
rc = one_v.allocate(v[:one])
if ::OpenNebula.is_error?(rc)
STDOUT.puts " Error creating Virtual Machine: "\
"#{rc.message}\n"
end
rc = one_v.deploy v[:host_id]
if ::OpenNebula.is_error?(rc)
STDOUT.puts " Error creating Virtual Machine: "\
"#{rc.message}\n"
else
STDOUT.puts " OpenNebula VM #{one_v.id} "\
"created!\n"
end
}
}
rescue Exception => e
STDOUT.puts "error: #{e.message}"
exit -1
end
exit 0
exit -1
end
network_desc = <<-EOT.unindent

View File

@ -104,6 +104,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do
" the --retry option."
}
SNAP={
:name => "snapshot",
:short => "-s snapshot",
:large => "--snapshot snapshot",
:format => String,
:description => "ID of the Snapshot to save."
}
########################################################################
# Global Options
########################################################################
@ -298,29 +306,36 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
disk_snapshot_desc = <<-EOT.unindent
Sets the specified VM disk to be saved in a new Image. The Image is
created immediately, but the contents are saved only after the VM is
shut down gracefully (i.e., using 'onevm shutdown' and not
'onevm delete')
If '--live' is specified, the Image will be saved immediately.
disk_saveas_desc = <<-EOT.unindent
Saves the specified VM disk as a new Image. The Image is
created immediately, and the contents of the VM disk will be saved to
it.
States: ANY
EOT
command :"disk-snapshot", disk_snapshot_desc, :vmid, :diskid, :img_name,
:options=>[TYPE, OneVMHelper::LIVE] do
disk_id = args[1].to_i
image_name = args[2]
image_type = options[:type] || ""
command :"disk-saveas", disk_saveas_desc, :vmid, :diskid, :img_name,
:options=>[TYPE, SNAP] do
verbose = "disk #{disk_id} prepared to be saved in " <<
"the image #{image_name}"
disk_id = args[1].to_i
image_name = args[2]
image_type = options[:type] || ""
snapshot_id = options[:snapshot]
if snapshot_id.nil? || snapshot_id.empty?
snapshot_id = -1
verbose = "disk #{disk_id} prepared to be saved in " <<
"the image #{image_name}"
else
snapshot_id = snapshot_id.to_i
verbose = "disk #{disk_id} snapshot #{snapshot_id} prepared to " <<
"be saved in the image #{image_name}"
end
helper.perform_action(args[0],options,verbose) do |vm|
res = vm.disk_snapshot(disk_id, image_name, image_type,
options[:live]==true)
res = vm.disk_saveas(disk_id, image_name, image_type, snapshot_id)
if !OpenNebula.is_error?(res)
puts "Image ID: #{res}"
@ -330,19 +345,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
disk_snapshot_cancel_desc = <<-EOT.unindent
Cancels a deferred disk snapshot that has been set by disk-snapshot.
The target image is also deleted.
States: ANY
EOT
command :"disk-snapshot-cancel", disk_snapshot_cancel_desc, :vmid, :diskid do
helper.perform_action(args[0],options,"disk snapshot canceled") do |vm|
vm.disk_snapshot_cancel(args[1].to_i)
end
end
shutdown_desc = <<-EOT.unindent
Shuts down the given VM. The VM life cycle will end.
@ -785,6 +787,45 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
disk_snapshot_create_desc = <<-EOT.unindent
Takes a new snapshot of the given disk. This operation needs support
from the Datastore drivers: QCOW2 or Ceph.
States: POWEROFF
EOT
command :"disk-snapshot-create", disk_snapshot_create_desc,
:vmid, :diskid, :tag do
helper.perform_action(args[0],options,"disk snapshot created") do |o|
o.disk_snapshot_create(args[1].to_i, args[2])
end
end
disk_snapshot_revert_desc = <<-EOT.unindent
Reverts disk state to a previously taken snapshot.
States: POWEROFF
EOT
command :"disk-snapshot-revert", disk_snapshot_revert_desc,
:vmid, :diskid, :snapshot_id do
helper.perform_action(args[0],options,"disk snapshot reverted") do |o|
o.disk_snapshot_revert(args[1].to_i, args[2].to_i)
end
end
disk_snapshot_delete_desc = <<-EOT.unindent
Deletes a disk snapshot.
States: POWEROFF
EOT
command :"disk-snapshot-delete", disk_snapshot_delete_desc,
:vmid, :diskid, :snapshot_id do
helper.perform_action(args[0],options,"disk snapshot deleted") do |o|
o.disk_snapshot_delete(args[1].to_i, args[2].to_i)
end
end
list_desc = <<-EOT.unindent
Lists VMs in the pool
EOT

View File

@ -218,10 +218,9 @@ class EC2QueryServer < CloudServer
return rc
end
image_id = vm.disk_snapshot(1,
params["Name"],
OpenNebula::Image::IMAGE_TYPES[0],
true)
image_id = vm.disk_saveas(1,
params["Name"],
OpenNebula::Image::IMAGE_TYPES[0])
# TODO Add AMI Tags
# TODO A new persistent image should be created for each instance

View File

@ -302,10 +302,9 @@ module EBS
disk_id = vm["TEMPLATE/DISK[IMAGE_ID=#{image_id}]/DISK_ID"]
if !disk_id.nil?
snapshot_id = vm.disk_snapshot(disk_id.to_i,
snapshot_id = vm.disk_saveas(disk_id.to_i,
params["Description"]||ImageEC2.generate_uuid,
OpenNebula::Image::IMAGE_TYPES[image["TYPE"].to_i],
true)
OpenNebula::Image::IMAGE_TYPES[image["TYPE"].to_i])
if OpenNebula::is_error?(snapshot_id)
return snapshot_id

View File

@ -50,7 +50,10 @@ class DatastoreDriver < OpenNebulaDriver
:log => "LOG",
:stat => "STAT",
:clone => "CLONE",
:monitor => "MONITOR"
:monitor => "MONITOR",
:snap_delete => "SNAP_DELETE",
:snap_revert => "SNAP_REVERT",
:snap_flatten=> "SNAP_FLATTEN"
}
# Register default actions for the protocol
@ -65,7 +68,10 @@ class DatastoreDriver < OpenNebulaDriver
ACTION[:rm] => nil,
ACTION[:mkfs] => nil,
ACTION[:clone] => nil,
ACTION[:monitor] => nil
ACTION[:monitor] => nil,
ACTION[:snap_delete] => nil,
ACTION[:snap_revert] => nil,
ACTION[:snap_flatten] => nil
}
}.merge!(options)
@ -87,6 +93,9 @@ class DatastoreDriver < OpenNebulaDriver
register_action(ACTION[:stat].to_sym, method("stat"))
register_action(ACTION[:clone].to_sym, method("clone"))
register_action(ACTION[:monitor].to_sym, method("monitor"))
register_action(ACTION[:snap_delete].to_sym, method("snap_delete"))
register_action(ACTION[:snap_revert].to_sym, method("snap_revert"))
register_action(ACTION[:snap_flatten].to_sym, method("snap_flatten"))
end
############################################################################
@ -123,6 +132,21 @@ class DatastoreDriver < OpenNebulaDriver
do_image_action(id, ds, :monitor, "#{drv_message} #{id}", true)
end
def snap_delete(id, drv_message)
ds = get_ds_type(drv_message)
do_image_action(id, ds, :snap_delete, "#{drv_message} #{id}")
end
def snap_revert(id, drv_message)
ds = get_ds_type(drv_message)
do_image_action(id, ds, :snap_revert, "#{drv_message} #{id}")
end
def snap_flatten(id, drv_message)
ds = get_ds_type(drv_message)
do_image_action(id, ds, :snap_flatten, "#{drv_message} #{id}")
end
private
def is_available?(ds, id, action)

View File

@ -17,7 +17,7 @@
#--------------------------------------------------------------------------- #
###############################################################################
# This script is used to remove a VM image (SRC) from the image repository
# This script is used to remove a VM image (RBD_SRC) from the image repository
###############################################################################
# ------------ Set up the environment to source common tools ------------
@ -48,7 +48,7 @@ done < <($XPATH /DS_DRIVER_ACTION_DATA/IMAGE/SOURCE \
/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/BRIDGE_LIST \
/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/CEPH_USER)
SRC="${XPATH_ELEMENTS[j++]}"
RBD_SRC="${XPATH_ELEMENTS[j++]}"
BRIDGE_LIST="${XPATH_ELEMENTS[j++]}"
CEPH_USER="${XPATH_ELEMENTS[j++]}"
@ -63,11 +63,52 @@ if [ -n "$CEPH_USER" ]; then
RBD="$RBD --id ${CEPH_USER}"
fi
# -------- Remove Image from Datastore ------------
log "Removing $SRC from the rbd image repository in $DST_HOST"
log "Removing $RBD_SRC from the rbd image repository in $DST_HOST"
ssh_exec_and_log "$DST_HOST" "$RBD rm $SRC" "Error removing $SRC in $DST_HOST"
DELETE_CMD=$(cat <<EOF
rm_children(){
local rbd_snap rbd snap_id child snap_list
rbd_snap=\$1
rbd=\${rbd_snap%%@*}
snap_list=\$(set +e; rbd snap ls \$rbd)
if [ -n "\$snap_list" ]; then
CHILDREN=\$(set +e; rbd children \$rbd_snap 2>/dev/null)
for child in \$CHILDREN; do
snap_id=\${child##*-}
child=\$child@\$snap_id
rm_children \$child
done
$RBD snap unprotect \$rbd_snap
$RBD snap rm \$rbd_snap
fi
$RBD rm \$rbd
}
RBD_FORMAT=\$($RBD info $RBD_SRC | sed -n 's/.*format: // p')
if [ "\$RBD_FORMAT" = "2" ]; then
has_snap_shots=\$($RBD info $RBD_SRC-0@0 2>/dev/null)
if [ -n "\$has_snap_shots" ]; then
rm_children $RBD_SRC-0@0
else
$RBD rm $RBD_SRC
fi
else
$RBD rm $RBD_SRC
fi
EOF
)
ssh_exec_and_log "$DST_HOST" "$DELETE_CMD" \
"Error deleting $RBD_SRC in $DST_HOST"
exit 0

View File

@ -0,0 +1,90 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2015, 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. #
#--------------------------------------------------------------------------- #
###############################################################################
# This script is used to delete a snapshot of an image
###############################################################################
# -------- Set up the environment to source common tools & conf ------------
if [ -z "${ONE_LOCATION}" ]; then
LIB_LOCATION=/usr/lib/one
else
LIB_LOCATION=$ONE_LOCATION/lib
fi
. $LIB_LOCATION/sh/scripts_common.sh
DRIVER_PATH=$(dirname $0)
source ${DRIVER_PATH}/../libfs.sh
source ${DRIVER_PATH}/ceph.conf
# -------- Get image and datastore arguments from OpenNebula core ------------
DRV_ACTION=$1
ID=$2
XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION"
unset i XPATH_ELEMENTS
while IFS= read -r -d '' element; do
XPATH_ELEMENTS[i++]="$element"
done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/BRIDGE_LIST \
/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/POOL_NAME \
/DS_DRIVER_ACTION_DATA/IMAGE/SOURCE \
/DS_DRIVER_ACTION_DATA/IMAGE/TARGET_SNAPSHOT \
/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/CEPH_USER)
unset i
BRIDGE_LIST="${XPATH_ELEMENTS[i++]}"
POOL_NAME="${XPATH_ELEMENTS[i++]:-$POOL_NAME}"
RBD_SRC="${XPATH_ELEMENTS[i++]}"
SNAP_ID="${XPATH_ELEMENTS[i++]}"
CEPH_USER="${XPATH_ELEMENTS[i++]}"
DST_HOST=`get_destination_host $ID`
if [ -z "$DST_HOST" ]; then
error_message "Datastore template missing 'BRIDGE_LIST' attribute."
exit -1
fi
if [ -n "$CEPH_USER" ]; then
RBD="$RBD --id ${CEPH_USER}"
fi
SNAP_DELETE_CMD=$(cat <<EOF
set -e
RBD_FORMAT=\$($RBD info $RBD_SRC | sed -n 's/.*format: // p')
if [ "\${RBD_FORMAT}" != "2" ]; then
echo "Only RBD Format 2 is supported for this operation" >&2
exit 1
fi
$RBD snap unprotect $RBD_SRC-$SNAP_ID@$SNAP_ID
$RBD snap rm $RBD_SRC-$SNAP_ID@$SNAP_ID
$RBD rm $RBD_SRC-$SNAP_ID
EOF
)
ssh_exec_and_log "$DST_HOST" "$SNAP_DELETE_CMD" \
"Error deleting snapshot $RBD_SRC-$SNAP_ID@$SNAP_ID"

View File

@ -0,0 +1,115 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2015, 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. #
#--------------------------------------------------------------------------- #
###############################################################################
# This script is used to flatten a snapshot of a persistent image
###############################################################################
# -------- Set up the environment to source common tools & conf ------------
if [ -z "${ONE_LOCATION}" ]; then
LIB_LOCATION=/usr/lib/one
else
LIB_LOCATION=$ONE_LOCATION/lib
fi
. $LIB_LOCATION/sh/scripts_common.sh
DRIVER_PATH=$(dirname $0)
source ${DRIVER_PATH}/../libfs.sh
source ${DRIVER_PATH}/ceph.conf
# -------- Get image and datastore arguments from OpenNebula core ------------
DRV_ACTION=$1
ID=$2
XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION"
unset i XPATH_ELEMENTS
while IFS= read -r -d '' element; do
XPATH_ELEMENTS[i++]="$element"
done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/BRIDGE_LIST \
/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/POOL_NAME \
/DS_DRIVER_ACTION_DATA/IMAGE/SOURCE \
/DS_DRIVER_ACTION_DATA/IMAGE/TARGET_SNAPSHOT \
/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/CEPH_USER)
unset i
BRIDGE_LIST="${XPATH_ELEMENTS[i++]}"
POOL_NAME="${XPATH_ELEMENTS[i++]:-$POOL_NAME}"
RBD_SRC="${XPATH_ELEMENTS[i++]}"
SNAP_ID="${XPATH_ELEMENTS[i++]}"
CEPH_USER="${XPATH_ELEMENTS[i++]}"
DST_HOST=`get_destination_host $ID`
if [ -z "$DST_HOST" ]; then
error_message "Datastore template missing 'BRIDGE_LIST' attribute."
exit -1
fi
if [ -n "$CEPH_USER" ]; then
RBD="$RBD --id ${CEPH_USER}"
fi
SNAP_FLATTEN_CMD=$(cat <<EOF
rm_children(){
local rbd_snap rbd snap_id child snap_list
rbd_snap=\$1
rbd=\${rbd_snap%%@*}
snap_list=\$(set +e; rbd snap ls \$rbd)
if [ -n "\$snap_list" ]; then
CHILDREN=\$(set +e; rbd children \$rbd_snap 2>/dev/null)
for child in \$CHILDREN; do
snap_id=\${child##*-}
child=\$child@\$snap_id
rm_children \$child
done
$RBD snap unprotect \$rbd_snap
$RBD snap rm \$rbd_snap
fi
$RBD rm \$rbd
}
RBD_FORMAT=\$($RBD info $RBD_SRC | sed -n 's/.*format: // p')
if [ "\${RBD_FORMAT}" != "2" ]; then
echo "Only RBD Format 2 is supported for this operation" >&2
exit 1
fi
$RBD clone $RBD_SRC-$SNAP_ID@$SNAP_ID $RBD_SRC.flatten
$RBD flatten $RBD_SRC.flatten
rm_children $RBD_SRC-0@0
$RBD rename $RBD_SRC.flatten $RBD_SRC
EOF
)
ssh_exec_and_log "$DST_HOST" "$SNAP_FLATTEN_CMD" \
"Error flattening snapshot $RBD_SRC-$SNAP_ID@$SNAP_ID"

View File

@ -0,0 +1,89 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2015, 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. #
#--------------------------------------------------------------------------- #
###############################################################################
# This script is used to revert a snapshot of an image
###############################################################################
# -------- Set up the environment to source common tools & conf ------------
if [ -z "${ONE_LOCATION}" ]; then
LIB_LOCATION=/usr/lib/one
else
LIB_LOCATION=$ONE_LOCATION/lib
fi
. $LIB_LOCATION/sh/scripts_common.sh
DRIVER_PATH=$(dirname $0)
source ${DRIVER_PATH}/../libfs.sh
source ${DRIVER_PATH}/ceph.conf
# -------- Get image and datastore arguments from OpenNebula core ------------
DRV_ACTION=$1
ID=$2
XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION"
unset i XPATH_ELEMENTS
while IFS= read -r -d '' element; do
XPATH_ELEMENTS[i++]="$element"
done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/BRIDGE_LIST \
/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/POOL_NAME \
/DS_DRIVER_ACTION_DATA/IMAGE/SOURCE \
/DS_DRIVER_ACTION_DATA/IMAGE/TARGET_SNAPSHOT \
/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/CEPH_USER)
unset i
BRIDGE_LIST="${XPATH_ELEMENTS[i++]}"
POOL_NAME="${XPATH_ELEMENTS[i++]:-$POOL_NAME}"
RBD_SRC="${XPATH_ELEMENTS[i++]}"
SNAP_ID="${XPATH_ELEMENTS[i++]}"
CEPH_USER="${XPATH_ELEMENTS[i++]}"
DST_HOST=`get_destination_host $ID`
if [ -z "$DST_HOST" ]; then
error_message "Datastore template missing 'BRIDGE_LIST' attribute."
exit -1
fi
if [ -n "$CEPH_USER" ]; then
RBD="$RBD --id ${CEPH_USER}"
fi
SNAP_REVERT_CMD=$(cat <<EOF
set -e
RBD_FORMAT=\$($RBD info $RBD_SRC | sed -n 's/.*format: // p')
if [ "\${RBD_FORMAT}" != "2" ]; then
echo "Only RBD Format 2 is supported for this operation" >&2
exit 1
fi
$RBD rm $RBD_SRC
$RBD clone $RBD_SRC-$SNAP_ID@$SNAP_ID $RBD_SRC
EOF
)
ssh_exec_and_log "$DST_HOST" "$SNAP_REVERT_CMD" \
"Error reverting snapshot $RBD_SRC-$SNAP_ID@$SNAP_ID"

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

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

View File

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

View File

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

View File

@ -52,6 +52,7 @@ done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/BASE_PATH \
/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/SAFE_DIRS \
/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/BRIDGE_LIST \
/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/STAGING_DIR \
/DS_DRIVER_ACTION_DATA/DATASTORE/TYPE \
/DS_DRIVER_ACTION_DATA/IMAGE/PATH \
/DS_DRIVER_ACTION_DATA/IMAGE/TEMPLATE/MD5 \
/DS_DRIVER_ACTION_DATA/IMAGE/TEMPLATE/SHA1 \
@ -65,6 +66,7 @@ RESTRICTED_DIRS="${XPATH_ELEMENTS[i++]}"
SAFE_DIRS="${XPATH_ELEMENTS[i++]}"
BRIDGE_LIST="${XPATH_ELEMENTS[i++]}"
STAGING_DIR="${XPATH_ELEMENTS[i++]:-/var/tmp}"
TYPE="${XPATH_ELEMENTS[i++]}"
SRC="${XPATH_ELEMENTS[i++]}"
MD5="${XPATH_ELEMENTS[i++]}"
SHA1="${XPATH_ELEMENTS[i++]}"
@ -76,6 +78,11 @@ IMAGE_HASH=`basename $DST`
set_up_datastore "$BASE_PATH" "$RESTRICTED_DIRS" "$SAFE_DIRS"
# Disable auto-decompress for the 'files' datastores (type 2)
if [ "$TYPE" = "2" ]; then
NO_DECOMPRESS="${NO_DECOMPRESS:-yes}"
fi
if [ -n "$BRIDGE_LIST" ]; then
DOWNLOADER_ARGS=`set_downloader_args "$MD5" "$SHA1" "$NO_DECOMPRESS" "$LIMIT_TRANSFER_BW" "$SRC" -`
else

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -0,0 +1 @@
../common/not_supported.sh

View File

@ -905,6 +905,7 @@ int DispatchManager::attach(int vid,
set<string> used_targets;
VectorAttribute * disk;
Snapshots * snap;
VirtualMachine * vm = vmpool->get(vid, true);
@ -958,6 +959,7 @@ int DispatchManager::attach(int vid,
max_disk_id,
uid,
image_id,
&snap,
error_str);
vm = vmpool->get(vid, true);
@ -968,6 +970,9 @@ int DispatchManager::attach(int vid,
imagem->release_image(oid, image_id, false);
}
delete snap;
delete disk;
oss << "Could not attach a new disk to VM " << vid
<< ", VM does not exist after setting its state to HOTPLUG." ;
error_str = oss.str();
@ -1001,7 +1006,7 @@ int DispatchManager::attach(int vid,
// VM template
vm->set_vm_info();
vm->set_attach_disk(disk);
vm->set_attach_disk(disk, snap);
if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG )
{
@ -1146,10 +1151,10 @@ int DispatchManager::detach(
/* -------------------------------------------------------------------------- */
int DispatchManager::snapshot_create(
int vid,
string& name,
int& snap_id,
string& error_str)
int vid,
string& name,
int& snap_id,
string& error_str)
{
ostringstream oss;
@ -1606,3 +1611,200 @@ int DispatchManager::detach_nic(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::disk_snapshot_create(
int vid,
int did,
const string& tag,
int& snap_id,
string& error_str)
{
ostringstream oss;
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "Could not create a new disk 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::POWEROFF ||
vm->get_lcm_state() != VirtualMachine::LCM_INIT )
{
oss << "Could not create a new snapshot for VM " << vid
<< ", wrong state " << vm->state_str() << ".";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
snap_id = vm->new_disk_snapshot(did, tag, error_str);
if (snap_id == -1)
{
vm->unlock();
return -1;
}
vm->set_state(VirtualMachine::ACTIVE);
vm->set_state(VirtualMachine::DISK_SNAPSHOT_POWEROFF);
vmpool->update(vm);
vm->unlock();
tm->trigger(TransferManager::SNAPSHOT_CREATE,vid);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::disk_snapshot_revert(
int vid,
int did,
int snap_id,
string& error_str)
{
ostringstream oss;
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "Could not revert to disk 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::POWEROFF ||
vm->get_lcm_state() != VirtualMachine::LCM_INIT )
{
oss << "Could not revert to disk snapshot for VM " << vid
<< ", wrong state " << vm->state_str() << ".";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
const Snapshots * snaps = vm->get_disk_snapshots(did, error_str);
if (snaps == 0)
{
vm->unlock();
return -1;
}
if (snaps->get_active_id() == snap_id)
{
error_str = "Snapshot is already the active one";
vm->unlock();
return -1;
}
if (vm->set_snapshot_disk(did, snap_id) == -1)
{
vm->unlock();
return -1;
}
vm->set_state(VirtualMachine::ACTIVE);
vm->set_state(VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF);
vmpool->update(vm);
vm->unlock();
tm->trigger(TransferManager::SNAPSHOT_REVERT, vid);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::disk_snapshot_delete(
int vid,
int did,
int snap_id,
string& error_str)
{
ostringstream oss;
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "Could not delete disk snapshot from VM " << vid
<< ", VM does not exist" ;
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
return -1;
}
if ( vm->get_state() != VirtualMachine::POWEROFF ||
vm->get_lcm_state() != VirtualMachine::LCM_INIT )
{
oss << "Could not delete disk snapshot from VM " << vid
<< ", wrong state " << vm->state_str() << ".";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
return -1;
}
const Snapshots * snaps = vm->get_disk_snapshots(did, error_str);
if (snaps == 0)
{
vm->unlock();
return -1;
}
if (!snaps->test_delete(snap_id, error_str))
{
vm->unlock();
return -1;
}
if (vm->set_snapshot_disk(did, snap_id) == -1)
{
vm->unlock();
return -1;
}
vm->set_state(VirtualMachine::ACTIVE);
vm->set_state(VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF);
vmpool->update(vm);
vm->unlock();
tm->trigger(TransferManager::SNAPSHOT_DELETE, vid);
return 0;
}

View File

@ -166,6 +166,9 @@ void DispatchManager::poweroff_success_action(int vid)
vm->get_lcm_state() == VirtualMachine::HOTPLUG_PROLOG_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::HOTPLUG_EPILOG_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::PROLOG_MIGRATE_POWEROFF_FAILURE))
{
vm->set_state(VirtualMachine::POWEROFF);

View File

@ -26,6 +26,8 @@ end
# TODO : use virsh freecell when available
######
ENV['LANG'] = 'C'
nodeinfo_text = `virsh -c qemu:///system nodeinfo`
exit(-1) if $?.exitstatus != 0
@ -40,36 +42,31 @@ nodeinfo_text.split(/\n/).each{|line|
}
######
# for everything else, top & proc
#####
# CPU
######
vmstat = `vmstat 1 2`
$free_cpu = $total_cpu * ((vmstat.split("\n").to_a.last.split)[14].to_i)/100
$used_cpu = $total_cpu - $free_cpu
NETINTERFACE = "eth|bond|em|p[0-9]+p[0-9]+"
######
# MEMORY
######
memory = `cat /proc/meminfo`
meminfo = Hash.new()
memory.each_line do |line|
key, value = line.split(':')
meminfo[key] = /\d+/.match(value)[0].to_i
end
top_text=`top -bin2`
exit(-1) if $?.exitstatus != 0
$total_memory = meminfo['MemTotal']
top_text.gsub!(/^top.*^top.*?$/m, "") # Strip first top output
$used_memory = meminfo['MemTotal'] - meminfo['MemFree'] - meminfo['Buffers'] - meminfo['Cached']
$free_memory = $total_memory - $used_memory
top_text.split(/\n/).each{|line|
if line.match('^%?Cpu')
line[7..-1].split(",").each{|elemento|
temp = elemento.strip.split(/[% ]/)
if temp[1]=="id"
idle = temp[0]
$free_cpu = idle.to_f * $total_cpu.to_f / 100
$used_cpu = $total_cpu.to_f - $free_cpu
break
end
}
end
}
$total_memory = `free -k|grep "Mem:" | awk '{print $2}'`
tmp=`free -k|grep "buffers\/cache"|awk '{print $3 " " $4}'`.split
$used_memory=tmp[0]
$free_memory=tmp[1]
######
# INTERFACE
######
NETINTERFACE = "eth|bond|em|enp|p[0-9]+p[0-9]+"
net_text=`cat /proc/net/dev`
exit(-1) if $?.exitstatus != 0

View File

@ -56,7 +56,9 @@ Image::Image(int _uid,
ds_id(-1),
ds_name(""),
vm_collection("VMS"),
img_clone_collection("CLONES")
img_clone_collection("CLONES"),
snapshots(-1),
target_snapshot(-1)
{
if (_image_template != 0)
{
@ -124,9 +126,9 @@ int Image::insert(SqlDB *db, string& error_str)
type_att = ImagePool::default_type();
}
if (set_type(type_att) != 0)
if (set_type(type_att, error_str) != 0)
{
goto error_type;
goto error_common;
}
// ------------ PERSISTENT & PREFIX --------------------
@ -181,7 +183,7 @@ int Image::insert(SqlDB *db, string& error_str)
erase_template_attribute("PATH", path);
erase_template_attribute("SOURCE", source);
if (!isSaving()) //Not a saving image
if (!is_saving()) //Not a saving image
{
if ( source.empty() && path.empty() )
{
@ -218,10 +220,6 @@ int Image::insert(SqlDB *db, string& error_str)
return rc;
error_type:
error_str = "Incorrect TYPE in template.";
goto error_common;
error_no_path:
error_str = "No PATH in template.";
goto error_common;
@ -334,11 +332,12 @@ error_common:
string& Image::to_xml(string& xml) const
{
string template_xml;
string perms_xml;
ostringstream oss;
string vm_collection_xml;
string clone_collection_xml;
string template_xml;
string perms_xml;
ostringstream oss;
string vm_collection_xml;
string clone_collection_xml;
string snapshots_xml;
oss <<
"<IMAGE>" <<
@ -361,11 +360,13 @@ string& Image::to_xml(string& xml) const
"<RUNNING_VMS>" << running_vms << "</RUNNING_VMS>" <<
"<CLONING_OPS>" << cloning_ops << "</CLONING_OPS>" <<
"<CLONING_ID>" << cloning_id << "</CLONING_ID>" <<
"<TARGET_SNAPSHOT>"<< target_snapshot << "</TARGET_SNAPSHOT>"<<
"<DATASTORE_ID>" << ds_id << "</DATASTORE_ID>"<<
"<DATASTORE>" << ds_name << "</DATASTORE>" <<
vm_collection.to_xml(vm_collection_xml) <<
img_clone_collection.to_xml(clone_collection_xml) <<
obj_template->to_xml(template_xml) <<
snapshots.to_xml(snapshots_xml) <<
"</IMAGE>";
xml = oss.str();
@ -410,6 +411,8 @@ int Image::from_xml(const string& xml)
rc += xpath(cloning_ops, "/IMAGE/CLONING_OPS", -1);
rc += xpath(cloning_id, "/IMAGE/CLONING_ID", -1);
xpath(target_snapshot, "/IMAGE/TARGET_SNAPSHOT", -1);
rc += xpath(ds_id, "/IMAGE/DATASTORE_ID", -1);
rc += xpath(ds_name, "/IMAGE/DATASTORE", "not_found");
@ -462,6 +465,17 @@ int Image::from_xml(const string& xml)
ObjectXML::free_nodes(content);
content.clear();
ObjectXML::get_nodes("/IMAGE/SNAPSHOTS", content);
if (!content.empty())
{
rc += snapshots.from_xml_node(content[0]);
ObjectXML::free_nodes(content);
content.clear();
}
if (rc != 0)
{
@ -610,9 +624,9 @@ int Image::disk_attribute( VectorAttribute * disk,
new_disk_type = RBD_CDROM;
break;
case SHEEPDOG:
new_disk_type = SHEEPDOG_CDROM;
break;
case SHEEPDOG:
new_disk_type = SHEEPDOG_CDROM;
break;
case GLUSTER:
new_disk_type = GLUSTER_CDROM;
@ -656,12 +670,18 @@ int Image::disk_attribute( VectorAttribute * disk,
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Image::set_type(string& _type)
int Image::set_type(string& _type, string& error)
{
int rc = 0;
TO_UPPER(_type);
if ((_type != "OS" && _type != "DATABLOCK") && (snapshots.size() > 0))
{
error = "Image with snapshots can be only of type OS or DATABLOCK";
return -1;
}
if ( _type == "OS" )
{
type = OS;
@ -688,6 +708,7 @@ int Image::set_type(string& _type)
}
else
{
error = "Unknown type " + type;
rc = -1;
}
@ -709,7 +730,7 @@ ImageTemplate * Image::clone_template(const string& new_name) const
tmpl->replace("FSTYPE", fs_type);
tmpl->replace("SIZE", size_mb);
if ( isPersistent() )
if ( is_persistent() )
{
tmpl->replace("PERSISTENT", "YES");
}

View File

@ -113,7 +113,7 @@ int ImageManager::acquire_image(int vm_id, Image *img, string& error)
case Image::READY:
img->inc_running(vm_id);
if ( img->isPersistent() )
if ( img->is_persistent() )
{
img->set_state(Image::USED_PERS);
}
@ -160,11 +160,9 @@ int ImageManager::acquire_image(int vm_id, Image *img, string& error)
void ImageManager::release_image(int vm_id, int iid, bool failed)
{
Image * img;
ostringstream oss;
ostringstream disk_file;
img = ipool->get(iid,true);
Image * img = ipool->get(iid,true);
if ( img == 0 )
{
@ -218,27 +216,10 @@ void ImageManager::release_image(int vm_id, int iid, bool failed)
break;
case Image::LOCKED:
if ( img->isSaving() ) //SAVE_AS images are LOCKED till released
{
if (failed == true)
{
img->set_state(Image::ERROR);
}
else
{
img->set_state(Image::READY);
}
oss << "Releasing image in wrong state: "
<< Image::state_to_str(img->get_state());
ipool->update(img);
}
else
{
stringstream oss;
oss << "Releasing image in wrong state: "
<< Image::state_to_str(img->get_state());
NebulaLog::log("ImM", Log::ERROR, oss.str());
}
NebulaLog::log("ImM", Log::ERROR, oss.str());
img->unlock();
break;
@ -249,7 +230,6 @@ void ImageManager::release_image(int vm_id, int iid, bool failed)
case Image::DISABLED:
case Image::READY:
case Image::ERROR:
ostringstream oss;
oss << "Releasing image in wrong state: "
<< Image::state_to_str(img->get_state());
@ -265,11 +245,7 @@ void ImageManager::release_image(int vm_id, int iid, bool failed)
void ImageManager::release_cloning_image(int iid, int clone_img_id)
{
Image * img;
ostringstream disk_file;
img = ipool->get(iid,true);
Image * img = ipool->get(iid,true);
if ( img == 0 )
{
@ -296,15 +272,13 @@ void ImageManager::release_cloning_image(int iid, int clone_img_id)
{
case Image::USED:
case Image::CLONE:
if (img->dec_cloning(clone_img_id) == 0 && img->get_running() == 0)
{
img->set_state(Image::READY);
}
ipool->update(img);
break;
break;
case Image::DELETE:
case Image::INIT:
@ -313,14 +287,13 @@ void ImageManager::release_cloning_image(int iid, int clone_img_id)
case Image::ERROR:
case Image::USED_PERS:
case Image::LOCKED:
ostringstream oss;
ostringstream oss;
oss << "Releasing image in wrong state: "
<< Image::state_to_str(img->get_state());
oss << "Releasing image in wrong state: "
<< Image::state_to_str(img->get_state());
NebulaLog::log("ImM", Log::ERROR, oss.str());
break;
NebulaLog::log("ImM", Log::ERROR, oss.str());
break;
}
img->unlock();
@ -639,7 +612,7 @@ int ImageManager::clone_image(int new_id,
case Image::READY:
img->inc_cloning(new_id);
if (img->isPersistent())
if (img->is_persistent())
{
img->set_state(Image::CLONE);
}
@ -738,12 +711,11 @@ int ImageManager::register_image(int iid, const string& ds_data, string& error)
{
string source = img->get_source();
if ( img->isSaving() || img->get_type() == Image::DATABLOCK )
if ( img->is_saving() || img->get_type() == Image::DATABLOCK )
{
imd->mkfs(img->get_oid(), *drv_msg);
oss << "Creating disk at " << source
<< " of "<< img->get_size()
oss << "Creating disk at " << source << " of "<< img->get_size()
<< "Mb (type: " << img->get_fstype() << ")";
}
else if ( !source.empty() ) //Source in Template
@ -895,3 +867,333 @@ string * ImageManager::format_message(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void ImageManager::set_image_snapshots(int iid, const Snapshots& s, bool failed)
{
Image * img = ipool->get(iid,true);
if ( img == 0 )
{
return;
}
switch(img->get_type())
{
case Image::OS:
case Image::DATABLOCK:
break;
case Image::KERNEL:
case Image::RAMDISK:
case Image::CONTEXT:
case Image::CDROM:
img->unlock();
return;
}
if (img->get_state() != Image::USED_PERS)
{
img->unlock();
return;
}
img->set_snapshots(s);
ipool->update(img);
img->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ImageManager::delete_snapshot(int iid, int sid, string& error)
{
const ImageManagerDriver* imd = get();
if ( imd == 0 )
{
error = "Could not get datastore driver";
NebulaLog::log("ImM",Log::ERROR, error);
return -1;
}
/* ---------------------------------------------------------------------- */
/* Check action consistency: */
/* state is READY */
/* snapshot can be deleted (not active, no childs, exists) */
/* ---------------------------------------------------------------------- */
Image * img = ipool->get(iid,true);
if ( img == 0 )
{
error = "Image does not exist";
return -1;
}
if (img->get_state() != Image::READY)
{
error = "Cannot delete snapshot in state " + Image::state_to_str(img->get_state());
img->unlock();
return -1;
}
const Snapshots& snaps = img->get_snapshots();
if (!snaps.test_delete(sid, error))
{
img->unlock();
return -1;
}
/* ---------------------------------------------------------------------- */
/* Get DS data for driver */
/* ---------------------------------------------------------------------- */
int ds_id = img->get_ds_id();
img->unlock();
string ds_data;
Datastore * ds = dspool->get(ds_id, true);
if ( ds == 0 )
{
error = "Datastore no longer exists";
return -1;
}
ds->to_xml(ds_data);
ds->unlock();
img = ipool->get(iid,true);
/* ---------------------------------------------------------------------- */
/* Format message and send action to driver */
/* ---------------------------------------------------------------------- */
if ( img == 0 )
{
error = "Image does not exist";
return -1;
}
img->set_target_snapshot(sid);
string img_tmpl;
string * drv_msg = format_message(img->to_xml(img_tmpl), ds_data);
imd->snapshot_delete(iid, *drv_msg);
img->set_state(Image::LOCKED);
ipool->update(img);
img->unlock();
delete drv_msg;
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ImageManager::revert_snapshot(int iid, int sid, string& error)
{
const ImageManagerDriver* imd = get();
if ( imd == 0 )
{
error = "Could not get datastore driver";
NebulaLog::log("ImM",Log::ERROR, error);
return -1;
}
/* ---------------------------------------------------------------------- */
/* Check action consistency: */
/* state is READY */
/* snapshot exists */
/* snapshot is not the active one */
/* ---------------------------------------------------------------------- */
Image * img = ipool->get(iid,true);
if ( img == 0 )
{
error = "Image does not exist";
return -1;
}
if (img->get_state() != Image::READY)
{
error = "Cannot revert to snapshot in state " + Image::state_to_str(img->get_state());
img->unlock();
return -1;
}
const Snapshots& snaps = img->get_snapshots();
if (!snaps.exists(sid))
{
error = "Snapshot does not exist";
img->unlock();
return -1;
}
if (snaps.get_active_id() == sid)
{
error = "Snapshot is already the active one";
img->unlock();
return -1;
}
/* ---------------------------------------------------------------------- */
/* Get DS data for driver */
/* ---------------------------------------------------------------------- */
int ds_id = img->get_ds_id();
img->unlock();
string ds_data;
Datastore * ds = dspool->get(ds_id, true);
if ( ds == 0 )
{
error = "Datastore no longer exists";
return -1;
}
ds->to_xml(ds_data);
ds->unlock();
/* ---------------------------------------------------------------------- */
/* Format message and send action to driver */
/* ---------------------------------------------------------------------- */
img = ipool->get(iid,true);
if ( img == 0 )
{
error = "Image does not exist";
return -1;
}
img->set_target_snapshot(sid);
string img_tmpl;
string * drv_msg = format_message(img->to_xml(img_tmpl), ds_data);
imd->snapshot_revert(iid, *drv_msg);
img->set_state(Image::LOCKED);
ipool->update(img);
img->unlock();
delete drv_msg;
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ImageManager::flatten_snapshot(int iid, int sid, string& error)
{
const ImageManagerDriver* imd = get();
if ( imd == 0 )
{
error = "Could not get datastore driver";
NebulaLog::log("ImM",Log::ERROR, error);
return -1;
}
/* ---------------------------------------------------------------------- */
/* Check action consistency: */
/* state is READY */
/* snapshot exists */
/* ---------------------------------------------------------------------- */
Image * img = ipool->get(iid,true);
if ( img == 0 )
{
error = "Image does not exist";
return -1;
}
if (img->get_state() != Image::READY)
{
error = "Cannot flatten snapshot in state " + Image::state_to_str(img->get_state());
img->unlock();
return -1;
}
const Snapshots& snaps = img->get_snapshots();
if (!snaps.exists(sid))
{
error = "Snapshot does not exist";
img->unlock();
return -1;
}
/* ---------------------------------------------------------------------- */
/* Get DS data for driver */
/* ---------------------------------------------------------------------- */
int ds_id = img->get_ds_id();
img->unlock();
string ds_data;
Datastore * ds = dspool->get(ds_id, true);
if ( ds == 0 )
{
error = "Datastore no longer exists";
return -1;
}
ds->to_xml(ds_data);
ds->unlock();
/* ---------------------------------------------------------------------- */
/* Format message and send action to driver */
/* ---------------------------------------------------------------------- */
img = ipool->get(iid,true);
if ( img == 0 )
{
error = "Image does not exist";
return -1;
}
img->set_target_snapshot(sid);
string img_tmpl;
string * drv_msg = format_message(img->to_xml(img_tmpl), ds_data);
imd->snapshot_flatten(iid, *drv_msg);
img->set_state(Image::LOCKED);
ipool->update(img);
img->unlock();
delete drv_msg;
return 0;
}

View File

@ -93,6 +93,39 @@ void ImageManagerDriver::monitor(int oid, const string& drv_msg) const
write(os);
}
/* -------------------------------------------------------------------------- */
void ImageManagerDriver::snapshot_delete(int oid, const string& drv_msg) const
{
ostringstream os;
os << "SNAP_DELETE " << oid << " " << drv_msg << endl;
write(os);
}
/* -------------------------------------------------------------------------- */
void ImageManagerDriver::snapshot_revert(int oid, const string& drv_msg) const
{
ostringstream os;
os << "SNAP_REVERT " << oid << " " << drv_msg << endl;
write(os);
}
/* -------------------------------------------------------------------------- */
void ImageManagerDriver::snapshot_flatten(int oid, const string& drv_msg) const
{
ostringstream os;
os << "SNAP_FLATTEN " << oid << " " << drv_msg << endl;
write(os);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -336,15 +369,12 @@ static int mkfs_action(istringstream& is,
string source;
Image * image;
bool is_saving = false;
bool is_hot = false;
string info;
int rc;
int vm_id = -1;
int ds_id = -1;
int disk_id;
int vm_id = -1;
int ds_id = -1;
int disk_id = -1;
VirtualMachine * vm;
ostringstream oss;
@ -378,14 +408,13 @@ static int mkfs_action(istringstream& is,
return ds_id;
}
is_saving = image->isSaving();
is_hot = image->isHot();
is_saving = image->is_saving();
ds_id = image->get_ds_id();
if ( is_saving )
{
image->get_template_attribute("SAVED_VM_ID", vm_id);
image->get_template_attribute("SAVED_DISK_ID", disk_id);
image->get_template_attribute("SAVED_VM_ID", vm_id);
}
if ( result == "FAILURE" )
@ -426,28 +455,12 @@ static int mkfs_action(istringstream& is,
goto error_save_get;
}
if ( is_hot ) //Saveas hot, trigger disk copy
if ( vm->set_saveas_disk(disk_id, source, id) == -1 )
{
rc = vm->save_disk_hot(disk_id, source, id);
if ( rc == -1 )
{
goto error_save_state;
}
tm->trigger(TransferManager::SAVEAS_HOT, vm_id);
goto error_save_state;
}
else //setup disk information
{
rc = vm->save_disk(disk_id, source, id);
if ( rc == -1 )
{
goto error_save_state;
}
vm->clear_saveas_state(disk_id, is_hot);
}
tm->trigger(TransferManager::SAVEAS_HOT, vm_id);
vmpool->update(vm);
@ -460,12 +473,12 @@ error_img:
goto error;
error_save_get:
oss << "Image created for SAVE_AS, but the associated VM does not exist.";
oss << "Image created to save as a disk but VM does not exist.";
goto error_save;
error_save_state:
vm->unlock();
oss << "Image created for SAVE_AS, but VM is no longer running";
oss << "Image created to save as disk but VM is no longer running";
error_save:
image = ipool->get(id, true);
@ -497,7 +510,10 @@ error:
{
if ((vm = vmpool->get(vm_id, true)) != 0)
{
vm->clear_saveas_state(disk_id, is_hot);
vm->clear_saveas_state();
vm->clear_saveas_disk();
vmpool->update(vm);
vm->unlock();
@ -666,6 +682,168 @@ static void monitor_action(istringstream& is,
return;
}
/* -------------------------------------------------------------------------- */
static void snap_delete_action(istringstream& is,
ImagePool* ipool,
int id,
const string& result)
{
ostringstream oss;
string info;
Image * image = ipool->get(id, true);
if ( image == 0 )
{
return;
}
image->set_state(Image::READY);
int snap_id = image->get_target_snapshot();
if (snap_id == -1)
{
NebulaLog::log("ImM", Log::ERROR, "No target snapshot in callback");
ipool->update(image);
image->unlock();
return;
}
if ( result == "SUCCESS")
{
image->delete_snapshot(snap_id);
}
else
{
oss << "Error removing snapshot " << snap_id << " from image " << id;
getline(is, info);
if (!info.empty() && (info[0] != '-'))
{
oss << ": " << info;
}
image->set_template_error_message(oss.str());
NebulaLog::log("ImM", Log::ERROR, oss);
}
image->clear_target_snapshot();
ipool->update(image);
image->unlock();
}
/* -------------------------------------------------------------------------- */
static void snap_revert_action(istringstream& is,
ImagePool* ipool,
int id,
const string& result)
{
ostringstream oss;
string info;
Image * image = ipool->get(id, true);
if ( image == 0 )
{
return;
}
int snap_id = image->get_target_snapshot();
image->set_state(Image::READY);
if (snap_id == -1)
{
NebulaLog::log("ImM", Log::ERROR, "No target snapshot in callback");
ipool->update(image);
image->unlock();
return;
}
if ( result == "SUCCESS")
{
image->revert_snapshot(snap_id);
}
else
{
oss << "Error reverting image " << id << " to snapshot " << snap_id;
getline(is, info);
if (!info.empty() && (info[0] != '-'))
{
oss << ": " << info;
}
image->set_template_error_message(oss.str());
NebulaLog::log("ImM", Log::ERROR, oss);
}
image->clear_target_snapshot();
ipool->update(image);
image->unlock();
}
/* -------------------------------------------------------------------------- */
static void snap_flatten_action(istringstream& is,
ImagePool* ipool,
int id,
const string& result)
{
ostringstream oss;
string info;
Image * image = ipool->get(id, true);
if ( image == 0 )
{
return;
}
if ( result == "SUCCESS")
{
image->clear_snapshots();
}
else
{
oss << "Error flattening image snapshot";
getline(is, info);
if (!info.empty() && (info[0] != '-'))
{
oss << ": " << info;
}
image->set_template_error_message(oss.str());
NebulaLog::log("ImM", Log::ERROR, oss);
}
image->set_state(Image::READY);
image->clear_target_snapshot();
ipool->update(image);
image->unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -717,30 +895,42 @@ void ImageManagerDriver::protocol(const string& message) const
else
return;
if ( action == "STAT" )
if (action == "STAT")
{
stat_action(is, id, result);
}
else if ( action == "CP" )
else if (action == "CP")
{
ds_id = cp_action(is, ipool, id, result);
}
else if ( action == "CLONE" )
else if (action == "CLONE")
{
ds_id = clone_action(is, ipool, id, result);
}
else if ( action == "MKFS" )
else if (action == "MKFS")
{
ds_id = mkfs_action(is, ipool, id, result);
}
else if ( action == "RM" )
else if (action == "RM")
{
ds_id = rm_action(is, ipool, id, result);
}
else if ( action == "MONITOR" )
else if (action == "MONITOR")
{
monitor_action(is, dspool, id, result);
}
else if (action == "SNAP_DELETE")
{
snap_delete_action(is, ipool, id, result);
}
else if (action == "SNAP_REVERT")
{
snap_revert_action(is, ipool, id, result);
}
else if (action == "SNAP_FLATTEN")
{
snap_flatten_action(is, ipool, id, result);
}
else if (action == "LOG")
{
getline(is,info);

View File

@ -19,6 +19,7 @@
/* ************************************************************************** */
#include "ImagePool.h"
#include "Snapshots.h"
#include "AuthManager.h"
#include "Nebula.h"
#include "PoolObjectAuth.h"
@ -313,6 +314,7 @@ int ImagePool::disk_attribute(int vm_id,
string& dev_prefix,
int uid,
int& image_id,
Snapshots ** snap,
string& error_str)
{
string source;
@ -326,6 +328,8 @@ int ImagePool::disk_attribute(int vm_id,
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
*snap = 0;
if (!(source = disk->vector_value("IMAGE")).empty())
{
int uiid = get_disk_uid(disk,uid);
@ -412,6 +416,12 @@ int ImagePool::disk_attribute(int vm_id,
image_id = img->get_oid();
datastore_id = img->get_ds_id();
if (img->snapshots.size() > 0)
{
*snap = new Snapshots(img->snapshots);
(*snap)->set_disk_id(disk_id);
}
img->unlock();
if (rc == -1)
@ -419,6 +429,9 @@ int ImagePool::disk_attribute(int vm_id,
imagem->release_image(vm_id, iid, false);
error_str = "Unknown internal error";
delete *snap;
*snap = 0;
return -1;
}
@ -429,6 +442,9 @@ int ImagePool::disk_attribute(int vm_id,
imagem->release_image(vm_id, iid, false);
error_str = "Associated datastore for the image does not exist";
delete *snap;
*snap = 0;
return -1;
}

View File

@ -21,8 +21,5 @@
vector<string> ImageTemplate::restricted_attributes;
string ImageTemplate::saving_attribute = "SAVE_AS";
string ImageTemplate::saving_hot_attribute = "SAVE_AS_HOT";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -917,6 +917,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag
case VirtualMachine::HOTPLUG:
vm->clear_attach_disk();
vmpool->update(vm);
vm->set_running_etime(the_time);
vmpool->update_history(vm);
@ -927,6 +928,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag
case VirtualMachine::HOTPLUG_NIC:
vm->clear_attach_nic();
vmpool->update(vm);
vm->set_running_etime(the_time);
vmpool->update_history(vm);
@ -936,11 +938,8 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag
break;
case VirtualMachine::HOTPLUG_SAVEAS:
case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF:
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
tm->trigger(TransferManager::DRIVER_CANCEL, vid);
vm->cancel_saveas_disk(image_id);
image_id = vm->clear_saveas_disk();
vmpool->update(vm);
vm->set_running_etime(the_time);
vmpool->update_history(vm);
@ -949,14 +948,36 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag
vmm->trigger(VirtualMachineManager::CLEANUP,vid);
break;
case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF:
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
tm->trigger(TransferManager::DRIVER_CANCEL, vid);
image_id = vm->clear_saveas_disk();
vmpool->update(vm);
vm->set_running_etime(the_time);
vmpool->update_history(vm);
break;
case VirtualMachine::HOTPLUG_PROLOG_POWEROFF:
case VirtualMachine::HOTPLUG_EPILOG_POWEROFF:
vm->clear_attach_disk();
vmpool->update(vm);
tm->trigger(TransferManager::DRIVER_CANCEL,vid);
tm->trigger(TransferManager::EPILOG_DELETE,vid);
break;
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF:
vm->clear_snapshot_disk();
vmpool->update(vm);
tm->trigger(TransferManager::DRIVER_CANCEL, vid);
tm->trigger(TransferManager::EPILOG_DELETE,vid);
break;
case VirtualMachine::MIGRATE:
vm->set_running_etime(the_time);
vmpool->update_history(vm);
@ -967,7 +988,8 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
hpool->del_capacity(vm->get_previous_hid(), vm->get_oid(), cpu, mem, disk);
hpool->del_capacity(vm->get_previous_hid(), vm->get_oid(), cpu,
mem, disk);
vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
vmm->trigger(VirtualMachineManager::CLEANUP_BOTH,vid);
@ -992,7 +1014,8 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag
vm->set_previous_reason(History::USER);
vmpool->update_previous_history(vm);
hpool->del_capacity(vm->get_previous_hid(), vm->get_oid(), cpu, mem, disk);
hpool->del_capacity(vm->get_previous_hid(), vm->get_oid(), cpu,
mem, disk);
vmm->trigger(VirtualMachineManager::DRIVER_CANCEL,vid);
vmm->trigger(VirtualMachineManager::CLEANUP_PREVIOUS,vid);
@ -1106,11 +1129,11 @@ void LifeCycleManager::recover(VirtualMachine * vm, bool success)
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
if (success)
{
lcm_action = LifeCycleManager::SAVEAS_HOT_SUCCESS;
lcm_action = LifeCycleManager::SAVEAS_SUCCESS;
}
else
{
lcm_action = LifeCycleManager::SAVEAS_HOT_FAILURE;
lcm_action = LifeCycleManager::SAVEAS_FAILURE;
}
break;
@ -1220,6 +1243,12 @@ void LifeCycleManager::recover(VirtualMachine * vm, bool success)
case VirtualMachine::HOTPLUG_SNAPSHOT:
lcm_action = LifeCycleManager::SNAPSHOT_CREATE_FAILURE;
break;
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF:
lcm_action = LifeCycleManager::DISK_SNAPSHOT_FAILURE;
break;
}
if (lcm_action != LifeCycleManager::FINALIZE)
@ -1420,6 +1449,9 @@ void LifeCycleManager::retry(VirtualMachine * vm)
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
case VirtualMachine::HOTPLUG_PROLOG_POWEROFF:
case VirtualMachine::HOTPLUG_EPILOG_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF:
case VirtualMachine::RUNNING:
case VirtualMachine::UNKNOWN:
break;

View File

@ -166,12 +166,12 @@ void LifeCycleManager::trigger(Actions action, int _vid)
aname = "DETACH_FAILURE";
break;
case SAVEAS_HOT_SUCCESS:
aname = "SAVEAS_HOT_SUCCESS";
case SAVEAS_SUCCESS:
aname = "SAVEAS_SUCCESS";
break;
case SAVEAS_HOT_FAILURE:
aname = "SAVEAS_HOT_FAILURE";
case SAVEAS_FAILURE:
aname = "SAVEAS_FAILURE";
break;
case ATTACH_NIC_SUCCESS:
@ -222,6 +222,14 @@ void LifeCycleManager::trigger(Actions action, int _vid)
aname = "SNAPSHOT_DELETE_FAILURE";
break;
case DISK_SNAPSHOT_SUCCESS:
aname = "DISK_SNAPSHOT_SUCCESS";
break;
case DISK_SNAPSHOT_FAILURE:
aname = "DISK_SNAPSHOT_FAILURE";
break;
case DEPLOY:
aname = "DEPLOY";
break;
@ -391,13 +399,13 @@ void LifeCycleManager::do_action(const string &action, void * arg)
{
detach_failure_action(vid);
}
else if (action == "SAVEAS_HOT_SUCCESS")
else if (action == "SAVEAS_SUCCESS")
{
saveas_hot_success_action(vid);
saveas_success_action(vid);
}
else if (action == "SAVEAS_HOT_FAILURE")
else if (action == "SAVEAS_FAILURE")
{
saveas_hot_failure_action(vid);
saveas_failure_action(vid);
}
else if (action == "ATTACH_NIC_SUCCESS")
{
@ -447,6 +455,14 @@ void LifeCycleManager::do_action(const string &action, void * arg)
{
snapshot_delete_failure(vid);
}
else if (action == "DISK_SNAPSHOT_SUCCESS")
{
disk_snapshot_success(vid);
}
else if (action == "DISK_SNAPSHOT_FAILURE")
{
disk_snapshot_failure(vid);
}
else if (action == "DEPLOY")
{
deploy_action(vid);

View File

@ -1232,7 +1232,7 @@ void LifeCycleManager::attach_failure_action(int vid)
{
vm->unlock();
vmpool->delete_attach_disk(vid, false);
vmpool->delete_attach_disk(vid);
vm = vmpool->get(vid,true);
@ -1282,7 +1282,7 @@ void LifeCycleManager::detach_success_action(int vid)
{
vm->unlock();
vmpool->delete_attach_disk(vid, true);
vmpool->delete_attach_disk(vid);
vm = vmpool->get(vid,true);
@ -1604,27 +1604,32 @@ void LifeCycleManager::detach_nic_failure_action(int vid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::saveas_hot_success_action(int vid)
void LifeCycleManager::saveas_success_action(int vid)
{
VirtualMachine * vm;
Image * image;
int image_id;
int disk_id;
string source;
string tm_mad;
string snap;
string ds_id;
string src;
vm = vmpool->get(vid,true);
VirtualMachine * vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
int rc = vm->get_saveas_disk_hot(disk_id, source, image_id);
int rc = vm->get_saveas_disk(disk_id, src, image_id, snap, tm_mad, ds_id);
if (vm->clear_saveas_state(disk_id, true) == -1)
vm->clear_saveas_disk();
if (vm->clear_saveas_state() == -1)
{
vm->log("LCM", Log::ERROR, "saveas_hot_success_action, VM in a wrong state");
vm->log("LCM",Log::ERROR, "saveas_success_action, VM in a wrong state");
vmpool->update(vm);
vm->unlock();
return;
@ -1634,14 +1639,14 @@ void LifeCycleManager::saveas_hot_success_action(int vid)
vm->unlock();
if ( rc != 0 )
if (rc != 0)
{
return;
}
image = ipool->get(image_id, true);
Image * image = ipool->get(image_id, true);
if ( image == 0 )
if (image == 0)
{
return;
}
@ -1656,27 +1661,32 @@ void LifeCycleManager::saveas_hot_success_action(int vid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::saveas_hot_failure_action(int vid)
void LifeCycleManager::saveas_failure_action(int vid)
{
VirtualMachine * vm;
Image * image;
int image_id;
int disk_id;
string source;
string tm_mad;
string snap;
string ds_id;
string src;
vm = vmpool->get(vid,true);
VirtualMachine * vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
int rc = vm->get_saveas_disk_hot(disk_id, source, image_id);
int rc = vm->get_saveas_disk(disk_id, src, image_id, snap, tm_mad, ds_id);
if (vm->clear_saveas_state(disk_id, true) == -1)
vm->clear_saveas_disk();
if (vm->clear_saveas_state() == -1)
{
vm->log("LCM", Log::ERROR, "saveas_hot_success_action, VM in a wrong state");
vm->log("LCM",Log::ERROR, "saveas_failure_action, VM in a wrong state");
vmpool->update(vm);
vm->unlock();
return;
@ -1686,14 +1696,14 @@ void LifeCycleManager::saveas_hot_failure_action(int vid)
vm->unlock();
if ( rc != 0 )
if (rc != 0)
{
return;
}
image = ipool->get(image_id, true);
Image * image = ipool->get(image_id, true);
if ( image == 0 )
if (image == 0)
{
return;
}
@ -1707,3 +1717,116 @@ void LifeCycleManager::saveas_hot_failure_action(int vid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::disk_snapshot_success(int vid)
{
string disk_id, tm_mad, ds_id, snap_id;
VirtualMachine * vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_snapshot_disk(ds_id, tm_mad, disk_id, snap_id) == -1)
{
vm->log("LCM", Log::ERROR, "Snapshot DISK could not be found");
dm->trigger(DispatchManager::POWEROFF_SUCCESS, vid);
vm->unlock();
return;
}
int isnap_id = strtol(snap_id.c_str(),NULL,0);
int idisk_id = strtol(disk_id.c_str(),NULL,0);
switch (vm->get_lcm_state())
{
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
vm->log("LCM", Log::INFO, "VM disk snapshot operation completed.");
vm->revert_disk_snapshot(idisk_id, isnap_id);
break;
case VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF:
vm->log("LCM", Log::INFO, "VM disk snapshot deleted.");
vm->delete_disk_snapshot(idisk_id, isnap_id);
break;
default:
vm->log("LCM",Log::ERROR,"disk_snapshot_success, VM in a wrong state");
vm->unlock();
return;
}
vm->clear_snapshot_disk();
vmpool->update(vm);
dm->trigger(DispatchManager::POWEROFF_SUCCESS, vid);
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::disk_snapshot_failure(int vid)
{
string disk_id, tm_mad, ds_id, snap_id;
VirtualMachine * vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_snapshot_disk(ds_id, tm_mad, disk_id, snap_id) == -1)
{
vm->log("LCM", Log::ERROR, "Snapshot DISK could not be found");
dm->trigger(DispatchManager::POWEROFF_SUCCESS, vid);
vm->unlock();
return;
}
int isnap_id = strtol(snap_id.c_str(),NULL,0);
int idisk_id = strtol(disk_id.c_str(),NULL,0);
switch (vm->get_lcm_state())
{
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
vm->log("LCM", Log::ERROR, "Could not take disk snapshot.");
vm->delete_disk_snapshot(idisk_id, isnap_id);
break;
case VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
vm->log("LCM", Log::ERROR, "VM disk snapshot operation failed.");
break;
default:
vm->log("LCM",Log::ERROR,"disk_snapshot_failure, VM in a wrong state");
vm->unlock();
return;
}
vm->clear_snapshot_disk();
vmpool->update(vm);
dm->trigger(DispatchManager::POWEROFF_SUCCESS, vid);
vm->unlock();
return;
}

View File

@ -320,7 +320,7 @@ function mkfs_command {
OPTS="-F"
;;
"reiserfs")
"reiserfs"|"xfs")
OPTS="-f -q"
;;
@ -355,7 +355,9 @@ function mkfs_command {
return 0
;;
*)
OPTS=""
echo ""
echo "Filesystem '$FSTYPE' not valid." 1>&2
return 1
;;
esac

View File

@ -356,11 +356,18 @@ void OpenNebulaTemplate::set_conf_default()
#*******************************************************************************
# Auth Manager Configuration
#*******************************************************************************
# DEFAULT_AUTH
# SESSION_EXPIRATION_TIME
# ENABLE_OTHER_PERMISSIONS
# DEFAULT_UMASK
#*******************************************************************************
*/
// DEFAULT_AUTH
value = "default";
attribute = new SingleAttribute("DEFAULT_AUTH",value);
conf_default.insert(make_pair(attribute->name(),attribute));
// SESSION_EXPIRATION_TIME
value = "0";

View File

@ -127,7 +127,10 @@ public class VirtualMachine extends PoolElement{
"BOOT_UNDEPLOY_FAILURE",
"BOOT_STOPPED_FAILURE",
"PROLOG_RESUME_FAILURE",
"PROLOG_UNDEPLOY_FAILURE"
"PROLOG_UNDEPLOY_FAILURE",
"DISK_SNAPSHOT_POWEROFF",
"DISK_SNAPSHOT_REVERT_POWEROFF",
"DISK_SNAPSHOT_DELETE_POWEROFF"
};
private static final String[] SHORT_LCM_STATES =
@ -182,7 +185,10 @@ public class VirtualMachine extends PoolElement{
"fail", // BOOT_UNDEPLOY_FAILURE
"fail", // BOOT_STOPPED_FAILURE
"fail", // PROLOG_RESUME_FAILURE
"fail" // PROLOG_UNDEPLOY_FAILURE
"fail", // PROLOG_UNDEPLOY_FAILURE
"snap", // DISK_SNAPSHOT_POWEROFF
"snap", // DISK_SNAPSHOT_REVERT_POWEROFF
"snap" // DISK_SNAPSHOT_DELETE_POWEROFF
};
/**

View File

@ -130,7 +130,7 @@ module OpenNebula
raise "ONE_AUTH file not present"
end
@one_auth.rstrip!
@one_auth = @one_auth.rstrip
if endpoint
@one_endpoint = endpoint
@ -144,6 +144,8 @@ module OpenNebula
@one_endpoint = "http://localhost:2633/RPC2"
end
@one_endpoint= @one_endpoint.rstrip
@async = !options[:sync]
timeout=nil

View File

@ -24,7 +24,6 @@ module OpenNebula
# Constants and Class Methods
#######################################################################
IMAGE_METHODS = {
:info => "image.info",
:allocate => "image.allocate",
@ -36,7 +35,10 @@ module OpenNebula
:chmod => "image.chmod",
:chtype => "image.chtype",
:clone => "image.clone",
:rename => "image.rename"
:rename => "image.rename",
:snapshotdelete => "image.snapshotdelete",
:snapshotrevert => "image.snapshotrevert",
:snapshotflatten=> "image.snapshotflatten"
}
IMAGE_STATES=%w{INIT READY USED DISABLED LOCKED ERROR CLONE DELETE USED_PERS}
@ -224,6 +226,32 @@ module OpenNebula
return call(IMAGE_METHODS[:rename], @pe_id, name)
end
# Deletes Image from snapshot
#
# @param snap_id [Integet] ID of the snapshot to delete
#
# @return [nil, OpenNebula::Error] nil in case of success or Error
def snapshot_delete(snap_id)
return call(IMAGE_METHODS[:snapshotdelete], @pe_id, snap_id)
end
# Reverts Image state to a previous snapshot
#
# @param snap_id [Integet] ID of the snapshot to delete
#
# @return [nil, OpenNebula::Error] nil in case of success or Error
def snapshot_revert(snap_id)
return call(IMAGE_METHODS[:snapshotrevert], @pe_id, snap_id)
end
# Flattens an image snapshot
#
# @param snap_id [Integet] ID of the snapshot to flatten
#
# @return [nil, OpenNebula::Error] nil in case of success or Error
def snapshot_flatten(snap_id)
return call(IMAGE_METHODS[:snapshotflatten], @pe_id, snap_id)
end
#######################################################################
# Helpers to get Image information
#######################################################################

View File

@ -29,8 +29,6 @@ module OpenNebula
:action => "vm.action",
:migrate => "vm.migrate",
:deploy => "vm.deploy",
:savedisk => "vm.savedisk",
:savediskcancel => "vm.savediskcancel",
:chown => "vm.chown",
:chmod => "vm.chmod",
:monitoring => "vm.monitoring",
@ -44,7 +42,11 @@ module OpenNebula
:snapshotdelete => "vm.snapshotdelete",
:attachnic => "vm.attachnic",
:detachnic => "vm.detachnic",
:recover => "vm.recover"
:recover => "vm.recover",
:disksaveas => "vm.disksaveas",
:disksnapshotcreate => "vm.disksnapshotcreate",
:disksnapshotrevert => "vm.disksnapshotrevert",
:disksnapshotdelete => "vm.disksnapshotdelete"
}
VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED
@ -102,6 +104,9 @@ module OpenNebula
BOOT_STOPPED_FAILURE
PROLOG_RESUME_FAILURE
PROLOG_UNDEPLOY_FAILURE
DISK_SNAPSHOT_POWEROFF
DISK_SNAPSHOT_REVERT_POWEROFF
DISK_SNAPSHOT_DELETE_POWEROFF
}
SHORT_VM_STATES={
@ -167,7 +172,10 @@ module OpenNebula
"BOOT_UNDEPLOY_FAILURE" => "fail",
"BOOT_STOPPED_FAILURE" => "fail",
"PROLOG_RESUME_FAILURE" => "fail",
"PROLOG_UNDEPLOY_FAILURE" => "fail"
"PROLOG_UNDEPLOY_FAILURE" => "fail",
"DISK_SNAPSHOT_POWEROFF" => "snap",
"DISK_SNAPSHOT_REVERT_POWEROFF" => "snap",
"DISK_SNAPSHOT_DELETE_POWEROFF" => "snap"
}
MIGRATE_REASON=%w{NONE ERROR USER}
@ -451,7 +459,7 @@ module OpenNebula
migrate(host_id, true, enforce)
end
# Set the specified vm's disk to be saved in a new image
# Set the specified vm's disk to be saved as a new image
# when the VirtualMachine shutdowns
#
# @param disk_id [Integer] ID of the disk to be saved
@ -459,36 +467,23 @@ module OpenNebula
# disk will be saved
# @param image_type [String] Type of the new image. Set to empty string
# to use the default type
# @param hot [true|false] True to save the disk immediately, false will
# perform the operation when the VM shuts down
# @param snap_id [Integer] ID of the snapshot to save, -1 to use the
# current disk image state
#
# @return [Integer, OpenNebula::Error] the new Image ID in case of
# success, error otherwise
def disk_snapshot(disk_id, image_name, image_type="", hot=false)
def disk_saveas(disk_id, image_name, image_type="", snap_id=-1)
return Error.new('ID not defined') if !@pe_id
rc = @client.call(VM_METHODS[:savedisk],
rc = @client.call(VM_METHODS[:disksaveas],
@pe_id,
disk_id,
image_name,
image_type,
hot)
snap_id)
return rc
end
# @deprecated use {#disk_snapshot}
def save_as(disk_id, image_name, image_type="", hot=false)
return disk_snapshot(disk_id, image_name, image_type, hot)
end
# Cancels a deferred snapshot that has been set by disk_snapshot.
# The target image is also deleted.
def disk_snapshot_cancel(disk_id)
return call(VM_METHODS[:savediskcancel],
@pe_id,
disk_id)
end
# Resize the VM
#
# @param capacity_template [String] Template containing the new capacity
@ -610,6 +605,38 @@ module OpenNebula
return call(VM_METHODS[:snapshotdelete], @pe_id, snap_id)
end
# Takes a new snapshot of a disk
#
# @param disk_id [Integer] Id of the disk
# @param tag [String] description for the snapshot
#
# @return [Integer, OpenNebula::Error] The new snapshot ID or error
def disk_snapshot_create(disk_id, tag)
return call(VM_METHODS[:disksnapshotcreate], @pe_id, disk_id, tag)
end
# Reverts disk state to a previously taken snapshot
#
# @param disk_id [Integer] Id of the disk
# @param snap_id [Integer] Id of the snapshot
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def disk_snapshot_revert(disk_id, snap_id)
return call(VM_METHODS[:disksnapshotrevert], @pe_id, disk_id, snap_id)
end
# Deletes a disk snapshot
#
# @param disk_id [Integer] Id of the disk
# @param snap_id [Integer] Id of the snapshot
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def disk_snapshot_delete(disk_id, snap_id)
return call(VM_METHODS[:disksnapshotdelete], @pe_id, disk_id, snap_id)
end
# Recovers an ACTIVE VM
#
# @param result [Integer] Recover with failure (0), success (1) or
@ -743,8 +770,7 @@ module OpenNebula
image_id = disk["IMAGE_ID"]
if !image_id.nil? && !image_id.empty?
rc = disk_snapshot(disk_id.to_i, "#{name}-disk-#{disk_id}",
"", true)
rc = disk_saveas(disk_id.to_i,"#{name}-disk-#{disk_id}","",-1)
return rc if OpenNebula.is_error?(rc)

View File

@ -225,6 +225,8 @@ int PoolObjectSQL::replace_template(
return -1;
}
delete old_tmpl;
return 0;
}
@ -282,6 +284,8 @@ int PoolObjectSQL::append_template(
return -1;
}
delete old_tmpl;
return 0;
}

View File

@ -293,8 +293,6 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr vm_deploy(new VirtualMachineDeploy());
xmlrpc_c::methodPtr vm_migrate(new VirtualMachineMigrate());
xmlrpc_c::methodPtr vm_action(new VirtualMachineAction());
xmlrpc_c::methodPtr vm_savedisk(new VirtualMachineSaveDisk());
xmlrpc_c::methodPtr vm_savedisk_cancel(new VirtualMachineSaveDiskCancel());
xmlrpc_c::methodPtr vm_monitoring(new VirtualMachineMonitoring());
xmlrpc_c::methodPtr vm_attach(new VirtualMachineAttach());
xmlrpc_c::methodPtr vm_detach(new VirtualMachineDetach());
@ -304,6 +302,10 @@ void RequestManager::register_xml_methods()
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_dsaveas(new VirtualMachineDiskSaveas());
xmlrpc_c::methodPtr vm_dsnap_create(new VirtualMachineDiskSnapshotCreate());
xmlrpc_c::methodPtr vm_dsnap_revert(new VirtualMachineDiskSnapshotRevert());
xmlrpc_c::methodPtr vm_dsnap_delete(new VirtualMachineDiskSnapshotDelete());
xmlrpc_c::methodPtr vm_recover(new VirtualMachineRecover());
xmlrpc_c::methodPtr vm_pool_acct(new VirtualMachinePoolAccounting());
@ -394,6 +396,9 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr image_enable(new ImageEnable());
xmlrpc_c::methodPtr image_chtype(new ImageChangeType());
xmlrpc_c::methodPtr image_clone(new ImageClone());
xmlrpc_c::methodPtr image_snap_delete(new ImageSnapshotDelete());
xmlrpc_c::methodPtr image_snap_revert(new ImageSnapshotRevert());
xmlrpc_c::methodPtr image_snap_flatten(new ImageSnapshotFlatten());
// Datastore Methods
xmlrpc_c::methodPtr datastore_enable(new DatastoreEnable());
@ -443,8 +448,6 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy);
RequestManagerRegistry.addMethod("one.vm.action", vm_action);
RequestManagerRegistry.addMethod("one.vm.migrate", vm_migrate);
RequestManagerRegistry.addMethod("one.vm.savedisk", vm_savedisk);
RequestManagerRegistry.addMethod("one.vm.savediskcancel", vm_savedisk_cancel);
RequestManagerRegistry.addMethod("one.vm.allocate", vm_allocate);
RequestManagerRegistry.addMethod("one.vm.info", vm_info);
RequestManagerRegistry.addMethod("one.vm.chown", vm_chown);
@ -460,6 +463,10 @@ void RequestManager::register_xml_methods()
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.vm.disksaveas", vm_dsaveas);
RequestManagerRegistry.addMethod("one.vm.disksnapshotcreate", vm_dsnap_create);
RequestManagerRegistry.addMethod("one.vm.disksnapshotrevert", vm_dsnap_revert);
RequestManagerRegistry.addMethod("one.vm.disksnapshotdelete", vm_dsnap_delete);
RequestManagerRegistry.addMethod("one.vm.recover", vm_recover);
RequestManagerRegistry.addMethod("one.vmpool.info", vm_pool_info);
@ -647,6 +654,9 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.image.chtype", image_chtype);
RequestManagerRegistry.addMethod("one.image.clone", image_clone);
RequestManagerRegistry.addMethod("one.image.rename", image_rename);
RequestManagerRegistry.addMethod("one.image.snapshotdelete", image_snap_delete);
RequestManagerRegistry.addMethod("one.image.snapshotrevert", image_snap_revert);
RequestManagerRegistry.addMethod("one.image.snapshotflatten", image_snap_flatten);
RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info);

View File

@ -179,55 +179,12 @@ int HostDelete::drop(int oid, PoolObjectSQL * object, string& error_msg)
int ImageDelete::drop(int oid, PoolObjectSQL * object, string& error_msg)
{
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
VirtualMachinePool * vmpool = nd.get_vmpool();
VirtualMachine * vm;
bool save_as;
int rc, img_id, vm_id, disk_id;
object->get_template_attribute("SAVE_AS", save_as);
save_as &= object->get_template_attribute("SAVED_VM_ID", vm_id) &
object->get_template_attribute("SAVED_DISK_ID", disk_id);
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
object->unlock();
rc = imagem->delete_image(oid, error_msg);
// -------------------------------------------------------------------------
// Cancel the disk snapshot
// -------------------------------------------------------------------------
if (rc == 0 && save_as)
{
vm = vmpool->get(vm_id, true);
if (vm == 0)
{
return rc;
}
if (vm->get_state() == VirtualMachine::DONE)
{
vm->unlock();
return rc;
}
img_id = vm->get_save_disk_image(disk_id);
if ( img_id == oid )
{
vm->clear_save_disk(disk_id);
vmpool->update(vm);
}
vm->unlock();
}
return rc;
return imagem->delete_image(oid, error_msg);
}
/* ------------------------------------------------------------------------- */

View File

@ -200,12 +200,10 @@ void ImageChangeType::request_execute(xmlrpc_c::paramList const& paramList,
break;
}
rc = image->set_type(type);
rc = image->set_type(type, err_msg);
if ( rc != 0 )
{
err_msg = "Unknown type " + type;
failure_response(INTERNAL,request_error(err_msg,""), att);
image->unlock();
@ -282,6 +280,16 @@ void ImageClone::request_execute(
return;
}
const Snapshots& snaps = img->get_snapshots();
if (snaps.size () > 0)
{
failure_response(ACTION,
request_error("Cannot clone images with snapshots",""), att);
img->unlock();
return;
}
tmpl = img->clone_template(name);
img->get_permissions(perms);
@ -461,4 +469,90 @@ void ImageClone::request_execute(
success_response(new_id, att);
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void ImageSnapshotDelete::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
int id = xmlrpc_c::value_int(paramList.getInt(1));
int snap_id = xmlrpc_c::value_int(paramList.getInt(2));
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
if ( basic_authorization(id, att) == false )
{
return;
}
string err_msg;
int rc = imagem->delete_snapshot(id, snap_id, err_msg);
if ( rc < 0 )
{
failure_response(ACTION, request_error(err_msg, ""), att);
return;
}
success_response(snap_id, att);
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void ImageSnapshotRevert::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
int id = xmlrpc_c::value_int(paramList.getInt(1));
int snap_id = xmlrpc_c::value_int(paramList.getInt(2));
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
if ( basic_authorization(id, att) == false )
{
return;
}
string err_msg;
int rc = imagem->revert_snapshot(id, snap_id, err_msg);
if ( rc < 0 )
{
failure_response(ACTION, request_error(err_msg, ""), att);
return;
}
success_response(snap_id, att);
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void ImageSnapshotFlatten::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
int id = xmlrpc_c::value_int(paramList.getInt(1));
int snap_id = xmlrpc_c::value_int(paramList.getInt(2));
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
if ( basic_authorization(id, att) == false )
{
return;
}
string err_msg;
int rc = imagem->flatten_snapshot(id, snap_id, err_msg);
if ( rc < 0 )
{
failure_response(ACTION, request_error(err_msg, ""), att);
return;
}
success_response(snap_id, att);
}

View File

@ -1176,66 +1176,72 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
void VirtualMachineDiskSaveas::request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
Nebula& nd = Nebula::instance();
ImagePool * ipool = nd.get_ipool();
DatastorePool * dspool = nd.get_dspool();
int id = xmlrpc_c::value_int(paramList.getInt(1));
int disk_id = xmlrpc_c::value_int(paramList.getInt(2));
string img_name = xmlrpc_c::value_string(paramList.getString(3));
string img_type = xmlrpc_c::value_string(paramList.getString(4));
bool is_hot = false; //Optional XML-RPC argument
if ( paramList.size() > 5 )
{
is_hot = xmlrpc_c::value_boolean(paramList.getBoolean(5));
}
int id = xmlrpc_c::value_int(paramList.getInt(1));
int disk_id = xmlrpc_c::value_int(paramList.getInt(2));
string img_name = xmlrpc_c::value_string(paramList.getString(3));
string img_type = xmlrpc_c::value_string(paramList.getString(4));
int snap_id = xmlrpc_c::value_int(paramList.getInt(5));
VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
VirtualMachine * vm;
Datastore * ds;
int iid;
Image * img;
int iid;
int iid_orig;
string error_str;
string ds_data;
PoolObjectAuth ds_perms;
long long avail;
bool ds_check;
string driver;
string target;
string dev_prefix;
int ds_id;
string ds_name;
long long size;
string iname_orig;
string iuname_orig;
Image::ImageType type;
Image::DiskType ds_disk_type;
ImageTemplate * itemplate;
Template img_usage;
int rc;
bool rc_auth;
string error;
// -------------------------------------------------------------------------
// Prepare and check the VM/DISK to be saved_as
// Prepare and check the VM/DISK to be saved as
// -------------------------------------------------------------------------
if ((vm = get_vm(id, att)) == 0)
{
return;
}
if ( vm->set_saveas_state(disk_id, is_hot) != 0 )
if (vm->set_saveas_state() != 0)
{
vm->unlock();
failure_response(INTERNAL,
request_error("VM has to be RUNNING, POWEROFF or"
" SUSPENDED to snapshot disks.",""), att);
return;
goto error_state;
}
int iid_orig = vm->get_image_from_disk(disk_id, is_hot, error_str);
iid_orig = vm->set_saveas_disk(disk_id, snap_id, error);
if ( iid_orig == -1 )
if (iid_orig == -1)
{
vm->clear_saveas_state(disk_id, is_hot);
vm->unlock();
failure_response(INTERNAL,
request_error("Cannot use selected DISK", error_str),
att);
return;
goto error_disk;
}
vmpool->update(vm);
@ -1245,32 +1251,21 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
// -------------------------------------------------------------------------
// Get the data of the Image to be saved
// -------------------------------------------------------------------------
Image * img = ipool->get(iid_orig, true);
img = ipool->get(iid_orig, true);
if ( img == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::IMAGE), iid_orig),
att);
if ((vm = vmpool->get(id, true)) != 0)
{
vm->clear_saveas_state(disk_id, is_hot);
vmpool->update(vm);
vm->unlock();
}
return;
goto error_image;
}
int ds_id = img->get_ds_id();
string ds_name = img->get_ds_name();
long long size = img->get_size();
ds_id = img->get_ds_id();
ds_name = img->get_ds_name();
string iname_orig = img->get_name();
string iuname_orig = img->get_uname();
Image::ImageType type = img->get_type();
size = img->get_size();
type = img->get_type();
iname_orig = img->get_name();
iuname_orig = img->get_uname();
img->get_template_attribute("DRIVER", driver);
img->get_template_attribute("TARGET", target);
@ -1283,74 +1278,39 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
case Image::OS:
case Image::DATABLOCK:
case Image::CDROM:
break;
break;
case Image::KERNEL:
case Image::RAMDISK:
case Image::CONTEXT:
failure_response(INTERNAL,
request_error("Cannot save_as image of type " +
Image::type_to_str(type), ""), att);
return;
goto error_image_type;
}
// -------------------------------------------------------------------------
// Get the data of the DataStore for the new image
// Get the data of the DataStore for the new image & size
// -------------------------------------------------------------------------
if ((ds = dspool->get(ds_id, true)) == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::DATASTORE), ds_id),
att);
if ((vm = vmpool->get(id, true)) != 0)
{
vm->clear_saveas_state(disk_id, is_hot);
vmpool->update(vm);
vm->unlock();
}
return;
goto error_ds;
}
string ds_data;
PoolObjectAuth ds_perms;
long long avail;
bool ds_check;
ds->get_permissions(ds_perms);
ds->to_xml(ds_data);
ds_check = ds->get_avail_mb(avail);
Image::DiskType ds_disk_type = ds->get_disk_type();
ds_check = ds->get_avail_mb(avail);
ds_disk_type = ds->get_disk_type();
ds->unlock();
// -------------------------------------------------------------------------
// Check Datastore Capacity
// -------------------------------------------------------------------------
if (ds_check && (size > avail))
{
failure_response(ACTION, "Not enough space in datastore", att);
if ((vm = vmpool->get(id, true)) != 0)
{
vm->clear_saveas_state(disk_id, is_hot);
vmpool->update(vm);
vm->unlock();
}
return;
goto error_size;
}
// -------------------------------------------------------------------------
// Create a template for the new Image
// -------------------------------------------------------------------------
ImageTemplate * itemplate = new ImageTemplate;
Template img_usage;
itemplate = new ImageTemplate;
itemplate->add("NAME", img_name);
itemplate->add("SIZE", size);
@ -1358,15 +1318,9 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
itemplate->add("SAVED_IMAGE_ID",iid_orig);
itemplate->add("SAVED_DISK_ID",disk_id);
itemplate->add("SAVED_VM_ID", id);
itemplate->set_saving();
if ( is_hot )
{
itemplate->set_saving_hot();
}
if ( img_type.empty() )
if (img_type.empty())
{
itemplate->add("TYPE", Image::type_to_str(type));
}
@ -1375,17 +1329,17 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
itemplate->add("TYPE", img_type);
}
if ( driver.empty() == false )
if (!driver.empty())
{
itemplate->add("DRIVER", driver);
}
if ( target.empty() == false )
if (!target.empty())
{
itemplate->add("TARGET", target);
}
if ( dev_prefix.empty() == false )
if (!dev_prefix.empty())
{
itemplate->add("DEV_PREFIX", dev_prefix);
}
@ -1396,7 +1350,7 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
// -------------------------------------------------------------------------
// Authorize the operation & check quotas
// -------------------------------------------------------------------------
bool rc_auth = vm_authorization(id, itemplate, 0, att, 0,&ds_perms,auth_op);
rc_auth = vm_authorization(id, itemplate, 0, att, 0,&ds_perms,auth_op);
if ( rc_auth == true )
{
@ -1405,216 +1359,111 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
if ( rc_auth == false)
{
delete itemplate;
if ((vm = vmpool->get(id, true)) != 0)
{
vm->clear_saveas_state(disk_id, is_hot);
vmpool->update(vm);
vm->unlock();
}
return;
goto error_auth;
}
// -------------------------------------------------------------------------
// Create the image
// -------------------------------------------------------------------------
int rc = ipool->allocate(att.uid,
att.gid,
att.uname,
att.gname,
att.umask,
itemplate,
ds_id,
ds_name,
ds_disk_type,
ds_data,
Datastore::IMAGE_DS,
-1,
&iid,
error_str);
rc = ipool->allocate(att.uid,
att.gid,
att.uname,
att.gname,
att.umask,
itemplate,
ds_id,
ds_name,
ds_disk_type,
ds_data,
Datastore::IMAGE_DS,
-1,
&iid,
error);
if (rc < 0)
{
quota_rollback(&img_usage, Quotas::DATASTORE, att);
if ((vm = vmpool->get(id, true)) != 0)
{
vm->clear_saveas_state(disk_id, is_hot);
vmpool->update(vm);
vm->unlock();
}
failure_response(INTERNAL,
allocate_error(PoolObjectSQL::IMAGE, error_str), att);
return;
goto error_allocate;
}
ds = dspool->get(ds_id, true);
if ( ds != 0 ) // TODO: error otherwise or leave image in ERROR?
if (ds == 0)
{
ds->add_image(iid);
dspool->update(ds);
ds->unlock();
goto error_ds_removed;
}
ds->add_image(iid);
dspool->update(ds);
ds->unlock();
success_response(iid, att);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
return;
void VirtualMachineSaveDiskCancel::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
error_state:
vm->unlock();
AclManager * aclm = nd.get_aclm();
ImageManager * imagem = nd.get_imagem();
ImagePool * ipool = nd.get_ipool();
Image * img;
int img_id;
failure_response(INTERNAL,request_error("VM has to be RUNNING, POWEROFF or "
"SUSPENDED to save disks.",""), att);
return;
VirtualMachinePool * vmpool = static_cast<VirtualMachinePool *>(pool);
VirtualMachine * vm;
error_disk:
vm->clear_saveas_state();
string error_str;
int id = xmlrpc_c::value_int(paramList.getInt(1));
int disk_id = xmlrpc_c::value_int(paramList.getInt(2));
// -------------------------------------------------------------------------
// Authorize the VM operation
// -------------------------------------------------------------------------
if (att.uid != UserPool::ONEADMIN_ID)
{
PoolObjectAuth vm_perms;
PoolObjectAuth img_perms;
if ((vm = get_vm(id, att)) == 0)
{
return;
}
vm->get_permissions(vm_perms);
img_id = vm->get_save_disk_image(disk_id);
vm->unlock();
AuthRequest ar(att.uid, att.group_ids);
ar.add_auth(auth_op, vm_perms); // MANAGE VM
img = ipool->get(img_id, true);
if ( img != 0 )
{
img->get_permissions(img_perms);
img->unlock();
ar.add_auth(AuthRequest::MANAGE, img_perms); // MANAGE IMAGE
}
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
return;
}
}
// -------------------------------------------------------------------------
// Check the VM state
// -------------------------------------------------------------------------
if ((vm = get_vm(id, att)) == 0)
{
return;
}
if ((vm->get_state() != VirtualMachine::ACTIVE ||
(vm->get_lcm_state() != VirtualMachine::RUNNING &&
vm->get_lcm_state() != VirtualMachine::UNKNOWN) ) &&
vm->get_state() != VirtualMachine::POWEROFF &&
vm->get_state() != VirtualMachine::SUSPENDED)
{
failure_response(ACTION,
request_error("Wrong state to perform action",""),
att);
vm->unlock();
return;
}
// -------------------------------------------------------------------------
// Cancel the disk snapshot
// -------------------------------------------------------------------------
img_id = vm->get_save_disk_image(disk_id);
if ( img_id == -1 )
{
ostringstream oss;
oss << "Disk with ID [" << disk_id << "] is not going to be saved";
failure_response(ACTION,
request_error(oss.str(), ""),
att);
vm->unlock();
return;
}
vm->clear_save_disk(disk_id);
vmpool->update(vm);
vm->clear_saveas_disk();
vm->unlock();
// -------------------------------------------------------------------------
// Delete the target Image
// -------------------------------------------------------------------------
failure_response(INTERNAL,request_error("Cannot use DISK", error), att);
return;
img = ipool->get(img_id, true);
error_image:
failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::IMAGE),
iid_orig), att);
goto error_common;
if ( img != 0 )
error_image_type:
failure_response(INTERNAL, request_error("Cannot save_as image of type " +
Image::type_to_str(type), ""), att);
goto error_common;
error_ds:
failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::DATASTORE),
ds_id), att);
goto error_common;
error_size:
failure_response(ACTION, "Not enough space in datastore", att);
goto error_common;
error_auth:
delete itemplate;
goto error_common;
error_allocate:
quota_rollback(&img_usage, Quotas::DATASTORE, att);
failure_response(INTERNAL, allocate_error(PoolObjectSQL::IMAGE, error),att);
goto error_common;
error_ds_removed:
failure_response(NO_EXISTS,get_error(object_name(PoolObjectSQL::DATASTORE),
ds_id), att);
goto error_common;
error_common:
if ((vm = vmpool->get(id, true)) != 0)
{
img->unlock();
vm->clear_saveas_state();
int rc = imagem->delete_image(img_id, error_str);
vm->clear_saveas_disk();
if (rc != 0)
{
ostringstream oss;
oss << "The snapshot was canceled, but "
<< object_name(PoolObjectSQL::IMAGE) << " [" << img_id
<< "] could not be deleted: " << error_str;
vmpool->update(vm);
failure_response(INTERNAL,
request_error(oss.str(), ""),
att);
return;
}
aclm->del_resource_rules(img_id, PoolObjectSQL::IMAGE);
vm->unlock();
}
// TODO: Delete the cloned template
success_response(id, att);
return;
}
/* -------------------------------------------------------------------------- */
@ -2483,3 +2332,120 @@ void VirtualMachinePoolCalculateShowback::request_execute(
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineDiskSnapshotCreate::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));
int did = xmlrpc_c::value_int(paramList.getInt(2));
string tag = xmlrpc_c::value_string(paramList.getString(3));
if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
{
return;
}
rc = dm->disk_snapshot_create(id, did, tag, snap_id, error_str);
if ( rc != 0 )
{
failure_response(ACTION,
request_error(error_str, ""),
att);
}
else
{
success_response(snap_id, att);
}
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineDiskSnapshotRevert::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 did = xmlrpc_c::value_int(paramList.getInt(2));
int snap_id = xmlrpc_c::value_int(paramList.getInt(3));
if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
{
return;
}
rc = dm->disk_snapshot_revert(id, did, snap_id, error_str);
if ( rc != 0 )
{
failure_response(ACTION,
request_error(error_str, ""),
att);
}
else
{
success_response(snap_id, att);
}
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineDiskSnapshotDelete::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 did = xmlrpc_c::value_int(paramList.getInt(2));
int snap_id = xmlrpc_c::value_int(paramList.getInt(3));
if ( vm_authorization(id, 0, 0, att, 0, 0, auth_op) == false )
{
return;
}
rc = dm->disk_snapshot_delete(id, did, snap_id, error_str);
if ( rc != 0 )
{
failure_response(ACTION,
request_error(error_str, ""),
att);
}
else
{
success_response(snap_id, att);
}
return;
}

View File

@ -83,6 +83,9 @@ VNC_STATES = [
#48, #BOOT_STOPPED_FAILURE
#49, #PROLOG_RESUME_FAILURE
#50, #PROLOG_UNDEPLOY_FAILURE
#51, #DISK_SNAPSHOT_POWEROFF
#52, #DISK_SNAPSHOT_REVERT_POWEROFF
#53, #DISK_SNAPSHOT_DELETE_POWEROFF
]
class OpenNebulaVNC

View File

@ -55,7 +55,6 @@ module OpenNebulaJSON
when "suspend" then self.suspend
when "reset" then self.reset
when "saveas" then self.save_as(action_hash['params'])
when "disk_snapshot_cancel" then self.disk_snapshot_cancel(action_hash['params'])
when "snapshot_create" then self.snapshot_create(action_hash['params'])
when "snapshot_revert" then self.snapshot_revert(action_hash['params'])
when "snapshot_delete" then self.snapshot_delete(action_hash['params'])
@ -105,14 +104,7 @@ module OpenNebulaJSON
end
def save_as(params=Hash.new)
clone = params['clonetemplate']
clone = false if clone.nil?
disk_snapshot(params['disk_id'].to_i, params['image_name'], params['type'], params['hot'], clone)
end
def disk_snapshot_cancel(params=Hash.new)
super(params['disk_id'].to_i)
disk_saveas(params['disk_id'].to_i, params['image_name'], params['type'])
end
def snapshot_create(params=Hash.new)

View File

@ -87,26 +87,6 @@ get '/vcenter/templates' do
end
end
get '/vcenter/vms' do
begin
vms = vcenter_client.running_vms(
$cloud_auth.client(session[:user], session[:active_zone_endpoint]))
if vms.nil?
msg = "No datacenter found"
logger.error("[vCenter] " + msg)
error = Error.new(msg)
error 404, error.to_json
end
[200, vms.to_json]
rescue Exception => e
logger.error("[vCenter] " + e.message)
error = Error.new(e.message)
error 403, error.to_json
end
end
get '/vcenter/networks' do
begin
networks = vcenter_client.vcenter_networks(

View File

@ -16,14 +16,13 @@
#include "Template.h"
#include "template_syntax.h"
#include "NebulaUtil.h"
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdio>
#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -524,7 +523,7 @@ bool Template::get(
return false;
}
TO_UPPER(sval);
one_util::toupper(sval);
if ( sval == "YES" )
{
@ -747,18 +746,7 @@ void Template::rebuild_attributes(const xmlNode * root_element)
Attribute * attr;
//Clear the template if not empty
if (!attributes.empty())
{
multimap<string,Attribute *>::iterator it;
for ( it = attributes.begin(); it != attributes.end(); it++)
{
delete it->second;
}
attributes.clear();
}
clear();
// Get the root's children and try to build attributes.
for (cur_node = root_element->children;
@ -976,17 +964,31 @@ void Template::remove_all_except_restricted(const vector<string> &restricted_att
remove(*res_it);
}
multimap<string,Attribute *>::iterator att_it;
for ( att_it = attributes.begin(); att_it != attributes.end(); att_it++)
{
delete att_it->second;
}
attributes.clear();
clear();
for (res_it = restricted.begin(); res_it != restricted.end(); res_it++)
{
set(*res_it);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Template::clear()
{
if (attributes.empty())
{
return;
}
multimap<string,Attribute *>::iterator it;
for ( it = attributes.begin(); it != attributes.end(); it++)
{
delete it->second;
}
attributes.clear();
}

View File

@ -139,6 +139,18 @@ void TransferManager::trigger(Actions action, int _vid)
aname = "DRIVER_CANCEL";
break;
case SNAPSHOT_CREATE:
aname = "SNAPSHOT_CREATE";
break;
case SNAPSHOT_REVERT:
aname = "SNAPSHOT_REVERT";
break;
case SNAPSHOT_DELETE:
aname = "SNAPSHOT_DELETE";
break;
case FINALIZE:
aname = ACTION_FINALIZE;
break;
@ -378,6 +390,18 @@ void TransferManager::do_action(const string &action, void * arg)
{
driver_cancel_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
{
ostringstream oss;
@ -1209,27 +1233,20 @@ void TransferManager::epilog_transfer_command(
const VectorAttribute * disk,
ostream& xfr)
{
string save;
string tm_mad;
int disk_id;
disk->vector_value("DISK_ID", disk_id);
save = disk->vector_value("SAVE");
string save = disk->vector_value("SAVE");
disk->vector_value("DISK_ID", disk_id);
transform(save.begin(),save.end(),save.begin(),(int(*)(int))toupper);
if ( save == "YES" )
{
string source;
string save_source;
string ds_id;
source = disk->vector_value("SOURCE");
save_source = disk->vector_value("SAVE_AS_SOURCE");
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
string source = disk->vector_value("SOURCE");
string tm_mad = disk->vector_value("TM_MAD");
string ds_id = disk->vector_value("DATASTORE_ID");
if ( ds_id.empty() || tm_mad.empty() )
{
@ -1237,17 +1254,12 @@ void TransferManager::epilog_transfer_command(
return;
}
if (source.empty() && save_source.empty())
if (source.empty())
{
vm->log("TM", Log::ERROR, "No SOURCE to save disk image");
return;
}
if (!save_source.empty())//Use the save_as_source instead
{
source = save_source;
}
//MVDS tm_mad hostname:remote_system_dir/disk.0 <fe:SOURCE|SOURCE> vmid dsid
xfr << "MVDS "
<< tm_mad << " "
@ -1260,6 +1272,8 @@ void TransferManager::epilog_transfer_command(
}
else //No saving disk
{
string tm_mad;
int ds_id_i;
int vv_rc = 0;
@ -2039,30 +2053,21 @@ void TransferManager::saveas_hot_action(int vid)
{
int disk_id;
int image_id;
string save_source;
string save;
string src;
string snap_id;
string tm_mad;
string ds_id;
int num;
int disk_id_iter;
ostringstream os;
ofstream xfr;
string xfr_name;
string source;
const VectorAttribute * disk;
vector<const Attribute *> attrs;
VirtualMachine * vm;
Nebula& nd = Nebula::instance();
const TransferManagerDriver * tm_md;
Nebula& nd = Nebula::instance();
// ------------------------------------------------------------------------
// Setup & Transfer script
// ------------------------------------------------------------------------
@ -2080,9 +2085,9 @@ void TransferManager::saveas_hot_action(int vid)
goto error_common;
}
if (vm->get_saveas_disk_hot(disk_id, save_source, image_id) == -1)
if (vm->get_saveas_disk(disk_id, src, image_id, snap_id, tm_mad, ds_id)!= 0)
{
vm->log("TM", Log::ERROR, "Could not get disk information to saveas it");
vm->log("TM", Log::ERROR,"Could not get disk information to export it");
goto error_common;
}
@ -2093,41 +2098,7 @@ void TransferManager::saveas_hot_action(int vid)
goto error_driver;
}
num = vm->get_template_attribute("DISK",attrs);
for (int i=0 ; i < num ; i++)
{
disk = dynamic_cast<const VectorAttribute *>(attrs[i]);
if ( disk == 0 )
{
continue;
}
disk->vector_value("DISK_ID", disk_id_iter);
if (disk_id == disk_id_iter)
{
tm_mad = disk->vector_value("TM_MAD");
ds_id = disk->vector_value("DATASTORE_ID");
break;
}
}
if ( ds_id.empty() || tm_mad.empty() )
{
vm->log("TM", Log::ERROR, "No DS_ID or TM_MAD to save disk image");
goto error_common;
}
if (save_source.empty())
{
vm->log("TM", Log::ERROR, "No SOURCE to save disk image");
goto error_common;
}
xfr_name = vm->get_transfer_file() + ".saveas_hot";
xfr_name = vm->get_transfer_file() + ".disk_saveas";
xfr.open(xfr_name.c_str(),ios::out | ios::trunc);
if (xfr.fail() == true)
@ -2135,12 +2106,13 @@ void TransferManager::saveas_hot_action(int vid)
goto error_file;
}
//MVDS tm_mad hostname:remote_system_dir/disk.0 <fe:SOURCE|SOURCE> vmid dsid
//CPDS tm_mad hostname:remote_system_dir/disk.0 source snapid vmid dsid
xfr << "CPDS "
<< tm_mad << " "
<< vm->get_hostname() << ":"
<< vm->get_remote_system_dir() << "/disk." << disk_id << " "
<< save_source << " "
<< src << " "
<< snap_id << " "
<< vm->get_oid() << " "
<< ds_id
<< endl;
@ -2165,7 +2137,7 @@ error_file:
error_common:
vm->log("TM", Log::ERROR, os);
(nd.get_lcm())->trigger(LifeCycleManager::SAVEAS_HOT_FAILURE, vid);
(nd.get_lcm())->trigger(LifeCycleManager::SAVEAS_FAILURE, vid);
vm->unlock();
return;
@ -2190,6 +2162,117 @@ void TransferManager::migrate_transfer_command(
<< endl;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void TransferManager::do_snapshot_action(int vid, const char * snap_action)
{
string tm_mad;
string ds_id;
string disk_id;
string parent_id;
string snap_id;
ostringstream os;
ofstream xfr;
string xfr_name;
VirtualMachine * vm;
const TransferManagerDriver * tm_md;
Nebula& nd = Nebula::instance();
// ------------------------------------------------------------------------
// Setup & Transfer script
// ------------------------------------------------------------------------
vm = vmpool->get(vid,true);
if (vm == 0)
{
vm->log("TM", Log::ERROR, "Could not obtain the VM");
goto error_common;
}
if (!vm->hasHistory())
{
vm->log("TM", Log::ERROR, "The VM has no history");
goto error_common;
}
if (vm->get_snapshot_disk(ds_id, tm_mad, disk_id, snap_id) == -1)
{
vm->log("TM", Log::ERROR, "Could not get disk information to"
"take snapshot");
goto error_common;
}
tm_md = get();
if (tm_md == 0)
{
goto error_driver;
}
xfr_name = vm->get_transfer_file() + ".disk_snapshot";
xfr.open(xfr_name.c_str(),ios::out | ios::trunc);
if (xfr.fail() == true)
{
goto error_file;
}
//SNAP_CREATE tm_mad host:remote_system_dir/disk.0 snapid vmid dsid
xfr << snap_action << " "
<< tm_mad << " "
<< vm->get_hostname() << ":"
<< vm->get_remote_system_dir() << "/disk." << disk_id << " "
<< snap_id << " "
<< vm->get_oid() << " "
<< ds_id
<< endl;
xfr.close();
tm_md->transfer(vid, xfr_name);
vm->unlock();
return;
error_driver:
os << "saveas_hot_transfer, error getting TM driver.";
goto error_common;
error_file:
os << "disk_snapshot_create, could not open file: " << xfr_name;
goto error_common;
error_common:
vm->log("TM", Log::ERROR, os);
(nd.get_lcm())->trigger(LifeCycleManager::DISK_SNAPSHOT_FAILURE, vid);
vm->unlock();
return;
}
void TransferManager::snapshot_create_action(int vid)
{
return do_snapshot_action(vid, "SNAP_CREATE");
};
void TransferManager::snapshot_revert_action(int vid)
{
return do_snapshot_action(vid, "SNAP_REVERT");
};
void TransferManager::snapshot_delete_action(int vid)
{
return do_snapshot_action(vid, "SNAP_DELETE");
};
/* ************************************************************************** */
/* MAD Loading */
/* ************************************************************************** */

View File

@ -136,7 +136,7 @@ void TransferManagerDriver::protocol(const string& message) const
case VirtualMachine::HOTPLUG_SAVEAS:
case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF:
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
lcm_action = LifeCycleManager::SAVEAS_HOT_SUCCESS;
lcm_action = LifeCycleManager::SAVEAS_SUCCESS;
break;
case VirtualMachine::HOTPLUG_PROLOG_POWEROFF:
@ -147,6 +147,12 @@ void TransferManagerDriver::protocol(const string& message) const
lcm_action = LifeCycleManager::DETACH_SUCCESS;
break;
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF:
lcm_action = LifeCycleManager::DISK_SNAPSHOT_SUCCESS;
break;
default:
goto error_state;
}
@ -191,7 +197,7 @@ void TransferManagerDriver::protocol(const string& message) const
case VirtualMachine::HOTPLUG_SAVEAS:
case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF:
case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED:
lcm_action = LifeCycleManager::SAVEAS_HOT_FAILURE;
lcm_action = LifeCycleManager::SAVEAS_FAILURE;
break;
case VirtualMachine::HOTPLUG_PROLOG_POWEROFF:
@ -202,6 +208,12 @@ void TransferManagerDriver::protocol(const string& message) const
lcm_action = LifeCycleManager::DETACH_FAILURE;
break;
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_REVERT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF:
lcm_action = LifeCycleManager::DISK_SNAPSHOT_FAILURE;
break;
default:
goto error_state;
}

View File

@ -16,16 +16,18 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
# mvds host:remote_system_ds/disk.i fe:SOURCE
# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid
# - fe is the front-end hostname
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
# - host is the target host to deploy the VM
# - remote_system_ds is the path for the system datastore in the host
# - snapid is the snapshot id. "-1" for none
SRC=$1
DST=$2
VM_ID=$3
DS_ID=$4
SNAP_ID=$3
VM_ID=$4
DS_ID=$5
if [ -z "${ONE_LOCATION}" ]; then
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
@ -43,13 +45,13 @@ source ${DRIVER_PATH}/../../datastore/ceph/ceph.conf
#-------------------------------------------------------------------------------
SRC_HOST=`arg_host $SRC`
SRC_PATH=`arg_path $SRC`
RBD_SRC=`arg_path $SRC`
#-------------------------------------------------------------------------------
# Get Image information
#-------------------------------------------------------------------------------
DISK_ID=$(echo "$SRC_PATH" | $AWK -F. '{print $NF}')
DISK_ID=$(echo "$RBD_SRC" | $AWK -F. '{print $NF}')
XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin"
@ -76,11 +78,14 @@ else
RBD_DST="${RBD_SRC}-${VM_ID}-${DISK_ID}"
fi
if [ "$SNAP_ID" != "-1" ]; then
RBD_DST="${RBD_DST}-${SNAP_ID}@${SNAP_ID}"
fi
if [ -n "$CEPH_USER" ]; then
RBD="$RBD --id ${CEPH_USER}"
fi
ssh_exec_and_log "$SRC_HOST" "$RBD copy $RBD_DST $DST" \
"Error cloning $RBD_DST to $DST in $SRC_HOST"

View File

@ -97,12 +97,45 @@ log "Deleting $DST_PATH"
# drivers, is executed in the worker node and not in the CEPH frontend.
DELETE_CMD=$(cat <<EOF
set -e
rm_children(){
local rbd_snap rbd snap_id child snap_list
rbd_snap=\$1
rbd=\${rbd_snap%%@*}
snap_list=\$(set +e; rbd snap ls \$rbd)
if [ -n "\$snap_list" ]; then
CHILDREN=\$(set +e; rbd children \$rbd_snap 2>/dev/null)
for child in \$CHILDREN; do
snap_id=\${child##*-}
child=\$child@\$snap_id
rm_children \$child
done
$RBD snap unprotect \$rbd_snap
$RBD snap rm \$rbd_snap
fi
$RBD rm \$rbd
}
RBD_FORMAT=\$($RBD info $RBD_SRC | sed -n 's/.*format: // p')
$RBD rm $RBD_SRC
if [ "\$RBD_FORMAT" = "2" ]; then
has_snap_shots=\$($RBD info $RBD_SRC-0@0 2>/dev/null)
if [ -n "\$has_snap_shots" ]; then
rm_children $RBD_SRC-0@0
else
$RBD rm $RBD_SRC
fi
else
$RBD rm $RBD_SRC
fi
# Remove the snapshot of the original image used to create a CLONE
if [ "\$RBD_FORMAT" = "2" ]; then
$RBD snap unprotect $SRC@$RBD_SNAP
$RBD snap rm $SRC@$RBD_SNAP

1
src/tm_mad/ceph/failmigrate Symbolic link
View File

@ -0,0 +1 @@
../common/failmigrate

View File

@ -16,91 +16,4 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
# mvds host:remote_system_ds/disk.i fe:SOURCE
# - fe is the front-end hostname
# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk
# - host is the target host to deploy the VM
# - remote_system_ds is the path for the system datastore in the host
SRC=$1
DST=$2
VM_ID=$3
DS_ID=$4
if [ -z "${ONE_LOCATION}" ]; then
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
else
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
fi
DRIVER_PATH=$(dirname $0)
source $TMCOMMON
source ${DRIVER_PATH}/../../datastore/ceph/ceph.conf
#-------------------------------------------------------------------------------
# Set dst path and dir
#-------------------------------------------------------------------------------
SRC_HOST=`arg_host $SRC`
SRC_PATH=`arg_path $SRC`
#-------------------------------------------------------------------------------
# Get Image information
#-------------------------------------------------------------------------------
DISK_ID=$(echo "$SRC_PATH" | $AWK -F. '{print $NF}')
XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin"
unset i j XPATH_ELEMENTS
while IFS= read -r -d '' element; do
XPATH_ELEMENTS[i++]="$element"
done < <(onevm show -x $VM_ID| $XPATH \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SOURCE \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER)
RBD_SRC="${XPATH_ELEMENTS[j++]}"
CLONE="${XPATH_ELEMENTS[j++]}"
CEPH_USER="${XPATH_ELEMENTS[j++]}"
# No need to copy back to datastore no cloned images
if [ "$CLONE" = "NO" ]; then
exit 0
fi
if [ -n "$CEPH_USER" ]; then
RBD="$RBD --id ${CEPH_USER}"
fi
# cloned, so the name will be "<pool>/one-<imageid>-<vmid>-<diskid>"
RBD_DST="${RBD_SRC}-${VM_ID}-${DISK_ID}"
RBD_SNAP="${VM_ID}-${DISK_ID}"
#-------------------------------------------------------------------------------
# Move the image back to the datastore
#-------------------------------------------------------------------------------
log "Dumping $RBD_DST to $DST"
DUMP_CMD=$(cat <<EOF
set -e
RBD_FORMAT=\$($RBD info $RBD_DST | sed -n 's/.*format: // p')
if [ "\${RBD_FORMAT}" = "2" ]; then
$RBD flatten $RBD_DST
$RBD snap unprotect $RBD_SRC@$RBD_SNAP
$RBD snap rm $RBD_SRC@$RBD_SNAP
fi
$RBD rename $RBD_DST $DST
EOF
)
ssh_exec_and_log "$SRC_HOST" "$DUMP_CMD" \
"Error saving $RBD_DST as $DST in $SRC_HOST"
exit 0

99
src/tm_mad/ceph/snap_create Executable file
View File

@ -0,0 +1,99 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2015, 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. #
#--------------------------------------------------------------------------- #
# snap_create host:parent_image snap_id vmid ds_id
SRC=$1
SNAP_ID=$2
VM_ID=$3
DS_ID=$4
if [ -z "${ONE_LOCATION}" ]; then
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
else
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
fi
DRIVER_PATH=$(dirname $0)
source $TMCOMMON
source ${DRIVER_PATH}/../../datastore/ceph/ceph.conf
#-------------------------------------------------------------------------------
# Set dst path and dir
#-------------------------------------------------------------------------------
SRC_HOST=`arg_host $SRC`
SRC_PATH=`arg_path $SRC`
#-------------------------------------------------------------------------------
# Get Image information
#-------------------------------------------------------------------------------
DISK_ID=$(echo "$SRC_PATH" | $AWK -F. '{print $NF}')
XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin"
unset i j XPATH_ELEMENTS
while IFS= read -r -d '' element; do
XPATH_ELEMENTS[i++]="$element"
done < <(onevm show -x $VM_ID| $XPATH \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SOURCE \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER)
RBD_SRC="${XPATH_ELEMENTS[j++]}"
CLONE="${XPATH_ELEMENTS[j++]}"
CEPH_USER="${XPATH_ELEMENTS[j++]}"
if [ "$CLONE" = "NO" ]; then
RBD_DST="${RBD_SRC}"
else
RBD_DST="${RBD_SRC}-${VM_ID}-${DISK_ID}"
fi
#-------------------------------------------------------------------------------
# Create snapshots
#-------------------------------------------------------------------------------
if [ -n "$CEPH_USER" ]; then
RBD="$RBD --id ${CEPH_USER}"
fi
SNAP_CREATE_CMD=$(cat <<EOF
set -e
RBD_FORMAT=\$($RBD info $RBD_SRC | sed -n 's/.*format: // p')
if [ "\${RBD_FORMAT}" != "2" ]; then
echo "Only RBD Format 2 is supported for this operation" >&2
exit 1
fi
$RBD snap create $RBD_DST@$SNAP_ID
$RBD snap protect $RBD_DST@$SNAP_ID
$RBD rename $RBD_DST $RBD_DST-$SNAP_ID
$RBD clone $RBD_DST-$SNAP_ID@$SNAP_ID $RBD_DST
EOF
)
ssh_exec_and_log "$SRC_HOST" "$SNAP_CREATE_CMD" \
"Error creating snapshot $RBD_DST@$SNAP_ID"
exit 0

98
src/tm_mad/ceph/snap_delete Executable file
View File

@ -0,0 +1,98 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2015, 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. #
#--------------------------------------------------------------------------- #
# snap_delete host:parent_image snap_id vmid ds_id
SRC=$1
SNAP_ID=$2
VM_ID=$3
DS_ID=$4
if [ -z "${ONE_LOCATION}" ]; then
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
else
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
fi
DRIVER_PATH=$(dirname $0)
source $TMCOMMON
source ${DRIVER_PATH}/../../datastore/ceph/ceph.conf
#-------------------------------------------------------------------------------
# Set dst path and dir
#-------------------------------------------------------------------------------
SRC_HOST=`arg_host $SRC`
SRC_PATH=`arg_path $SRC`
#-------------------------------------------------------------------------------
# Get Image information
#-------------------------------------------------------------------------------
DISK_ID=$(echo "$SRC_PATH" | $AWK -F. '{print $NF}')
XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin"
unset i j XPATH_ELEMENTS
while IFS= read -r -d '' element; do
XPATH_ELEMENTS[i++]="$element"
done < <(onevm show -x $VM_ID| $XPATH \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SOURCE \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER)
RBD_SRC="${XPATH_ELEMENTS[j++]}"
CLONE="${XPATH_ELEMENTS[j++]}"
CEPH_USER="${XPATH_ELEMENTS[j++]}"
if [ "$CLONE" = "NO" ]; then
RBD_DST="${RBD_SRC}"
else
RBD_DST="${RBD_SRC}-${VM_ID}-${DISK_ID}"
fi
#-------------------------------------------------------------------------------
# Delete snapshots
#-------------------------------------------------------------------------------
if [ -n "$CEPH_USER" ]; then
RBD="$RBD --id ${CEPH_USER}"
fi
SNAP_DELETE_CMD=$(cat <<EOF
set -e
RBD_FORMAT=\$($RBD info $RBD_SRC | sed -n 's/.*format: // p')
if [ "\${RBD_FORMAT}" != "2" ]; then
echo "Only RBD Format 2 is supported for this operation" >&2
exit 1
fi
$RBD snap unprotect $RBD_DST-$SNAP_ID@$SNAP_ID
$RBD snap rm $RBD_DST-$SNAP_ID@$SNAP_ID
$RBD rm $RBD_DST-$SNAP_ID
EOF
)
ssh_exec_and_log "$SRC_HOST" "$SNAP_DELETE_CMD" \
"Error deleting snapshot $RBD_DST-$SNAP_ID@$SNAP_ID"
exit 0

97
src/tm_mad/ceph/snap_revert Executable file
View File

@ -0,0 +1,97 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2015, 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. #
#--------------------------------------------------------------------------- #
# snap_revert host:parent_image snap_id vmid ds_id
SRC=$1
SNAP_ID=$2
VM_ID=$3
DS_ID=$4
if [ -z "${ONE_LOCATION}" ]; then
TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh
else
TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh
fi
DRIVER_PATH=$(dirname $0)
source $TMCOMMON
source ${DRIVER_PATH}/../../datastore/ceph/ceph.conf
#-------------------------------------------------------------------------------
# Set dst path and dir
#-------------------------------------------------------------------------------
SRC_HOST=`arg_host $SRC`
SRC_PATH=`arg_path $SRC`
#-------------------------------------------------------------------------------
# Get Image information
#-------------------------------------------------------------------------------
DISK_ID=$(echo "$SRC_PATH" | $AWK -F. '{print $NF}')
XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin"
unset i j XPATH_ELEMENTS
while IFS= read -r -d '' element; do
XPATH_ELEMENTS[i++]="$element"
done < <(onevm show -x $VM_ID| $XPATH \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SOURCE \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \
/VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER)
RBD_SRC="${XPATH_ELEMENTS[j++]}"
CLONE="${XPATH_ELEMENTS[j++]}"
CEPH_USER="${XPATH_ELEMENTS[j++]}"
if [ "$CLONE" = "NO" ]; then
RBD_DST="${RBD_SRC}"
else
RBD_DST="${RBD_SRC}-${VM_ID}-${DISK_ID}"
fi
#-------------------------------------------------------------------------------
# Create snapshots
#-------------------------------------------------------------------------------
if [ -n "$CEPH_USER" ]; then
RBD="$RBD --id ${CEPH_USER}"
fi
SNAP_REVERT_CMD=$(cat <<EOF
set -e
RBD_FORMAT=\$($RBD info $RBD_SRC | sed -n 's/.*format: // p')
if [ "\${RBD_FORMAT}" != "2" ]; then
echo "Only RBD Format 2 is supported for this operation" >&2
exit 1
fi
$RBD rm $RBD_DST
$RBD clone $RBD_DST-$SNAP_ID@$SNAP_ID $RBD_DST
EOF
)
ssh_exec_and_log "$SRC_HOST" "$SNAP_REVERT_CMD" \
"Error reverting snapshot $RBD_DST-$SNAP_ID@$SNAP_ID"
exit 0

29
src/tm_mad/common/failmigrate Executable file
View File

@ -0,0 +1,29 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2015, 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. #
#--------------------------------------------------------------------------- #
# FAILMIGRATE SOURCE DST remote_system_dir vmid dsid template
# - SOURCE is the host where the VM is running
# - DST is the host where the VM failed to be migrated
# - remote_system_dir is the path for the VM home in the system datastore
# - vmid is the id of the VM
# - dsid is the target datastore
# - template is the template of the VM in XML and base64 encoded
# To access the vm_template you can use the xpath.rb utility. Check the
# datastore drivers for an example.
exit 0

1
src/tm_mad/dev/failmigrate Symbolic link
View File

@ -0,0 +1 @@
../common/failmigrate

1
src/tm_mad/dev/snap_create Symbolic link
View File

@ -0,0 +1 @@
../common/not_supported.sh

Some files were not shown because too many files have changed in this diff Show More