mirror of
https://github.com/OpenNebula/one.git
synced 2025-02-18 17:57:24 +03:00
Merge branch 'master' into bug-4349
This commit is contained in:
commit
51aff13b6e
@ -261,17 +261,16 @@ private:
|
||||
* @return true if any rule grants permission
|
||||
*/
|
||||
bool match_rules(
|
||||
long long user_req,
|
||||
long long resource_oid_req,
|
||||
long long resource_gid_req,
|
||||
long long resource_cid_req,
|
||||
long long resource_all_req,
|
||||
long long rights_req,
|
||||
long long individual_obj_type,
|
||||
long long group_obj_type,
|
||||
long long cluster_obj_type,
|
||||
multimap<long long, AclRule*> &rules);
|
||||
|
||||
long long user_req,
|
||||
long long resource_oid_req,
|
||||
long long resource_gid_req,
|
||||
const set<long long>& resource_cid_req,
|
||||
long long resource_all_req,
|
||||
long long rights_req,
|
||||
long long resource_oid_mask,
|
||||
long long resource_gid_mask,
|
||||
long long resource_cid_mask,
|
||||
const multimap<long long, AclRule*>& rules);
|
||||
/**
|
||||
* Wrapper for match_rules. It will check if any rules in the temporary
|
||||
* multimap or in the internal one grants permission.
|
||||
@ -290,17 +289,16 @@ private:
|
||||
* @return true if any rule grants permission
|
||||
*/
|
||||
bool match_rules_wrapper(
|
||||
long long user_req,
|
||||
long long resource_oid_req,
|
||||
long long resource_gid_req,
|
||||
long long resource_cid_req,
|
||||
long long resource_all_req,
|
||||
long long rights_req,
|
||||
long long individual_obj_type,
|
||||
long long group_obj_type,
|
||||
long long cluster_obj_type,
|
||||
multimap<long long, AclRule*> &tmp_rules);
|
||||
|
||||
long long user_req,
|
||||
long long resource_oid_req,
|
||||
long long resource_gid_req,
|
||||
const set<long long>& resource_cid_req,
|
||||
long long resource_all_req,
|
||||
long long rights_req,
|
||||
long long individual_obj_type,
|
||||
long long group_obj_type,
|
||||
long long cluster_obj_type,
|
||||
const multimap<long long, AclRule*> &tmp_rules);
|
||||
/**
|
||||
* Deletes all rules that match the user mask
|
||||
*
|
||||
|
@ -42,7 +42,12 @@ public:
|
||||
/* Set the action in the set */
|
||||
void set(T action)
|
||||
{
|
||||
action_set += 1 << static_cast<int>(action);
|
||||
action_set |= 1 << static_cast<int>(action);
|
||||
};
|
||||
|
||||
void clear(T action)
|
||||
{
|
||||
action_set &= (~ (1 << static_cast<int>(action)));
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "NebulaUtil.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
@ -163,8 +165,8 @@ public:
|
||||
{
|
||||
string * xml = new string;
|
||||
|
||||
*xml = "<" + name() + "><![CDATA[" + attribute_value
|
||||
+ "]]></"+ name() + ">";
|
||||
*xml = "<" + name() + ">" + one_util::escape_xml(attribute_value) +
|
||||
"</"+ name() + ">";
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <xmlrpc-c/base.hpp>
|
||||
#include <xmlrpc-c/client_simple.hpp>
|
||||
#include <xmlrpc-c/girerr.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@ -34,19 +35,67 @@ using namespace std;
|
||||
// http://xmlrpc-c.sourceforge.net/doc/libxmlrpc_client++.html#simple_client
|
||||
// =============================================================================
|
||||
|
||||
//TODO add documentation to the Client methods...
|
||||
|
||||
/**
|
||||
* This class represents the connection with the core and handles the
|
||||
* xml-rpc calls.
|
||||
*/
|
||||
class Client : public xmlrpc_c::clientSimple
|
||||
class Client
|
||||
{
|
||||
public:
|
||||
//--------------------------------------------------------------------------
|
||||
// PUBLIC INTERFACE
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
* Singleton accessor
|
||||
*/
|
||||
static Client * client()
|
||||
{
|
||||
return _client;
|
||||
};
|
||||
|
||||
/**
|
||||
* Singleton initializer
|
||||
*/
|
||||
static Client * initialize(const std::string& secret,
|
||||
const std::string& endpoint, size_t message_size, unsigned int tout)
|
||||
{
|
||||
if ( _client == 0 )
|
||||
{
|
||||
_client = new Client(secret, endpoint, message_size, tout);
|
||||
}
|
||||
|
||||
return _client;
|
||||
};
|
||||
|
||||
size_t get_message_size() const
|
||||
{
|
||||
return xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID);
|
||||
};
|
||||
|
||||
/**
|
||||
* Reads ONE_AUTH from environment or its default location at
|
||||
* $HOME/.one/one_auth
|
||||
*/
|
||||
static int read_oneauth(std::string &secret, std::string& error);
|
||||
|
||||
/**
|
||||
* Performs an xmlrpc call to the initialized server and credentials.
|
||||
* This method automatically adds the credential argument.
|
||||
* @param method name
|
||||
* @param format of the arguments, supported arguments are i:int, s:string
|
||||
* and b:bool
|
||||
* @param result to store the xmlrpc call result
|
||||
* @param ... xmlrpc arguments
|
||||
*/
|
||||
void call(const std::string &method, const std::string format,
|
||||
xmlrpc_c::value * const result, ...);
|
||||
|
||||
/**
|
||||
* Performs a xmlrpc call to the initialized server
|
||||
* @param method name
|
||||
* @param plist initialized param list
|
||||
* @param result of the xmlrpc call
|
||||
*/
|
||||
void call(const std::string& method, const xmlrpc_c::paramList& plist,
|
||||
xmlrpc_c::value * const result);
|
||||
private:
|
||||
/**
|
||||
* Creates a new xml-rpc client with specified options.
|
||||
*
|
||||
@ -58,42 +107,15 @@ public:
|
||||
* @param message_size for XML elements in the client library (in bytes)
|
||||
* @throws Exception if the authorization options are invalid
|
||||
*/
|
||||
Client(const string& secret, const string& endpoint, size_t message_size)
|
||||
{
|
||||
set_one_auth(secret);
|
||||
set_one_endpoint(endpoint);
|
||||
Client(const string& secret, const string& endpoint, size_t message_size,
|
||||
unsigned int tout);
|
||||
|
||||
xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, message_size);
|
||||
}
|
||||
|
||||
const string& get_oneauth()
|
||||
{
|
||||
return one_auth;
|
||||
}
|
||||
|
||||
const string& get_endpoint()
|
||||
{
|
||||
return one_endpoint;
|
||||
}
|
||||
|
||||
size_t get_message_size()
|
||||
{
|
||||
return xmlrpc_limit_get(XMLRPC_XML_SIZE_LIMIT_ID);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// PRIVATE ATTRIBUTES AND METHODS
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
string one_auth;
|
||||
string one_endpoint;
|
||||
|
||||
void set_one_auth(string secret);
|
||||
unsigned int timeout;
|
||||
|
||||
void set_one_endpoint(string endpoint);
|
||||
|
||||
void read_oneauth(string &secret);
|
||||
static Client * _client;
|
||||
};
|
||||
|
||||
#endif /*ONECLIENT_H_*/
|
||||
|
@ -30,15 +30,6 @@ using namespace std;
|
||||
class Cluster : public PoolObjectSQL
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Returns the DATASTORE_LOCATION for the hosts of the cluster. If not
|
||||
* defined that in oned.conf is returned.
|
||||
*
|
||||
* @param ds_location string to copy the DATASTORE_LOCATION to
|
||||
* @return DATASTORE_LOCATION
|
||||
*/
|
||||
string& get_ds_location(string &ds_location);
|
||||
|
||||
// *************************************************************************
|
||||
// Object Collections (Public)
|
||||
// *************************************************************************
|
||||
@ -82,11 +73,10 @@ public:
|
||||
/**
|
||||
* Adds this datastore ID to the set.
|
||||
* @param id to be added to the cluster
|
||||
* @param ds_type Datastore type
|
||||
* @param error_msg Error message, if any
|
||||
* @return 0 on success
|
||||
*/
|
||||
int add_datastore(int id, Datastore::DatastoreType ds_type, string& error_msg);
|
||||
int add_datastore(int id, string& error_msg);
|
||||
|
||||
/**
|
||||
* Deletes this datastore ID from the set.
|
||||
@ -213,7 +203,6 @@ private:
|
||||
// *************************************************************************
|
||||
// Constructor
|
||||
// *************************************************************************
|
||||
|
||||
Cluster(int id,
|
||||
const string& name,
|
||||
ClusterTemplate* cl_template);
|
||||
@ -223,7 +212,6 @@ private:
|
||||
// *************************************************************************
|
||||
// Attributes (Private)
|
||||
// *************************************************************************
|
||||
|
||||
ObjectCollection hosts;
|
||||
ObjectCollection datastores;
|
||||
ObjectCollection vnets;
|
||||
@ -231,13 +219,18 @@ private:
|
||||
// *************************************************************************
|
||||
// DataBase implementation (Private)
|
||||
// *************************************************************************
|
||||
|
||||
static const char * db_names;
|
||||
|
||||
static const char * db_bootstrap;
|
||||
|
||||
static const char * table;
|
||||
|
||||
static const char * datastore_table;
|
||||
static const char * datastore_db_names;
|
||||
static const char * datastore_db_bootstrap;
|
||||
|
||||
static const char * network_table;
|
||||
static const char * network_db_names;
|
||||
static const char * network_db_bootstrap;
|
||||
|
||||
/**
|
||||
* Execute an INSERT or REPLACE Sql query.
|
||||
* @param db The SQL DB
|
||||
@ -253,9 +246,19 @@ private:
|
||||
*/
|
||||
static int bootstrap(SqlDB * db)
|
||||
{
|
||||
ostringstream oss(Cluster::db_bootstrap);
|
||||
int rc;
|
||||
ostringstream oss;
|
||||
|
||||
return db->exec(oss);
|
||||
oss.str(Cluster::db_bootstrap);
|
||||
rc = db->exec(oss);
|
||||
|
||||
oss.str(Cluster::datastore_db_bootstrap);
|
||||
rc += db->exec(oss);
|
||||
|
||||
oss.str(Cluster::network_db_bootstrap);
|
||||
rc += db->exec(oss);
|
||||
|
||||
return rc;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,16 @@ public:
|
||||
*/
|
||||
static const int NONE_CLUSTER_ID;
|
||||
|
||||
/**
|
||||
* Name for the default cluster
|
||||
*/
|
||||
static const string DEFAULT_CLUSTER_NAME;
|
||||
|
||||
/**
|
||||
* Identifier for the default cluster
|
||||
*/
|
||||
static const int DEFAULT_CLUSTER_ID;
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Methods for DB management */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
@ -136,8 +146,16 @@ public:
|
||||
limit);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates the cluster part of the ACL filter to look for objects. This
|
||||
* filter is generated for objects that can be part of a cluster
|
||||
* @param acl_filter stream to write the filter
|
||||
* @param auth_object to generate the filter for
|
||||
* @param cids vector of cluster ids
|
||||
*/
|
||||
static void cluster_acl_filter(ostringstream& filter,
|
||||
PoolObjectSQL::ObjectType auth_object, const vector<int>& cids);
|
||||
private:
|
||||
|
||||
/**
|
||||
* Factory method to produce objects
|
||||
* @return a pointer to the new object
|
||||
|
@ -17,62 +17,66 @@
|
||||
#ifndef CLUSTERABLE_H_
|
||||
#define CLUSTERABLE_H_
|
||||
|
||||
using namespace std;
|
||||
#include "ObjectCollection.h"
|
||||
|
||||
class Clusterable
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Changes the cluster this object belongs to
|
||||
*
|
||||
* @param _cluster_id Id of the new cluster
|
||||
* @param _cluster Name of the new cluster
|
||||
*/
|
||||
void set_cluster(int _cluster_id, const string& _cluster)
|
||||
int add_cluster(int cluster_id)
|
||||
{
|
||||
cluster_id = _cluster_id;
|
||||
cluster = _cluster;
|
||||
return cluster_ids.add(cluster_id);
|
||||
};
|
||||
|
||||
int del_cluster(int cluster_id)
|
||||
{
|
||||
return cluster_ids.del(cluster_id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the cluster ID
|
||||
* Returns the cluster IDs
|
||||
*
|
||||
* @return The cluster ID
|
||||
* @return The cluster IDs set
|
||||
*/
|
||||
int get_cluster_id() const
|
||||
std::set<int> get_cluster_ids() const
|
||||
{
|
||||
return cluster_id;
|
||||
return cluster_ids.clone();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the cluster name
|
||||
* Rebuilds the cluster collection from an xml object
|
||||
* @param xml xml object
|
||||
* @param xpath_prefix Parent nodes, e.g. "/DATASTORE/"
|
||||
*
|
||||
* @return The cluster name
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
const string& get_cluster_name() const
|
||||
int from_xml(const ObjectXML* xml, const std::string& xpath_prefix)
|
||||
{
|
||||
return cluster;
|
||||
return cluster_ids.from_xml(xml, xpath_prefix);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to print the cluster IDs into a string in
|
||||
* XML format
|
||||
* @param xml the resulting XML string
|
||||
* @return a reference to the generated string
|
||||
*/
|
||||
std::string& to_xml(std::string& xml) const
|
||||
{
|
||||
return cluster_ids.to_xml(xml);
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
Clusterable(int _cluster_id, const string& _cluster):
|
||||
cluster_id(_cluster_id),
|
||||
cluster(_cluster){};
|
||||
Clusterable(const std::set<int> &_cluster_ids):
|
||||
cluster_ids("CLUSTERS", _cluster_ids){};
|
||||
|
||||
~Clusterable(){};
|
||||
|
||||
/**
|
||||
* ID of the cluster this object belongs to.
|
||||
* IDs of the clusters this object belongs to.
|
||||
*/
|
||||
int cluster_id;
|
||||
|
||||
/**
|
||||
* Name of the cluster this object belongs to.
|
||||
*/
|
||||
string cluster;
|
||||
ObjectCollection cluster_ids;
|
||||
};
|
||||
|
||||
#endif /*CLUSTERABLE_H_*/
|
||||
|
76
include/ClusterableSingle.h
Normal file
76
include/ClusterableSingle.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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 CLUSTERABLE_SINGLE_H_
|
||||
#define CLUSTERABLE_SINGLE_H_
|
||||
|
||||
class ClusterableSingle
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Changes the cluster this object belongs to
|
||||
*
|
||||
* @param _cluster_id Id of the new cluster
|
||||
* @param _cluster Name of the new cluster
|
||||
*/
|
||||
void set_cluster(int _cluster_id, const std::string& _cluster)
|
||||
{
|
||||
cluster_id = _cluster_id;
|
||||
cluster = _cluster;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the cluster ID
|
||||
*
|
||||
* @return The cluster ID
|
||||
*/
|
||||
int get_cluster_id() const
|
||||
{
|
||||
return cluster_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the cluster name
|
||||
*
|
||||
* @return The cluster name
|
||||
*/
|
||||
const std::string& get_cluster_name() const
|
||||
{
|
||||
return cluster;
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
ClusterableSingle(int _cluster_id, const std::string& _cluster):
|
||||
cluster_id(_cluster_id),
|
||||
cluster(_cluster){};
|
||||
|
||||
~ClusterableSingle(){};
|
||||
|
||||
/**
|
||||
* ID of the cluster this object belongs to.
|
||||
*/
|
||||
int cluster_id;
|
||||
|
||||
/**
|
||||
* Name of the cluster this object belongs to.
|
||||
*/
|
||||
std::string cluster;
|
||||
};
|
||||
|
||||
#endif /*CLUSTERABLE_SINGLE_H_*/
|
@ -319,8 +319,7 @@ private:
|
||||
const string& gname,
|
||||
int umask,
|
||||
DatastoreTemplate* ds_template,
|
||||
int cluster_id,
|
||||
const string& cluster_name);
|
||||
const set<int> &cluster_ids);
|
||||
|
||||
virtual ~Datastore();
|
||||
|
||||
|
@ -78,8 +78,7 @@ public:
|
||||
* @param umask permissions umask
|
||||
* @param ds_template Datastore definition template
|
||||
* @param oid the id assigned to the Datastore
|
||||
* @param cluster_id the id of the cluster this Datastore will belong to
|
||||
* @param cluster_name the name of the cluster this Datastore will belong to
|
||||
* @param cluster_ids the ids of the clusters this Datastore will belong to
|
||||
* @param error_str Returns the error reason, if any
|
||||
*
|
||||
* @return the oid assigned to the object, -1 in case of failure
|
||||
@ -92,8 +91,7 @@ public:
|
||||
int umask,
|
||||
DatastoreTemplate * ds_template,
|
||||
int * oid,
|
||||
int cluster_id,
|
||||
const string& cluster_name,
|
||||
const set<int> &cluster_ids,
|
||||
string& error_str);
|
||||
|
||||
/**
|
||||
@ -201,7 +199,9 @@ private:
|
||||
*/
|
||||
PoolObjectSQL * create()
|
||||
{
|
||||
return new Datastore(-1,-1,"","", 0, 0, -1, "");
|
||||
set<int> empty;
|
||||
|
||||
return new Datastore(-1,-1,"","", 0, 0, empty);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "PoolSQL.h"
|
||||
#include "HostTemplate.h"
|
||||
#include "HostShare.h"
|
||||
#include "Clusterable.h"
|
||||
#include "ClusterableSingle.h"
|
||||
#include "ObjectCollection.h"
|
||||
#include "NebulaLog.h"
|
||||
#include "NebulaUtil.h"
|
||||
@ -30,7 +30,7 @@ using namespace std;
|
||||
/**
|
||||
* The Host class.
|
||||
*/
|
||||
class Host : public PoolObjectSQL, public Clusterable
|
||||
class Host : public PoolObjectSQL, public ClusterableSingle
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -322,9 +322,20 @@ public:
|
||||
return cloning_ops;
|
||||
}
|
||||
|
||||
int dec_cloning(int img_id)
|
||||
int dec_cloning(PoolObjectSQL::ObjectType ot, int oid)
|
||||
{
|
||||
if ( img_clone_collection.del(img_id) == 0 )
|
||||
int rc = -1;
|
||||
|
||||
if (ot == PoolObjectSQL::IMAGE)
|
||||
{
|
||||
rc = img_clone_collection.del(oid);
|
||||
}
|
||||
else //if (ot == PoolObjectSQL::MARKETPLACEAPP)
|
||||
{
|
||||
rc = app_clone_collection.del(oid);
|
||||
}
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
cloning_ops--;
|
||||
}
|
||||
@ -332,9 +343,20 @@ public:
|
||||
return cloning_ops;
|
||||
}
|
||||
|
||||
int inc_cloning(int img_id)
|
||||
int inc_cloning(PoolObjectSQL::ObjectType ot, int oid)
|
||||
{
|
||||
if ( img_clone_collection.add(img_id) == 0 )
|
||||
int rc = -1;
|
||||
|
||||
if (ot == PoolObjectSQL::IMAGE)
|
||||
{
|
||||
rc = img_clone_collection.add(oid);
|
||||
}
|
||||
else //if (ot == PoolObjectSQL::MARKETPLACEAPP)
|
||||
{
|
||||
rc = app_clone_collection.add(oid);
|
||||
}
|
||||
|
||||
if ( rc == 0 )
|
||||
{
|
||||
cloning_ops++;
|
||||
}
|
||||
@ -581,7 +603,7 @@ private:
|
||||
int running_vms;
|
||||
|
||||
/**
|
||||
* Number of pending cloning operations
|
||||
* Number of pending cloning operations, for both images and apps
|
||||
*/
|
||||
int cloning_ops;
|
||||
|
||||
@ -611,6 +633,11 @@ private:
|
||||
*/
|
||||
ObjectCollection img_clone_collection;
|
||||
|
||||
/**
|
||||
* Stores a collection with the Marketplace apps cloning this image
|
||||
*/
|
||||
ObjectCollection app_clone_collection;
|
||||
|
||||
/**
|
||||
* Snapshot list for this image
|
||||
*/
|
||||
|
@ -116,9 +116,30 @@ public:
|
||||
/**
|
||||
* Closes any cloning operation on the image, updating the state if needed
|
||||
* @param iid image id of the image to that was being cloned
|
||||
* @param clone_img_id the cloned image (id > 0) or market app (id =< 0)
|
||||
* @param ot Object type, image or market app
|
||||
* @param clone_oid the cloned resource id
|
||||
*/
|
||||
void release_cloning_image(int iid, int clone_img_id);
|
||||
void release_cloning_resource(int iid, PoolObjectSQL::ObjectType ot, int clone_oid);
|
||||
|
||||
/**
|
||||
* Closes any cloning operation on the image, updating the state if needed
|
||||
* @param iid image id of the image to that was being cloned
|
||||
* @param clone_img_id the cloned image id
|
||||
*/
|
||||
void release_cloning_image(int iid, int clone_img_id)
|
||||
{
|
||||
release_cloning_resource(iid, PoolObjectSQL::IMAGE, clone_img_id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes any cloning operation on the image, updating the state if needed
|
||||
* @param iid image id of the image to that was being cloned
|
||||
* @param clone_oid the cloned marketplace app id
|
||||
*/
|
||||
void release_cloning_app(int iid, int clone_oid)
|
||||
{
|
||||
release_cloning_resource(iid, PoolObjectSQL::MARKETPLACEAPP, clone_oid);
|
||||
};
|
||||
|
||||
/**
|
||||
* Enables the image
|
||||
@ -155,12 +176,38 @@ public:
|
||||
|
||||
/**
|
||||
* Sets the state to CLONE for the given image
|
||||
* @param new_id for the target image (new_id>0) or market app (new_id =<0)
|
||||
* @param ot Object type, image or market app
|
||||
* @param new_id for the target image or market app
|
||||
* @param clonning_id the ID of the image to be cloned
|
||||
* @param error if any
|
||||
* @return 0 if siccess
|
||||
* @return 0 on success
|
||||
*/
|
||||
int set_clone_state(int new_id, int cloning_id, std::string& error);
|
||||
int set_clone_state(PoolObjectSQL::ObjectType ot, int new_id,
|
||||
int cloning_id, std::string& error);
|
||||
|
||||
/**
|
||||
* Sets the state to CLONE for the given image
|
||||
* @param new_id for the target image
|
||||
* @param clonning_id the ID of the image to be cloned
|
||||
* @param error if any
|
||||
* @return 0 on success
|
||||
*/
|
||||
int set_img_clone_state(int new_id, int cloning_id, std::string& error)
|
||||
{
|
||||
return set_clone_state(PoolObjectSQL::IMAGE, new_id, cloning_id, error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the state to CLONE for the given image
|
||||
* @param new_id for the target market app
|
||||
* @param clonning_id the ID of the image to be cloned
|
||||
* @param error if any
|
||||
* @return 0 on success
|
||||
*/
|
||||
int set_app_clone_state(int new_id, int cloning_id, std::string& error)
|
||||
{
|
||||
return set_clone_state(PoolObjectSQL::MARKETPLACEAPP, new_id, cloning_id, error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clone an existing image to the repository
|
||||
|
@ -147,7 +147,11 @@ private:
|
||||
class StdLog : public Log
|
||||
{
|
||||
public:
|
||||
StdLog(const MessageType level = WARNING):Log(level){};
|
||||
StdLog(const MessageType level):Log(level){};
|
||||
|
||||
StdLog(const MessageType level,
|
||||
int oid,
|
||||
const PoolObjectSQL::ObjectType obj_type);
|
||||
|
||||
~StdLog(){};
|
||||
|
||||
@ -155,6 +159,9 @@ public:
|
||||
const char * module,
|
||||
const MessageType type,
|
||||
const char * message);
|
||||
|
||||
private:
|
||||
string resource_label;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -82,6 +82,14 @@ public:
|
||||
return market_mad;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get zone for this market
|
||||
* @return zone id
|
||||
*/
|
||||
int get_zone_id() const
|
||||
{
|
||||
return zone_id;
|
||||
};
|
||||
/**
|
||||
* Set monitor information for the MarketPlace
|
||||
* @param data template with monitor information
|
||||
@ -98,8 +106,31 @@ public:
|
||||
return supported_actions.is_set(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this is a public (external) marketplace
|
||||
*/
|
||||
bool is_public() const;
|
||||
|
||||
/**
|
||||
* Disbale de monitor action for this marketplace
|
||||
* @return true if the monitor was enabled
|
||||
*/
|
||||
bool disable_monitor()
|
||||
{
|
||||
bool enabled = supported_actions.is_set(MarketPlaceApp::MONITOR);
|
||||
|
||||
supported_actions.clear(MarketPlaceApp::MONITOR);
|
||||
|
||||
return enabled;
|
||||
}
|
||||
/**
|
||||
* Enable the monitor action
|
||||
*/
|
||||
void enable_monitor()
|
||||
{
|
||||
supported_actions.set(MarketPlaceApp::MONITOR);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
friend class MarketPlacePool;
|
||||
@ -127,6 +158,11 @@ private:
|
||||
*/
|
||||
long long used_mb;
|
||||
|
||||
/**
|
||||
* Zone where this market lives
|
||||
*/
|
||||
int zone_id;
|
||||
|
||||
/**
|
||||
* Supported actions on MarketPlaceApps
|
||||
*/
|
||||
@ -160,6 +196,14 @@ private:
|
||||
|
||||
static const char * table;
|
||||
|
||||
/**
|
||||
* Builds the marketplace from the template. This function MUST be called
|
||||
* with the template initialized
|
||||
* @param error_str describing the error
|
||||
* @return 0 on success;
|
||||
*/
|
||||
int parse_template(string& error_str);
|
||||
|
||||
/**
|
||||
* Execute an INSERT or REPLACE Sql query.
|
||||
* @param db The SQL DB
|
||||
|
@ -235,6 +235,11 @@ public:
|
||||
return state;
|
||||
}
|
||||
|
||||
int get_zone_id() const
|
||||
{
|
||||
return zone_id;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Set Marketplace app attributes
|
||||
//--------------------------------------------------------------------------
|
||||
@ -335,6 +340,11 @@ private:
|
||||
*/
|
||||
int origin_id;
|
||||
|
||||
/**
|
||||
* ID of the zone where this app lives
|
||||
*/
|
||||
int zone_id;
|
||||
|
||||
// *************************************************************************
|
||||
// Constructor
|
||||
// *************************************************************************
|
||||
@ -358,6 +368,14 @@ private:
|
||||
|
||||
static const char * table;
|
||||
|
||||
/**
|
||||
* Builds the market app from the template. This function MUST be called
|
||||
* with apptemplate initialized
|
||||
* @param error_str describing the error
|
||||
* @return 0 on success;
|
||||
*/
|
||||
int parse_template(string& error_str);
|
||||
|
||||
/**
|
||||
* Execute an INSERT or REPLACE Sql query.
|
||||
* @param db The SQL DB
|
||||
|
@ -45,7 +45,6 @@ public:
|
||||
* @param apptemplate MarketPlaceApp definition template
|
||||
* @param mp_id of the MarketPlace to store de App
|
||||
* @param mp_name of the MarketPlace
|
||||
* @param mp_data XML representation of the target MarketPlace
|
||||
* @param oid the id assigned to the MarketPlace
|
||||
* @param error_str Returns the error reason, if any
|
||||
*
|
||||
@ -60,7 +59,6 @@ public:
|
||||
MarketPlaceAppTemplate * apptemplate,
|
||||
int mp_id,
|
||||
const std::string& mp_name,
|
||||
const std::string& mp_data,
|
||||
int * oid,
|
||||
std::string& error_str);
|
||||
|
||||
@ -142,8 +140,6 @@ public:
|
||||
*/
|
||||
int update(PoolObjectSQL * objsql);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Factory method to produce objects
|
||||
* @return a pointer to the new object
|
||||
|
@ -148,8 +148,6 @@ public:
|
||||
return PoolSQL::list(oids, MarketPlace::table);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Factory method to produce objects
|
||||
* @return a pointer to the new object
|
||||
|
@ -281,7 +281,7 @@ public:
|
||||
*
|
||||
*
|
||||
*/
|
||||
int get_ds_location(int cluster_id, string& dsloc);
|
||||
void get_ds_location(string& dsloc);
|
||||
|
||||
/**
|
||||
* Returns the default vms location. When ONE_LOCATION is defined this path
|
||||
@ -338,7 +338,7 @@ public:
|
||||
*/
|
||||
static string shared_db_version()
|
||||
{
|
||||
return "4.11.80";
|
||||
return "4.90.0";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -347,7 +347,7 @@ public:
|
||||
*/
|
||||
static string local_db_version()
|
||||
{
|
||||
return "4.13.85";
|
||||
return "4.90.0";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
namespace one_util
|
||||
{
|
||||
@ -150,6 +151,19 @@ namespace one_util
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins the given element with the delimiter
|
||||
*
|
||||
* @param values set of values
|
||||
* @param delim delimiter character
|
||||
* @return the joined strings
|
||||
*/
|
||||
template <class T>
|
||||
std::string join(const std::set<T> values, char delim)
|
||||
{
|
||||
return join(values.begin(), values.end(), delim);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string from the given float, using fixed notation. If the
|
||||
* number has any decimals, they will be truncated to 2.
|
||||
@ -212,6 +226,18 @@ namespace one_util
|
||||
*/
|
||||
std::string gsub(const std::string& st, const std::string& sfind,
|
||||
const std::string& replacement);
|
||||
|
||||
template <class T>
|
||||
std::set<T> set_intersection(const std::set<T> &first, const std::set<T> &second)
|
||||
{
|
||||
std::set<T> output;
|
||||
|
||||
std::set_intersection(
|
||||
first.begin(), first.end(), second.begin(), second.end(),
|
||||
std::inserter(output, output.begin()));
|
||||
|
||||
return output;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _NEBULA_UTIL_H_ */
|
||||
|
@ -33,6 +33,9 @@ public:
|
||||
ObjectCollection(const string& _collection_name)
|
||||
:collection_name(_collection_name){};
|
||||
|
||||
ObjectCollection(const string& cname, const set<int>& cset)
|
||||
:collection_name(cname), collection_set(cset){};
|
||||
|
||||
~ObjectCollection(){};
|
||||
|
||||
/**
|
||||
@ -69,12 +72,13 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml node
|
||||
* @param node The xml node pointer
|
||||
* Rebuilds the object from an xml object
|
||||
* @param xml xml object
|
||||
* @param xpath_prefix Parent nodes, e.g. "/DATASTORE/"
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml_node(const xmlNodePtr node);
|
||||
int from_xml(const ObjectXML* xml, const string& xpath_prefix);
|
||||
|
||||
/**
|
||||
* Function to print the Collection object into a string in
|
||||
@ -135,6 +139,13 @@ private:
|
||||
*/
|
||||
set<int> collection_set;
|
||||
|
||||
/**
|
||||
* Rebuilds the object from an xml node
|
||||
* @param node The xml node pointer
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int from_xml_node(const xmlNodePtr node);
|
||||
};
|
||||
|
||||
#endif /*OBJECT_COLLECTION_H_*/
|
||||
|
@ -172,19 +172,20 @@ public:
|
||||
*
|
||||
* @return -1 if the element was not found
|
||||
*/
|
||||
virtual int search(const char *name, std::string& value);
|
||||
virtual int search(const char *name, std::string& value)
|
||||
{
|
||||
return __search(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the Object for a given attribute in a set of object specific
|
||||
* routes. integer version
|
||||
*/
|
||||
virtual int search(const char *name, int& value);
|
||||
virtual int search(const char *name, int& value)
|
||||
{
|
||||
return __search(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the Object for a given attribute in a set of object specific
|
||||
* routes. float version
|
||||
*/
|
||||
virtual int search(const char *name, float& value);
|
||||
virtual int search(const char *name, float& value)
|
||||
{
|
||||
return __search(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get xml nodes by Xpath
|
||||
@ -193,7 +194,8 @@ public:
|
||||
* returned as pointers to the object nodes.
|
||||
* @return the number of nodes found
|
||||
*/
|
||||
int get_nodes(const char * xpath_expr, std::vector<xmlNodePtr>& content);
|
||||
int get_nodes(const std::string& xpath_expr,
|
||||
std::vector<xmlNodePtr>& content) const;
|
||||
|
||||
/**
|
||||
* Adds a copy of the node as a child of the node in the xpath expression.
|
||||
@ -211,7 +213,7 @@ public:
|
||||
* Frees a vector of XMLNodes, as returned by the get_nodes function
|
||||
* @param content the vector of xmlNodePtr
|
||||
*/
|
||||
void free_nodes(std::vector<xmlNodePtr>& content)
|
||||
void free_nodes(std::vector<xmlNodePtr>& content) const
|
||||
{
|
||||
std::vector<xmlNodePtr>::iterator it;
|
||||
|
||||
@ -327,9 +329,57 @@ private:
|
||||
* @param name of the attribute
|
||||
* @results vector of attributes that matches the query
|
||||
*/
|
||||
void search(const char* name, std::vector<std::string>& results);
|
||||
template<typename T>
|
||||
void __search(const char* name, std::vector<T>& results)
|
||||
{
|
||||
|
||||
if (name[0] == '/')
|
||||
{
|
||||
xpaths(results, name);
|
||||
}
|
||||
else if (num_paths == 0)
|
||||
{
|
||||
results.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream xpath;
|
||||
|
||||
xpath << paths[0] << name;
|
||||
|
||||
for (int i = 1; i < num_paths ; i++)
|
||||
{
|
||||
xpath << '|' << paths[i] << name;
|
||||
}
|
||||
|
||||
xpaths(results, xpath.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the Object for a given attribute in a set of object specific
|
||||
* routes.
|
||||
* @param name of the attribute
|
||||
* @param value of the attribute
|
||||
*
|
||||
* @return -1 if the element was not found
|
||||
*/
|
||||
template<typename T>
|
||||
int __search(const char *name, T& value)
|
||||
{
|
||||
std::vector<T> results;
|
||||
|
||||
__search(name, results);
|
||||
|
||||
if (results.size() != 0)
|
||||
{
|
||||
value = results[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
};
|
||||
};
|
||||
|
||||
#endif /*OBJECT_XML_H_*/
|
||||
|
@ -1,322 +0,0 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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 ONECLIENT_H_
|
||||
#define ONECLIENT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <xmlrpc-c/base.hpp>
|
||||
#include <xmlrpc-c/client_simple.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
/**
|
||||
* OneClient class. Provides a simple interface to invoke the ONE methods. This
|
||||
* class can be used as base to build complex clients or VM applications
|
||||
*/
|
||||
|
||||
class OneClient : public xmlrpc_c::clientSimple
|
||||
{
|
||||
public:
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ONE Session Constructors */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Set the connection values to communicate with ONE
|
||||
* @param oneurl the ONE front-end to interact with, defaults to "localhost".
|
||||
* @param socket the socket where ONE listen to, defaults to 2633.
|
||||
*/
|
||||
OneClient(string oneurl="localhost",unsigned int socket=2633)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "http://" << oneurl << ":" << socket << "/RPC2";
|
||||
url=oss.str();
|
||||
|
||||
session = "oneclient";
|
||||
};
|
||||
|
||||
~OneClient(){};
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ONE Virtual Machine Methods */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Add a new VM to the VM pool and starts it.
|
||||
* @param template_file path, description of the Virtual Machine template
|
||||
* @param vmid, the id of the new VM
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int allocate(string template_file, int& vmid, string& error);
|
||||
|
||||
/**
|
||||
* Add a new VM to the VM pool and starts it.
|
||||
* @param template description of the Virtual Machine template
|
||||
* @param vmid, the id of the new VM
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int allocate_template(const string& template_file,
|
||||
int& vmid,
|
||||
string& error);
|
||||
|
||||
/**
|
||||
* Deploys the virtual machine "vmid" into the host "hid".
|
||||
* @param vmid the virtual machine to deploy.
|
||||
* @param hid the host id to deploy the VM.
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int deploy(int vmid, int hid, string& error);
|
||||
|
||||
/**
|
||||
* Migrate the virtual machine "vmid" to the host "hid".
|
||||
* @param vmid the virtual machine to migrate.
|
||||
* @param hid the destination host.
|
||||
* @param live try a "live migration".
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int migrate(int vmid, int hid, bool live, string& error);
|
||||
|
||||
/**
|
||||
* Shutdown a virtual machine.
|
||||
* @param vmid the vm identifier to shutdown.
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int shutdown(int vmid, string& error)
|
||||
{
|
||||
return action(vmid,"shutdown",error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a VM to hold, scheduler will not deploy it.
|
||||
* @param vmid the vm identifier to hold.
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int hold(int vmid, string& error)
|
||||
{
|
||||
return action(vmid,"hold",error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Release a VM from hold state.
|
||||
* @param vmid the vm identifier to release.
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int release(int vmid, string& error)
|
||||
{
|
||||
return action(vmid,"release",error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop a running VM
|
||||
* @param vmid the vm identifier to stop.
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int stop(int vmid, string& error)
|
||||
{
|
||||
return action(vmid,"stop",error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves a running VM
|
||||
* @param vmid the vm identifier to suspend.
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int suspend(int vmid, string& error)
|
||||
{
|
||||
return action(vmid,"suspend",error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resumes the execution of a saved VM
|
||||
* @param vmid the vm identifier to resume.
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int resume(int vmid, string& error)
|
||||
{
|
||||
return action(vmid,"resume",error);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cancel the execution of a VM,
|
||||
* @param vmid the vm identifier to resume.
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int cancel(int vmid, string& error)
|
||||
{
|
||||
return action(vmid,"cancel",error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the VM from the DB
|
||||
* @param vmid the vm identifier to resume.
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int finalize(int vmid, string& error)
|
||||
{
|
||||
return action(vmid,"finalize",error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets information on a virtual machine
|
||||
* @param vmid the vm identifier.
|
||||
* @param info the VM information
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int info(int vmid, string& info, string& error);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* ONE Host Methods */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Gets system info from a single host ( "hid" ).
|
||||
* @param hid the host id to get for information
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int host_info(int hid, string& info, string& error);
|
||||
|
||||
/**
|
||||
* Removes a host from the pool
|
||||
* @param hid the host id to remove
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int host_delete(int hid, string& error);
|
||||
|
||||
/**
|
||||
* Enables a given host.
|
||||
* @param hid the host id to enable.
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int host_enable(int hid, string& error)
|
||||
{
|
||||
return host_available(hid,true,error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Disables a given host.
|
||||
* @param hid the host id to disable.
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int host_disable(int hid, string& error)
|
||||
{
|
||||
return host_available(hid,false,error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a new Host to the Pool
|
||||
* @param name hostname of the host to add
|
||||
* @param im_mad the name of the information driver, from oned.conf
|
||||
* @param vmm_mad the name of the virtual machine manager driver, from oned.conf
|
||||
* @param error if an error occurs this is the error message
|
||||
* @return -1 if an error occurs, 0 on success.
|
||||
*/
|
||||
int host_allocate(string& name,
|
||||
string& im_mad,
|
||||
string& vmm_mad,
|
||||
int& hid,
|
||||
string& error);
|
||||
private:
|
||||
|
||||
/**
|
||||
* URl - url to connect to ONE.
|
||||
*/
|
||||
string url;
|
||||
|
||||
/**
|
||||
* Session - Client session id
|
||||
*/
|
||||
string session;
|
||||
|
||||
/**
|
||||
* Submits an action to be performed on a VM.
|
||||
* @param vmid the VM id.
|
||||
* @param action the "transition" to execute.
|
||||
* @param error if an error occurs this is error message.
|
||||
* @return -1 if an error occurs, otherwise 0.
|
||||
*/
|
||||
int action(int vmid, const char * action, string& error);
|
||||
|
||||
/**
|
||||
* Enables or disables a given host.
|
||||
* @param hid the host id to enable/disable.
|
||||
* @param enable true to enavle the target host.
|
||||
* @param error if an error occurs this is error message.
|
||||
* @return -1 if an error occurs, otherwise "0".
|
||||
*/
|
||||
int host_available(int hid, bool enable, string& error);
|
||||
};
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void c_oneStart(void);
|
||||
|
||||
int c_oneDeploy(int vmid, int hid);
|
||||
|
||||
int c_oneMigrate(int vmid, int hid, int flag);
|
||||
|
||||
int c_oneAllocate(char* vm_template);
|
||||
|
||||
int c_oneAllocateTemplate(char* vm_template);
|
||||
|
||||
int c_oneAction(int vmid,char* action);
|
||||
|
||||
int c_oneShutdown(int vmid);
|
||||
|
||||
int c_oneSuspend(int vmid);
|
||||
|
||||
int c_oneStop(int vmid);
|
||||
|
||||
int c_oneResume(int vmid);
|
||||
|
||||
int c_oneCancel(int vmid);
|
||||
|
||||
int c_oneFinalize(int vmid);
|
||||
|
||||
int c_oneVmInfo(int vmid, char* ret_info,int leng);
|
||||
|
||||
void c_oneFree(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*ONECLIENT_H_*/
|
@ -34,7 +34,6 @@ public:
|
||||
oid(-1),
|
||||
uid(-1),
|
||||
gid(-1),
|
||||
cid(-1),
|
||||
owner_u(1),
|
||||
owner_m(1),
|
||||
owner_a(0),
|
||||
@ -65,7 +64,7 @@ public:
|
||||
int oid;
|
||||
int uid;
|
||||
int gid;
|
||||
int cid;
|
||||
set<int> cids;
|
||||
|
||||
int owner_u;
|
||||
int owner_m;
|
||||
|
@ -79,7 +79,7 @@ protected:
|
||||
return pool_allocate(_paramList, tmpl, id, att);
|
||||
};
|
||||
|
||||
virtual int get_cluster_id(xmlrpc_c::paramList const& paramList)
|
||||
virtual int get_cluster_id(xmlrpc_c::paramList const& paramList)
|
||||
{
|
||||
return ClusterPool::NONE_CLUSTER_ID;
|
||||
};
|
||||
@ -87,7 +87,6 @@ protected:
|
||||
virtual int add_to_cluster(
|
||||
Cluster* cluster,
|
||||
int id,
|
||||
Datastore::DatastoreType ds_type,
|
||||
string& error_msg)
|
||||
{
|
||||
return -1;
|
||||
@ -101,6 +100,17 @@ protected:
|
||||
protected:
|
||||
ClusterPool * clpool;
|
||||
|
||||
int get_cluster_id(xmlrpc_c::paramList const& paramList, int cluster_pos)
|
||||
{
|
||||
int cid = xmlrpc_c::value_int(paramList.getInt(cluster_pos));
|
||||
|
||||
if (cid == -1)
|
||||
{
|
||||
cid = ClusterPool::DEFAULT_CLUSTER_ID;
|
||||
}
|
||||
|
||||
return cid;
|
||||
};
|
||||
private:
|
||||
|
||||
bool do_template;
|
||||
@ -176,15 +186,14 @@ public:
|
||||
int cluster_id,
|
||||
const string& cluster_name);
|
||||
|
||||
int get_cluster_id(xmlrpc_c::paramList const& paramList)
|
||||
int get_cluster_id(xmlrpc_c::paramList const& paramList)
|
||||
{
|
||||
return xmlrpc_c::value_int(paramList.getInt(2));
|
||||
return RequestManagerAllocate::get_cluster_id(paramList, 2);
|
||||
};
|
||||
|
||||
int add_to_cluster(
|
||||
Cluster* cluster,
|
||||
int id,
|
||||
Datastore::DatastoreType ds_type,
|
||||
string& error_msg)
|
||||
{
|
||||
return cluster->add_vnet(id, error_msg);
|
||||
@ -280,15 +289,14 @@ public:
|
||||
int cluster_id,
|
||||
const string& cluster_name);
|
||||
|
||||
int get_cluster_id(xmlrpc_c::paramList const& paramList)
|
||||
int get_cluster_id(xmlrpc_c::paramList const& paramList)
|
||||
{
|
||||
return xmlrpc_c::value_int(paramList.getInt(5));
|
||||
return RequestManagerAllocate::get_cluster_id(paramList, 5);
|
||||
};
|
||||
|
||||
int add_to_cluster(
|
||||
Cluster* cluster,
|
||||
int id,
|
||||
Datastore::DatastoreType ds_type,
|
||||
string& error_msg)
|
||||
{
|
||||
return cluster->add_host(id, error_msg);
|
||||
@ -385,32 +393,17 @@ public:
|
||||
int cluster_id,
|
||||
const string& cluster_name);
|
||||
|
||||
int get_cluster_id(xmlrpc_c::paramList const& paramList)
|
||||
int get_cluster_id(xmlrpc_c::paramList const& paramList)
|
||||
{
|
||||
return xmlrpc_c::value_int(paramList.getInt(2));
|
||||
};
|
||||
|
||||
virtual Datastore::DatastoreType get_ds_type(int oid)
|
||||
{
|
||||
Datastore::DatastoreType ds_type = Datastore::FILE_DS;
|
||||
Datastore *ds = static_cast<DatastorePool*>(pool)->get(oid, true);
|
||||
|
||||
if ( ds != 0 )
|
||||
{
|
||||
ds_type = ds->get_type();
|
||||
ds->unlock();
|
||||
}
|
||||
|
||||
return ds_type;
|
||||
return RequestManagerAllocate::get_cluster_id(paramList, 2);
|
||||
};
|
||||
|
||||
int add_to_cluster(
|
||||
Cluster* cluster,
|
||||
int id,
|
||||
Datastore::DatastoreType ds_type,
|
||||
string& error_msg)
|
||||
{
|
||||
return cluster->add_datastore(id, ds_type, error_msg);
|
||||
return cluster->add_datastore(id, error_msg);
|
||||
};
|
||||
};
|
||||
|
||||
|
118
include/RequestManagerAllocateDB.h
Normal file
118
include/RequestManagerAllocateDB.h
Normal file
@ -0,0 +1,118 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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 REQUEST_MANAGER_ALLOCATE_DB_H
|
||||
#define REQUEST_MANAGER_ALLOCATE_DB_H
|
||||
|
||||
#include "Request.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class RequestManagerAllocateDB: public Request
|
||||
{
|
||||
protected:
|
||||
RequestManagerAllocateDB(): Request("AllocateDB", "A:ss",
|
||||
"Allocates a new object from its template representation")
|
||||
{
|
||||
auth_op = AuthRequest::MANAGE;
|
||||
};
|
||||
|
||||
virtual ~RequestManagerAllocateDB(){};
|
||||
|
||||
virtual PoolObjectSQL * create(const std::string& xml) = 0;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& pl, RequestAttributes& att)
|
||||
{
|
||||
std::string xml = xmlrpc_c::value_string(pl.getString(1));
|
||||
|
||||
if ( att.uid != UserPool::ONEADMIN_ID )
|
||||
{
|
||||
failure_response(AUTHORIZATION, att);
|
||||
return;
|
||||
}
|
||||
|
||||
PoolObjectSQL * obj = create(xml);
|
||||
|
||||
int rc = pool->allocate(obj, att.resp_msg);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
failure_response(INTERNAL, att);
|
||||
return;
|
||||
}
|
||||
|
||||
success_response(rc, att);
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class MarketPlaceAppAllocateDB: public RequestManagerAllocateDB
|
||||
{
|
||||
public:
|
||||
MarketPlaceAppAllocateDB(): RequestManagerAllocateDB()
|
||||
{
|
||||
auth_object = PoolObjectSQL::MARKETPLACEAPP;
|
||||
pool = Nebula::instance().get_apppool();
|
||||
};
|
||||
|
||||
virtual ~MarketPlaceAppAllocateDB(){};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
PoolObjectSQL * create(const std::string& xml)
|
||||
{
|
||||
PoolObjectSQL * app = static_cast<MarketPlaceAppPool *>(pool)->create();
|
||||
|
||||
app->from_xml(xml);
|
||||
|
||||
return app;
|
||||
}
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class MarketPlaceAllocateDB: public RequestManagerAllocateDB
|
||||
{
|
||||
public:
|
||||
MarketPlaceAllocateDB(): RequestManagerAllocateDB()
|
||||
{
|
||||
auth_object = PoolObjectSQL::MARKETPLACE;
|
||||
pool = Nebula::instance().get_marketpool();
|
||||
};
|
||||
|
||||
virtual ~MarketPlaceAllocateDB(){};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
PoolObjectSQL * create(const std::string& xml)
|
||||
{
|
||||
PoolObjectSQL * mp = static_cast<MarketPlacePool *>(pool)->create();
|
||||
|
||||
mp->from_xml(xml);
|
||||
|
||||
return mp;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* REQUEST_MANAGER_ALLOCATE_DB_H */
|
@ -36,7 +36,6 @@ protected:
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
clpool = nd.get_clpool();
|
||||
hpool = nd.get_hpool();
|
||||
dspool = nd.get_dspool();
|
||||
vnpool = nd.get_vnpool();
|
||||
|
||||
@ -49,7 +48,6 @@ protected:
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
ClusterPool * clpool;
|
||||
HostPool * hpool;
|
||||
DatastorePool * dspool;
|
||||
VirtualNetworkPool * vnpool;
|
||||
|
||||
@ -63,12 +61,28 @@ protected:
|
||||
int object_id,
|
||||
RequestAttributes& att,
|
||||
PoolSQL * pool,
|
||||
PoolObjectSQL::ObjectType type);
|
||||
|
||||
virtual Datastore::DatastoreType get_ds_type(PoolObjectSQL *obj)
|
||||
PoolObjectSQL::ObjectType type)
|
||||
{
|
||||
return Datastore::FILE_DS;
|
||||
};
|
||||
action_generic(cluster_id, object_id, att, pool, type, true);
|
||||
}
|
||||
|
||||
void del_generic(
|
||||
int cluster_id,
|
||||
int object_id,
|
||||
RequestAttributes& att,
|
||||
PoolSQL * pool,
|
||||
PoolObjectSQL::ObjectType type)
|
||||
{
|
||||
action_generic(cluster_id, object_id, att, pool, type, false);
|
||||
}
|
||||
|
||||
void action_generic(
|
||||
int cluster_id,
|
||||
int object_id,
|
||||
RequestAttributes& att,
|
||||
PoolSQL * pool,
|
||||
PoolObjectSQL::ObjectType type,
|
||||
bool add);
|
||||
|
||||
/**
|
||||
* Add object to cluster id collection
|
||||
@ -81,7 +95,6 @@ protected:
|
||||
virtual int add_object(
|
||||
Cluster* cluster,
|
||||
int id,
|
||||
Datastore::DatastoreType ds_type,
|
||||
string& error_msg) = 0;
|
||||
|
||||
virtual int del_object(Cluster* cluster, int id, string& error_msg) = 0;
|
||||
@ -92,38 +105,36 @@ protected:
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class RequestManagerClusterHost : public RequestManagerCluster
|
||||
class RequestManagerClusterHost: public Request
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
RequestManagerClusterHost(
|
||||
const string& method_name,
|
||||
const string& help,
|
||||
const string& params):
|
||||
RequestManagerCluster(method_name, help, params){};
|
||||
const string& params)
|
||||
:Request(method_name,params,help)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
clpool = nd.get_clpool();
|
||||
hpool = nd.get_hpool();
|
||||
|
||||
auth_object = PoolObjectSQL::CLUSTER;
|
||||
auth_op = AuthRequest::ADMIN;
|
||||
};
|
||||
|
||||
~RequestManagerClusterHost(){};
|
||||
|
||||
virtual int add_object(
|
||||
Cluster* cluster,
|
||||
int id,
|
||||
Datastore::DatastoreType ds_type,
|
||||
string& error_msg)
|
||||
{
|
||||
return cluster->add_host(id, error_msg);
|
||||
};
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
virtual int del_object(Cluster* cluster, int id, string& error_msg)
|
||||
{
|
||||
return cluster->del_host(id, error_msg);
|
||||
};
|
||||
ClusterPool * clpool;
|
||||
HostPool * hpool;
|
||||
|
||||
virtual void get(int oid, bool lock, PoolObjectSQL ** object, Clusterable ** cluster_obj)
|
||||
{
|
||||
Host * host = hpool->get(oid, lock);
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
*object = static_cast<PoolObjectSQL *>(host);
|
||||
*cluster_obj = static_cast<Clusterable *>(host);
|
||||
};
|
||||
void add_generic(
|
||||
int cluster_id,
|
||||
int host_id,
|
||||
RequestAttributes& att);
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -145,8 +156,7 @@ public:
|
||||
int cluster_id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
int object_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
|
||||
return add_generic(cluster_id, object_id, att,
|
||||
hpool, PoolObjectSQL::HOST);
|
||||
return add_generic(cluster_id, object_id, att);
|
||||
}
|
||||
};
|
||||
|
||||
@ -168,11 +178,10 @@ public:
|
||||
{
|
||||
// First param is ignored, as objects can be assigned to only
|
||||
// one cluster
|
||||
int cluster_id = ClusterPool::NONE_CLUSTER_ID;
|
||||
int cluster_id = ClusterPool::DEFAULT_CLUSTER_ID;
|
||||
int object_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
|
||||
return add_generic(cluster_id, object_id, att,
|
||||
hpool, PoolObjectSQL::HOST);
|
||||
return add_generic(cluster_id, object_id, att);
|
||||
}
|
||||
};
|
||||
|
||||
@ -190,18 +199,12 @@ public:
|
||||
|
||||
~RequestManagerClusterDatastore(){};
|
||||
|
||||
virtual Datastore::DatastoreType get_ds_type(PoolObjectSQL *obj)
|
||||
{
|
||||
return static_cast<Datastore*>(obj)->get_type();
|
||||
};
|
||||
|
||||
virtual int add_object(
|
||||
Cluster* cluster,
|
||||
int id,
|
||||
Datastore::DatastoreType ds_type,
|
||||
string& error_msg)
|
||||
{
|
||||
return cluster->add_datastore(id, ds_type, error_msg);
|
||||
return cluster->add_datastore(id, error_msg);
|
||||
};
|
||||
|
||||
virtual int del_object(Cluster* cluster, int id, string& error_msg)
|
||||
@ -258,12 +261,10 @@ public:
|
||||
void request_execute(xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
// First param is ignored, as objects can be assigned to only
|
||||
// one cluster
|
||||
int cluster_id = ClusterPool::NONE_CLUSTER_ID;
|
||||
int cluster_id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
int object_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
|
||||
return add_generic(cluster_id, object_id, att,
|
||||
return del_generic(cluster_id, object_id, att,
|
||||
dspool, PoolObjectSQL::DATASTORE);
|
||||
}
|
||||
};
|
||||
@ -286,7 +287,6 @@ public:
|
||||
virtual int add_object(
|
||||
Cluster* cluster,
|
||||
int id,
|
||||
Datastore::DatastoreType ds_type,
|
||||
string& error_msg)
|
||||
{
|
||||
return cluster->add_vnet(id, error_msg);
|
||||
@ -346,12 +346,10 @@ public:
|
||||
void request_execute(xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
// First param is ignored, as objects can be assigned to only
|
||||
// one cluster
|
||||
int cluster_id = ClusterPool::NONE_CLUSTER_ID;
|
||||
int cluster_id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
int object_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
|
||||
return add_generic(cluster_id, object_id, att,
|
||||
return del_generic(cluster_id, object_id, att,
|
||||
vnpool, PoolObjectSQL::NET);
|
||||
}
|
||||
};
|
||||
|
@ -70,9 +70,10 @@ protected:
|
||||
|
||||
virtual int drop(int oid, PoolObjectSQL * object, string& error_msg);
|
||||
|
||||
virtual int get_cluster_id(PoolObjectSQL * object)
|
||||
virtual set<int> get_cluster_ids(PoolObjectSQL * object)
|
||||
{
|
||||
return ClusterPool::NONE_CLUSTER_ID;
|
||||
set<int> empty;
|
||||
return empty;
|
||||
};
|
||||
|
||||
virtual int del_from_cluster(Cluster* cluster, int id, string& error_msg)
|
||||
@ -127,9 +128,9 @@ public:
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
int get_cluster_id(PoolObjectSQL * object)
|
||||
set<int> get_cluster_ids(PoolObjectSQL * object)
|
||||
{
|
||||
return static_cast<VirtualNetwork*>(object)->get_cluster_id();
|
||||
return static_cast<VirtualNetwork*>(object)->get_cluster_ids();
|
||||
};
|
||||
|
||||
int del_from_cluster(Cluster* cluster, int id, string& error_msg)
|
||||
@ -181,9 +182,13 @@ public:
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
int get_cluster_id(PoolObjectSQL * object)
|
||||
set<int> get_cluster_ids(PoolObjectSQL * object)
|
||||
{
|
||||
return static_cast<Host*>(object)->get_cluster_id();
|
||||
set<int> ids;
|
||||
|
||||
ids.insert( static_cast<Host*>(object)->get_cluster_id() );
|
||||
|
||||
return ids;
|
||||
};
|
||||
|
||||
int del_from_cluster(Cluster* cluster, int id, string& error_msg)
|
||||
@ -266,9 +271,9 @@ public:
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
int get_cluster_id(PoolObjectSQL * object)
|
||||
set<int> get_cluster_ids(PoolObjectSQL * object)
|
||||
{
|
||||
return static_cast<Datastore*>(object)->get_cluster_id();
|
||||
return static_cast<Datastore*>(object)->get_cluster_ids();
|
||||
};
|
||||
|
||||
int del_from_cluster(Cluster* cluster, int id, string& error_msg)
|
||||
|
87
include/RequestManagerDropDB.h
Normal file
87
include/RequestManagerDropDB.h
Normal file
@ -0,0 +1,87 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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 REQUEST_MANAGER_DROP_DB_H
|
||||
#define REQUEST_MANAGER_DROP_DB_H
|
||||
|
||||
#include "Request.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class RequestManagerDropDB: public Request
|
||||
{
|
||||
protected:
|
||||
RequestManagerDropDB(): Request("DropDB", "A:si",
|
||||
"Drops an object from DB")
|
||||
{
|
||||
auth_op = AuthRequest::MANAGE;
|
||||
};
|
||||
|
||||
virtual ~RequestManagerDropDB(){};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& pl, RequestAttributes& att)
|
||||
{
|
||||
std::string error;
|
||||
int oid = xmlrpc_c::value_int(pl.getInt(1));
|
||||
|
||||
if ( att.uid != UserPool::ONEADMIN_ID )
|
||||
{
|
||||
failure_response(AUTHORIZATION, att);
|
||||
return;
|
||||
}
|
||||
|
||||
PoolObjectSQL * object = pool->get(oid,true);
|
||||
|
||||
if ( object == 0 )
|
||||
{
|
||||
att.resp_id = oid;
|
||||
failure_response(NO_EXISTS, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pool->drop(object, error) != 0 )
|
||||
{
|
||||
att.resp_msg = error;
|
||||
failure_response(ACTION, att);
|
||||
}
|
||||
else
|
||||
{
|
||||
success_response(oid, att);
|
||||
}
|
||||
|
||||
object->unlock();
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
class MarketPlaceAppDropDB : public RequestManagerDropDB
|
||||
{
|
||||
public:
|
||||
MarketPlaceAppDropDB():RequestManagerDropDB()
|
||||
{
|
||||
auth_object = PoolObjectSQL::MARKETPLACEAPP;
|
||||
pool = Nebula::instance().get_apppool();
|
||||
}
|
||||
|
||||
~MarketPlaceAppDropDB(){};
|
||||
};
|
||||
|
||||
#endif /* REQUEST_MANAGER_DROP_DB_H */
|
@ -28,18 +28,23 @@ using namespace std;
|
||||
class RequestManagerProxy: public Request
|
||||
{
|
||||
public:
|
||||
RequestManagerProxy(string _method);
|
||||
RequestManagerProxy(string _method): Request("RequestManagerProxy", "?",
|
||||
"Forwards the request to another OpenNebula"), method(_method)
|
||||
{
|
||||
method_name = ("RequestManagerProxy." + method);
|
||||
};
|
||||
|
||||
~RequestManagerProxy();
|
||||
~RequestManagerProxy(){};
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att);
|
||||
|
||||
void hide_argument(int arg);
|
||||
void hide_argument(int arg)
|
||||
{
|
||||
hidden_params.insert(arg);
|
||||
};
|
||||
|
||||
private:
|
||||
Client * client;
|
||||
|
||||
string method;
|
||||
};
|
||||
|
||||
|
118
include/RequestManagerUpdateDB.h
Normal file
118
include/RequestManagerUpdateDB.h
Normal file
@ -0,0 +1,118 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Copyright 2002-2015, OpenNebula Project, OpenNebula Systems */
|
||||
/* */
|
||||
/* 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 REQUEST_MANAGER_UPDATE_DB_H
|
||||
#define REQUEST_MANAGER_UPDATE_DB_H
|
||||
|
||||
#include "Request.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class RequestManagerUpdateDB: public Request
|
||||
{
|
||||
protected:
|
||||
RequestManagerUpdateDB(): Request("UpdateDB", "A:sis",
|
||||
"Updates the DB object from a XML document")
|
||||
{
|
||||
auth_op = AuthRequest::MANAGE;
|
||||
};
|
||||
|
||||
virtual ~RequestManagerUpdateDB(){};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& pl, RequestAttributes& att)
|
||||
{
|
||||
int oid = xmlrpc_c::value_int(pl.getInt(1));
|
||||
std::string xml = xmlrpc_c::value_string(pl.getString(2));
|
||||
|
||||
if ( att.uid != UserPool::ONEADMIN_ID )
|
||||
{
|
||||
failure_response(AUTHORIZATION, att);
|
||||
return;
|
||||
}
|
||||
|
||||
PoolObjectSQL * object = pool->get(oid,true);
|
||||
|
||||
if ( object == 0 )
|
||||
{
|
||||
att.resp_id = oid;
|
||||
failure_response(NO_EXISTS, att);
|
||||
return;
|
||||
}
|
||||
|
||||
string old_xml;
|
||||
|
||||
object->to_xml(old_xml);
|
||||
|
||||
if ( object->from_xml(xml) != 0 )
|
||||
{
|
||||
object->from_xml(old_xml);
|
||||
|
||||
att.resp_msg = "Cannot update object from XML";
|
||||
failure_response(INTERNAL, att);
|
||||
|
||||
object->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( object->get_oid() != oid )
|
||||
{
|
||||
object->from_xml(old_xml);
|
||||
|
||||
att.resp_msg = "Consistency check failed";
|
||||
failure_response(INTERNAL, att);
|
||||
|
||||
object->unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
pool->update(object);
|
||||
|
||||
object->unlock();
|
||||
|
||||
success_response(oid, att);
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
class MarketPlaceAppUpdateDB : public RequestManagerUpdateDB
|
||||
{
|
||||
public:
|
||||
MarketPlaceAppUpdateDB():RequestManagerUpdateDB()
|
||||
{
|
||||
auth_object = PoolObjectSQL::MARKETPLACEAPP;
|
||||
pool = Nebula::instance().get_apppool();
|
||||
}
|
||||
|
||||
~MarketPlaceAppUpdateDB(){};
|
||||
};
|
||||
|
||||
class MarketPlaceUpdateDB : public RequestManagerUpdateDB
|
||||
{
|
||||
public:
|
||||
MarketPlaceUpdateDB():RequestManagerUpdateDB()
|
||||
{
|
||||
auth_object = PoolObjectSQL::MARKETPLACE;
|
||||
pool = Nebula::instance().get_marketpool();
|
||||
}
|
||||
|
||||
~MarketPlaceUpdateDB(){};
|
||||
};
|
||||
|
||||
#endif /* REQUEST_MANAGER_UPDATE_DB_H */
|
@ -80,7 +80,7 @@ protected:
|
||||
|
||||
int get_ds_information(
|
||||
int ds_id,
|
||||
int& ds_cluster_id,
|
||||
set<int>& ds_cluster_ids,
|
||||
string& tm_mad,
|
||||
RequestAttributes& att,
|
||||
bool& ds_migr);
|
||||
|
@ -129,14 +129,16 @@ public:
|
||||
* @param vm The VM
|
||||
* @param token_password Owner user's token password
|
||||
* @param system_tm_mad The Transfer Manager for the system datastore
|
||||
* @param disk_id of the context disk
|
||||
* @param xfr Stream where the transfer command will be written
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 in case of error, 0 if the VM has no context, 1 on success
|
||||
*/
|
||||
int prolog_context_command(
|
||||
VirtualMachine * vm,
|
||||
const string& token_password,
|
||||
string& system_tm_mad,
|
||||
int& disk_id,
|
||||
ostream& xfr);
|
||||
|
||||
/**
|
||||
|
@ -165,8 +165,10 @@ public:
|
||||
DISK_SNAPSHOT_REVERT_SUSPENDED = 55,
|
||||
DISK_SNAPSHOT_DELETE_SUSPENDED = 56,
|
||||
DISK_SNAPSHOT = 57,
|
||||
DISK_SNAPSHOT_REVERT = 58,
|
||||
DISK_SNAPSHOT_DELETE = 59
|
||||
//DISK_SNAPSHOT_REVERT = 58,
|
||||
DISK_SNAPSHOT_DELETE = 59,
|
||||
PROLOG_MIGRATE_UNKNOWN = 60,
|
||||
PROLOG_MIGRATE_UNKNOWN_FAILURE = 61
|
||||
};
|
||||
|
||||
static int lcm_state_from_str(string& st, LcmState& state)
|
||||
@ -229,8 +231,9 @@ public:
|
||||
else if ( st == "DISK_SNAPSHOT_REVERT_SUSPENDED") { state = DISK_SNAPSHOT_REVERT_SUSPENDED; }
|
||||
else if ( st == "DISK_SNAPSHOT_DELETE_SUSPENDED") { state = DISK_SNAPSHOT_DELETE_SUSPENDED; }
|
||||
else if ( st == "DISK_SNAPSHOT") { state = DISK_SNAPSHOT; }
|
||||
else if ( st == "DISK_SNAPSHOT_REVERT") { state = DISK_SNAPSHOT_REVERT; }
|
||||
else if ( st == "DISK_SNAPSHOT_DELETE") { state = DISK_SNAPSHOT_DELETE; }
|
||||
else if ( st == "PROLOG_MIGRATE_UNKNOWN") { state = PROLOG_MIGRATE_UNKNOWN; }
|
||||
else if ( st == "PROLOG_MIGRATE_UNKNOWN_FAILURE") { state = PROLOG_MIGRATE_UNKNOWN_FAILURE; }
|
||||
else {return -1;}
|
||||
|
||||
return 0;
|
||||
@ -296,8 +299,9 @@ public:
|
||||
case DISK_SNAPSHOT_REVERT_SUSPENDED: st = "DISK_SNAPSHOT_REVERT_SUSPENDED"; break;
|
||||
case DISK_SNAPSHOT_DELETE_SUSPENDED: st = "DISK_SNAPSHOT_DELETE_SUSPENDED"; break;
|
||||
case DISK_SNAPSHOT: st = "DISK_SNAPSHOT"; break;
|
||||
case DISK_SNAPSHOT_REVERT: st = "DISK_SNAPSHOT_REVERT"; break;
|
||||
case DISK_SNAPSHOT_DELETE: st = "DISK_SNAPSHOT_DELETE"; break;
|
||||
case PROLOG_MIGRATE_UNKNOWN: st = "PROLOG_MIGRATE_UNKNOWN"; break;
|
||||
case PROLOG_MIGRATE_UNKNOWN_FAILURE: st = "PROLOG_MIGRATE_UNKNOWN_FAILURE"; break;
|
||||
}
|
||||
|
||||
return st;
|
||||
@ -1289,6 +1293,11 @@ public:
|
||||
*/
|
||||
bool is_imported() const;
|
||||
|
||||
/**
|
||||
* Return state of the VM right before import
|
||||
*/
|
||||
string get_import_state();
|
||||
|
||||
/**
|
||||
* Checks if the current VM MAD supports the given action for imported VMs
|
||||
* @param action VM action to check
|
||||
@ -1342,15 +1351,10 @@ public:
|
||||
* in the context block device (CBD)
|
||||
* @param files space separated list of paths to be included in the CBD
|
||||
* @param disk_id CONTEXT/DISK_ID attribute value
|
||||
* @param token_password Password to encrypt the token, if it is set
|
||||
* @param password Password to encrypt the token, if it is set
|
||||
* @return -1 in case of error, 0 if the VM has no context, 1 on success
|
||||
*/
|
||||
int generate_context(string &files, int &disk_id, const string& token_password);
|
||||
|
||||
const VectorAttribute* get_context() const
|
||||
{
|
||||
return obj_template->get("CONTEXT");
|
||||
}
|
||||
int generate_context(string &files, int &disk_id, const string& password);
|
||||
|
||||
/**
|
||||
* Returns the CREATED_BY template attribute, or the uid if it does not exist
|
||||
@ -1987,6 +1991,24 @@ private:
|
||||
|
||||
static const int NUM_NO_NIC_DEFAULTS;
|
||||
|
||||
/**
|
||||
* Parse and generate the ETH_ network attributed of a NIC
|
||||
* @param context attribute
|
||||
* @param nic attribute
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
void parse_nic_context(VectorAttribute * context, VectorAttribute * nic);
|
||||
|
||||
/**
|
||||
* Generate the NETWORK related CONTEXT setions, i.e. ETH_*. This function
|
||||
* is invoked when ever the context is prepared for the VM to capture
|
||||
* netowrking updates.
|
||||
* @param context attribute of the VM
|
||||
* @return true if the net context was generated.
|
||||
*/
|
||||
bool generate_network_context(VectorAttribute * context);
|
||||
|
||||
/**
|
||||
* Parse the "NIC_DEFAULT" attribute
|
||||
* @param error_str Returns the error reason, if any
|
||||
|
@ -67,8 +67,7 @@ public:
|
||||
SNAPSHOT_CREATE,
|
||||
SNAPSHOT_REVERT,
|
||||
SNAPSHOT_DELETE,
|
||||
DISK_SNAPSHOT_CREATE,
|
||||
DISK_SNAPSHOT_REVERT
|
||||
DISK_SNAPSHOT_CREATE
|
||||
};
|
||||
|
||||
/**
|
||||
@ -432,13 +431,6 @@ private:
|
||||
*/
|
||||
void disk_snapshot_create_action(int vid);
|
||||
|
||||
/**
|
||||
* Reverts to a disk snapshot.
|
||||
*
|
||||
* @param vid the id of the VM.
|
||||
*/
|
||||
void disk_snapshot_revert_action(int vid);
|
||||
|
||||
/**
|
||||
* This function cancels the current driver operation
|
||||
*/
|
||||
|
@ -384,19 +384,6 @@ private:
|
||||
write_drv("DISKSNAPSHOTCREATE", oid, drv_msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a disk snapshot revert request to the MAD:
|
||||
* "DISKSNAPSHOTREVERT ID XML_DRV_MSG"
|
||||
* @param oid the virtual machine id.
|
||||
* @param drv_msg xml data for the mad operation
|
||||
*/
|
||||
void disk_snapshot_revert (
|
||||
const int oid,
|
||||
const string& drv_msg) const
|
||||
{
|
||||
write_drv("DISKSNAPSHOTREVERT", oid, drv_msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a request to update the VM security groups:
|
||||
* "UPDATESG ID XML_DRV_MSG"
|
||||
|
@ -457,6 +457,11 @@ private:
|
||||
// Binded physical attributes
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Name of the vn mad
|
||||
*/
|
||||
string vn_mad;
|
||||
|
||||
/**
|
||||
* Name of the bridge this VNW binds to
|
||||
*/
|
||||
@ -472,11 +477,6 @@ private:
|
||||
*/
|
||||
string vlan_id;
|
||||
|
||||
/**
|
||||
* Whether or not to isolate this network with the vnm driver
|
||||
*/
|
||||
int vlan;
|
||||
|
||||
/**
|
||||
* Parent VNET ID if any
|
||||
*/
|
||||
@ -541,7 +541,7 @@ private:
|
||||
int from_xml(const string &xml_str);
|
||||
|
||||
/**
|
||||
* Updates the BRIDGE, PHY_DEV, VLAN_ID and VLAN attributes.
|
||||
* Updates the BRIDGE, PHY_DEV, and VLAN_ID attributes.
|
||||
* @param error string describing the error if any
|
||||
* @return 0 on success
|
||||
*/
|
||||
@ -557,8 +557,7 @@ private:
|
||||
const string& _gname,
|
||||
int _umask,
|
||||
int _parent_vid,
|
||||
int _cluster_id,
|
||||
const string& _cluster_name,
|
||||
const set<int> &_cluster_ids,
|
||||
VirtualNetworkTemplate * _vn_template = 0);
|
||||
|
||||
~VirtualNetwork();
|
||||
|
@ -49,8 +49,7 @@ public:
|
||||
* @param umask permissions umask
|
||||
* @param vn_template a VirtualNetworkTemplate describing the VNET
|
||||
* @param oid the id assigned to the VM (output)
|
||||
* @param cluster_id the id of the cluster this VNET will belong to
|
||||
* @param cluster_name the name of the cluster this VNET will belong to
|
||||
* @param cluster_ids the ids of the clusters this VNET will belong to
|
||||
* @param error_str Returns the error reason, if any
|
||||
* @return oid on success, -1 error
|
||||
*/
|
||||
@ -63,8 +62,7 @@ public:
|
||||
int parent_vid,
|
||||
VirtualNetworkTemplate * vn_template,
|
||||
int * oid,
|
||||
int cluster_id,
|
||||
const string& cluster_name,
|
||||
const set<int> &cluster_ids,
|
||||
string& error_str);
|
||||
|
||||
/**
|
||||
@ -203,7 +201,8 @@ private:
|
||||
*/
|
||||
PoolObjectSQL * create()
|
||||
{
|
||||
return new VirtualNetwork(-1,-1,"","",0,-1,-1,"",0);
|
||||
set <int> empty;
|
||||
return new VirtualNetwork(-1,-1,"","",0,-1,empty,0);
|
||||
};
|
||||
|
||||
/**
|
||||
|
87
install.sh
87
install.sh
@ -233,11 +233,6 @@ LIB_DIRS="$LIB_LOCATION/ruby \
|
||||
$LIB_LOCATION/ruby/onedb/local \
|
||||
$LIB_LOCATION/ruby/onedb/patches \
|
||||
$LIB_LOCATION/ruby/vendors \
|
||||
$LIB_LOCATION/ruby/vendors/rbvmomi \
|
||||
$LIB_LOCATION/ruby/vendors/rbvmomi/lib \
|
||||
$LIB_LOCATION/ruby/vendors/rbvmomi/lib/rbvmomi \
|
||||
$LIB_LOCATION/ruby/vendors/rbvmomi/lib/rbvmomi/utils \
|
||||
$LIB_LOCATION/ruby/vendors/rbvmomi/lib/rbvmomi/vim \
|
||||
$LIB_LOCATION/mads \
|
||||
$LIB_LOCATION/sh \
|
||||
$LIB_LOCATION/ruby/cli \
|
||||
@ -284,6 +279,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
|
||||
$VAR_LOCATION/remotes/tm/lvm \
|
||||
$VAR_LOCATION/remotes/tm/ceph \
|
||||
$VAR_LOCATION/remotes/tm/dev \
|
||||
$VAR_LOCATION/remotes/tm/vcenter \
|
||||
$VAR_LOCATION/remotes/tm/iscsi \
|
||||
$VAR_LOCATION/remotes/hooks \
|
||||
$VAR_LOCATION/remotes/hooks/ft \
|
||||
@ -294,6 +290,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
|
||||
$VAR_LOCATION/remotes/datastore/lvm \
|
||||
$VAR_LOCATION/remotes/datastore/ceph \
|
||||
$VAR_LOCATION/remotes/datastore/dev \
|
||||
$VAR_LOCATION/remotes/datastore/vcenter \
|
||||
$VAR_LOCATION/remotes/market \
|
||||
$VAR_LOCATION/remotes/market/http \
|
||||
$VAR_LOCATION/remotes/market/one \
|
||||
@ -422,6 +419,7 @@ INSTALL_FILES=(
|
||||
TM_DEV_FILES:$VAR_LOCATION/remotes/tm/dev
|
||||
TM_ISCSI_FILES:$VAR_LOCATION/remotes/tm/iscsi
|
||||
TM_DUMMY_FILES:$VAR_LOCATION/remotes/tm/dummy
|
||||
TM_VCENTER_FILES:$VAR_LOCATION/remotes/tm/vcenter
|
||||
DATASTORE_DRIVER_COMMON_SCRIPTS:$VAR_LOCATION/remotes/datastore/
|
||||
DATASTORE_DRIVER_DUMMY_SCRIPTS:$VAR_LOCATION/remotes/datastore/dummy
|
||||
DATASTORE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/datastore/fs
|
||||
@ -429,6 +427,7 @@ INSTALL_FILES=(
|
||||
DATASTORE_DRIVER_LVM_SCRIPTS:$VAR_LOCATION/remotes/datastore/lvm
|
||||
DATASTORE_DRIVER_CEPH_SCRIPTS:$VAR_LOCATION/remotes/datastore/ceph
|
||||
DATASTORE_DRIVER_DEV_SCRIPTS:$VAR_LOCATION/remotes/datastore/dev
|
||||
DATASTORE_DRIVER_VCENTER_SCRIPTS:$VAR_LOCATION/remotes/datastore/vcenter
|
||||
DATASTORE_DRIVER_ISCSI_SCRIPTS:$VAR_LOCATION/remotes/datastore/iscsi
|
||||
MARKETPLACE_DRIVER_HTTP_SCRIPTS:$VAR_LOCATION/remotes/market/http
|
||||
MARKETPLACE_DRIVER_ONE_SCRIPTS:$VAR_LOCATION/remotes/market/one
|
||||
@ -455,11 +454,7 @@ INSTALL_FILES=(
|
||||
DOCS_FILES:$DOCS_LOCATION
|
||||
CLI_LIB_FILES:$LIB_LOCATION/ruby/cli
|
||||
ONE_CLI_LIB_FILES:$LIB_LOCATION/ruby/cli/one_helper
|
||||
RBVMOMI_VENDOR_RUBY_FILES:$LIB_LOCATION/ruby/vendors/rbvmomi
|
||||
RBVMOMI_VENDOR_RUBY_LIB_FILES:$LIB_LOCATION/ruby/vendors/rbvmomi/lib
|
||||
RBVMOMI_VENDOR_RUBY_LIB_RBVMOMI_FILES:$LIB_LOCATION/ruby/vendors/rbvmomi/lib/rbvmomi
|
||||
RBVMOMI_VENDOR_RUBY_LIB_RBVMOMI_VIM_FILES:$LIB_LOCATION/ruby/vendors/rbvmomi/lib/rbvmomi/vim
|
||||
RBVMOMI_VENDOR_RUBY_LIB_RBVMOMI_UTILS_FILES:$LIB_LOCATION/ruby/vendors/rbvmomi/lib/rbvmomi/utils
|
||||
VENDOR_DIRS:$LIB_LOCATION/ruby/vendors
|
||||
)
|
||||
|
||||
INSTALL_CLIENT_FILES=(
|
||||
@ -936,7 +931,6 @@ AUTH_PLAIN_FILES="src/authm_mad/remotes/plain/authenticate"
|
||||
NETWORK_FILES="src/vnm_mad/remotes/lib/vnm_driver.rb \
|
||||
src/vnm_mad/remotes/lib/vnmmad.rb \
|
||||
src/vnm_mad/remotes/OpenNebulaNetwork.conf \
|
||||
src/vnm_mad/remotes/lib/fw_driver.rb \
|
||||
src/vnm_mad/remotes/lib/sg_driver.rb \
|
||||
src/vnm_mad/remotes/lib/address.rb \
|
||||
src/vnm_mad/remotes/lib/command.rb \
|
||||
@ -1156,6 +1150,20 @@ TM_DEV_FILES="src/tm_mad/dev/clone \
|
||||
src/tm_mad/dev/failmigrate \
|
||||
src/tm_mad/dev/delete"
|
||||
|
||||
TM_VCENTER_FILES="src/tm_mad/vcenter/clone \
|
||||
src/tm_mad/vcenter/ln \
|
||||
src/tm_mad/vcenter/mv \
|
||||
src/tm_mad/vcenter/mvds \
|
||||
src/tm_mad/vcenter/cpds \
|
||||
src/tm_mad/vcenter/premigrate \
|
||||
src/tm_mad/vcenter/postmigrate \
|
||||
src/tm_mad/vcenter/snap_create \
|
||||
src/tm_mad/vcenter/snap_create_live \
|
||||
src/tm_mad/vcenter/snap_delete \
|
||||
src/tm_mad/vcenter/snap_revert \
|
||||
src/tm_mad/vcenter/failmigrate \
|
||||
src/tm_mad/vcenter/delete"
|
||||
|
||||
TM_ISCSI_FILES="src/tm_mad/iscsi/clone \
|
||||
src/tm_mad/iscsi/ln \
|
||||
src/tm_mad/iscsi/mv \
|
||||
@ -1180,6 +1188,8 @@ TM_ISCSI_FILES="src/tm_mad/iscsi/clone \
|
||||
|
||||
DATASTORE_DRIVER_COMMON_SCRIPTS="src/datastore_mad/remotes/xpath.rb \
|
||||
src/datastore_mad/remotes/downloader.sh \
|
||||
src/datastore_mad/remotes/vcenter_uploader.rb \
|
||||
src/datastore_mad/remotes/vcenter_downloader.rb \
|
||||
src/datastore_mad/remotes/url.rb \
|
||||
src/datastore_mad/remotes/libfs.sh"
|
||||
|
||||
@ -1250,6 +1260,17 @@ DATASTORE_DRIVER_DEV_SCRIPTS="src/datastore_mad/remotes/dev/cp \
|
||||
src/datastore_mad/remotes/dev/snap_flatten \
|
||||
src/datastore_mad/remotes/dev/clone"
|
||||
|
||||
DATASTORE_DRIVER_VCENTER_SCRIPTS="src/datastore_mad/remotes/vcenter/cp \
|
||||
src/datastore_mad/remotes/vcenter/mkfs \
|
||||
src/datastore_mad/remotes/vcenter/stat \
|
||||
src/datastore_mad/remotes/vcenter/rm \
|
||||
src/datastore_mad/remotes/vcenter/monitor \
|
||||
src/datastore_mad/remotes/vcenter/snap_delete \
|
||||
src/datastore_mad/remotes/vcenter/snap_revert \
|
||||
src/datastore_mad/remotes/vcenter/snap_flatten \
|
||||
src/datastore_mad/remotes/vcenter/clone \
|
||||
src/datastore_mad/remotes/vcenter/export"
|
||||
|
||||
DATASTORE_DRIVER_ISCSI_SCRIPTS="src/datastore_mad/remotes/iscsi/cp \
|
||||
src/datastore_mad/remotes/iscsi/mkfs \
|
||||
src/datastore_mad/remotes/iscsi/stat \
|
||||
@ -1951,49 +1972,7 @@ DOCS_FILES="LICENSE NOTICE README.md"
|
||||
# Ruby VENDOR files
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
RBVMOMI_VENDOR_RUBY_FILES="share/vendor/ruby/gems/rbvmomi/LICENSE \
|
||||
share/vendor/ruby/gems/rbvmomi/README.rdoc \
|
||||
share/vendor/ruby/gems/rbvmomi/VERSION \
|
||||
share/vendor/ruby/gems/rbvmomi/vmodl.db"
|
||||
|
||||
RBVMOMI_VENDOR_RUBY_LIB_FILES="share/vendor/ruby/gems/rbvmomi/lib/rbvmomi.rb"
|
||||
|
||||
RBVMOMI_VENDOR_RUBY_LIB_RBVMOMI_FILES="share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/basic_types.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/connection.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/deserialization.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/fault.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/pbm.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/trivial_soap.rb
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/trollop.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/type_loader.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim.rb"
|
||||
|
||||
RBVMOMI_VENDOR_RUBY_LIB_RBVMOMI_UTILS_FILES="share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/utils/admission_control.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/utils/deploy.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/utils/leases.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/utils/perfdump.rb"
|
||||
|
||||
RBVMOMI_VENDOR_RUBY_LIB_RBVMOMI_VIM_FILES="share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/ComputeResource.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/Datacenter.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/Datastore.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/DynamicTypeMgrAllTypeInfo.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/DynamicTypeMgrDataTypeInfo.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/DynamicTypeMgrManagedTypeInfo.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/Folder.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/HostSystem.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/ManagedEntity.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/ManagedObject.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/ObjectContent.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/ObjectUpdate.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/OvfManager.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/PerfCounterInfo.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/PerformanceManager.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/PropertyCollector.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/ReflectManagedMethodExecuter.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/ResourcePool.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/ServiceInstance.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/Task.rb \
|
||||
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/vim/VirtualMachine.rb"
|
||||
VENDOR_DIRS="share/vendor/ruby/gems/rbvmomi"
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#-----------------------------------------------------------------------------
|
||||
|
@ -71,6 +71,8 @@ digraph OpenNebula {
|
||||
prolog_migrate_suspend;
|
||||
prolog_migrate_suspend_failure;
|
||||
prolog_undeploy;
|
||||
prolog_migrate_unknown;
|
||||
prolog_migrate_unknown_failure;
|
||||
color="white"
|
||||
}
|
||||
subgraph {
|
||||
@ -154,7 +156,8 @@ digraph OpenNebula {
|
||||
prolog_migrate -> boot_migrate [style="dashed", color="blue"];
|
||||
boot_migrate -> running [style="dashed", color="blue"];
|
||||
|
||||
unknown -> boot [label="migrate"];
|
||||
unknown -> prolog_migrate_unknown [label="migrate"];
|
||||
prolog_migrate_unknown -> boot [style="dashed", color="blue"];
|
||||
|
||||
poweroff -> prolog_migrate_poweroff [label="migrate"];
|
||||
prolog_migrate_poweroff -> poweroff [style="dashed", color="blue"];
|
||||
@ -304,6 +307,9 @@ digraph OpenNebula {
|
||||
prolog_resume -> stopped [style="dotted", color="red"];
|
||||
prolog_undeploy -> undeployed [style="dotted", color="red"];
|
||||
|
||||
prolog_migrate_unknown -> prolog_migrate_unknown_failure [label=" ", style="dotted", color="red"];
|
||||
prolog_migrate_unknown_failure -> prolog_migrate_unknown [label="migrate"];
|
||||
|
||||
boot -> boot_failure [label=" ", style="dotted", color="red"];
|
||||
boot_migrate -> boot_migrate_failure [label=" ", style="dotted", color="red"];
|
||||
boot_poweroff -> poweroff [style="dotted", color="red"];
|
||||
|
@ -174,7 +174,9 @@
|
||||
DISK_SNAPSHOT_DELETE_SUSPENDED = 56,
|
||||
DISK_SNAPSHOT = 57,
|
||||
DISK_SNAPSHOT_REVERT = 58,
|
||||
DISK_SNAPSHOT_DELETE = 59
|
||||
DISK_SNAPSHOT_DELETE = 59,
|
||||
PROLOG_MIGRATE_UNKNOWN = 60,
|
||||
PROLOG_MIGRATE_UNKNOWN_FAILURE = 61
|
||||
-->
|
||||
<xs:element name="LCM_STATE" type="xs:integer"/>
|
||||
<xs:element name="PREV_STATE" type="xs:integer"/>
|
||||
|
@ -24,15 +24,19 @@
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="DS_MAD" type="xs:string"/>
|
||||
<xs:element name="TM_MAD" type="xs:string"/>
|
||||
<xs:element name="BASE_PATH" type="xs:string"/>
|
||||
<xs:element name="TYPE" type="xs:integer"/>
|
||||
<xs:element name="DISK_TYPE" type="xs:integer"/>
|
||||
<xs:element name="STATE" type="xs:integer"/>
|
||||
<xs:element name="CLUSTER_ID" type="xs:integer"/>
|
||||
<xs:element name="CLUSTER" type="xs:string"/>
|
||||
<xs:element name="CLUSTERS">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="ID" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="TOTAL_MB" type="xs:integer"/>
|
||||
<xs:element name="FREE_MB" type="xs:integer"/>
|
||||
<xs:element name="USED_MB" type="xs:integer"/>
|
||||
|
@ -65,6 +65,13 @@
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="APP_CLONES">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="ID" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="TEMPLATE" type="xs:anyType"/>
|
||||
<xs:element name="SNAPSHOTS">
|
||||
<xs:complexType>
|
||||
|
@ -105,7 +105,9 @@
|
||||
DISK_SNAPSHOT_DELETE_SUSPENDED = 56,
|
||||
DISK_SNAPSHOT = 57,
|
||||
DISK_SNAPSHOT_REVERT = 58,
|
||||
DISK_SNAPSHOT_DELETE = 59
|
||||
DISK_SNAPSHOT_DELETE = 59,
|
||||
PROLOG_MIGRATE_UNKNOWN = 60,
|
||||
PROLOG_MIGRATE_UNKNOWN_FAILURE = 61
|
||||
-->
|
||||
<xs:element name="LCM_STATE" type="xs:integer"/>
|
||||
<xs:element name="PREV_STATE" type="xs:integer"/>
|
||||
|
@ -25,10 +25,15 @@
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="CLUSTER_ID" type="xs:integer"/>
|
||||
<xs:element name="CLUSTER" type="xs:string"/>
|
||||
<xs:element name="CLUSTERS">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="ID" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="BRIDGE" type="xs:string"/>
|
||||
<xs:element name="VLAN" type="xs:integer"/>
|
||||
<xs:element name="VN_MAD" type="xs:integer"/>
|
||||
<xs:element name="PARENT_NETWORK_ID" type="xs:string"/>
|
||||
<xs:element name="PHYDEV" type="xs:string"/>
|
||||
<xs:element name="VLAN_ID" type="xs:string"/>
|
||||
@ -48,7 +53,7 @@
|
||||
<xs:element name="SIZE" type="xs:integer"/>
|
||||
<xs:element name="TYPE" type="xs:string"/>
|
||||
<xs:element name="ULA_PREFIX" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="VLAN" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="VN_MAD" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="MAC_END" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="IP_END" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="IP6_ULA" type="xs:string" minOccurs="0"/>
|
||||
|
@ -32,7 +32,7 @@
|
||||
<xs:element name="CLUSTER_ID" type="xs:integer"/>
|
||||
<xs:element name="CLUSTER" type="xs:string"/>
|
||||
<xs:element name="BRIDGE" type="xs:string"/>
|
||||
<xs:element name="VLAN" type="xs:integer"/>
|
||||
<xs:element name="VN_MAD" type="xs:integer"/>
|
||||
<xs:element name="PARENT_NETWORK_ID" type="xs:string"/>
|
||||
<xs:element name="PHYDEV" type="xs:string"/>
|
||||
<xs:element name="VLAN_ID" type="xs:string"/>
|
||||
@ -53,7 +53,7 @@
|
||||
<xs:element name="SIZE" type="xs:integer"/>
|
||||
<xs:element name="TYPE" type="xs:string"/>
|
||||
<xs:element name="ULA_PREFIX" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="VLAN" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="VN_MAD" type="xs:string" minOccurs="0"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
@ -145,7 +145,8 @@ DEFAULT_COST = [
|
||||
# a single connection
|
||||
#
|
||||
# TIMEOUT: Maximum time in seconds the server will wait for the client to
|
||||
# do anything while processing an RPC
|
||||
# do anything while processing an RPC. This timeout will be also used when
|
||||
# proxy calls to the master in a federation.
|
||||
#
|
||||
# RPC_LOG: Create a separated log file for xml-rpc requests, in
|
||||
# "/var/log/one/one_xmlrpc.log".
|
||||
@ -196,9 +197,6 @@ MAC_PREFIX = "02:00"
|
||||
# HOSTS AND *NOT* THE FRONT-END. It defaults to /var/lib/one/datastores (or
|
||||
# $ONE_LOCATION/var/datastores in self-contained mode)
|
||||
#
|
||||
# You can define a different DATASTORE_LOCATION in each cluster by updating
|
||||
# its properties with onecluster update.
|
||||
#
|
||||
# DATASTORE_BASE_PATH: This is the base path for the SOURCE attribute of
|
||||
# the images registered in a Datastore. This is a default value, that can be
|
||||
# changed when the datastore is created.
|
||||
@ -449,11 +447,6 @@ IM_MAD = [
|
||||
# An example: "-l migrate=migrate_local,save"
|
||||
# -p more than one action per host in parallel, needs support from hypervisor
|
||||
# -s <shell> to execute remote commands, bash by default
|
||||
# -d default snapshot strategy. It can be either 'detach' or 'suspend'. It
|
||||
# defaults to 'suspend'.
|
||||
# -i try to do live-snapshot if available. Currently supported only for kvm
|
||||
# with qcow2 as the datastore TM_MAD. If not available, it will fallback
|
||||
# on the default (-d)
|
||||
#
|
||||
# Note: You can use type = "qemu" to use qemu emulated guests, e.g. if your
|
||||
# CPU does not have virtualization extensions or use nested Qemu-KVM hosts
|
||||
@ -461,7 +454,7 @@ IM_MAD = [
|
||||
VM_MAD = [
|
||||
name = "kvm",
|
||||
executable = "one_vmm_exec",
|
||||
arguments = "-t 15 -r 0 -i kvm",
|
||||
arguments = "-t 15 -r 0 kvm",
|
||||
default = "vmm_exec/vmm_exec_kvm.conf",
|
||||
type = "kvm",
|
||||
imported_vms_actions = "shutdown, shutdown-hard, hold, release, suspend,
|
||||
@ -629,7 +622,7 @@ VM_MAD = [
|
||||
|
||||
TM_MAD = [
|
||||
executable = "one_tm",
|
||||
arguments = "-t 15 -d dummy,lvm,shared,fs_lvm,qcow2,ssh,vmfs,ceph,dev,iscsi"
|
||||
arguments = "-t 15 -d dummy,lvm,shared,fs_lvm,qcow2,ssh,vmfs,ceph,dev,vcenter,iscsi"
|
||||
]
|
||||
|
||||
#*******************************************************************************
|
||||
@ -648,7 +641,7 @@ TM_MAD = [
|
||||
|
||||
DATASTORE_MAD = [
|
||||
executable = "one_datastore",
|
||||
arguments = "-t 15 -d dummy,fs,vmfs,lvm,ceph,dev,iscsi -s shared,ssh,ceph"
|
||||
arguments = "-t 15 -d dummy,fs,vmfs,lvm,ceph,dev,iscsi,vcenter -s shared,ssh,ceph"
|
||||
]
|
||||
|
||||
#*******************************************************************************
|
||||
@ -893,14 +886,14 @@ IMAGE_RESTRICTED_ATTR = "SOURCE"
|
||||
# Normal VNets do not have restricted attributes.
|
||||
#*******************************************************************************
|
||||
|
||||
VNET_RESTRICTED_ATTR = "VN_MAD"
|
||||
VNET_RESTRICTED_ATTR = "PHYDEV"
|
||||
VNET_RESTRICTED_ATTR = "VLAN_ID"
|
||||
VNET_RESTRICTED_ATTR = "VLAN"
|
||||
VNET_RESTRICTED_ATTR = "BRIDGE"
|
||||
|
||||
VNET_RESTRICTED_ATTR = "AR/VN_MAD"
|
||||
VNET_RESTRICTED_ATTR = "AR/PHYDEV"
|
||||
VNET_RESTRICTED_ATTR = "AR/VLAN_ID"
|
||||
VNET_RESTRICTED_ATTR = "AR/VLAN"
|
||||
VNET_RESTRICTED_ATTR = "AR/BRIDGE"
|
||||
|
||||
#*******************************************************************************
|
||||
@ -942,6 +935,12 @@ INHERIT_IMAGE_ATTR = "ISCSI_IQN"
|
||||
INHERIT_DATASTORE_ATTR = "GLUSTER_HOST"
|
||||
INHERIT_DATASTORE_ATTR = "GLUSTER_VOLUME"
|
||||
|
||||
INHERIT_DATASTORE_ATTR = "DISK_TYPE"
|
||||
INHERIT_DATASTORE_ATTR = "ADAPTER_TYPE"
|
||||
|
||||
INHERIT_IMAGE_ATTR = "DISK_TYPE"
|
||||
INHERIT_IMAGE_ATTR = "ADAPTER_TYPE"
|
||||
|
||||
INHERIT_VNET_ATTR = "VLAN_TAGGED_ID"
|
||||
INHERIT_VNET_ATTR = "BRIDGE_OVS"
|
||||
INHERIT_VNET_ATTR = "FILTER_IP_SPOOFING"
|
||||
@ -1017,6 +1016,10 @@ TM_MAD_CONF = [
|
||||
NAME = "dev", LN_TARGET = "NONE", CLONE_TARGET = "NONE", SHARED = "YES"
|
||||
]
|
||||
|
||||
TM_MAD_CONF = [
|
||||
NAME = "vcenter", LN_TARGET = "NONE", CLONE_TARGET = "NONE", SHARED = "YES"
|
||||
]
|
||||
|
||||
#*******************************************************************************
|
||||
# Datastore Manager Driver Behavior Configuration
|
||||
#*******************************************************************************
|
||||
@ -1071,6 +1074,10 @@ DS_MAD_CONF = [
|
||||
NAME = "vmfs", REQUIRED_ATTRS = "BRIDGE_LIST", PERSISTENT_ONLY = "NO"
|
||||
]
|
||||
|
||||
DS_MAD_CONF = [
|
||||
NAME = "vcenter", REQUIRED_ATTRS = "VCENTER_CLUSTER", PERSISTENT_ONLY = "YES"
|
||||
]
|
||||
|
||||
#*******************************************************************************
|
||||
# MarketPlace Driver Behavior Configuration
|
||||
#*******************************************************************************
|
||||
|
2
share/vendor/ruby/gems/rbvmomi/Rakefile
vendored
2
share/vendor/ruby/gems/rbvmomi/Rakefile
vendored
@ -1,5 +1,5 @@
|
||||
require 'rake/testtask'
|
||||
require 'rake/rdoctask'
|
||||
require 'rdoc/task'
|
||||
require 'yard'
|
||||
|
||||
begin
|
||||
|
2
share/vendor/ruby/gems/rbvmomi/VERSION
vendored
2
share/vendor/ruby/gems/rbvmomi/VERSION
vendored
@ -1 +1 @@
|
||||
1.6.0
|
||||
1.8.2
|
||||
|
@ -185,7 +185,9 @@ class ManagedObject < ObjectWithMethods
|
||||
:objectSet => [{ :obj => self }],
|
||||
}])[0]
|
||||
|
||||
if ret.propSet.empty?
|
||||
if !ret
|
||||
return nil
|
||||
elsif ret.propSet.empty?
|
||||
return nil if ret.missingSet.empty?
|
||||
raise ret.missingSet[0].fault
|
||||
else
|
||||
@ -217,7 +219,7 @@ class ManagedObject < ObjectWithMethods
|
||||
|
||||
def == x
|
||||
out = (x.class == self.class && x._ref == @ref)
|
||||
out = (out && x._connection.instanceUuid == self._connection.instanceUuid)
|
||||
out = (x._connection.instanceUuid == self._connection.instanceUuid) if out && x._connection.host
|
||||
out
|
||||
end
|
||||
|
||||
|
@ -115,27 +115,29 @@ class Connection < TrivialSoap
|
||||
# hic sunt dracones
|
||||
def obj2xml xml, name, type, is_array, o, attrs={}
|
||||
expected = type(type)
|
||||
fail "expected array, got #{o.class.wsdl_name}" if is_array and not (o.is_a? Array or (o.is_a? Hash and expected == BasicTypes::KeyValue))
|
||||
fail "expected array for '#{name}', got #{o.class.wsdl_name}" if is_array and not (o.is_a? Array or (o.is_a? Hash and expected == BasicTypes::KeyValue))
|
||||
case o
|
||||
when Array, BasicTypes::KeyValue
|
||||
if o.is_a? BasicTypes::KeyValue and expected != BasicTypes::KeyValue
|
||||
fail "expected #{expected.wsdl_name}, got KeyValue"
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got KeyValue"
|
||||
elsif expected == BasicTypes::KeyValue and not is_array
|
||||
xml.tag! name, attrs do
|
||||
xml.tag! 'key', o[0].to_s
|
||||
xml.tag! 'value', o[1].to_s
|
||||
end
|
||||
else
|
||||
fail "expected #{expected.wsdl_name}, got array" unless is_array
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got array" unless is_array
|
||||
o.each do |e|
|
||||
obj2xml xml, name, expected.wsdl_name, false, e, attrs
|
||||
end
|
||||
end
|
||||
when BasicTypes::ManagedObject
|
||||
fail "expected #{expected.wsdl_name}, got #{o.class.wsdl_name} for field #{name.inspect}" if expected and not expected >= o.class and not expected == BasicTypes::AnyType
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got #{o.class.wsdl_name} for field #{name.inspect}" if expected and not expected >= o.class and not expected == BasicTypes::AnyType
|
||||
xml.tag! name, o._ref, :type => o.class.wsdl_name
|
||||
when BasicTypes::DataObject
|
||||
fail "expected #{expected.wsdl_name}, got #{o.class.wsdl_name} for field #{name.inspect}" if expected and not expected >= o.class and not expected == BasicTypes::AnyType
|
||||
if expected and not expected >= o.class and not expected == BasicTypes::AnyType
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got #{o.class.wsdl_name} for field #{name.inspect}"
|
||||
end
|
||||
xml.tag! name, attrs.merge("xsi:type" => o.class.wsdl_name) do
|
||||
o.class.full_props_desc.each do |desc|
|
||||
if o.props.member? desc['name'].to_sym
|
||||
@ -151,11 +153,11 @@ class Connection < TrivialSoap
|
||||
if expected == BasicTypes::KeyValue and is_array
|
||||
obj2xml xml, name, type, is_array, o.to_a, attrs
|
||||
else
|
||||
fail "expected #{expected.wsdl_name}, got a hash" unless expected <= BasicTypes::DataObject
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got a hash" unless expected <= BasicTypes::DataObject
|
||||
obj2xml xml, name, type, false, expected.new(o), attrs
|
||||
end
|
||||
when true, false
|
||||
fail "expected #{expected.wsdl_name}, got a boolean" unless [BasicTypes::Boolean, BasicTypes::AnyType].member? expected
|
||||
fail "expected #{expected.wsdl_name} for '#{name}', got a boolean" unless [BasicTypes::Boolean, BasicTypes::AnyType].member? expected
|
||||
attrs['xsi:type'] = 'xsd:boolean' if expected == BasicTypes::AnyType
|
||||
xml.tag! name, (o ? '1' : '0'), attrs
|
||||
when Symbol, String
|
||||
@ -181,7 +183,7 @@ class Connection < TrivialSoap
|
||||
when BasicTypes::Int
|
||||
attrs['xsi:type'] = 'xsd:int'
|
||||
xml.tag! name, o.to_s, attrs
|
||||
else fail "unexpected object class #{o.class}"
|
||||
else fail "unexpected object class #{o.class} for '#{name}'"
|
||||
end
|
||||
xml
|
||||
rescue
|
||||
|
@ -43,6 +43,13 @@ class NewDeserializer
|
||||
|
||||
def deserialize node, type=nil
|
||||
type_attr = node['type']
|
||||
|
||||
# Work around for 1.5.x which doesn't populate node['type']
|
||||
# XXX what changed
|
||||
if node.attributes['type'] and not type_attr
|
||||
type_attr = node.attributes['type'].value
|
||||
end
|
||||
|
||||
type = type_attr if type_attr
|
||||
|
||||
if action = BUILTIN_TYPE_ACTIONS[type]
|
||||
@ -64,15 +71,18 @@ class NewDeserializer
|
||||
else fail
|
||||
end
|
||||
else
|
||||
if type =~ /:/
|
||||
type = type.split(":", 2)[1]
|
||||
end
|
||||
if type =~ /^ArrayOf/
|
||||
type = DEMANGLED_ARRAY_TYPES[$'] || $'
|
||||
return node.children.select(&:element?).map { |c| deserialize c, type }
|
||||
end
|
||||
|
||||
if type =~ /:/
|
||||
type = type.split(":", 2)[1]
|
||||
end
|
||||
klass = @loader.get(type) or fail "no such type #{type}"
|
||||
|
||||
klass = @loader.get(type) or fail "no such type '#{type}'"
|
||||
case klass.kind
|
||||
when :data
|
||||
traverse_data node, klass
|
||||
@ -229,7 +239,7 @@ class OldDeserializer
|
||||
end
|
||||
end
|
||||
|
||||
if ENV['RBVMOMI_NEW_DESERIALIZER'] == '1'
|
||||
if ENV['RBVMOMI_NEW_DESERIALIZER'] == '1' || true # Always use new one now
|
||||
Deserializer = NewDeserializer
|
||||
else
|
||||
Deserializer = OldDeserializer
|
||||
|
@ -49,9 +49,9 @@ class PBM < Connection
|
||||
@serviceInstance ||= VIM::PbmServiceInstance self, 'ServiceInstance'
|
||||
end
|
||||
|
||||
# Alias to serviceInstance.RetrieveServiceContent
|
||||
# Alias to serviceInstance.PbmRetrieveServiceContent
|
||||
def serviceContent
|
||||
@serviceContent ||= serviceInstance.RetrieveServiceContent
|
||||
@serviceContent ||= serviceInstance.PbmRetrieveServiceContent
|
||||
end
|
||||
|
||||
# @private
|
||||
|
61
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/sms.rb
vendored
Normal file
61
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/sms.rb
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
# Copyright (c) 2013 VMware, Inc. All Rights Reserved.
|
||||
require 'rbvmomi'
|
||||
module RbVmomi
|
||||
|
||||
# A connection to one vSphere SMS endpoint.
|
||||
# @see #serviceInstance
|
||||
class SMS < Connection
|
||||
# Connect to a vSphere SMS endpoint
|
||||
#
|
||||
# @param [VIM] Connection to main vSphere API endpoint
|
||||
# @param [Hash] opts The options hash.
|
||||
# @option opts [String] :host Host to connect to.
|
||||
# @option opts [Numeric] :port (443) Port to connect to.
|
||||
# @option opts [Boolean] :ssl (true) Whether to use SSL.
|
||||
# @option opts [Boolean] :insecure (false) If true, ignore SSL certificate errors.
|
||||
# @option opts [String] :path (/sms/sdk) SDK endpoint path.
|
||||
# @option opts [Boolean] :debug (false) If true, print SOAP traffic to stderr.
|
||||
def self.connect vim, opts = {}
|
||||
fail unless opts.is_a? Hash
|
||||
opts[:host] = vim.host
|
||||
opts[:ssl] = true unless opts.member? :ssl or opts[:"no-ssl"]
|
||||
opts[:insecure] ||= true
|
||||
opts[:port] ||= (opts[:ssl] ? 443 : 80)
|
||||
opts[:path] ||= '/sms/sdk'
|
||||
opts[:ns] ||= 'urn:sms'
|
||||
rev_given = opts[:rev] != nil
|
||||
opts[:rev] = '4.0' unless rev_given
|
||||
opts[:debug] = (!ENV['RBVMOMI_DEBUG'].empty? rescue false) unless opts.member? :debug
|
||||
|
||||
new(opts).tap do |sms|
|
||||
sms.vcSessionCookie = vim.cookie.split('"')[1]
|
||||
end
|
||||
end
|
||||
|
||||
def vcSessionCookie= cookie
|
||||
@vcSessionCookie = cookie
|
||||
end
|
||||
|
||||
def rev= x
|
||||
super
|
||||
@serviceContent = nil
|
||||
end
|
||||
|
||||
# Return the ServiceInstance
|
||||
#
|
||||
# The ServiceInstance is the root of the vSphere inventory.
|
||||
def serviceInstance
|
||||
@serviceInstance ||= VIM::SmsServiceInstance self, 'ServiceInstance'
|
||||
end
|
||||
|
||||
# @private
|
||||
def pretty_print pp
|
||||
pp.text "SMS(#{@opts[:host]})"
|
||||
end
|
||||
|
||||
add_extension_dir File.join(File.dirname(__FILE__), "sms")
|
||||
load_vmodl(ENV['VMODL'] || File.join(File.dirname(__FILE__), "../../vmodl.db"))
|
||||
end
|
||||
|
||||
end
|
||||
|
7
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/sms/SmsStorageManager.rb
vendored
Normal file
7
share/vendor/ruby/gems/rbvmomi/lib/rbvmomi/sms/SmsStorageManager.rb
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
class RbVmomi::SMS::SmsStorageManager
|
||||
|
||||
def RegisterProvider_Task2 providerSpec
|
||||
self.RegisterProvider_Task providerSpec
|
||||
end
|
||||
|
||||
end
|
@ -14,7 +14,7 @@ class RbVmomi::TrivialSoap
|
||||
@opts = opts
|
||||
return unless @opts[:host] # for testcases
|
||||
@debug = @opts[:debug]
|
||||
@cookie = nil
|
||||
@cookie = @opts[:cookie]
|
||||
@lock = Mutex.new
|
||||
@http = nil
|
||||
restart_http
|
||||
|
@ -52,7 +52,7 @@ class TypeLoader
|
||||
end
|
||||
|
||||
def get name
|
||||
fail unless name.is_a? String
|
||||
fail "name '#{name}' is #{name.class} expecting String" unless name.is_a? String
|
||||
|
||||
first_char = name[0].chr
|
||||
if first_char.downcase == first_char
|
||||
|
@ -41,6 +41,8 @@
|
||||
# computer (cluster), resource pool, vm_folder and datastore. Currently once
|
||||
# computed, a new updated placement can't be generated.
|
||||
class AdmissionControlledResourceScheduler
|
||||
attr_reader :rp
|
||||
|
||||
def initialize vim, opts = {}
|
||||
@vim = vim
|
||||
|
||||
@ -330,6 +332,10 @@ class AdmissionControlledResourceScheduler
|
||||
# datastore without much intelligence, as long as it passes admission control.
|
||||
# @return [VIM::Datastore] Chosen datastore
|
||||
def datastore placementHint = nil
|
||||
if @datastore
|
||||
return @datastore
|
||||
end
|
||||
|
||||
pod_datastores = pick_computer.datastore & datastores
|
||||
|
||||
eligible = pod_datastores.select do |ds|
|
||||
|
@ -102,6 +102,13 @@ class CachedOvfDeployer
|
||||
# simplicity this function assumes we need to read the OVF file
|
||||
# ourselves to know the names, and we map all of them to the same
|
||||
# VIM::Network.
|
||||
|
||||
# If we're handling a file:// URI we need to strip the scheme as open-uri
|
||||
# can't handle them.
|
||||
if URI(ovf_url).scheme == "file" && URI(ovf_url).host.nil?
|
||||
ovf_url = URI(ovf_url).path
|
||||
end
|
||||
|
||||
ovf = open(ovf_url, 'r'){|io| Nokogiri::XML(io.read)}
|
||||
ovf.remove_namespaces!
|
||||
networks = ovf.xpath('//NetworkSection/Network').map{|x| x['name']}
|
||||
@ -178,11 +185,10 @@ class CachedOvfDeployer
|
||||
# prepare it for (linked) cloning and mark it as a template to signal
|
||||
# we are done.
|
||||
if !wait_for_template
|
||||
vm.add_delta_disk_layer_on_all_disks
|
||||
if opts[:config]
|
||||
# XXX: Should we add a version that does retries?
|
||||
vm.ReconfigVM_Task(:spec => opts[:config]).wait_for_completion
|
||||
end
|
||||
config = opts[:config] || {}
|
||||
config = vm.update_spec_add_delta_disk_layer_on_all_disks(config)
|
||||
# XXX: Should we add a version that does retries?
|
||||
vm.ReconfigVM_Task(:spec => config).wait_for_completion
|
||||
vm.MarkAsTemplate
|
||||
end
|
||||
end
|
||||
@ -207,7 +213,7 @@ class CachedOvfDeployer
|
||||
# or nil
|
||||
def lookup_template template_name
|
||||
template_path = "#{template_name}-#{@computer.name}"
|
||||
template = @template_folder.traverse(template_path, VIM::VirtualMachine)
|
||||
template = @template_folder.traverse(template_path, RbVmomi::VIM::VirtualMachine)
|
||||
if template
|
||||
config = template.config
|
||||
is_template = config && config.template
|
||||
|
@ -93,7 +93,8 @@ class PerfAggregator
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsFolder'),
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsDatacenterVmFolder'),
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsDatacenterHostFolder'),
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsCluster'),
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsClusterRP'),
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsClusterHost'),
|
||||
]
|
||||
),
|
||||
RbVmomi::VIM.TraversalSpec(
|
||||
@ -115,7 +116,7 @@ class PerfAggregator
|
||||
]
|
||||
),
|
||||
RbVmomi::VIM.TraversalSpec(
|
||||
:name => 'tsCluster',
|
||||
:name => 'tsClusterRP',
|
||||
:type => 'ClusterComputeResource',
|
||||
:path => 'resourcePool',
|
||||
:skip => false,
|
||||
@ -123,6 +124,13 @@ class PerfAggregator
|
||||
RbVmomi::VIM.SelectionSpec(:name => 'tsRP'),
|
||||
]
|
||||
),
|
||||
RbVmomi::VIM.TraversalSpec(
|
||||
:name => 'tsClusterHost',
|
||||
:type => 'ClusterComputeResource',
|
||||
:path => 'host',
|
||||
:skip => false,
|
||||
:selectSet => []
|
||||
),
|
||||
RbVmomi::VIM.TraversalSpec(
|
||||
:name => 'tsRP',
|
||||
:type => 'ResourcePool',
|
||||
@ -141,6 +149,7 @@ class PerfAggregator
|
||||
:pathSet => ['name', 'parent', 'summary.effectiveCpu', 'summary.effectiveMemory']
|
||||
},
|
||||
{ :type => 'ResourcePool', :pathSet => ['name', 'parent'] },
|
||||
{ :type => 'HostSystem', :pathSet => ['name', 'parent', 'runtime.connectionState'] },
|
||||
{ :type => 'VirtualMachine', :pathSet => vm_prop_names },
|
||||
]
|
||||
)
|
||||
@ -316,9 +325,18 @@ class PerfAggregator
|
||||
'virtualDisk.totalWriteLatency' => :avg_ignore_zero,
|
||||
}
|
||||
end
|
||||
host_perf_metrics = opts[:host_perf_metrics]
|
||||
if !host_perf_metrics
|
||||
host_perf_metrics = {
|
||||
'cpu.usage' => :avg,
|
||||
'mem.usage' => :avg,
|
||||
}
|
||||
end
|
||||
|
||||
vms_props, inventory = all_inventory_flat root_folder, prop_names
|
||||
vms = vms_props.keys
|
||||
|
||||
hosts_props = inventory.select{|k, v| k.is_a?(VIM::HostSystem)}
|
||||
|
||||
conn = root_folder._connection
|
||||
sc = conn.serviceContent
|
||||
@ -349,8 +367,31 @@ class PerfAggregator
|
||||
end
|
||||
raise
|
||||
end
|
||||
|
||||
connected_hosts = hosts_props.select do |k,v|
|
||||
v['runtime.connectionState'] != "disconnected"
|
||||
end
|
||||
if connected_hosts.length > 0
|
||||
hosts_stats = pm.retrieve_stats(
|
||||
connected_hosts.keys, host_perf_metrics.keys,
|
||||
:max_samples => 3
|
||||
)
|
||||
end
|
||||
hosts_props.each do |host, props|
|
||||
if !connected_hosts[host]
|
||||
next
|
||||
end
|
||||
|
||||
stats = hosts_stats[host] || {}
|
||||
stats = stats[:metrics] || {}
|
||||
stats = _aggregate_metrics [stats], host_perf_metrics
|
||||
props.merge!(stats)
|
||||
end
|
||||
|
||||
vms_props.each do |vm, props|
|
||||
if !connected_vms.member?(vm)
|
||||
next
|
||||
end
|
||||
props['num.vm'] = 1
|
||||
powered_on = (props['runtime.powerState'] == 'poweredOn')
|
||||
props['num.poweredonvm'] = powered_on ? 1 : 0
|
||||
@ -392,25 +433,35 @@ class PerfAggregator
|
||||
props['vc_uuid'] = vc_uuid
|
||||
end
|
||||
|
||||
[vms_props, inventory]
|
||||
[vms_props, inventory, hosts_props]
|
||||
end
|
||||
|
||||
def collect_info_on_all_vms root_folders, opts = {}
|
||||
log "Fetching information from all VCs ..."
|
||||
vms_props = {}
|
||||
hosts_props = {}
|
||||
inventory = {}
|
||||
lock = Mutex.new
|
||||
root_folders.map do |root_folder|
|
||||
Thread.new do
|
||||
single_vms_props, single_inventory =
|
||||
_collect_info_on_all_vms_single(root_folder, opts)
|
||||
|
||||
lock.synchronize do
|
||||
vms_props.merge!(single_vms_props)
|
||||
if inventory['root']
|
||||
single_inventory['root']['children'] += inventory['root']['children']
|
||||
begin
|
||||
single_vms_props, single_inventory, single_hosts_props =
|
||||
_collect_info_on_all_vms_single(root_folder, opts)
|
||||
|
||||
lock.synchronize do
|
||||
vms_props.merge!(single_vms_props)
|
||||
if inventory['root']
|
||||
single_inventory['root']['children'] += inventory['root']['children']
|
||||
end
|
||||
inventory.merge!(single_inventory)
|
||||
hosts_props.merge!(single_hosts_props)
|
||||
end
|
||||
inventory.merge!(single_inventory)
|
||||
rescue Exception => ex
|
||||
log "#{ex.class}: #{ex.message}"
|
||||
ex.backtrace.each do |line|
|
||||
log line
|
||||
end
|
||||
raise
|
||||
end
|
||||
end
|
||||
end.each{|t| t.join}
|
||||
@ -418,6 +469,7 @@ class PerfAggregator
|
||||
log "Make data marshal friendly ..."
|
||||
inventory = _make_marshal_friendly(inventory)
|
||||
vms_props = _make_marshal_friendly(vms_props)
|
||||
hosts_props = _make_marshal_friendly(hosts_props)
|
||||
|
||||
log "Perform external post processing ..."
|
||||
if @vm_processing_callback
|
||||
@ -442,7 +494,11 @@ class PerfAggregator
|
||||
@inventory = inventory
|
||||
@vms_props = vms_props
|
||||
|
||||
nil
|
||||
{
|
||||
'inventory' => inventory,
|
||||
'vms_props' => vms_props,
|
||||
'hosts_props' => hosts_props,
|
||||
}
|
||||
end
|
||||
|
||||
def _make_marshal_friendly hash
|
||||
|
@ -13,6 +13,7 @@ class VIM < Connection
|
||||
# @option opts [Numeric] :port (443) Port to connect to.
|
||||
# @option opts [Boolean] :ssl (true) Whether to use SSL.
|
||||
# @option opts [Boolean] :insecure (false) If true, ignore SSL certificate errors.
|
||||
# @option opts [String] :cookie If set, use cookie to connect instead of user/password
|
||||
# @option opts [String] :user (root) Username.
|
||||
# @option opts [String] :password Password.
|
||||
# @option opts [String] :path (/sdk) SDK endpoint path.
|
||||
@ -20,6 +21,7 @@ class VIM < Connection
|
||||
def self.connect opts
|
||||
fail unless opts.is_a? Hash
|
||||
fail "host option required" unless opts[:host]
|
||||
opts[:cookie] ||= nil
|
||||
opts[:user] ||= 'root'
|
||||
opts[:password] ||= ''
|
||||
opts[:ssl] = true unless opts.member? :ssl or opts[:"no-ssl"]
|
||||
@ -32,10 +34,12 @@ class VIM < Connection
|
||||
opts[:debug] = (!ENV['RBVMOMI_DEBUG'].empty? rescue false) unless opts.member? :debug
|
||||
|
||||
new(opts).tap do |vim|
|
||||
vim.serviceContent.sessionManager.Login :userName => opts[:user], :password => opts[:password]
|
||||
unless opts[:cookie]
|
||||
vim.serviceContent.sessionManager.Login :userName => opts[:user], :password => opts[:password]
|
||||
end
|
||||
unless rev_given
|
||||
rev = vim.serviceContent.about.apiVersion
|
||||
vim.rev = [rev, '5.0'].min
|
||||
vim.rev = [rev, '5.5'].min
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -45,7 +49,7 @@ class VIM < Connection
|
||||
self.cookie = nil
|
||||
super
|
||||
end
|
||||
|
||||
|
||||
def rev= x
|
||||
super
|
||||
@serviceContent = nil
|
||||
@ -85,11 +89,36 @@ class VIM < Connection
|
||||
def pretty_print pp
|
||||
pp.text "VIM(#{@opts[:host]})"
|
||||
end
|
||||
|
||||
|
||||
def instanceUuid
|
||||
serviceContent.about.instanceUuid
|
||||
end
|
||||
|
||||
def get_log_lines logKey, lines=5, start=nil, host=nil
|
||||
diagMgr = self.serviceContent.diagnosticManager
|
||||
if !start
|
||||
log = diagMgr.BrowseDiagnosticLog(:host => host, :key => logKey, :start => 999999999)
|
||||
lineEnd = log.lineEnd
|
||||
start = lineEnd - lines
|
||||
end
|
||||
start = start < 0 ? 0 : start
|
||||
log = diagMgr.BrowseDiagnosticLog(:host => host, :key => logKey, :start => start)
|
||||
if log.lineText.size > 0
|
||||
[log.lineText.slice(-lines, log.lineText.size), log.lineEnd]
|
||||
else
|
||||
[log.lineText, log.lineEnd]
|
||||
end
|
||||
end
|
||||
|
||||
def get_log_keys host=nil
|
||||
diagMgr = self.serviceContent.diagnosticManager
|
||||
keys = []
|
||||
diagMgr.QueryDescriptions(:host => host).each do |desc|
|
||||
keys << "#{desc.key}"
|
||||
end
|
||||
keys
|
||||
end
|
||||
|
||||
add_extension_dir File.join(File.dirname(__FILE__), "vim")
|
||||
(ENV['RBVMOMI_VIM_EXTENSION_PATH']||'').split(':').each { |dir| add_extension_dir dir }
|
||||
|
||||
|
@ -53,6 +53,16 @@ class RbVmomi::VIM::Folder
|
||||
x if x.is_a? type
|
||||
end
|
||||
|
||||
# Retrieve a managed entity by inventory path.
|
||||
# @param path [String] A path of the form "My Folder/My Datacenter/vm/Discovered VM/VM1"
|
||||
# @return [VIM::ManagedEntity]
|
||||
def findByInventoryPath path
|
||||
propSpecs = {
|
||||
:entity => self, :inventoryPath => path
|
||||
}
|
||||
x = _connection.searchIndex.FindByInventoryPath(propSpecs)
|
||||
end
|
||||
|
||||
# Alias to <tt>traverse path, type, true</tt>
|
||||
# @see #traverse
|
||||
def traverse! path, type=Object
|
||||
|
@ -35,7 +35,12 @@ class RbVmomi::VIM::ManagedObject
|
||||
:type => self.class.wsdl_name
|
||||
}]
|
||||
}
|
||||
_connection.propertyCollector.RetrieveProperties(:specSet => [spec])[0].to_hash
|
||||
ret = _connection.propertyCollector.RetrieveProperties(:specSet => [spec])
|
||||
if ret && ret.length > 0
|
||||
ret[0].to_hash
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
# Efficiently retrieve multiple properties from an object.
|
||||
|
@ -48,7 +48,16 @@ class RbVmomi::VIM::OvfManager
|
||||
result.warning.each{|x| puts "OVF Warning: #{x.localizedMessage.chomp}" }
|
||||
end
|
||||
|
||||
nfcLease = opts[:resourcePool].ImportVApp(:spec => result.importSpec,
|
||||
importSpec = result.importSpec
|
||||
if importSpec && importSpec.instantiationOst && importSpec.instantiationOst.child
|
||||
importSpec.instantiationOst.child.each do |child|
|
||||
child.section.map do |section|
|
||||
section.xml = _handle_ost(section.xml, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
nfcLease = opts[:resourcePool].ImportVApp(:spec => importSpec,
|
||||
:folder => opts[:vmFolder],
|
||||
:host => opts[:host])
|
||||
|
||||
@ -56,30 +65,70 @@ class RbVmomi::VIM::OvfManager
|
||||
raise nfcLease.error if nfcLease.state == "error"
|
||||
begin
|
||||
nfcLease.HttpNfcLeaseProgress(:percent => 5)
|
||||
timeout, = nfcLease.collect 'info.leaseTimeout'
|
||||
puts "DEBUG: Timeout: #{timeout}"
|
||||
if timeout < 4 * 60
|
||||
puts "WARNING: OVF upload NFC lease timeout less than 4 minutes"
|
||||
end
|
||||
progress = 5.0
|
||||
result.fileItem.each do |fileItem|
|
||||
deviceUrl = nfcLease.info.deviceUrl.find{|x| x.importKey == fileItem.deviceId}
|
||||
leaseInfo, leaseState, leaseError = nfcLease.collect 'info', 'state', 'error'
|
||||
# Retry nfcLease.collect because of PR 969599:
|
||||
# If retrying property collector works, this means there is a network
|
||||
# or VC overloading problem.
|
||||
retrynum = 5
|
||||
i = 1
|
||||
while i <= retrynum && !leaseState
|
||||
puts "Retrying at iteration #{i}"
|
||||
sleep 1
|
||||
leaseInfo, leaseState, leaseError = nfcLease.collect 'info', 'state', 'error'
|
||||
i += 1
|
||||
end
|
||||
if leaseState != "ready"
|
||||
raise "NFC lease is no longer ready: #{leaseState}: #{leaseError}"
|
||||
end
|
||||
if leaseInfo == nil
|
||||
raise "NFC lease disappeared?"
|
||||
end
|
||||
deviceUrl = leaseInfo.deviceUrl.find{|x| x.importKey == fileItem.deviceId}
|
||||
if !deviceUrl
|
||||
raise "Couldn't find deviceURL for device '#{fileItem.deviceId}'"
|
||||
end
|
||||
|
||||
# XXX handle file:// URIs
|
||||
ovfFilename = opts[:uri].to_s
|
||||
tmp = ovfFilename.split(/\//)
|
||||
tmp.pop
|
||||
tmp << fileItem.path
|
||||
filename = tmp.join("/")
|
||||
|
||||
# If filename doesn't have a URI scheme, we're considering it a local file
|
||||
if URI(filename).scheme.nil?
|
||||
filename = "file://" + filename
|
||||
end
|
||||
|
||||
method = fileItem.create ? "PUT" : "POST"
|
||||
|
||||
keepAliveThread = Thread.new do
|
||||
while true
|
||||
sleep 2 * 60
|
||||
nfcLease.HttpNfcLeaseProgress(:percent => progress.to_i)
|
||||
sleep 1 * 60
|
||||
end
|
||||
end
|
||||
|
||||
href = deviceUrl.url.gsub("*", opts[:host].config.network.vnic[0].spec.ip.ipAddress)
|
||||
i = 1
|
||||
ip = nil
|
||||
begin
|
||||
begin
|
||||
puts "Iteration #{i}: Trying to get host's IP address ..."
|
||||
ip = opts[:host].config.network.vnic[0].spec.ip.ipAddress
|
||||
rescue Exception=>e
|
||||
puts "Iteration #{i}: Couldn't get host's IP address: #{e}"
|
||||
end
|
||||
sleep 1
|
||||
i += 1
|
||||
end while i <= 5 && !ip
|
||||
raise "Couldn't get host's IP address" unless ip
|
||||
href = deviceUrl.url.gsub("*", ip)
|
||||
downloadCmd = "#{CURLBIN} -L '#{URI::escape(filename)}'"
|
||||
uploadCmd = "#{CURLBIN} -Ss -X #{method} --insecure -T - -H 'Content-Type: application/x-vnd.vmware-streamVmdk' '#{URI::escape(href)}'"
|
||||
# Previously we used to append "-H 'Content-Length: #{fileItem.size}'"
|
||||
@ -96,12 +145,56 @@ class RbVmomi::VIM::OvfManager
|
||||
end
|
||||
|
||||
nfcLease.HttpNfcLeaseProgress(:percent => 100)
|
||||
vm = nfcLease.info.entity
|
||||
nfcLease.HttpNfcLeaseComplete
|
||||
raise nfcLease.error if nfcLease.state == "error"
|
||||
i = 1
|
||||
vm = nil
|
||||
begin
|
||||
begin
|
||||
puts "Iteration #{i}: Trying to access nfcLease.info.entity ..."
|
||||
vm = nfcLease.info.entity
|
||||
rescue Exception=>e
|
||||
puts "Iteration #{i}: Couldn't access nfcLease.info.entity: #{e}"
|
||||
end
|
||||
sleep 1
|
||||
i += 1
|
||||
end while i <= 5 && !vm
|
||||
raise "Couldn't access nfcLease.info.entity" unless vm
|
||||
|
||||
# Ignore sporadic connection errors caused by PR 1019166..
|
||||
# Three attempts are made to execute HttpNfcLeaseComplete.
|
||||
# Not critical if none goes through, as long as vm is obtained
|
||||
#
|
||||
# TODO: find the reason why HttpNfcLeaseComplete gets a wrong
|
||||
# response (RetrievePropertiesResponse)
|
||||
i = 0
|
||||
begin
|
||||
nfcLease.HttpNfcLeaseComplete
|
||||
puts "HttpNfcLeaseComplete succeeded"
|
||||
rescue RbVmomi::VIM::InvalidState
|
||||
puts "HttpNfcLeaseComplete already finished.."
|
||||
rescue Exception => e
|
||||
puts "HttpNfcLeaseComplete failed at iteration #{i} with exception: #{e}"
|
||||
i += 1
|
||||
retry if i < 3
|
||||
puts "Giving up HttpNfcLeaseComplete.."
|
||||
end
|
||||
vm
|
||||
end
|
||||
rescue Exception
|
||||
(nfcLease.HttpNfcLeaseAbort rescue nil) if nfcLease
|
||||
raise
|
||||
end
|
||||
|
||||
def _handle_ost ost, opts = {}
|
||||
ost = Nokogiri::XML(ost)
|
||||
if opts[:vservice] == ['com.vmware.vim.vsm:extension_vservice']
|
||||
ost.xpath('//vmw:Annotations/vmw:Providers/vmw:Provider').each do |x|
|
||||
x['vmw:selected'] = 'selected'
|
||||
end
|
||||
ost.xpath('//vmw:Annotations/vmw:Providers').each do |x|
|
||||
x['vmw:selected'] = 'com.vmware.vim.vsm:extension_vservice'
|
||||
end
|
||||
end
|
||||
ost.to_s
|
||||
end
|
||||
end
|
||||
|
@ -46,13 +46,21 @@ class RbVmomi::VIM::PerformanceManager
|
||||
end
|
||||
end
|
||||
|
||||
metric_ids = metrics.map do |x|
|
||||
instances = opts[:instance] || '*'
|
||||
if !instances.is_a?(Array)
|
||||
instances = [instances]
|
||||
end
|
||||
metric_ids = []
|
||||
metrics.each do |x|
|
||||
counter = perfcounter_hash[x]
|
||||
if !counter
|
||||
pp perfcounter_hash.keys
|
||||
fail "Counter for #{x} couldn't be found"
|
||||
end
|
||||
RbVmomi::VIM::PerfMetricId(:counterId => counter.key, :instance => '*')
|
||||
instances.each do |instance|
|
||||
metric_ids << RbVmomi::VIM::PerfMetricId(:counterId => counter.key,
|
||||
:instance => instance)
|
||||
end
|
||||
end
|
||||
query_specs = objects.map do |obj|
|
||||
RbVmomi::VIM::PerfQuerySpec({
|
||||
@ -65,19 +73,36 @@ class RbVmomi::VIM::PerformanceManager
|
||||
end
|
||||
stats = QueryPerf(:querySpec => query_specs)
|
||||
|
||||
Hash[stats.map do |res|
|
||||
[
|
||||
res.entity,
|
||||
{
|
||||
:sampleInfo => res.sampleInfo,
|
||||
:metrics => Hash[res.value.map do |metric|
|
||||
[perfcounter_idhash[metric.id.counterId].name, metric.value]
|
||||
end]
|
||||
}
|
||||
]
|
||||
end]
|
||||
if !opts[:multi_instance]
|
||||
Hash[stats.map do |res|
|
||||
[
|
||||
res.entity,
|
||||
{
|
||||
:sampleInfo => res.sampleInfo,
|
||||
:metrics => Hash[res.value.map do |metric|
|
||||
metric_name = perfcounter_idhash[metric.id.counterId].name
|
||||
[metric_name, metric.value]
|
||||
end]
|
||||
}
|
||||
]
|
||||
end]
|
||||
else
|
||||
Hash[stats.map do |res|
|
||||
[
|
||||
res.entity,
|
||||
{
|
||||
:sampleInfo => res.sampleInfo,
|
||||
:metrics => Hash[res.value.map do |metric|
|
||||
metric_name = perfcounter_idhash[metric.id.counterId].name
|
||||
[[metric_name, metric.id.instance], metric.value]
|
||||
end]
|
||||
}
|
||||
]
|
||||
end]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def active_intervals
|
||||
intervals = historicalInterval
|
||||
Hash[(1..4).map { |level| [level, intervals.select { |x| x.enabled && x.level >= level }] }]
|
||||
|
@ -34,26 +34,41 @@ class RbVmomi::VIM::VirtualMachine
|
||||
def add_delta_disk_layer_on_all_disks
|
||||
devices, = self.collect 'config.hardware.device'
|
||||
disks = devices.grep(RbVmomi::VIM::VirtualDisk)
|
||||
# XXX: Should create a single reconfig spec instead of one per disk
|
||||
spec = update_spec_add_delta_disk_layer_on_all_disks
|
||||
self.ReconfigVM_Task(:spec => spec).wait_for_completion
|
||||
end
|
||||
|
||||
# Updates a passed in spec to perform the task of adding a delta disk layer
|
||||
# on top of all disks. Does the same as add_delta_disk_layer_on_all_disks
|
||||
# but instead of issuing the ReconfigVM_Task, it just constructs the
|
||||
# spec, so that the caller can batch a couple of updates into one
|
||||
# ReconfigVM_Task.
|
||||
def update_spec_add_delta_disk_layer_on_all_disks spec = {}
|
||||
devices, = self.collect 'config.hardware.device'
|
||||
disks = devices.grep(RbVmomi::VIM::VirtualDisk)
|
||||
device_change = []
|
||||
disks.each do |disk|
|
||||
spec = {
|
||||
:deviceChange => [
|
||||
{
|
||||
:operation => :remove,
|
||||
:device => disk
|
||||
},
|
||||
{
|
||||
:operation => :add,
|
||||
:fileOperation => :create,
|
||||
:device => disk.dup.tap { |x|
|
||||
x.backing = x.backing.dup
|
||||
x.backing.fileName = "[#{disk.backing.datastore.name}]"
|
||||
x.backing.parent = disk.backing
|
||||
},
|
||||
}
|
||||
]
|
||||
device_change << {
|
||||
:operation => :remove,
|
||||
:device => disk
|
||||
}
|
||||
device_change << {
|
||||
:operation => :add,
|
||||
:fileOperation => :create,
|
||||
:device => disk.dup.tap { |x|
|
||||
x.backing = x.backing.dup
|
||||
x.backing.fileName = "[#{disk.backing.datastore.name}]"
|
||||
x.backing.parent = disk.backing
|
||||
},
|
||||
}
|
||||
self.ReconfigVM_Task(:spec => spec).wait_for_completion
|
||||
end
|
||||
if spec.is_a?(RbVmomi::VIM::VirtualMachineConfigSpec)
|
||||
spec.deviceChange ||= []
|
||||
spec.deviceChange += device_change
|
||||
else
|
||||
spec[:deviceChange] ||= []
|
||||
spec[:deviceChange] += device_change
|
||||
end
|
||||
spec
|
||||
end
|
||||
end
|
||||
|
BIN
share/vendor/ruby/gems/rbvmomi/vmodl.db
vendored
BIN
share/vendor/ruby/gems/rbvmomi/vmodl.db
vendored
Binary file not shown.
@ -209,8 +209,6 @@ const bool AclManager::authorize(
|
||||
const PoolObjectAuth& obj_perms,
|
||||
AuthRequest::Operation op)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
bool auth = false;
|
||||
|
||||
// Build masks for request
|
||||
@ -241,17 +239,19 @@ const bool AclManager::authorize(
|
||||
resource_gid_req = AclRule::NONE_ID;
|
||||
}
|
||||
|
||||
long long resource_cid_req;
|
||||
set<long long> resource_cid_req;
|
||||
|
||||
if ((obj_perms.cid >= 0) && (!obj_perms.disable_cluster_acl))
|
||||
if (!obj_perms.disable_cluster_acl)
|
||||
{
|
||||
resource_cid_req = obj_perms.obj_type |
|
||||
AclRule::CLUSTER_ID |
|
||||
obj_perms.cid;
|
||||
}
|
||||
else
|
||||
{
|
||||
resource_cid_req = AclRule::NONE_ID;
|
||||
set<int>::iterator i;
|
||||
|
||||
for(i = obj_perms.cids.begin(); i != obj_perms.cids.end(); i++)
|
||||
{
|
||||
resource_cid_req.insert( obj_perms.obj_type |
|
||||
AclRule::CLUSTER_ID |
|
||||
*i
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
long long resource_all_req ;
|
||||
@ -279,34 +279,35 @@ const bool AclManager::authorize(
|
||||
AclRule::CLUSTER_ID |
|
||||
0x00000000FFFFFFFFLL;
|
||||
|
||||
// Create a temporal rule, to log the request
|
||||
long long log_resource;
|
||||
if (NebulaLog::log_level() >= Log::DDEBUG)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
if ( obj_perms.oid >= 0 )
|
||||
{
|
||||
log_resource = resource_oid_req;
|
||||
}
|
||||
else if ( obj_perms.gid >= 0 )
|
||||
{
|
||||
log_resource = resource_gid_req;
|
||||
}
|
||||
else if ( obj_perms.cid >= 0 )
|
||||
{
|
||||
log_resource = resource_cid_req;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_resource = resource_all_req;
|
||||
}
|
||||
// Create a temporal rule, to log the request
|
||||
long long log_resource;
|
||||
|
||||
AclRule log_rule(-1,
|
||||
AclRule::INDIVIDUAL_ID | uid,
|
||||
log_resource,
|
||||
rights_req,
|
||||
AclRule::INDIVIDUAL_ID | zone_id);
|
||||
if ( obj_perms.oid >= 0 )
|
||||
{
|
||||
log_resource = resource_oid_req;
|
||||
}
|
||||
else if ( obj_perms.gid >= 0 )
|
||||
{
|
||||
log_resource = resource_gid_req;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_resource = resource_all_req;
|
||||
}
|
||||
|
||||
oss << "Request " << log_rule.to_str();
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
AclRule log_rule(-1,
|
||||
AclRule::INDIVIDUAL_ID | uid,
|
||||
log_resource,
|
||||
rights_req,
|
||||
AclRule::INDIVIDUAL_ID | zone_id);
|
||||
|
||||
oss << "Request " << log_rule.to_str();
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Create temporary rules from the object permissions
|
||||
@ -388,8 +389,7 @@ const bool AclManager::authorize(
|
||||
}
|
||||
}
|
||||
|
||||
oss.str("No more rules, permission not granted ");
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
NebulaLog::log("ACL",Log::DDEBUG,"No more rules, permission not granted ");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -398,16 +398,16 @@ const bool AclManager::authorize(
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
bool AclManager::match_rules_wrapper(
|
||||
long long user_req,
|
||||
long long resource_oid_req,
|
||||
long long resource_gid_req,
|
||||
long long resource_cid_req,
|
||||
long long resource_all_req,
|
||||
long long rights_req,
|
||||
long long individual_obj_type,
|
||||
long long group_obj_type,
|
||||
long long cluster_obj_type,
|
||||
multimap<long long, AclRule*> &tmp_rules)
|
||||
long long user_req,
|
||||
long long resource_oid_req,
|
||||
long long resource_gid_req,
|
||||
const set<long long>& resource_cid_req,
|
||||
long long resource_all_req,
|
||||
long long rights_req,
|
||||
long long individual_obj_type,
|
||||
long long group_obj_type,
|
||||
long long cluster_obj_type,
|
||||
const multimap<long long, AclRule*> &tmp_rules)
|
||||
{
|
||||
bool auth = false;
|
||||
|
||||
@ -452,26 +452,47 @@ bool AclManager::match_rules_wrapper(
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
bool AclManager::match_rules(
|
||||
long long user_req,
|
||||
long long resource_oid_req,
|
||||
long long resource_gid_req,
|
||||
long long resource_cid_req,
|
||||
long long resource_all_req,
|
||||
long long rights_req,
|
||||
long long resource_oid_mask,
|
||||
long long resource_gid_mask,
|
||||
static bool match_cluster_req(
|
||||
const set<long long> &resource_cid_req,
|
||||
long long resource_cid_mask,
|
||||
multimap<long long, AclRule*> &rules)
|
||||
long long rule_resource)
|
||||
{
|
||||
set<long long>::iterator i;
|
||||
|
||||
for(i = resource_cid_req.begin(); i != resource_cid_req.end(); i++)
|
||||
{
|
||||
// rule's object type and cluster object ID match
|
||||
if ( ( rule_resource & resource_cid_mask ) == *i )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
bool AclManager::match_rules(
|
||||
long long user_req,
|
||||
long long resource_oid_req,
|
||||
long long resource_gid_req,
|
||||
const set<long long>& resource_cid_req,
|
||||
long long resource_all_req,
|
||||
long long rights_req,
|
||||
long long resource_oid_mask,
|
||||
long long resource_gid_mask,
|
||||
long long resource_cid_mask,
|
||||
const multimap<long long, AclRule*> &rules)
|
||||
|
||||
{
|
||||
bool auth = false;
|
||||
ostringstream oss;
|
||||
|
||||
multimap<long long, AclRule *>::iterator it;
|
||||
multimap<long long, AclRule *>::const_iterator it;
|
||||
|
||||
pair<multimap<long long, AclRule *>::iterator,
|
||||
multimap<long long, AclRule *>::iterator> index;
|
||||
pair<multimap<long long, AclRule *>::const_iterator,
|
||||
multimap<long long, AclRule *>::const_iterator> index;
|
||||
|
||||
long long zone_oid_mask = AclRule::INDIVIDUAL_ID | 0x00000000FFFFFFFFLL;
|
||||
long long zone_req = AclRule::INDIVIDUAL_ID | zone_id;
|
||||
@ -481,9 +502,12 @@ bool AclManager::match_rules(
|
||||
|
||||
for ( it = index.first; it != index.second; it++)
|
||||
{
|
||||
oss.str("");
|
||||
oss << "> Rule " << it->second->to_str();
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
if (NebulaLog::log_level() >= Log::DDEBUG)
|
||||
{
|
||||
oss.str("");
|
||||
oss << "> Rule " << it->second->to_str();
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
}
|
||||
|
||||
auth =
|
||||
(
|
||||
@ -507,14 +531,14 @@ bool AclManager::match_rules(
|
||||
// Or rule's object type and individual object ID match
|
||||
( ( it->second->resource & resource_oid_mask ) == resource_oid_req )
|
||||
||
|
||||
// Or rule's object type and cluster object ID match
|
||||
( ( it->second->resource & resource_cid_mask ) == resource_cid_req )
|
||||
// Or rule's object type and one of the cluster object ID match
|
||||
match_cluster_req(resource_cid_req, resource_cid_mask,
|
||||
it->second->resource)
|
||||
);
|
||||
|
||||
if ( auth == true )
|
||||
{
|
||||
oss.str("Permission granted");
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
NebulaLog::log("ACL",Log::DDEBUG,"Permission granted");
|
||||
|
||||
break;
|
||||
}
|
||||
@ -960,19 +984,22 @@ void AclManager::reverse_search(int uid,
|
||||
|
||||
long long zone_all_req = AclRule::ALL_ID;
|
||||
|
||||
// Create a temporal rule, to log the request
|
||||
long long log_resource;
|
||||
if (NebulaLog::log_level() >= Log::DDEBUG)
|
||||
{
|
||||
// Create a temporal rule, to log the request
|
||||
long long log_resource;
|
||||
|
||||
log_resource = resource_all_req;
|
||||
log_resource = resource_all_req;
|
||||
|
||||
AclRule log_rule(-1,
|
||||
AclRule::INDIVIDUAL_ID | uid,
|
||||
log_resource,
|
||||
rights_req,
|
||||
zone_oid_req);
|
||||
AclRule log_rule(-1,
|
||||
AclRule::INDIVIDUAL_ID | uid,
|
||||
log_resource,
|
||||
rights_req,
|
||||
zone_oid_req);
|
||||
|
||||
oss << "Reverse search request " << log_rule.to_str();
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
oss << "Reverse search request " << log_rule.to_str();
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Look for the rules that match
|
||||
@ -1015,9 +1042,12 @@ void AclManager::reverse_search(int uid,
|
||||
)
|
||||
)
|
||||
{
|
||||
oss.str("");
|
||||
oss << "> Rule " << it->second->to_str();
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
if (NebulaLog::log_level() >= Log::DDEBUG)
|
||||
{
|
||||
oss.str("");
|
||||
oss << "> Rule " << it->second->to_str();
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
}
|
||||
|
||||
// Rule grants permission for all objects of this type
|
||||
if ((!disable_all_acl) &&
|
||||
@ -1099,7 +1129,6 @@ int AclManager::select_cb(void *nil, int num, char **values, char **names)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ostringstream oss;
|
||||
istringstream iss;
|
||||
|
||||
int oid = atoi(values[0]);
|
||||
@ -1126,8 +1155,13 @@ int AclManager::select_cb(void *nil, int num, char **values, char **names)
|
||||
rule_values[2],
|
||||
rule_values[3]);
|
||||
|
||||
oss << "Loading ACL Rule " << rule->to_str();
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
if (NebulaLog::log_level() >= Log::DDEBUG)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
||||
oss << "Loading ACL Rule " << rule->to_str();
|
||||
NebulaLog::log("ACL",Log::DDEBUG,oss);
|
||||
}
|
||||
|
||||
acl_rules.insert( make_pair(rule->user, rule) );
|
||||
acl_rules_oids.insert( make_pair(rule->oid, rule) );
|
||||
|
@ -27,8 +27,8 @@
|
||||
:size: 5
|
||||
:left: true
|
||||
|
||||
:CLUSTER:
|
||||
:desc: Name of the Cluster
|
||||
:CLUSTERS:
|
||||
:desc: Cluster IDs
|
||||
:size: 12
|
||||
:left: true
|
||||
|
||||
@ -61,7 +61,7 @@
|
||||
- :NAME
|
||||
- :SIZE
|
||||
- :AVAIL
|
||||
- :CLUSTER
|
||||
- :CLUSTERS
|
||||
- :IMAGES
|
||||
- :TYPE
|
||||
- :DS
|
||||
|
@ -18,8 +18,8 @@
|
||||
:size: 19
|
||||
:left: true
|
||||
|
||||
:CLUSTER:
|
||||
:desc: Name of the Cluster
|
||||
:CLUSTERS:
|
||||
:desc: Cluster IDs
|
||||
:size: 10
|
||||
:left: true
|
||||
|
||||
@ -37,6 +37,6 @@
|
||||
- :USER
|
||||
- :GROUP
|
||||
- :NAME
|
||||
- :CLUSTER
|
||||
- :CLUSTERS
|
||||
- :BRIDGE
|
||||
- :LEASES
|
||||
|
@ -289,8 +289,8 @@ EOT
|
||||
:name => 'ssh',
|
||||
:large => '--ssh [file]',
|
||||
:description => "Add an ssh public key to the context. If the \n"<<
|
||||
(' '*31)<<"file is omited then the user variable \n"<<
|
||||
(' '*31)<<"SSH_PUBLIC_KEY will be used.",
|
||||
(' '*31) << "file is omited then the user variable \n"<<
|
||||
(' '*31) << "SSH_PUBLIC_KEY will be used.",
|
||||
:format => String,
|
||||
:proc => lambda do |o, options|
|
||||
if !o
|
||||
@ -332,6 +332,12 @@ EOT
|
||||
}
|
||||
]
|
||||
|
||||
FORCE={
|
||||
:name => 'force',
|
||||
:large => '--force',
|
||||
:description => 'Overwrite the file'
|
||||
}
|
||||
|
||||
TEMPLATE_OPTIONS_VM=[TEMPLATE_NAME_VM]+TEMPLATE_OPTIONS+[DRY]
|
||||
|
||||
CAPACITY_OPTIONS_VM=[TEMPLATE_OPTIONS[0],TEMPLATE_OPTIONS[1],TEMPLATE_OPTIONS[3]]
|
||||
@ -820,6 +826,15 @@ EOT
|
||||
end
|
||||
end
|
||||
|
||||
def OpenNebulaHelper.clusters_str(clusters)
|
||||
if clusters.nil?
|
||||
"-"
|
||||
else
|
||||
[clusters].flatten.join(',')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def OpenNebulaHelper.update_template(id, resource, path=nil, xpath='TEMPLATE')
|
||||
return update_template_helper(false, id, resource, path, xpath)
|
||||
end
|
||||
@ -955,7 +970,7 @@ EOT
|
||||
end
|
||||
|
||||
if !lines.empty?
|
||||
"CONTEXT=[\n"<<lines.map{|l| " "<<l }.join(",\n")<<"\n]\n"
|
||||
"CONTEXT=[\n" << lines.map{|l| " " << l }.join(",\n") << "\n]\n"
|
||||
else
|
||||
nil
|
||||
end
|
||||
@ -1006,7 +1021,7 @@ EOT
|
||||
if options[:vnc_password]
|
||||
template << ", PASSWD=\"#{options[:vnc_password]}\""
|
||||
end
|
||||
template<<' ]'<<"\n"
|
||||
template<<' ]' << "\n"
|
||||
end
|
||||
|
||||
if options[:spice]
|
||||
@ -1015,7 +1030,7 @@ EOT
|
||||
if options[:spice_password]
|
||||
template << ", PASSWD=\"#{options[:spice_password]}\""
|
||||
end
|
||||
template<<' ]'<<"\n"
|
||||
template<<' ]' << "\n"
|
||||
end
|
||||
|
||||
context=create_context(options)
|
||||
@ -1046,4 +1061,105 @@ EOT
|
||||
# in options hash
|
||||
(template_options-options.keys)!=template_options
|
||||
end
|
||||
|
||||
def self.sunstone_url
|
||||
if (one_sunstone = ENV['ONE_SUNSTONE'])
|
||||
one_sunstone
|
||||
elsif (one_xmlrpc = ENV['ONE_XMLRPC'])
|
||||
uri = URI(one_xmlrpc)
|
||||
"#{uri.scheme}://#{uri.host}:9869"
|
||||
else
|
||||
"http://localhost:9869"
|
||||
end
|
||||
end
|
||||
|
||||
def self.download_resource_sunstone(kind, id, path, force)
|
||||
client = OneHelper.client
|
||||
user, password = client.one_auth.split(":", 2)
|
||||
|
||||
# Step 1: Build Session to get Cookie
|
||||
uri = URI(File.join(sunstone_url,"login"))
|
||||
|
||||
req = Net::HTTP::Post.new(uri)
|
||||
req.basic_auth user, password
|
||||
|
||||
begin
|
||||
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
||||
http.request(req)
|
||||
end
|
||||
rescue
|
||||
return OpenNebula::Error.new("Error connecting to '#{uri}'.")
|
||||
end
|
||||
|
||||
cookie = res.response['set-cookie'].split('; ')[0]
|
||||
|
||||
if cookie.nil?
|
||||
return OpenNebula::Error.new("Unable to get Cookie. Is OpenNebula running?")
|
||||
end
|
||||
|
||||
# Step 2: Open '/' to get the csrftoken
|
||||
uri = URI(sunstone_url)
|
||||
|
||||
req = Net::HTTP::Get.new(uri)
|
||||
req['Cookie'] = cookie
|
||||
|
||||
begin
|
||||
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
||||
http.request(req)
|
||||
end
|
||||
rescue
|
||||
return OpenNebula::Error.new("Error connecting to '#{uri}'.")
|
||||
end
|
||||
|
||||
m = res.body.match(/var csrftoken = '(.*)';/)
|
||||
csrftoken = m[1] rescue nil
|
||||
|
||||
if csrftoken.nil?
|
||||
return OpenNebula::Error.new("Unable to get csrftoken.")
|
||||
end
|
||||
|
||||
# Step 3: Download resource
|
||||
uri = URI(File.join(sunstone_url,
|
||||
kind.to_s,
|
||||
id.to_s,
|
||||
"download?csrftoken=#{csrftoken}"))
|
||||
|
||||
req = Net::HTTP::Get.new(uri)
|
||||
|
||||
req['Cookie'] = cookie
|
||||
req['User-Agent'] = "OpenNebula CLI"
|
||||
|
||||
begin
|
||||
File.open(path, 'wb') do |f|
|
||||
Net::HTTP.start(uri.hostname, uri.port) do |http|
|
||||
http.request(req) do |res|
|
||||
res.read_body do |chunk|
|
||||
f.write(chunk)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue Errno::EACCES
|
||||
return OpenNebula::Error.new("Target file not writable.")
|
||||
end
|
||||
|
||||
error_message = nil
|
||||
|
||||
File.open(path, 'rb') do |f|
|
||||
begin
|
||||
f.seek(-1024, IO::SEEK_END)
|
||||
rescue Errno::EINVAL
|
||||
end
|
||||
|
||||
tail = f.read
|
||||
|
||||
m = tail.match(/@\^_\^@ (.*) @\^_\^@/m)
|
||||
error_message = m[1] if m
|
||||
end
|
||||
|
||||
if error_message
|
||||
File.unlink(path)
|
||||
return OpenNebula::Error.new("Remote server error: #{error_message}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -75,8 +75,8 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper
|
||||
end
|
||||
end
|
||||
|
||||
column :CLUSTER, "Name of the Cluster", :left, :size=>12 do |d|
|
||||
OpenNebulaHelper.cluster_str(d["CLUSTER"])
|
||||
column :CLUSTERS, "Cluster IDs", :left, :size=>12 do |d|
|
||||
OpenNebulaHelper.clusters_str(d["CLUSTERS"]["ID"])
|
||||
end
|
||||
|
||||
column :IMAGES, "Number of Images", :size=>6 do |d|
|
||||
@ -105,7 +105,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper
|
||||
Datastore::SHORT_DATASTORE_STATES[state]
|
||||
end
|
||||
|
||||
default :ID, :USER, :GROUP, :NAME, :SIZE, :AVAIL, :CLUSTER, :IMAGES,
|
||||
default :ID, :USER, :GROUP, :NAME, :SIZE, :AVAIL, :CLUSTERS, :IMAGES,
|
||||
:TYPE, :DS, :TM, :STAT
|
||||
end
|
||||
|
||||
@ -136,7 +136,8 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper
|
||||
puts str % ["NAME", datastore.name]
|
||||
puts str % ["USER", datastore['UNAME']]
|
||||
puts str % ["GROUP", datastore['GNAME']]
|
||||
puts str % ["CLUSTER", OpenNebulaHelper.cluster_str(datastore['CLUSTER'])]
|
||||
puts str % ["CLUSTERS",
|
||||
OpenNebulaHelper.clusters_str(datastore.retrieve_elements("CLUSTERS/ID"))]
|
||||
|
||||
puts str % ["TYPE", datastore.type_str]
|
||||
puts str % ["DS_MAD", datastore['DS_MAD']]
|
||||
|
@ -17,6 +17,32 @@
|
||||
require 'one_helper'
|
||||
|
||||
class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
|
||||
TEMPLATE_OPTIONS=[
|
||||
{
|
||||
:name => "name",
|
||||
:large => "--name name",
|
||||
:format => String,
|
||||
:description => "Name of the new MarketPlaceApp"
|
||||
},
|
||||
{
|
||||
:name => "description",
|
||||
:large => "--description description",
|
||||
:format => String,
|
||||
:description => "Description for the new MarketPlaceApp"
|
||||
},
|
||||
{
|
||||
:name => "image",
|
||||
:large => "--image id|name" ,
|
||||
:description => "Selects the image",
|
||||
:format => String,
|
||||
:template_key => "origin_id",
|
||||
:proc => lambda { |o, options|
|
||||
OpenNebulaHelper.rname_to_id(o, "IMAGE")
|
||||
}
|
||||
},
|
||||
OpenNebulaHelper::DRY
|
||||
]
|
||||
|
||||
def self.rname
|
||||
"MARKETPLACEAPP"
|
||||
end
|
||||
@ -74,6 +100,18 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
|
||||
table
|
||||
end
|
||||
|
||||
def self.create_template_options_used?(options)
|
||||
# Get the template options names as symbols. options hash
|
||||
# uses symbols
|
||||
template_options=self::TEMPLATE_OPTIONS.map do |o|
|
||||
o[:name].to_sym
|
||||
end
|
||||
|
||||
# Check if one at least one of the template options is
|
||||
# in options hash
|
||||
(template_options-options.keys)!=template_options
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def factory(id=nil)
|
||||
@ -141,4 +179,34 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
|
||||
|
||||
puts
|
||||
end
|
||||
|
||||
def self.create_variables(options, name)
|
||||
if Array===name
|
||||
names=name
|
||||
else
|
||||
names=[name]
|
||||
end
|
||||
|
||||
t=''
|
||||
names.each do |n|
|
||||
if options[n]
|
||||
t<<"#{n.to_s.upcase}=\"#{options[n]}\"\n"
|
||||
end
|
||||
end
|
||||
|
||||
t
|
||||
end
|
||||
|
||||
def self.create_datastore_template(options)
|
||||
template_options=TEMPLATE_OPTIONS.map do |o|
|
||||
o[:name].to_sym
|
||||
end
|
||||
|
||||
template=create_variables(options, template_options-[:dry,:image])
|
||||
|
||||
template<<"ORIGIN_ID=#{options[:image]}\n" if options[:image]
|
||||
template << "TYPE=image\n"
|
||||
|
||||
[0, template]
|
||||
end
|
||||
end
|
||||
|
@ -131,7 +131,7 @@ EOT
|
||||
puts "There are some parameters that require user input. Use the string <<EDITOR>> to launch an editor (e.g. for multi-line inputs)"
|
||||
|
||||
user_inputs.each do |key, val|
|
||||
input_cfg = val.split('|')
|
||||
input_cfg = val.split('|', -1)
|
||||
|
||||
if input_cfg.length < 3
|
||||
STDERR.puts "Malformed user input. It should have at least 3 parts separated by '|':"
|
||||
@ -139,8 +139,8 @@ EOT
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
optional, type, description, params, initial = input_cfg
|
||||
optional.strip!
|
||||
mandatory, type, description, params, initial = input_cfg
|
||||
optional = mandatory.strip == "O"
|
||||
type.strip!
|
||||
description.strip!
|
||||
|
||||
@ -195,7 +195,13 @@ EOT
|
||||
answer = STDIN.readline.chop
|
||||
|
||||
answer = initial if (answer == "")
|
||||
end while (answer =~ exp) == nil
|
||||
|
||||
noanswer = ((answer == "") && optional)
|
||||
end while !noanswer && (answer =~ exp) == nil
|
||||
|
||||
if noanswer
|
||||
next
|
||||
end
|
||||
|
||||
when 'range', 'range-float'
|
||||
min,max = params.split('..')
|
||||
@ -225,7 +231,13 @@ EOT
|
||||
answer = STDIN.readline.chop
|
||||
|
||||
answer = initial if (answer == "")
|
||||
end while ((answer =~ exp) == nil || answer.to_f < min || answer.to_f > max)
|
||||
|
||||
noanswer = ((answer == "") && optional)
|
||||
end while !noanswer && ((answer =~ exp) == nil || answer.to_f < min || answer.to_f > max)
|
||||
|
||||
if noanswer
|
||||
next
|
||||
end
|
||||
|
||||
when 'list'
|
||||
options = params.split(",")
|
||||
@ -248,7 +260,17 @@ EOT
|
||||
answer = options[answer.to_i]
|
||||
end
|
||||
|
||||
end while (!options.include?(answer))
|
||||
noanswer = ((answer == "") && optional)
|
||||
|
||||
end while !noanswer && (!options.include?(answer))
|
||||
|
||||
if noanswer
|
||||
next
|
||||
end
|
||||
|
||||
when 'fixed'
|
||||
puts " Fixed value of (#{initial}). Cannot be changed"
|
||||
answer = initial
|
||||
|
||||
else
|
||||
STDERR.puts "Wrong type for user input:"
|
||||
@ -256,8 +278,12 @@ EOT
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
answers << "#{key} = \""
|
||||
answers << answer.gsub('"', "\\\"") << "\"\n"
|
||||
# Do not replace values that are equal to the ones already in the
|
||||
# template. Useful for cpu, mem, vcpu
|
||||
if answer != template['VMTEMPLATE']['TEMPLATE'][key]
|
||||
answers << "#{key} = \""
|
||||
answers << answer.gsub('"', "\\\"") << "\"\n"
|
||||
end
|
||||
end
|
||||
|
||||
answers
|
||||
|
@ -336,6 +336,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
:PROLOG_MIGRATE_FAILURE => :migrate,
|
||||
:PROLOG_MIGRATE_POWEROFF_FAILURE => :migrate,
|
||||
:PROLOG_MIGRATE_SUSPEND_FAILURE => :migrate,
|
||||
:PROLOG_MIGRATE_UNKNOWN_FAILURE => :migrate,
|
||||
:PROLOG_FAILURE => :prolog,
|
||||
:PROLOG_RESUME_FAILURE => :resume,
|
||||
:PROLOG_UNDEPLOY_FAILURE => :resume,
|
||||
@ -729,7 +730,6 @@ in the frontend machine.
|
||||
nic_default = {"NETWORK" => "-",
|
||||
"IP" => "-",
|
||||
"MAC"=> "-",
|
||||
"VLAN"=>"no",
|
||||
"BRIDGE"=>"-"}
|
||||
|
||||
shown_ips = []
|
||||
@ -781,8 +781,7 @@ in the frontend machine.
|
||||
"NIC_ID" => "-",
|
||||
"IP" => ip,
|
||||
"NETWORK" => "Additional IP",
|
||||
"BRIDGE" => "-",
|
||||
"VLAN" => "-"
|
||||
"BRIDGE" => "-"
|
||||
}
|
||||
end
|
||||
|
||||
@ -803,14 +802,6 @@ in the frontend machine.
|
||||
end
|
||||
end
|
||||
|
||||
column :VLAN, "", :size=>4 do |d|
|
||||
if d["DOUBLE_ENTRY"]
|
||||
""
|
||||
else
|
||||
d["VLAN"].downcase
|
||||
end
|
||||
end
|
||||
|
||||
column :BRIDGE, "", :left, :size=>12 do |d|
|
||||
if d["DOUBLE_ENTRY"]
|
||||
""
|
||||
|
@ -102,10 +102,11 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
:description=> "Netmask in dot notation"
|
||||
]
|
||||
|
||||
VLAN = [
|
||||
:name => "vlan",
|
||||
:large => "--vlan",
|
||||
:description=> "Use network isolation"
|
||||
VN_MAD = [
|
||||
:name => "vn_mad",
|
||||
:large => "--vn_mad mad",
|
||||
:format => String,
|
||||
:description=> "Use this driver for the network"
|
||||
]
|
||||
|
||||
VLAN_ID = [
|
||||
@ -116,7 +117,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
]
|
||||
|
||||
ADDAR_OPTIONS = [
|
||||
SIZE, MAC, IP, IP6_GLOBAL, IP6_ULA, GATEWAY, NETMASK, VLAN, VLAN_ID ]
|
||||
SIZE, MAC, IP, IP6_GLOBAL, IP6_ULA, GATEWAY, NETMASK, VN_MAD, VLAN_ID ]
|
||||
|
||||
def self.rname
|
||||
"VNET"
|
||||
@ -149,8 +150,8 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
d["NAME"]
|
||||
end
|
||||
|
||||
column :CLUSTER, "Name of the Cluster", :left, :size=>10 do |d|
|
||||
OpenNebulaHelper.cluster_str(d["CLUSTER"])
|
||||
column :CLUSTERS, "Cluster IDs", :left, :size=>10 do |d|
|
||||
OpenNebulaHelper.clusters_str(d["CLUSTERS"]["ID"])
|
||||
end
|
||||
|
||||
column :BRIDGE, "Bridge associated to the Virtual Network", :left,
|
||||
@ -163,7 +164,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
d["USED_LEASES"]
|
||||
end
|
||||
|
||||
default :ID, :USER, :GROUP, :NAME, :CLUSTER, :BRIDGE, :LEASES
|
||||
default :ID, :USER, :GROUP, :NAME, :CLUSTERS, :BRIDGE, :LEASES
|
||||
end
|
||||
|
||||
table
|
||||
@ -209,9 +210,10 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
puts str % ["NAME", vn['NAME']]
|
||||
puts str % ["USER", vn['UNAME']]
|
||||
puts str % ["GROUP", vn['GNAME']]
|
||||
puts str % ["CLUSTER", OpenNebulaHelper.cluster_str(vn['CLUSTER'])]
|
||||
puts str % ["CLUSTERS",
|
||||
OpenNebulaHelper.clusters_str(vn.retrieve_elements("CLUSTERS/ID"))]
|
||||
puts str % ["BRIDGE", vn["BRIDGE"]]
|
||||
puts str % ["VLAN", OpenNebulaHelper.boolean_to_str(vn['VLAN'])]
|
||||
puts str % ["VN_MAD", vn['VN_MAD']] if !vn['VN_MAD'].empty?
|
||||
puts str % ["PHYSICAL DEVICE", vn["PHYDEV"]] if !vn["PHYDEV"].empty?
|
||||
puts str % ["VLAN ID", vn["VLAN_ID"]] if !vn["VLAN_ID"].empty?
|
||||
puts str % ["USED LEASES", vn['USED_LEASES']]
|
||||
@ -251,6 +253,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
str="%-15s: %-20s"
|
||||
puts str % ["SIZE", ar["SIZE"]]
|
||||
puts str % ["LEASES", ar["USED_LEASES"]]
|
||||
puts str % ["VN_MAD", ar["VN_MAD"]] if ar["VN_MAD"]
|
||||
puts
|
||||
|
||||
format = "%-10s %34s %34s"
|
||||
|
@ -176,16 +176,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
end
|
||||
end
|
||||
|
||||
download_desc = <<-EOT.unindent
|
||||
Downloads an image to a file
|
||||
EOT
|
||||
|
||||
command :download, download_desc, :imageid, :path do
|
||||
helper.perform_action(args[0],options,"downloaded") do |image|
|
||||
image.download(args[1], helper.client)
|
||||
end
|
||||
end
|
||||
|
||||
delete_desc = <<-EOT.unindent
|
||||
Deletes the given Image
|
||||
EOT
|
||||
|
@ -88,7 +88,8 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
Creates a new marketplace app in the given marketplace
|
||||
EOT
|
||||
|
||||
command :create, create_desc, :file, :options=>CREATE_OPTIONS do
|
||||
command :create, create_desc, [:file, nil], :options=>CREATE_OPTIONS +
|
||||
OneMarketPlaceAppHelper::TEMPLATE_OPTIONS do
|
||||
|
||||
if options[:marketplace].nil?
|
||||
STDERR.puts "Marketplace to save the app is mandatory: "
|
||||
@ -96,12 +97,35 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
if args[0] && OneMarketPlaceAppHelper.create_template_options_used?(options)
|
||||
STDERR.puts "You can not use both template file and template"<<
|
||||
" creation options."
|
||||
next -1
|
||||
end
|
||||
|
||||
helper.create_resource(options) do |app|
|
||||
begin
|
||||
template=File.read(args[0])
|
||||
if args[0]
|
||||
template=File.read(args[0])
|
||||
else
|
||||
res = OneMarketPlaceAppHelper.create_datastore_template(options)
|
||||
|
||||
if res.first != 0
|
||||
STDERR.puts res.last
|
||||
next -1
|
||||
end
|
||||
|
||||
template = res.last
|
||||
end
|
||||
|
||||
if options[:dry]
|
||||
puts template
|
||||
exit 0
|
||||
end
|
||||
|
||||
app.allocate(template, options[:marketplace])
|
||||
rescue => e
|
||||
STDERR.puts e.messsage
|
||||
STDERR.puts e.message
|
||||
exit(-1)
|
||||
end
|
||||
end
|
||||
@ -131,9 +155,11 @@ CommandParser::CmdParser.new(ARGV) do
|
||||
Downloads a MarketApp to a file
|
||||
EOT
|
||||
|
||||
command :download, download_desc, :appid, :path do
|
||||
command :download, download_desc, :appid, :path,
|
||||
:options => [OpenNebulaHelper::FORCE] do
|
||||
helper.perform_action(args[0],options,"downloaded") do |app|
|
||||
app.download(args[1], helper.client)
|
||||
download_args = [:marketplaceapp, args[0], args[1], options[:force]]
|
||||
OpenNebulaHelper.download_resource_sunstone(*download_args)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -195,6 +195,115 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
next if STDIN.gets.strip.downcase != 'y'
|
||||
|
||||
ds_input = ""
|
||||
rp_input = ""
|
||||
|
||||
# Datastores
|
||||
|
||||
STDOUT.print "\n This template is currently set to be "\
|
||||
"deployed in datastore #{t[:default_ds]}."\
|
||||
"\n Do you want to keep the default [y/n]? "
|
||||
|
||||
if STDIN.gets.strip.downcase == 'n'
|
||||
ds_split = t[:ds].split("|")
|
||||
list_of_ds = ds_split[-2]
|
||||
default_ds = ds_split[-1]
|
||||
ds_input = ds_split[0] + "|" + ds_split[1] + "|" +
|
||||
ds_split[2] + "|"
|
||||
|
||||
# Available list of datastores
|
||||
|
||||
input_str = " The list of available datastores to be"\
|
||||
" presented to the user are \"#{list_of_ds}\""
|
||||
input_str+= "\n Press y to agree, or input a comma"\
|
||||
" separated list of datastores to edit "\
|
||||
"[y/comma separated list] "
|
||||
STDOUT.print input_str
|
||||
|
||||
answer = STDIN.gets.strip
|
||||
|
||||
if answer.downcase == 'y'
|
||||
ds_input += ds_split[3] + "|"
|
||||
else
|
||||
ds_input += answer + "|"
|
||||
end
|
||||
|
||||
# Default
|
||||
input_str = " The default datastore presented to "\
|
||||
"the end user is set to \"#{default_ds}\"."
|
||||
input_str+= "\n Press y to agree, or input a new "\
|
||||
"datastore [y/datastore name] "
|
||||
STDOUT.print input_str
|
||||
|
||||
answer = STDIN.gets.strip
|
||||
|
||||
if answer.downcase == 'y'
|
||||
ds_input += ds_split[4]
|
||||
else
|
||||
ds_input += answer
|
||||
end
|
||||
end
|
||||
|
||||
# Resource Pools
|
||||
|
||||
rp_split = t[:rp].split("|")
|
||||
|
||||
if rp_split.size > 3
|
||||
STDOUT.print "\n Do you want VMs cloned from this"\
|
||||
" template to run in the default"\
|
||||
" resource pool [y/n]? "
|
||||
|
||||
if STDIN.gets.strip.downcase == 'n'
|
||||
list_of_rp = rp_split[-2]
|
||||
default_rp = rp_split[-1]
|
||||
rp_input = rp_split[0] + "|" + rp_split[1] + "|" +
|
||||
rp_split[2] + "|"
|
||||
|
||||
# Available list of resource pools
|
||||
|
||||
input_str = " The list of available resource pools "\
|
||||
"to be presented to the user are "\
|
||||
"\"#{list_of_rp}\""
|
||||
input_str+= "\n Press y to agree, or input a comma"\
|
||||
" separated list of resource pools to edit "\
|
||||
"[y/comma separated list] "
|
||||
STDOUT.print input_str
|
||||
|
||||
answer = STDIN.gets.strip
|
||||
|
||||
if answer.downcase == 'y'
|
||||
rp_input += rp_split[3] + "|"
|
||||
else
|
||||
rp_input += answer + "|"
|
||||
end
|
||||
|
||||
# Default
|
||||
input_str = " The default resource pool presented "\
|
||||
"to the end user is set to"\
|
||||
" \"#{default_rp}\"."
|
||||
input_str+= "\n Press y to agree, or input a new "\
|
||||
"resource pool [y/resource pool name] "
|
||||
STDOUT.print input_str
|
||||
|
||||
answer = STDIN.gets.strip
|
||||
|
||||
if answer.downcase == 'y'
|
||||
rp_input += rp_split[4]
|
||||
else
|
||||
rp_input += answer
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ds_input != "" ||
|
||||
rp_input != ""
|
||||
t[:one] += "USER_INPUTS=["
|
||||
t[:one] += "VCENTER_DATASTORE=\"#{ds_input}\"," if ds_input != ""
|
||||
t[:one] += "RESOURCE_POOL=\"#{rp_input}\"," if rp_input != ""
|
||||
t[:one] = t[:one][0..-2]
|
||||
t[:one] += "]"
|
||||
end
|
||||
|
||||
one_t = ::OpenNebula::Template.new(
|
||||
::OpenNebula::Template.build_xml, vc.one)
|
||||
|
||||
@ -368,4 +477,148 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
|
||||
exit 0
|
||||
end
|
||||
|
||||
datastores_desc = <<-EOT.unindent
|
||||
Import vCenter Datastores into OpenNebula
|
||||
EOT
|
||||
|
||||
command :datastores, datastores_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"\
|
||||
" Datastores:\n"\
|
||||
"\t --vcenter vCenter hostname\n"\
|
||||
"\t --vuser username to login in vcenter\n"\
|
||||
"\t --vpass password for the user"
|
||||
exit -1
|
||||
end
|
||||
|
||||
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 Datastores..."
|
||||
|
||||
rs = vc.vcenter_datastores
|
||||
|
||||
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 Datastores found in #{dc}...\n\n"
|
||||
next
|
||||
end
|
||||
|
||||
tmps.each{ |d|
|
||||
STDOUT.print "\n * Datastore found:\n"\
|
||||
" - Name : #{d[:name]}\n"\
|
||||
" - Total MB : #{d[:total_mb]}\n"\
|
||||
" - Free MB : #{d[:free_mb]}\n"\
|
||||
" - Cluster : #{d[:cluster]}\n"\
|
||||
" Import this Datastore [y/n]? "
|
||||
|
||||
next if STDIN.gets.strip.downcase != 'y'
|
||||
|
||||
one_d = ::OpenNebula::Datastore.new(
|
||||
::OpenNebula::Datastore.build_xml, vc.one)
|
||||
|
||||
rc = one_d.allocate(d[:one])
|
||||
|
||||
if ::OpenNebula.is_error?(rc)
|
||||
STDOUT.puts " Error creating datastore: #{rc.message}\n"\
|
||||
" One datastore can exist only once, and "\
|
||||
"can be used in any vCenter Cluster that "\
|
||||
"has access to it. Also, no spaces allowed "\
|
||||
"in datastore name (rename it in vCenter "\
|
||||
"and try again)"
|
||||
else
|
||||
STDOUT.puts " OpenNebula datastore #{one_d.id} created!\n"
|
||||
end
|
||||
}
|
||||
}
|
||||
rescue Exception => e
|
||||
STDOUT.puts "error: #{e.message}"
|
||||
exit -1
|
||||
end
|
||||
|
||||
exit 0
|
||||
end
|
||||
|
||||
images_desc = <<-EOT.unindent
|
||||
Import vCenter Images into OpenNebula
|
||||
EOT
|
||||
|
||||
command :images, images_desc, :ds_name, :options=>[ VCENTER, USER, PASS ] do
|
||||
ds_name = args[0]
|
||||
|
||||
if !ds_name
|
||||
STDERR.puts "Datastore name needed to import images from"
|
||||
exit -1
|
||||
end
|
||||
|
||||
if options[:vuser].nil? ||
|
||||
options[:vpass].nil? ||
|
||||
options[:vcenter].nil?
|
||||
STDERR.puts "vCenter connection parameters are mandatory to import"\
|
||||
" Datastores:\n"\
|
||||
"\t --vcenter vCenter hostname\n"\
|
||||
"\t --vuser username to login in vcenter\n"\
|
||||
"\t --vpass password for the user"
|
||||
exit -1
|
||||
end
|
||||
|
||||
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 Images..."
|
||||
|
||||
images = vc.vcenter_images(ds_name)
|
||||
|
||||
STDOUT.print "done!\n"
|
||||
|
||||
images.each{ |i|
|
||||
STDOUT.print "\n * Image found:\n"\
|
||||
" - Name : #{i[:name]}\n"\
|
||||
" - Path : #{i[:path]}\n"\
|
||||
" - Type : #{i[:type]}\n"\
|
||||
" Import this Image [y/n]? "
|
||||
|
||||
next if STDIN.gets.strip.downcase != 'y'
|
||||
|
||||
one_i = ::OpenNebula::Image.new(
|
||||
::OpenNebula::Image.build_xml, vc.one)
|
||||
|
||||
rc = one_i.allocate(i[:one], i[:dsid].to_i)
|
||||
|
||||
if ::OpenNebula.is_error?(rc)
|
||||
STDOUT.puts " Error creating image: #{rc.message}\n"
|
||||
else
|
||||
STDOUT.puts " OpenNebula image #{one_i.id} created!\n"
|
||||
end
|
||||
}
|
||||
rescue Exception => e
|
||||
STDOUT.puts "error: #{e.message}"
|
||||
exit -1
|
||||
end
|
||||
|
||||
exit 0
|
||||
end
|
||||
end
|
||||
|
@ -826,7 +826,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
disk_snapshot_revert_desc = <<-EOT.unindent
|
||||
Reverts disk state to a previously taken snapshot.
|
||||
|
||||
States: RUNNING, POWEROFF, SUSPENDED
|
||||
States: POWEROFF, SUSPENDED
|
||||
EOT
|
||||
|
||||
command :"disk-snapshot-revert", disk_snapshot_revert_desc,
|
||||
|
@ -148,9 +148,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
ar << ", ULA_PREFIX = " <<
|
||||
options[:ip6_ula] if options[:ip6_ula]
|
||||
ar << ", GATEWAY = " << options[:gateway] if options[:gateway]
|
||||
ar << ", MASK = " << options[:netmask] if options[:netmask]
|
||||
ar << ", VLAN = YES" if options[:vlan]
|
||||
ar << ", VLAN_ID = " << options[:vlanid] if options[:vlanid]
|
||||
ar << ", MASK = " << options[:netmask] if options[:netmask]
|
||||
ar << ", VN_MAD = " << options[:vn_mad] if options[:vn_mad]
|
||||
ar << ", VLAN_ID = " << options[:vlanid] if options[:vlanid]
|
||||
|
||||
ar << "]"
|
||||
end
|
||||
|
@ -30,108 +30,180 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
Client * Client::_client = 0;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void Client::set_one_auth(string secret)
|
||||
Client::Client(const string& secret, const string& endpoint,
|
||||
size_t message_size, unsigned int tout)
|
||||
{
|
||||
if (secret.empty())
|
||||
string error;
|
||||
char * xmlrpc_env;
|
||||
|
||||
if (!secret.empty())
|
||||
{
|
||||
read_oneauth(secret);
|
||||
one_auth = secret;
|
||||
}
|
||||
else if (read_oneauth(one_auth, error) != 0 )
|
||||
{
|
||||
NebulaLog::log("XMLRPC", Log::ERROR, error);
|
||||
throw runtime_error(error);
|
||||
}
|
||||
|
||||
one_auth = secret;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void Client::read_oneauth(string &secret)
|
||||
{
|
||||
ostringstream oss;
|
||||
string one_auth_file;
|
||||
|
||||
const char * one_auth_env;
|
||||
ifstream file;
|
||||
|
||||
int rc = -1;
|
||||
|
||||
// Read $ONE_AUTH file and copy its contents into secret.
|
||||
one_auth_env = getenv("ONE_AUTH");
|
||||
|
||||
if (!one_auth_env)
|
||||
if(!endpoint.empty())
|
||||
{
|
||||
one_endpoint = endpoint;
|
||||
}
|
||||
else if ( (xmlrpc_env = getenv("ONE_XMLRPC"))!= 0 )
|
||||
{
|
||||
one_endpoint = xmlrpc_env;
|
||||
}
|
||||
else
|
||||
{
|
||||
one_endpoint = "http://localhost:2633/RPC2";
|
||||
}
|
||||
|
||||
xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, message_size);
|
||||
|
||||
timeout = tout * 1000;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Client::read_oneauth(string &secret, string& error_msg)
|
||||
{
|
||||
string one_auth_file;
|
||||
ifstream file;
|
||||
|
||||
const char * one_auth_env = getenv("ONE_AUTH");
|
||||
|
||||
if (!one_auth_env) //No $ONE_AUTH, read $HOME/.one/one_auth
|
||||
{
|
||||
// If $ONE_AUTH doesn't exist, read $HOME/.one/one_auth
|
||||
struct passwd * pw_ent;
|
||||
|
||||
pw_ent = getpwuid(getuid());
|
||||
|
||||
if ((pw_ent != NULL) && (pw_ent->pw_dir != NULL))
|
||||
if ((pw_ent == NULL) || (pw_ent->pw_dir == NULL))
|
||||
{
|
||||
one_auth_file = pw_ent->pw_dir;
|
||||
one_auth_file += "/.one/one_auth";
|
||||
error_msg = "Could not get one_auth file location";
|
||||
return -1;
|
||||
}
|
||||
|
||||
one_auth_env = one_auth_file.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "Could not get one_auth file location";
|
||||
}
|
||||
one_auth_file = pw_ent->pw_dir;
|
||||
one_auth_file += "/.one/one_auth";
|
||||
|
||||
one_auth_env = one_auth_file.c_str();
|
||||
}
|
||||
|
||||
file.open(one_auth_env);
|
||||
|
||||
if (file.good())
|
||||
if (!file.good())
|
||||
{
|
||||
getline(file, secret);
|
||||
|
||||
if (file.fail())
|
||||
{
|
||||
oss << "Error reading file: " << one_auth_env;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
error_msg = "Could not open file " + one_auth_file;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
|
||||
getline(file, secret);
|
||||
|
||||
if (file.fail())
|
||||
{
|
||||
oss << "Could not open file: " << one_auth_env;
|
||||
error_msg = "Error reading file " + one_auth_file;
|
||||
|
||||
file.close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
NebulaLog::log("XMLRPC",Log::ERROR,oss);
|
||||
throw runtime_error( oss.str() );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void Client::set_one_endpoint(string endpoint)
|
||||
void Client::call(const std::string &method, const std::string format,
|
||||
xmlrpc_c::value * const result, ...)
|
||||
{
|
||||
one_endpoint = "http://localhost:2633/RPC2";
|
||||
va_list args;
|
||||
va_start(args, result);
|
||||
|
||||
if(endpoint != "")
|
||||
std::string::const_iterator i;
|
||||
|
||||
std::string sval;
|
||||
int ival;
|
||||
bool bval;
|
||||
|
||||
const char* pval;
|
||||
|
||||
xmlrpc_c::paramList plist;
|
||||
|
||||
plist.add(xmlrpc_c::value_string(one_auth));
|
||||
|
||||
for (i = format.begin(); i != format.end(); ++i)
|
||||
{
|
||||
one_endpoint = endpoint;
|
||||
switch(*i)
|
||||
{
|
||||
case 's':
|
||||
pval = static_cast<const char*>(va_arg(args, char *));
|
||||
sval = pval;
|
||||
|
||||
plist.add(xmlrpc_c::value_string(sval));
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
ival = va_arg(args, int);
|
||||
|
||||
plist.add(xmlrpc_c::value_int(ival));
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
bval = va_arg(args, int);
|
||||
|
||||
plist.add(xmlrpc_c::value_boolean(bval));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
|
||||
call(method, plist, result);
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void Client::call(const std::string& method, const xmlrpc_c::paramList& plist,
|
||||
xmlrpc_c::value * const result)
|
||||
{
|
||||
xmlrpc_c::clientXmlTransport_curl ctrans;
|
||||
xmlrpc_c::client_xml client(&ctrans);
|
||||
|
||||
xmlrpc_c::rpcPtr rpc(method, plist);
|
||||
xmlrpc_c::carriageParm_curl0 cparam(one_endpoint);
|
||||
|
||||
rpc->start(&client, &cparam);
|
||||
|
||||
client.finishAsync(xmlrpc_c::timeout(timeout));
|
||||
|
||||
if (!rpc->isFinished())
|
||||
{
|
||||
rpc->finishErr(girerr::error("XMLRPC method " + method +
|
||||
" timeout, resetting call"));
|
||||
}
|
||||
|
||||
if (rpc->isSuccessful())
|
||||
{
|
||||
*result = rpc->getResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
char * xmlrpc_env;
|
||||
xmlrpc_env = getenv("ONE_XMLRPC");
|
||||
xmlrpc_c::fault failure = rpc->getFault();
|
||||
|
||||
if ( xmlrpc_env != 0 )
|
||||
{
|
||||
one_endpoint = xmlrpc_env;
|
||||
}
|
||||
girerr::error(failure.getDescription());
|
||||
}
|
||||
|
||||
// TODO Check url format, and log error (if any)
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
@ -34,6 +34,18 @@ const char * Cluster::db_bootstrap = "CREATE TABLE IF NOT EXISTS cluster_pool ("
|
||||
"gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, "
|
||||
"UNIQUE(name))";
|
||||
|
||||
const char * Cluster::datastore_table = "cluster_datastore_relation";
|
||||
const char * Cluster::datastore_db_names = "cid, oid";
|
||||
const char * Cluster::datastore_db_bootstrap =
|
||||
"CREATE TABLE IF NOT EXISTS cluster_datastore_relation ("
|
||||
"cid INTEGER, oid INTEGER, PRIMARY KEY(cid, oid))";
|
||||
|
||||
const char * Cluster::network_table = "cluster_network_relation";
|
||||
const char * Cluster::network_db_names = "cid, oid";
|
||||
const char * Cluster::network_db_bootstrap =
|
||||
"CREATE TABLE IF NOT EXISTS cluster_network_relation ("
|
||||
"cid INTEGER, oid INTEGER, PRIMARY KEY(cid, oid))";
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Cluster :: Constructor/Destructor */
|
||||
/* ************************************************************************** */
|
||||
@ -105,24 +117,7 @@ error_common:
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
string& Cluster::get_ds_location(string &ds_location)
|
||||
{
|
||||
obj_template->get("DATASTORE_LOCATION", ds_location);
|
||||
|
||||
if ( ds_location.empty() == true )
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
|
||||
nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location);
|
||||
}
|
||||
|
||||
return ds_location;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int Cluster::add_datastore(int id, Datastore::DatastoreType ds_type, string& error_msg)
|
||||
int Cluster::add_datastore(int id, string& error_msg)
|
||||
{
|
||||
int rc = datastores.add(id);
|
||||
|
||||
@ -247,6 +242,98 @@ int Cluster::insert_replace(SqlDB *db, bool replace, string& error_str)
|
||||
db->free_str(sql_name);
|
||||
db->free_str(sql_xml);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
if (db->multiple_values_support())
|
||||
{
|
||||
set<int>::iterator i;
|
||||
|
||||
rc = 0;
|
||||
|
||||
oss.str("");
|
||||
oss << "DELETE FROM " << network_table << " WHERE cid = " << oid;
|
||||
rc += db->exec(oss);
|
||||
|
||||
oss.str("");
|
||||
oss << "DELETE FROM " << datastore_table<< " WHERE cid = " << oid;
|
||||
rc += db->exec(oss);
|
||||
|
||||
set<int> datastore_set = datastores.get_collection();
|
||||
|
||||
if (!datastore_set.empty())
|
||||
{
|
||||
oss.str("");
|
||||
oss << "INSERT INTO " << datastore_table
|
||||
<< " (" << datastore_db_names << ") VALUES ";
|
||||
|
||||
i = datastore_set.begin();
|
||||
|
||||
oss << "(" << oid << "," << *i << ")";
|
||||
|
||||
for(++i; i != datastore_set.end(); i++)
|
||||
{
|
||||
oss << ", (" << oid << "," << *i << ")";
|
||||
}
|
||||
|
||||
rc += db->exec(oss);
|
||||
}
|
||||
|
||||
set<int> vnet_set = vnets.get_collection();
|
||||
|
||||
if (!vnet_set.empty())
|
||||
{
|
||||
oss.str("");
|
||||
oss << "INSERT INTO " << network_table
|
||||
<< " (" << network_db_names << ") VALUES ";
|
||||
|
||||
i = vnet_set.begin();
|
||||
|
||||
oss << "(" << oid << "," << *i << ")";
|
||||
|
||||
for(++i; i != vnet_set.end(); i++)
|
||||
{
|
||||
oss << ", (" << oid << "," << *i << ")";
|
||||
}
|
||||
|
||||
rc += db->exec(oss);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
oss.str("");
|
||||
|
||||
oss << "BEGIN; "
|
||||
<< "DELETE FROM " << network_table << " WHERE cid = " << oid << "; "
|
||||
<< "DELETE FROM " << datastore_table<< " WHERE cid = " << oid << "; ";
|
||||
|
||||
set<int>::iterator i;
|
||||
|
||||
set<int> datastore_set = datastores.get_collection();
|
||||
|
||||
for(i = datastore_set.begin(); i != datastore_set.end(); i++)
|
||||
{
|
||||
oss << "INSERT INTO " << datastore_table
|
||||
<< " (" << datastore_db_names << ") VALUES ("
|
||||
<< oid << ","
|
||||
<< *i << "); ";
|
||||
}
|
||||
|
||||
set<int> vnet_set = vnets.get_collection();
|
||||
|
||||
for(i = vnet_set.begin(); i != vnet_set.end(); i++)
|
||||
{
|
||||
oss << "INSERT INTO " << network_table
|
||||
<< " (" << network_db_names << ") VALUES ("
|
||||
<< oid << ","
|
||||
<< *i << "); ";
|
||||
}
|
||||
|
||||
oss << "COMMIT";
|
||||
|
||||
rc = db->exec(oss);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
error_xml:
|
||||
@ -317,55 +404,11 @@ int Cluster::from_xml(const string& xml)
|
||||
// Set the Cluster ID as the cluster it belongs to
|
||||
set_group(oid, name);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Get associated hosts
|
||||
// -------------------------------------------------------------------------
|
||||
ObjectXML::get_nodes("/CLUSTER/HOSTS", content);
|
||||
|
||||
if (content.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set of IDs
|
||||
rc += hosts.from_xml_node(content[0]);
|
||||
|
||||
ObjectXML::free_nodes(content);
|
||||
content.clear();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Get associated datastores
|
||||
// -------------------------------------------------------------------------
|
||||
ObjectXML::get_nodes("/CLUSTER/DATASTORES", content);
|
||||
|
||||
if (content.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set of IDs
|
||||
rc += datastores.from_xml_node(content[0]);
|
||||
|
||||
ObjectXML::free_nodes(content);
|
||||
content.clear();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Get associated vnets
|
||||
// -------------------------------------------------------------------------
|
||||
ObjectXML::get_nodes("/CLUSTER/VNETS", content);
|
||||
|
||||
if (content.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set of IDs
|
||||
rc += vnets.from_xml_node(content[0]);
|
||||
|
||||
ObjectXML::free_nodes(content);
|
||||
content.clear();
|
||||
|
||||
// Get associated classes
|
||||
rc += hosts.from_xml(this, "/CLUSTER/");
|
||||
rc += datastores.from_xml(this, "/CLUSTER/");
|
||||
rc += vnets.from_xml(this, "/CLUSTER/");
|
||||
|
||||
ObjectXML::get_nodes("/CLUSTER/TEMPLATE", content);
|
||||
|
||||
if (content.empty())
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <stdexcept>
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* There is a default cluster boostrapped by the core: */
|
||||
/* There is a default cluster boostrapped by the core: 0, default */
|
||||
/* The first 100 cluster IDs are reserved for system clusters. */
|
||||
/* Regular ones start from ID 100 */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -29,6 +29,9 @@
|
||||
const string ClusterPool::NONE_CLUSTER_NAME = "";
|
||||
const int ClusterPool::NONE_CLUSTER_ID = -1;
|
||||
|
||||
const string ClusterPool::DEFAULT_CLUSTER_NAME = "default";
|
||||
const int ClusterPool::DEFAULT_CLUSTER_ID = 0;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -37,12 +40,48 @@ ClusterPool::ClusterPool(SqlDB * db):PoolSQL(db, Cluster::table, true, true)
|
||||
ostringstream oss;
|
||||
string error_str;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Create the default cluster
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
if (get_lastOID() == -1) //lastOID is set in PoolSQL::init_cb
|
||||
{
|
||||
int rc;
|
||||
|
||||
allocate(DEFAULT_CLUSTER_NAME, &rc, error_str);
|
||||
|
||||
if( rc != DEFAULT_CLUSTER_ID )
|
||||
{
|
||||
goto error_bootstrap;
|
||||
}
|
||||
|
||||
Cluster* cluster = get(DEFAULT_CLUSTER_ID, true);
|
||||
|
||||
if (cluster == 0)
|
||||
{
|
||||
goto error_bootstrap;
|
||||
}
|
||||
|
||||
cluster->add_datastore(DatastorePool::SYSTEM_DS_ID, error_str);
|
||||
cluster->add_datastore(DatastorePool::DEFAULT_DS_ID, error_str);
|
||||
cluster->add_datastore(DatastorePool::FILE_DS_ID, error_str);
|
||||
|
||||
update(cluster);
|
||||
|
||||
cluster->unlock();
|
||||
|
||||
// User created clusters will start from ID 100
|
||||
set_update_lastOID(99);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
error_bootstrap:
|
||||
oss.str("");
|
||||
oss << "Error trying to create default cluster: " << error_str;
|
||||
NebulaLog::log("CLUSTER",Log::ERROR,oss);
|
||||
|
||||
throw runtime_error(oss.str());
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -122,3 +161,51 @@ int ClusterPool::drop(PoolObjectSQL * objsql, string& error_msg)
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void ClusterPool::cluster_acl_filter(ostringstream& filter,
|
||||
PoolObjectSQL::ObjectType auth_object, const vector<int>& cids)
|
||||
{
|
||||
if ( cids.empty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string fc = "";
|
||||
|
||||
switch (auth_object)
|
||||
{
|
||||
case PoolObjectSQL::HOST:
|
||||
filter << " OR ";
|
||||
break;
|
||||
|
||||
case PoolObjectSQL::DATASTORE:
|
||||
filter << " OR oid IN ( SELECT oid from " << Cluster::datastore_table
|
||||
<< " WHERE ";
|
||||
fc = ")";
|
||||
break;
|
||||
|
||||
case PoolObjectSQL::NET:
|
||||
filter << " OR oid IN ( SELECT oid from " << Cluster::network_table
|
||||
<< " WHERE ";
|
||||
fc = ")";
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
for ( vector<int>::const_iterator it = cids.begin(); it < cids.end(); it++ )
|
||||
{
|
||||
if ( it != cids.begin() )
|
||||
{
|
||||
filter << " OR ";
|
||||
}
|
||||
|
||||
filter << "cid = " << *it;
|
||||
}
|
||||
|
||||
filter << fc;
|
||||
}
|
||||
|
@ -19,8 +19,7 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "Attribute.h"
|
||||
|
||||
#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper)
|
||||
#include "NebulaUtil.h"
|
||||
|
||||
const char * VectorAttribute::magic_sep = "@^_^@";
|
||||
const int VectorAttribute::magic_sep_size = 5;
|
||||
@ -101,8 +100,9 @@ void VectorAttribute::to_xml(ostringstream &oss) const
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "<" << it->first << "><![CDATA[" << it->second
|
||||
<< "]]></"<< it->first << ">";
|
||||
oss << "<" << it->first << ">"
|
||||
<< one_util::escape_xml(it->second)
|
||||
<< "</" << it->first << ">";
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +294,7 @@ int VectorAttribute::vector_value(const char *name, bool& value) const
|
||||
|
||||
string tmp = it->second;
|
||||
|
||||
TO_UPPER(tmp);
|
||||
one_util::toupper(tmp);
|
||||
|
||||
if (tmp == "YES")
|
||||
{
|
||||
|
@ -22,13 +22,12 @@
|
||||
const char * Datastore::table = "datastore_pool";
|
||||
|
||||
const char * Datastore::db_names =
|
||||
"oid, name, body, uid, gid, owner_u, group_u, other_u, cid";
|
||||
"oid, name, body, uid, gid, owner_u, group_u, other_u";
|
||||
|
||||
const char * Datastore::db_bootstrap =
|
||||
"CREATE TABLE IF NOT EXISTS datastore_pool ("
|
||||
"oid INTEGER PRIMARY KEY, name VARCHAR(128), body MEDIUMTEXT, uid INTEGER, "
|
||||
"gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, "
|
||||
"cid INTEGER)";
|
||||
"gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER)";
|
||||
|
||||
/* ************************************************************************ */
|
||||
/* Datastore :: Constructor/Destructor */
|
||||
@ -41,10 +40,9 @@ Datastore::Datastore(
|
||||
const string& gname,
|
||||
int umask,
|
||||
DatastoreTemplate* ds_template,
|
||||
int cluster_id,
|
||||
const string& cluster_name):
|
||||
const set<int> &cluster_ids):
|
||||
PoolObjectSQL(-1,DATASTORE,"",uid,gid,uname,gname,table),
|
||||
Clusterable(cluster_id, cluster_name),
|
||||
Clusterable(cluster_ids),
|
||||
ds_mad(""),
|
||||
tm_mad(""),
|
||||
base_path(""),
|
||||
@ -119,12 +117,11 @@ void Datastore::disk_attribute(
|
||||
disk->replace("DATASTORE_ID", oss.str());
|
||||
disk->replace("TM_MAD", get_tm_mad());
|
||||
|
||||
if ( get_cluster_id() != ClusterPool::NONE_CLUSTER_ID )
|
||||
{
|
||||
oss.str("");
|
||||
oss << get_cluster_id();
|
||||
set<int> cluster_ids = get_cluster_ids();
|
||||
|
||||
disk->replace("CLUSTER_ID", oss.str());
|
||||
if (!cluster_ids.empty())
|
||||
{
|
||||
disk->replace("CLUSTER_ID", one_util::join(cluster_ids, ','));
|
||||
}
|
||||
|
||||
get_template_attribute("CLONE_TARGET", st);
|
||||
@ -607,9 +604,7 @@ int Datastore::insert_replace(SqlDB *db, bool replace, string& error_str)
|
||||
<< gid << ","
|
||||
<< owner_u << ","
|
||||
<< group_u << ","
|
||||
<< other_u << ","
|
||||
<< cluster_id << ")";
|
||||
|
||||
<< other_u << ")";
|
||||
|
||||
rc = db->exec(oss);
|
||||
|
||||
@ -645,32 +640,32 @@ error_common:
|
||||
string& Datastore::to_xml(string& xml) const
|
||||
{
|
||||
ostringstream oss;
|
||||
string collection_xml;
|
||||
string clusters_xml;
|
||||
string images_xml;
|
||||
string template_xml;
|
||||
string perms_xml;
|
||||
|
||||
oss <<
|
||||
"<DATASTORE>" <<
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<UID>" << uid << "</UID>" <<
|
||||
"<GID>" << gid << "</GID>" <<
|
||||
"<UNAME>" << uname << "</UNAME>" <<
|
||||
"<GNAME>" << gname << "</GNAME>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<UID>" << uid << "</UID>" <<
|
||||
"<GID>" << gid << "</GID>" <<
|
||||
"<UNAME>" << uname << "</UNAME>" <<
|
||||
"<GNAME>" << gname << "</GNAME>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
perms_to_xml(perms_xml) <<
|
||||
"<DS_MAD><![CDATA[" << ds_mad << "]]></DS_MAD>" <<
|
||||
"<TM_MAD><![CDATA[" << tm_mad << "]]></TM_MAD>" <<
|
||||
"<BASE_PATH><![CDATA[" << base_path << "]]></BASE_PATH>"<<
|
||||
"<TYPE>" << type << "</TYPE>" <<
|
||||
"<DISK_TYPE>" << disk_type << "</DISK_TYPE>" <<
|
||||
"<STATE>" << state << "</STATE>" <<
|
||||
"<CLUSTER_ID>" << cluster_id << "</CLUSTER_ID>" <<
|
||||
"<CLUSTER>" << cluster << "</CLUSTER>" <<
|
||||
"<TOTAL_MB>" << total_mb << "</TOTAL_MB>" <<
|
||||
"<FREE_MB>" << free_mb << "</FREE_MB>" <<
|
||||
"<USED_MB>" << used_mb << "</USED_MB>" <<
|
||||
images.to_xml(collection_xml) <<
|
||||
obj_template->to_xml(template_xml) <<
|
||||
"<DS_MAD>" << one_util::escape_xml(ds_mad) << "</DS_MAD>" <<
|
||||
"<TM_MAD>" << one_util::escape_xml(tm_mad) << "</TM_MAD>" <<
|
||||
"<BASE_PATH>" << one_util::escape_xml(base_path)<< "</BASE_PATH>"<<
|
||||
"<TYPE>" << type << "</TYPE>" <<
|
||||
"<DISK_TYPE>" << disk_type << "</DISK_TYPE>" <<
|
||||
"<STATE>" << state << "</STATE>" <<
|
||||
Clusterable::to_xml(clusters_xml) <<
|
||||
"<TOTAL_MB>" << total_mb << "</TOTAL_MB>" <<
|
||||
"<FREE_MB>" << free_mb << "</FREE_MB>" <<
|
||||
"<USED_MB>" << used_mb << "</USED_MB>" <<
|
||||
images.to_xml(images_xml) <<
|
||||
obj_template->to_xml(template_xml) <<
|
||||
"</DATASTORE>";
|
||||
|
||||
xml = oss.str();
|
||||
@ -706,9 +701,6 @@ int Datastore::from_xml(const string& xml)
|
||||
rc += xpath(int_disk_type,"/DATASTORE/DISK_TYPE", -1);
|
||||
rc += xpath(int_state, "/DATASTORE/STATE", 0);
|
||||
|
||||
rc += xpath(cluster_id, "/DATASTORE/CLUSTER_ID", -1);
|
||||
rc += xpath(cluster, "/DATASTORE/CLUSTER", "not_found");
|
||||
|
||||
rc += xpath<long long>(total_mb,"/DATASTORE/TOTAL_MB",0);
|
||||
rc += xpath<long long>(free_mb, "/DATASTORE/FREE_MB", 0);
|
||||
rc += xpath<long long>(used_mb, "/DATASTORE/USED_MB", 0);
|
||||
@ -720,19 +712,11 @@ int Datastore::from_xml(const string& xml)
|
||||
type = static_cast<Datastore::DatastoreType>(int_ds_type);
|
||||
state = static_cast<DatastoreState>(int_state);
|
||||
|
||||
// Get associated classes
|
||||
ObjectXML::get_nodes("/DATASTORE/IMAGES", content);
|
||||
// Set of Image IDs
|
||||
rc += images.from_xml(this, "/DATASTORE/");
|
||||
|
||||
if (content.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set of IDs
|
||||
rc += images.from_xml_node(content[0]);
|
||||
|
||||
ObjectXML::free_nodes(content);
|
||||
content.clear();
|
||||
// Set of cluster IDs
|
||||
rc += Clusterable::from_xml(this, "/DATASTORE/");
|
||||
|
||||
// Get associated classes
|
||||
ObjectXML::get_nodes("/DATASTORE/TEMPLATE", content);
|
||||
|
@ -57,7 +57,10 @@ DatastorePool::DatastorePool(
|
||||
if (get_lastOID() == -1) //lastOID is set in PoolSQL::init_cb
|
||||
{
|
||||
DatastoreTemplate * ds_tmpl;
|
||||
int rc;
|
||||
int rc;
|
||||
set<int> cluster_ids;
|
||||
|
||||
cluster_ids.insert(ClusterPool::DEFAULT_CLUSTER_ID);
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Create the system datastore
|
||||
@ -82,8 +85,7 @@ DatastorePool::DatastorePool(
|
||||
0137,
|
||||
ds_tmpl,
|
||||
&rc,
|
||||
ClusterPool::NONE_CLUSTER_ID,
|
||||
ClusterPool::NONE_CLUSTER_NAME,
|
||||
cluster_ids,
|
||||
error_str);
|
||||
|
||||
if( rc < 0 )
|
||||
@ -116,8 +118,7 @@ DatastorePool::DatastorePool(
|
||||
0137,
|
||||
ds_tmpl,
|
||||
&rc,
|
||||
ClusterPool::NONE_CLUSTER_ID,
|
||||
ClusterPool::NONE_CLUSTER_NAME,
|
||||
cluster_ids,
|
||||
error_str);
|
||||
|
||||
if( rc < 0 )
|
||||
@ -150,8 +151,7 @@ DatastorePool::DatastorePool(
|
||||
0137,
|
||||
ds_tmpl,
|
||||
&rc,
|
||||
ClusterPool::NONE_CLUSTER_ID,
|
||||
ClusterPool::NONE_CLUSTER_NAME,
|
||||
cluster_ids,
|
||||
error_str);
|
||||
|
||||
if( rc < 0 )
|
||||
@ -184,8 +184,7 @@ int DatastorePool::allocate(
|
||||
int umask,
|
||||
DatastoreTemplate * ds_template,
|
||||
int * oid,
|
||||
int cluster_id,
|
||||
const string& cluster_name,
|
||||
const set<int> &cluster_ids,
|
||||
string& error_str)
|
||||
{
|
||||
Datastore * ds;
|
||||
@ -196,7 +195,7 @@ int DatastorePool::allocate(
|
||||
ostringstream oss;
|
||||
|
||||
ds = new Datastore(uid, gid, uname, gname, umask,
|
||||
ds_template, cluster_id, cluster_name);
|
||||
ds_template, cluster_ids);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Check name & duplicates
|
||||
|
@ -115,10 +115,14 @@ else
|
||||
CHECKSUM="$MD5"
|
||||
fi
|
||||
|
||||
if [ -z "\$CHECKSUM" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat <<EOT
|
||||
<MD5>\$CHECKSUM</MD5>
|
||||
<SIZE>$SIZE</SIZE>
|
||||
<FORMAT>${FORMAT}</FORMAT>
|
||||
<MD5><![CDATA[\$CHECKSUM]]></MD5>
|
||||
<SIZE><![CDATA[$SIZE]]></SIZE>
|
||||
<FORMAT><![CDATA[${FORMAT}]]></FORMAT>
|
||||
EOT
|
||||
EOF
|
||||
)
|
||||
@ -133,7 +137,7 @@ fi
|
||||
|
||||
cat <<EOF
|
||||
<IMPORT_INFO>
|
||||
<IMPORT_SOURCE>$IMPORT_SOURCE</IMPORT_SOURCE>
|
||||
<IMPORT_SOURCE><![CDATA[$IMPORT_SOURCE]]></IMPORT_SOURCE>
|
||||
$INFO
|
||||
<DISPOSE>NO</DISPOSE>
|
||||
</IMPORT_INFO>"
|
||||
|
@ -18,8 +18,10 @@
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
LIB_LOCATION=/usr/lib/one
|
||||
VAR_LOCATION=/var/lib/one
|
||||
else
|
||||
LIB_LOCATION=$ONE_LOCATION/lib
|
||||
VAR_LOCATION=$ONE_LOCATION/var
|
||||
fi
|
||||
|
||||
. $LIB_LOCATION/sh/scripts_common.sh
|
||||
@ -295,6 +297,9 @@ s3://*)
|
||||
rbd://*)
|
||||
command="$(get_rbd_cmd $FROM)"
|
||||
;;
|
||||
vcenter://*)
|
||||
command="$VAR_LOCATION/remotes/datastore/vcenter_downloader.rb \"$FROM\""
|
||||
;;
|
||||
*)
|
||||
if [ ! -r $FROM ]; then
|
||||
echo "Cannot read from $FROM" >&2
|
||||
|
@ -56,15 +56,17 @@ BRIDGE_LIST="${XPATH_ELEMENTS[i++]}"
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
INFO_SCRIPT=$(cat <<EOF
|
||||
|
||||
CHECKSUM=\$(${MD5SUM} ${SRC} | cut -f1 -d' ')
|
||||
SIZE=\$(${DU} -Lm ${SRC} | cut -f1)
|
||||
FORMAT=\$(${QEMU_IMG} info ${SRC} 2>/dev/null | grep -Po '(?<=file format: )\w+')
|
||||
|
||||
echo "<MD5>\$CHECKSUM</MD5>"
|
||||
echo "<SIZE>\$SIZE</SIZE>"
|
||||
echo "<FORMAT>\${FORMAT-"unknown"}</FORMAT>"
|
||||
if [ -z "\$CHECKSUM" -o -z "\$SIZE" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "<MD5><![CDATA[\$CHECKSUM]]></MD5>"
|
||||
echo "<SIZE><![CDATA[\$SIZE]]></SIZE>"
|
||||
echo "<FORMAT><![CDATA[\${FORMAT:-unknown}]]></FORMAT>"
|
||||
EOF
|
||||
)
|
||||
|
||||
@ -83,7 +85,7 @@ if [ "$INFO_STATUS" != "0" ]; then
|
||||
exit $INFO_STATUS
|
||||
fi
|
||||
|
||||
echo "<IMPORT_INFO><IMPORT_SOURCE>$SRC</IMPORT_SOURCE> \
|
||||
echo "<IMPORT_INFO><IMPORT_SOURCE><![CDATA[$SRC]]></IMPORT_SOURCE> \
|
||||
$INFO \
|
||||
<DISPOSE>NO</DISPOSE></IMPORT_INFO>"
|
||||
|
||||
|
@ -170,12 +170,12 @@ function fs_size {
|
||||
http://*|https://*)
|
||||
HEADERS=`curl -LIk --max-time 60 $1 2>&1`
|
||||
|
||||
if echo "$HEADERS" | grep -q "OpenNebula-AppMarket-Size"; then
|
||||
if echo "$HEADERS" | grep -i -q "OpenNebula-AppMarket-Size"; then
|
||||
# An AppMarket/Marketplace URL
|
||||
SIZE=$(echo "$HEADERS" | grep "^OpenNebula-AppMarket-Size:" | tail -n1 | cut -d: -f2)
|
||||
SIZE=$(echo "$HEADERS" | grep -i "^OpenNebula-AppMarket-Size:" | tail -n1 | cut -d: -f2)
|
||||
else
|
||||
# Not an AppMarket/Marketplace URL
|
||||
SIZE=$(echo "$HEADERS" | grep "^Content-Length:" | tail -n1 | cut -d: -f2)
|
||||
SIZE=$(echo "$HEADERS" | grep -i "^Content-Length:" | tail -n1 | cut -d: -f2)
|
||||
fi
|
||||
error=$?
|
||||
;;
|
||||
|
65
src/datastore_mad/remotes/vcenter/clone
Executable file
65
src/datastore_mad/remotes/vcenter/clone
Executable file
@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2015, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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 retrieve the file size of a disk
|
||||
###############################################################################
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << File.dirname(__FILE__)
|
||||
|
||||
require 'vcenter_driver'
|
||||
require 'digest'
|
||||
|
||||
drv_action_enc = ARGV[0]
|
||||
id = ARGV[1]
|
||||
|
||||
drv_action = OpenNebula::XMLElement.new
|
||||
drv_action.initialize_xml(Base64.decode64(drv_action_enc), 'DS_DRIVER_ACTION_DATA')
|
||||
|
||||
ds_name = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/NAME"]
|
||||
hostname = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/VCENTER_CLUSTER"]
|
||||
img_path = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/PATH"]
|
||||
|
||||
if ds_name.nil? || hostname.nil? || img_path.nil?
|
||||
STDERR.puts "Not enough information to clone the image, missing datastore"\
|
||||
" name or vcenter cluster name or image path."
|
||||
exit -1
|
||||
end
|
||||
|
||||
# Generate target path
|
||||
str_for_target_path = Time.now.to_s + id.to_s
|
||||
target_path = Digest::MD5.hexdigest(str_for_target_path) + ".vmdk"
|
||||
|
||||
begin
|
||||
host_id = VCenterDriver::VIClient.translate_hostname(hostname)
|
||||
vi_client = VCenterDriver::VIClient.new host_id
|
||||
|
||||
puts vi_client.copy_virtual_disk(img_path, ds_name, target_path)
|
||||
rescue Exception => e
|
||||
STDERR.puts "Error cloning img #{img_path} size. Reason: #{e.message}"
|
||||
exit -1
|
||||
end
|
234
src/datastore_mad/remotes/vcenter/cp
Executable file
234
src/datastore_mad/remotes/vcenter/cp
Executable file
@ -0,0 +1,234 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2015, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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 retrieve the file size of a disk
|
||||
###############################################################################
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
VAR_LOCATION="/var/lib/one" if !defined?(VAR_LOCATION)
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
VAR_LOCATION=ONE_LOCATION+"/var" if !defined?(VAR_LOCATION)
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << File.dirname(__FILE__)
|
||||
|
||||
require 'opennebula'
|
||||
require 'fileutils'
|
||||
require 'tempfile'
|
||||
|
||||
def is_remote?(file)
|
||||
file.match(%r{^https?://})
|
||||
end
|
||||
|
||||
def get_type(file)
|
||||
type = %x{file -b --mime-type #{file}}
|
||||
if $?.exitstatus != 0
|
||||
STDERR.puts "Can not read file #{file}"
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
type.strip
|
||||
end
|
||||
|
||||
def needs_unpack?(file)
|
||||
temp = Tempfile.new('one-')
|
||||
temp.close
|
||||
|
||||
file_path = file
|
||||
|
||||
if is_remote?(file)
|
||||
rc = system("curl --fail -sS -k -L #{file_path} | head -c 1024 > #{temp.path}")
|
||||
if !rc
|
||||
STDERR.puts "Can not download file #{file_path}"
|
||||
exit(-1)
|
||||
end
|
||||
file_path = temp.path
|
||||
end
|
||||
|
||||
type = get_type(file_path)
|
||||
type.gsub!(%r{^application/x-}, '')
|
||||
unpack = %w{bzip2 gzip tar}.include?(type)
|
||||
|
||||
temp.unlink
|
||||
|
||||
unpack
|
||||
end
|
||||
|
||||
def vmdk_info(file)
|
||||
file_path = file
|
||||
|
||||
if File.directory?(file_path)
|
||||
files = Dir["#{file_path}/*.vmdk"]
|
||||
found = false
|
||||
count = 0
|
||||
last = nil
|
||||
|
||||
files.each do |f|
|
||||
if get_type(f).strip == "text/plain"
|
||||
file_path = f
|
||||
found = true
|
||||
break
|
||||
else
|
||||
count += 1
|
||||
last = f
|
||||
end
|
||||
end
|
||||
|
||||
if !found
|
||||
if count == 1
|
||||
file_path = last
|
||||
found = true
|
||||
else
|
||||
STDERR.puts "Could not find vmdk"
|
||||
exit(-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if get_type(file_path).strip == "application/octet-stream"
|
||||
return {
|
||||
:type => :standalone,
|
||||
:file => file_path,
|
||||
:dir => File.dirname(file_path)
|
||||
}
|
||||
elsif get_type(file_path).strip == "text/plain"
|
||||
info = {
|
||||
:type => :flat,
|
||||
:file => file_path,
|
||||
:dir => File.dirname(file_path)
|
||||
}
|
||||
|
||||
files_list = []
|
||||
descriptor = File.read(file_path).split("\n")
|
||||
flat_files = descriptor.select {|l| l.start_with?("RW")}
|
||||
|
||||
flat_files.each do |f|
|
||||
files_list << info[:dir] + "/" +
|
||||
f.split(" ")[3].chomp.chomp('"').reverse.chomp('"').reverse
|
||||
end
|
||||
|
||||
info[:flat_files] = files_list
|
||||
|
||||
return info
|
||||
else
|
||||
STDERR.puts "Unrecognized file type"
|
||||
exit(-1)
|
||||
end
|
||||
end
|
||||
|
||||
drv_action_enc = ARGV[0]
|
||||
id = ARGV[1]
|
||||
|
||||
drv_action = OpenNebula::XMLElement.new
|
||||
drv_action.initialize_xml(Base64.decode64(drv_action_enc), 'DS_DRIVER_ACTION_DATA')
|
||||
|
||||
img_path = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/PATH"]
|
||||
md5 = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/TEMPLATE/MD5"]
|
||||
sha1 = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/TEMPLATE/SHA1"]
|
||||
nodecomp = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/NO_DECOMPRESS"]
|
||||
limit_bw = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/LIMIT_TRANSFER_BW"]
|
||||
hostname = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/VCENTER_CLUSTER"]
|
||||
ds_name = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/NAME"]
|
||||
|
||||
|
||||
if img_path.nil?
|
||||
STDERR.puts "Not enough information to register the image,"\
|
||||
" missing image path."
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
if img_path.start_with? "vcenter://"
|
||||
# File already in the vCenter datastore
|
||||
|
||||
puts img_path.sub("vcenter://","")
|
||||
exit(0)
|
||||
end
|
||||
|
||||
downsh_args = " "
|
||||
downsh_args += "--md5 #{md5} " if md5 and !md5.empty? and !md5.eql? "-"
|
||||
downsh_args += "--sha1 #{sha1} " if sha1 and !sha1.empty?
|
||||
downsh_args += "--nodecomp " if nodecomp and !nodecomp.empty?
|
||||
downsh_args += "--limit #{limit_bw} " if limit_bw and !limit_bw.empty?
|
||||
|
||||
downloader = "#{File.dirname(__FILE__)}/../downloader.sh #{downsh_args}"
|
||||
|
||||
# Generate target path
|
||||
str_for_target_path = Time.now.to_s + id.to_s
|
||||
target_path = Digest::MD5.hexdigest(str_for_target_path)
|
||||
|
||||
files_to_upload = Array.new
|
||||
|
||||
file_path = img_path
|
||||
skip_download = false
|
||||
delete_file = false
|
||||
files_to_upload = []
|
||||
|
||||
if is_remote?(file_path) || needs_unpack?(file_path)
|
||||
temp_folder = File.join(VAR_LOCATION, "vcenter")
|
||||
temp_file = File.join(temp_folder, File.basename(target_path))
|
||||
FileUtils.mkdir_p(temp_folder) if !File.directory?(temp_folder)
|
||||
|
||||
rc = system("#{downloader} #{file_path} #{temp_file}")
|
||||
if !rc
|
||||
STDERR.puts "Error downloading #{file_path}"
|
||||
FileUtils.rm_rf(temp_file)
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
delete_file = true
|
||||
file_path = temp_file
|
||||
end
|
||||
|
||||
info = vmdk_info(file_path)
|
||||
|
||||
case info[:type]
|
||||
when :standalone
|
||||
files_to_upload << info[:file]
|
||||
when :flat
|
||||
files_to_upload = info[:flat_files]
|
||||
files_to_upload << info[:file]
|
||||
end
|
||||
|
||||
files_to_upload.each_with_index do |f, index|
|
||||
path = "#{target_path}/#{File.basename(f)}"
|
||||
if index == files_to_upload.size - 1
|
||||
uploader_args = hostname + " " + ds_name + " " + path + " " + f
|
||||
else
|
||||
uploader_args = hostname + " " + ds_name + " " +
|
||||
path + " " + f + " &> /dev/null"
|
||||
end
|
||||
|
||||
cmd = "#{File.dirname(__FILE__)}/../vcenter_uploader.rb #{uploader_args}"
|
||||
rc = system(cmd)
|
||||
|
||||
if !rc
|
||||
STDERR.puts "Can not upload file #{f}"
|
||||
FileUtils.rm_rf(temp_file) if delete_file
|
||||
exit(-1)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
FileUtils.rm_rf(temp_file) if delete_file
|
||||
|
75
src/datastore_mad/remotes/vcenter/export
Executable file
75
src/datastore_mad/remotes/vcenter/export
Executable file
@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2015, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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 retrieve the file size of a disk
|
||||
###############################################################################
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << File.dirname(__FILE__)
|
||||
|
||||
require 'opennebula'
|
||||
|
||||
drv_action_enc = ARGV[0]
|
||||
id = ARGV[1]
|
||||
|
||||
drv_action = OpenNebula::XMLElement.new
|
||||
drv_action.initialize_xml(Base64.decode64(drv_action_enc), 'DS_DRIVER_ACTION_DATA')
|
||||
|
||||
|
||||
|
||||
img_source = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/SOURCE"]
|
||||
img_size = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/SIZE"]
|
||||
md5 = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/TEMPLATE/MD5"]
|
||||
|
||||
md5 = md5.nil? ? "-" : md5
|
||||
|
||||
hostname = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/VCENTER_CLUSTER"]
|
||||
ds_name = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/NAME"]
|
||||
|
||||
|
||||
if img_source.nil?
|
||||
STDERR.puts "Not enough information to export the image,"\
|
||||
" missing image source."
|
||||
exit -1
|
||||
end
|
||||
|
||||
# Create vcenter url with all needed information to extract the file from
|
||||
# the vCenter datastore
|
||||
|
||||
vcenter_url_img = "vcenter://#{img_source}?"\
|
||||
"param_dsname=#{ds_name}&"\
|
||||
"param_host=#{hostname}"
|
||||
|
||||
# Create import info document for marketplace import script
|
||||
|
||||
puts "<IMPORT_INFO>
|
||||
<IMPORT_SOURCE><![CDATA[#{vcenter_url_img}]]></IMPORT_SOURCE>
|
||||
<MD5><![CDATA[#{md5}]]></MD5>
|
||||
<SIZE><![CDATA[#{img_size}]]></SIZE>
|
||||
<FORMAT>VMDK</FORMAT>
|
||||
<DISPOSE>NO</DISPOSE>
|
||||
</IMPORT_INFO>"
|
72
src/datastore_mad/remotes/vcenter/mkfs
Executable file
72
src/datastore_mad/remotes/vcenter/mkfs
Executable file
@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2015, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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 retrieve the file size of a disk
|
||||
###############################################################################
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << File.dirname(__FILE__)
|
||||
|
||||
require 'vcenter_driver'
|
||||
|
||||
drv_action_enc = ARGV[0]
|
||||
id = ARGV[1]
|
||||
|
||||
drv_action =OpenNebula::XMLElement.new
|
||||
drv_action.initialize_xml(Base64.decode64(drv_action_enc), 'DS_DRIVER_ACTION_DATA')
|
||||
|
||||
ds_name = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/NAME"]
|
||||
hostname = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/VCENTER_CLUSTER"]
|
||||
adapter_type = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/TEMPLATE/ADAPTER_TYPE"]
|
||||
disk_type = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/TEMPLATE/DISK_TYPE"]
|
||||
size = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/SIZE"]
|
||||
img_name = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/NAME"]
|
||||
|
||||
if ds_name.nil? ||
|
||||
hostname.nil? ||
|
||||
adapter_type.nil? ||
|
||||
disk_type.nil? ||
|
||||
size.nil? ||
|
||||
img_name.nil?
|
||||
STDERR.puts "Not enough information to create the image."
|
||||
exit -1
|
||||
end
|
||||
|
||||
begin
|
||||
host_id = VCenterDriver::VIClient.translate_hostname(hostname)
|
||||
vi_client = VCenterDriver::VIClient.new host_id
|
||||
|
||||
puts vi_client.create_virtual_disk(img_name,
|
||||
ds_name,
|
||||
size,
|
||||
adapter_type,
|
||||
disk_type)
|
||||
rescue Exception => e
|
||||
STDERR.puts "Error creating virtual disk in #{ds_name}."\
|
||||
" Reason: #{e.message}"
|
||||
exit -1
|
||||
end
|
59
src/datastore_mad/remotes/vcenter/monitor
Executable file
59
src/datastore_mad/remotes/vcenter/monitor
Executable file
@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2015, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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 monitor the free and used space of a datastore
|
||||
###############################################################################
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << File.dirname(__FILE__)
|
||||
|
||||
require 'vcenter_driver'
|
||||
|
||||
drv_action_enc = ARGV[0]
|
||||
id = ARGV[1]
|
||||
|
||||
drv_action = OpenNebula::XMLElement.new
|
||||
drv_action.initialize_xml(Base64.decode64(drv_action_enc), 'DS_DRIVER_ACTION_DATA')
|
||||
|
||||
ds_name = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/NAME"]
|
||||
hostname = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/VCENTER_CLUSTER"]
|
||||
|
||||
if ds_name.nil? ||
|
||||
hostname.nil?
|
||||
STDERR.puts "Not enough information to monitor the image."
|
||||
exit -1
|
||||
end
|
||||
|
||||
begin
|
||||
host_id = VCenterDriver::VIClient.translate_hostname(hostname)
|
||||
vi_client = VCenterDriver::VIClient.new host_id
|
||||
|
||||
puts vi_client.monitor_ds(ds_name)
|
||||
rescue Exception => e
|
||||
STDERR.puts "Error monitoring #{ds_name}. Reason: #{e.message}"
|
||||
exit -1
|
||||
end
|
63
src/datastore_mad/remotes/vcenter/rm
Executable file
63
src/datastore_mad/remotes/vcenter/rm
Executable file
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# ---------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2015, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# 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 retrieve the file size of a disk
|
||||
###############################################################################
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << File.dirname(__FILE__)
|
||||
|
||||
require 'vcenter_driver'
|
||||
|
||||
drv_action_enc = ARGV[0]
|
||||
id = ARGV[1]
|
||||
|
||||
drv_action =OpenNebula::XMLElement.new
|
||||
drv_action.initialize_xml(Base64.decode64(drv_action_enc), 'DS_DRIVER_ACTION_DATA')
|
||||
|
||||
ds_name = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/NAME"]
|
||||
hostname = drv_action["/DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/VCENTER_CLUSTER"]
|
||||
img_src = drv_action["/DS_DRIVER_ACTION_DATA/IMAGE/SOURCE"]
|
||||
|
||||
if ds_name.nil? ||
|
||||
hostname.nil? ||
|
||||
img_src.nil?
|
||||
STDERR.puts "Not enough information to delete the image."
|
||||
exit -1
|
||||
end
|
||||
|
||||
begin
|
||||
host_id = VCenterDriver::VIClient.translate_hostname(hostname)
|
||||
vi_client = VCenterDriver::VIClient.new host_id
|
||||
|
||||
vi_client.delete_virtual_disk(img_src,
|
||||
ds_name)
|
||||
rescue Exception => e
|
||||
STDERR.puts "Error delete virtual disk #{img_src} in #{ds_name}."\
|
||||
" Reason: #{e.message}"
|
||||
exit -1
|
||||
end
|
1
src/datastore_mad/remotes/vcenter/snap_delete
Symbolic link
1
src/datastore_mad/remotes/vcenter/snap_delete
Symbolic link
@ -0,0 +1 @@
|
||||
../common/not_supported.sh
|
1
src/datastore_mad/remotes/vcenter/snap_flatten
Symbolic link
1
src/datastore_mad/remotes/vcenter/snap_flatten
Symbolic link
@ -0,0 +1 @@
|
||||
../common/not_supported.sh
|
1
src/datastore_mad/remotes/vcenter/snap_revert
Symbolic link
1
src/datastore_mad/remotes/vcenter/snap_revert
Symbolic link
@ -0,0 +1 @@
|
||||
../common/not_supported.sh
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user