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

Merge branch 'feature-3456'

This commit is contained in:
Ruben S. Montero 2015-02-14 21:58:42 +01:00
commit 96778d7c84
21 changed files with 473 additions and 27 deletions

View File

@ -62,6 +62,30 @@ public:
*/
static DatastoreType str_to_type(string& str_type);
/**
* Datastore State
*/
enum DatastoreState
{
READY = 0, /** < Datastore ready to use */
DISABLED = 1 /** < System Datastore can not be used */
};
/**
* Returns the string representation of a DatastoreState
* @param state The state
* @return the string representation
*/
static string state_to_str(DatastoreState state)
{
switch(state)
{
case READY: return "READY"; break;
case DISABLED: return "DISABLED"; break;
default: return "";
}
};
/**
* Function to print the Datastore object into a string in XML format
* @param xml the resulting XML string
@ -200,6 +224,15 @@ public:
return shared;
};
/**
* Enable or disable the DS. Only for System DS.
* @param enable true to enable
* @param error_str Returns the error reason, if any
*
* @return 0 on success
*/
int enable(bool enable, string& error_str);
private:
// -------------------------------------------------------------------------
@ -252,6 +285,11 @@ private:
*/
long long used_mb;
/**
* Datastore state
*/
DatastoreState state;
// *************************************************************************
// Constructor
// *************************************************************************

View File

@ -0,0 +1,72 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef REQUEST_MANAGER_DATASTORE_H
#define REQUEST_MANAGER_DATASTORE_H
#include "Request.h"
#include "Nebula.h"
using namespace std;
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class RequestManagerDatastore: public Request
{
protected:
RequestManagerDatastore(const string& method_name,
const string& help,
const string& params)
:Request(method_name,params,help)
{
Nebula& nd = Nebula::instance();
pool = nd.get_dspool();
auth_object = PoolObjectSQL::DATASTORE;
auth_op = AuthRequest::MANAGE;
};
~RequestManagerDatastore(){};
/* --------------------------------------------------------------------- */
virtual void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att) = 0;
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class DatastoreEnable : public RequestManagerDatastore
{
public:
DatastoreEnable():
RequestManagerDatastore("DatastoreEnable", "Enables or disables an datastore",
"A:sib"){};
~DatastoreEnable(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
#endif

View File

@ -30,6 +30,7 @@
<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="TOTAL_MB" type="xs:integer"/>

View File

@ -33,12 +33,17 @@
:DS:
:desc: Datastore driver
:size: 8
:size: 7
:left: true
:TM:
:desc: Transfer driver
:size: 8
:size: 7
:left: true
:STAT:
:desc: State of the Datastore
:size: 4
:left: true
:default:
@ -51,4 +56,5 @@
- :TYPE
- :DS
- :TM
- :STAT

View File

@ -82,15 +82,21 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper
Datastore::SHORT_DATASTORE_TYPES[type]
end
column :DS, "Datastore driver", :left, :size=>8 do |d|
column :DS, "Datastore driver", :left, :size=>7 do |d|
d["DS_MAD"]
end
column :TM, "Transfer driver", :left, :size=>8 do |d|
column :TM, "Transfer driver", :left, :size=>7 do |d|
d["TM_MAD"]
end
default :ID, :NAME, :SIZE, :AVAIL, :CLUSTER, :IMAGES, :TYPE, :DS, :TM
column :STAT, "State of the Datastore", :left, :size=>3 do |d|
state = Datastore::DATASTORE_STATES[d["STATE"].to_i]
Datastore::SHORT_DATASTORE_STATES[state]
end
default :ID, :NAME, :SIZE, :AVAIL, :CLUSTER, :IMAGES,
:TYPE, :DS, :TM, :STAT
end
table
@ -128,6 +134,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper
puts str % ["TM_MAD", datastore['TM_MAD']]
puts str % ["BASE PATH",datastore['BASE_PATH']]
puts str % ["DISK_TYPE",Image::DISK_TYPES[datastore['DISK_TYPE'].to_i]]
puts str % ["STATE", datastore.state_str]
puts
CLIHelper.print_header(str_h1 % "DATASTORE CAPACITY", false)

View File

@ -184,4 +184,24 @@ cmd=CommandParser::CmdParser.new(ARGV) do
o.rename(args[1])
end
end
enable_desc = <<-EOT.unindent
Enables the given Datastore. Only available for System Datastores
EOT
command :enable, enable_desc, [:range,:datastoreid_list] do
helper.perform_actions(args[0],options,"enabled") do |obj|
obj.enable
end
end
disable_desc = <<-EOT.unindent
Disables the given Datastore. Only available for System Datastores
EOT
command :disable, disable_desc, [:range,:datastoreid_list] do
helper.perform_actions(args[0],options,"disabled") do |obj|
obj.disable
end
end
end

View File

@ -52,7 +52,8 @@ Datastore::Datastore(
type(IMAGE_DS),
total_mb(0),
free_mb(0),
used_mb(0)
used_mb(0),
state(READY)
{
if (ds_template != 0)
{
@ -76,6 +77,30 @@ Datastore::~Datastore()
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Datastore::enable(bool enable, string& error_str)
{
if (type != SYSTEM_DS)
{
error_str = "Only SYSTEM_DS can be disabled or enabled";
return -1;
}
if (enable)
{
state = READY;
}
else
{
state = DISABLED;
}
return 0;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Datastore::disk_attribute(
VectorAttribute * disk,
const vector<string>& inherit_attrs)
@ -495,6 +520,7 @@ string& Datastore::to_xml(string& xml) const
"<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>" <<
@ -517,6 +543,7 @@ int Datastore::from_xml(const string& xml)
int rc = 0;
int int_disk_type;
int int_ds_type;
int int_state;
vector<xmlNodePtr> content;
// Initialize the internal XML object
@ -532,8 +559,9 @@ int Datastore::from_xml(const string& xml)
rc += xpath(ds_mad, "/DATASTORE/DS_MAD", "not_found");
rc += xpath(tm_mad, "/DATASTORE/TM_MAD", "not_found");
rc += xpath(base_path, "/DATASTORE/BASE_PATH", "not_found");
rc += xpath(int_ds_type, "/DATASTORE/TYPE", -1);
rc += xpath(int_ds_type, "/DATASTORE/TYPE", -1);
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");
@ -547,6 +575,7 @@ int Datastore::from_xml(const string& xml)
disk_type = static_cast<Image::DiskType>(int_disk_type);
type = static_cast<Datastore::DatastoreType>(int_ds_type);
state = static_cast<DatastoreState>(int_state);
// Get associated classes
ObjectXML::get_nodes("/DATASTORE/IMAGES", content);

View File

@ -36,11 +36,16 @@ public class Datastore extends PoolElement
private static final String CHOWN = METHOD_PREFIX + "chown";
private static final String CHMOD = METHOD_PREFIX + "chmod";
private static final String RENAME = METHOD_PREFIX + "rename";
private static final String ENABLE = METHOD_PREFIX + "enable";
private static final String[] DATASTORE_TYPES = {"IMAGE", "SYSTEM", "FILE"};
private static final String[] SHORT_DATASTORE_TYPES = {"img", "sys", "fil"};
private static final String[] DATASTORE_STATES = {"READY", "DISABLED"};
private static final String[] SHORT_DATASTORE_STATES = {"rdy", "disa"};
/**
* Creates a new Datastore representation.
* @param id The datastore id.
@ -217,7 +222,7 @@ public class Datastore extends PoolElement
* Renames this Datastore.
*
* @param client XML-RPC Client.
* @param id The image id of the target host we want to modify.
* @param id The id of the target object.
* @param name New name for the Datastore
* @return If successful the message contains the datastore id.
*/
@ -226,6 +231,19 @@ public class Datastore extends PoolElement
return client.call(RENAME, id, name);
}
/**
* Enables or disables this Datastore.
*
* @param client XML-RPC Client.
* @param id The id of the target object.
* @param enable True for enabling, false for disabling.
* @return If successful the message contains the datastore id.
*/
public static OneResponse enable(Client client, int id, boolean enable)
{
return client.call(ENABLE, id, enable);
}
// =================================
// Instanced object XML-RPC methods
// =================================
@ -398,6 +416,37 @@ public class Datastore extends PoolElement
return rename(client, id, name);
}
/**
* Enables or disables the datastore.
*
* @param enable True for enabling, false for disabling.
* @return If successful the message contains the datastore id.
*/
public OneResponse enable(boolean enable)
{
return enable(client, id, enable);
}
/**
* Enables the datastore.
*
* @return If successful the message contains the datastore id.
*/
public OneResponse enable()
{
return enable(true);
}
/**
* Disables the datastore.
*
* @return If successful the message contains the datastore id.
*/
public OneResponse disable()
{
return enable(false);
}
// =================================
// Helpers
// =================================
@ -434,6 +483,39 @@ public class Datastore extends PoolElement
return type != -1 ? SHORT_DATASTORE_TYPES[type] : null;
}
/**
* Returns the state of the Datastore.
*
* @return The state of the Datastore.
*/
public int state()
{
String state = xpath("STATE");
return state != null ? Integer.parseInt( state ) : -1;
}
/**
* Returns the state of the Datastore as a String.
*
* @return The state of the Datastore as a String.
*/
public String stateStr()
{
int state = state();
return state != -1 ? DATASTORE_STATES[state] : null;
}
/**
* Returns the state of the Datastore as a short String.
*
* @return The state of the Datastore as a short String.
*/
public String shortStateStr()
{
int state = state();
return state != -1 ? SHORT_DATASTORE_STATES[state] : null;
}
/**
* Returns whether or not the image is part of this datastore
*

View File

@ -30,7 +30,8 @@ module OpenNebula
:update => "datastore.update",
:chown => "datastore.chown",
:chmod => "datastore.chmod",
:rename => "datastore.rename"
:rename => "datastore.rename",
:enable => "datastore.enable"
}
DATASTORE_TYPES=%w{IMAGE SYSTEM FILE}
@ -41,6 +42,13 @@ module OpenNebula
"FILE" => "fil"
}
DATASTORE_STATES=%w{READY DISABLED}
SHORT_DATASTORE_STATES={
"READY" => "on",
"DISABLED" => "off"
}
# Creates a Datastore description with just its identifier
# this method should be used to create plain Datastore objects.
# +id+ the id of the user
@ -66,20 +74,6 @@ module OpenNebula
#######################################################################
# XML-RPC Methods for the Datastore Object
#######################################################################
# Returns the datastore type
def type
self['TYPE'].to_i
end
# Returns the datastore type (string value)
def type_str
DATASTORE_TYPES[type]
end
# Returns the datastore type (string value)
def short_type_str
SHORT_DATASTORE_TYPES[type_str]
end
# Retrieves the information of the given Datastore.
def info()
@ -157,10 +151,50 @@ module OpenNebula
return call(DATASTORE_METHODS[:rename], @pe_id, name)
end
# Enables a Datastore
def enable
return call(DATASTORE_METHODS[:enable], @pe_id, true)
end
# Disables a Datastore
def disable
return call(DATASTORE_METHODS[:enable], @pe_id, false)
end
# ---------------------------------------------------------------------
# Helpers to get information
# ---------------------------------------------------------------------
# Returns the datastore type
def type
self['TYPE'].to_i
end
# Returns the datastore type (string value)
def type_str
DATASTORE_TYPES[type]
end
# Returns the datastore type (string value)
def short_type_str
SHORT_DATASTORE_TYPES[type_str]
end
# Returns the state of the datastore (numeric value)
def state
self['STATE'].to_i
end
# Returns the state of the datastore (string value)
def state_str
DATASTORE_STATES[state]
end
# Returns the state of the datastore (string value)
def short_state_str
SHORT_DATASTORE_STATES[state_str]
end
# Returns whether or not the image with id 'id' is part of this datastore
def contains(id)
#This doesn't work in ruby 1.8.5

View File

@ -101,6 +101,36 @@ module Migrator
log_time()
########################################################################
# Datastore status
########################################################################
@db.run "ALTER TABLE datastore_pool RENAME TO old_datastore_pool;"
@db.run "CREATE TABLE 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, UNIQUE(name));"
@db.transaction do
@db.fetch("SELECT * FROM old_datastore_pool") do |row|
doc = Nokogiri::XML(row[:body]){|c| c.default_xml.noblanks}
doc.root.add_child(doc.create_element("STATE")).content = "0"
@db[:datastore_pool].insert(
:oid => row[:oid],
:name => row[:name],
:body => doc.root.to_s,
:uid => row[:uid],
:gid => row[:gid],
:owner_u => row[:owner_u],
:group_u => row[:group_u],
:other_u => row[:other_u],
:cid => row[:cid])
end
end
@db.run "DROP TABLE old_datastore_pool;"
log_time()
return true
end
end

View File

@ -38,6 +38,7 @@
#include "RequestManagerCluster.h"
#include "RequestManagerGroup.h"
#include "RequestManagerVdc.h"
#include "RequestManagerDatastore.h"
#include "RequestManagerSystem.h"
#include "RequestManagerProxy.h"
@ -385,6 +386,9 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr image_chtype(new ImageChangeType());
xmlrpc_c::methodPtr image_clone(new ImageClone());
// Datastore Methods
xmlrpc_c::methodPtr datastore_enable(new DatastoreEnable());
// Chown Methods
xmlrpc_c::methodPtr vm_chown(new VirtualMachineChown());
xmlrpc_c::methodPtr template_chown(new TemplateChown());
@ -669,6 +673,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.datastore.chown", datastore_chown);
RequestManagerRegistry.addMethod("one.datastore.chmod", datastore_chmod);
RequestManagerRegistry.addMethod("one.datastore.rename", datastore_rename);
RequestManagerRegistry.addMethod("one.datastore.enable", datastore_enable);
RequestManagerRegistry.addMethod("one.datastorepool.info",datastorepool_info);

View File

@ -0,0 +1,65 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "RequestManagerDatastore.h"
using namespace std;
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
void DatastoreEnable::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
int id = xmlrpc_c::value_int(paramList.getInt(1));
bool enable_flag = xmlrpc_c::value_boolean(paramList.getBoolean(2));
int rc;
Datastore * ds;
string err_msg;
if ( basic_authorization(id, att) == false )
{
return;
}
ds = static_cast<Datastore *>(pool->get(id,true));
if ( ds == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),id),
att);
return;
}
rc = ds->enable(enable_flag, err_msg);
if ( rc != 0 )
{
failure_response(INTERNAL,request_error(err_msg,""), att);
ds->unlock();
return;
}
pool->update(ds);
ds->unlock();
success_response(id, att);
}

View File

@ -45,6 +45,7 @@ source_files=[
'RequestManagerRename.cc',
'RequestManagerProxy.cc',
'RequestManagerVdc.cc',
'RequestManagerDatastore.cc',
]
# Build library

View File

@ -62,7 +62,7 @@ public:
protected:
int get_suitable_nodes(vector<xmlNodePtr>& content)
{
return get_nodes("/DATASTORE_POOL/DATASTORE[TYPE=1]", content);
return get_nodes("/DATASTORE_POOL/DATASTORE[TYPE=1 and STATE=0]", content);
};
};

View File

@ -349,6 +349,7 @@ tabs:
#- 8 # TM
#- 9 # DS
- 10 # Type
- 11 # Status
actions:
Datastore.refresh: true
Datastore.create_dialog: true

View File

@ -350,6 +350,7 @@ tabs:
#- 8 # TM
#- 9 # DS
#- 10 # Type
#- 11 # Status
actions:
Datastore.refresh: true
Datastore.create_dialog: false

View File

@ -349,6 +349,7 @@ tabs:
#- 8 # TM
#- 9 # DS
- 10 # Type
- 11 # Status
actions:
Datastore.refresh: true
Datastore.create_dialog: true

View File

@ -51,6 +51,8 @@ module OpenNebulaJSON
when "chown" then self.chown(action_hash['params'])
when "chmod" then self.chmod_octet(action_hash['params'])
when "rename" then self.rename(action_hash['params'])
when "enable" then self.enable
when "disable" then self.disable
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"

View File

@ -164,6 +164,11 @@ var OpenNebula = {
"DELETE",
"USED_PERS"][value]);
break;
case "DATASTORE":
case "datastore":
state = tr(["ON",
"OFF"][value]);
break;
case "VM_MIGRATE_REASON":
case "vm_migrate_reason":
state = tr(["NONE",
@ -1500,6 +1505,12 @@ var OpenNebula = {
OpenNebula.Datastore.resource,
"rename",
action_obj);
},
"enable": function(params){
OpenNebula.Action.simple_action(params,OpenNebula.Datastore.resource,"enable");
},
"disable": function(params){
OpenNebula.Action.simple_action(params,OpenNebula.Datastore.resource,"disable");
}
},

View File

@ -489,6 +489,28 @@ var datastore_actions = {
},
error: onError,
notify: true
},
"Datastore.enable" : {
type: "multiple",
call: OpenNebula.Datastore.enable,
callback: function (req) {
Sunstone.runAction("Datastore.show",req.request.data[0]);
},
elements: datastoreElements,
error: onError,
notify: true
},
"Datastore.disable" : {
type: "multiple",
call: OpenNebula.Datastore.disable,
callback: function (req) {
Sunstone.runAction("Datastore.show",req.request.data[0]);
},
elements: datastoreElements,
error: onError,
notify: true
}
};
@ -538,6 +560,16 @@ var datastore_buttons = {
layout: "del",
condition: mustBeAdmin
},
"Datastore.enable" : {
type: "action",
layout: "more_select",
text: tr("Enable")
},
"Datastore.disable" : {
type: "action",
layout: "more_select",
text: tr("Disable")
}
}
var datastore_info_panel = {
@ -571,6 +603,7 @@ var datastores_tab = {
<th>'+tr("TM MAD")+'</th>\
<th>'+tr("DS MAD")+'</th>\
<th>'+tr("Type")+'</th>\
<th>'+tr("Status")+'</th>\
</tr>\
</thead>\
<tbody id="tbodydatastores">\
@ -632,7 +665,8 @@ function datastoreElementArray(element_json){
element.BASE_PATH,
element.TM_MAD,
element.DS_MAD,
ds_type_str.toLowerCase().split('_')[0]
ds_type_str.toLowerCase().split('_')[0],
OpenNebula.Helper.resource_state("datastore",element.STATE)
];
}
@ -720,6 +754,11 @@ function updateDatastoreInfo(request,ds){
'<tr>'+
cluster_str +
'</tr>\
<tr>\
<td class="key_td">'+tr("State")+'</td>\
<td class="value_td">'+OpenNebula.Helper.resource_state("datastore",info.STATE)+'</td>\
<td></td>\
</tr>\
<tr>\
<td class="key_td">'+tr("Base path")+'</td>\
<td class="value_td">'+info.BASE_PATH+'</td>\

View File

@ -6458,7 +6458,8 @@ function generateDatastoreTableSelect(context_id){
tr("Basepath"),
tr("TM MAD"),
tr("DS MAD"),
tr("Type")
tr("Type"),
tr("Status")
];
var options = {
@ -6561,7 +6562,7 @@ function setupDatastoreTableSelect(section, context_id, opts){
}
});
var n_columns = 11; // SET FOR EACH RESOURCE
var n_columns = 12; // SET FOR EACH RESOURCE
$.each(fixed_ids_map, function(id,v){
var empty = [];