1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-06 13:17:42 +03:00

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

This commit is contained in:
Carlos Martín 2016-02-12 10:55:21 +01:00
commit 5135098e5e
67 changed files with 1691 additions and 675 deletions

62
include/ActionSet.h Normal file
View File

@ -0,0 +1,62 @@
/* -------------------------------------------------------------------------- */
/* 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 ACTION_SET_H
#define ACTION_SET_H
/**
* This class defines actions sets (for example the set of actions supported
* by the driver). Just the basic methods to initialize the set and check if a
* an action is included is provided (similar to FD_SET(3) or SIGSETOPS(3))
*
* Types should be enums with uint values.
*/
template <typename T>
class ActionSet
{
public:
ActionSet():action_set(0){};
ActionSet(const T * actions, int actions_len):action_set(0)
{
for (int i=0; i<actions_len; i++)
{
set(actions[i]);
}
};
~ActionSet(){};
/* Set the action in the set */
void set(T action)
{
action_set += 1 << static_cast<int>(action);
};
/**
* Check if action is included in the set
* @param action
* @return true if included
*/
bool is_set(T action) const
{
return (action_set & (1 << static_cast<int>(action))) != 0;
};
private:
long long action_set;
};
#endif /*ACTION_SET_H*/

View File

@ -20,6 +20,8 @@
#include "PoolSQL.h"
#include "ObjectCollection.h"
#include "MarketPlaceTemplate.h"
#include "MarketPlaceApp.h"
#include "ActionSet.h"
/**
* The MarketPlace class. It represents an abstract container for OpenNebula
@ -86,6 +88,16 @@ public:
*/
void update_monitor(const Template& data);
/**
* Check if action is supported for the apps
* @param action
* @return true if it is supported
*/
bool is_action_supported(MarketPlaceApp::Action action) const
{
return supported_actions.is_set(action);
}
private:
friend class MarketPlacePool;
@ -93,7 +105,6 @@ private:
// *************************************************************************
// MarketPlace Attributes
// *************************************************************************
/**
* Name of the marketplace driver used to import apps
*/
@ -114,6 +125,11 @@ private:
*/
long long used_mb;
/**
* Supported actions on MarketPlaceApps
*/
ActionSet<MarketPlaceApp::Action> supported_actions;
// *************************************************************************
// Constructor
// *************************************************************************

View File

@ -28,10 +28,44 @@
class MarketPlaceApp : public PoolObjectSQL
{
public:
/**
* MarketPlaceApp actions
*/
enum Action
{
NONE = 0,
CREATE = 1,
DELETE = 2,
MONITOR = 3
};
static int action_from_str(string& st, Action& action)
{
if (st == "create")
{
action = CREATE;
}
else if (st == "delete")
{
action = DELETE;
}
else if (st == "monitor")
{
action = MONITOR;
}
else
{
action = NONE;
return -1;
}
return 0;
};
/**
* MarketPlaceApp states
*/
enum MarketPlaceAppState
enum State
{
INIT = 0, /** < Initialization state */
READY = 1, /** < Ready to use */
@ -45,7 +79,7 @@ public:
* @param state The state
* @return the string representation
*/
static string state_to_str(MarketPlaceAppState state)
static string state_to_str(State state)
{
switch(state)
{
@ -61,7 +95,7 @@ public:
/**
* MarketPlaceApp container types
*/
enum MarketPlaceAppType
enum Type
{
UNKNOWN = 0, /** < Unknown types */
IMAGE = 1, /** < Image MarketPlace App*/
@ -74,7 +108,7 @@ public:
* @param ob the type
* @return the string
*/
static string type_to_str(MarketPlaceAppType ob)
static string type_to_str(Type ob)
{
switch (ob)
{
@ -91,7 +125,7 @@ public:
* @param str_type string representing the type
* @return the MarketPlaceType
*/
static MarketPlaceAppType str_to_type(string& str_type);
static Type str_to_type(string& str_type);
/**
* Function to print the MarketPlaceApp object into a string in XML format
@ -161,7 +195,7 @@ public:
* Returns the marketplace app type
* @return marketplace app type
*/
MarketPlaceAppType get_type() const
Type get_type() const
{
return type;
};
@ -196,7 +230,7 @@ public:
}
MarketPlaceAppState get_state() const
State get_state() const
{
return state;
}
@ -204,7 +238,7 @@ public:
//--------------------------------------------------------------------------
// Set Marketplace app attributes
//--------------------------------------------------------------------------
void set_state(MarketPlaceAppState _state)
void set_state(State _state)
{
state = _state;
};
@ -239,7 +273,7 @@ private:
/**
* Publishing date
*/
time_t date;
time_t regtime;
/**
* Source URL for the marketplace app
@ -261,11 +295,6 @@ private:
*/
std::string description;
/**
* User sharing the app
*/
std::string publisher;
/**
* Version of the app
*/
@ -294,12 +323,12 @@ private:
/**
* Marketplace App state
*/
MarketPlaceAppState state;
State state;
/**
* The marketplace type
*/
MarketPlaceAppType type;
Type type;
/**
* Origin of this App

View File

@ -67,7 +67,8 @@ public:
* @param mp_name of the MarketPlace
* @param error_str Returns the error reason, if any
*
* @return 0 on success
* @return the oid assigned to the object, -1 in case of failure, -2
* already imported
*/
int import(const std::string& t64, int mp_id, const std::string& mp_name,
std::string& error_str);

View File

@ -408,38 +408,35 @@ public:
nebula_configuration->get(name, value);
};
/**
* Gets a configuration attribute for oned, bool version
*/
void get_configuration_attribute(
const char * name,
bool& value) const
{
string _name(name);
nebula_configuration->Template::get(_name, value);
};
/**
* Gets a DS configuration attribute
*/
int get_ds_conf_attribute(
const std::string& ds_name,
const VectorAttribute* &value) const;
const VectorAttribute* &value) const
{
return get_conf_attribute("DS_MAD_CONF", ds_name, value);
};
/**
* Gets a TM configuration attribute
*/
int get_tm_conf_attribute(
const string& tm_name,
const VectorAttribute* &value) const;
const VectorAttribute* &value) const
{
return get_conf_attribute("TM_MAD_CONF", tm_name, value);
};
/**
* Gets a Market configuration attribute
*/
int get_market_conf_attribute(
const string& tm_name,
const VectorAttribute* &value) const;
const string& mk_name,
const VectorAttribute* &value) const
{
return get_conf_attribute("MARKET_MAD_CONF", mk_name, value);
};
/**
* Gets an XML document with all of the configuration attributes

View File

@ -1326,12 +1326,6 @@ public:
*/
bool is_vrouter();
/**
* Checks if the given action is supported for Virtual Router VMs
* @param action VM action to check
* @return true if the action is supported for Virtual Router VMs
*/
static bool is_vrouter_action_supported(History::VMAction action);
// ------------------------------------------------------------------------
// Context related functions

View File

@ -22,6 +22,7 @@
#include <sstream>
#include "Mad.h"
#include "ActionSet.h"
#include "VirtualMachinePool.h"
#include "History.h"
@ -91,7 +92,7 @@ public:
*/
bool is_imported_action_supported(History::VMAction action) const
{
return (imported_vm_actions && (1 << static_cast<int>(action))) != 0;
return imported_actions.is_set(action);
}
protected:
@ -101,13 +102,10 @@ protected:
* @param name of config attribute
* @param value of the attribute
*/
void get_default(
const char * name,
string& value) const
template<typename T>
void get_default(const string& name, T& value) const
{
string sn = name;
driver_conf.get(sn,value);
driver_conf.get(name, value);
}
/**
@ -117,26 +115,25 @@ protected:
* @param vname of the attribute
* @param value of the attribute
*/
void get_default(
const char * name,
const char * vname,
string& value) const;
template<typename T>
int get_default(const char* name, const char* vname, T& value) const
{
const VectorAttribute * vattr = driver_conf.get(name);
/**
* Gets a configuration attr from driver configuration file (vector
* version)
* @param name of config vector attribute for the domain
* @param vname of the attribute
* @param value of the attribute
*
* @return true if the attribute was found
*/
bool get_default(
const char * name,
const char * vname,
bool& value) const;
if (vattr != 0)
{
return -1;
}
return vattr->vector_value(vname, value);
}
private:
friend class VirtualMachineManager;
static const string imported_actions_default;
static const string imported_actions_default_public;
/**
* Configuration file for the driver
*/
@ -146,15 +143,13 @@ private:
* List of available actions for imported VMs. Each bit is an action
* as defined in History.h, 1=supported and 0=not supported
*/
long long imported_vm_actions;
ActionSet<History::VMAction> imported_actions;
/**
* Pointer to the Virtual Machine Pool, to access VMs
*/
VirtualMachinePool * vmpool;
friend class VirtualMachineManager;
/**
* Sends a deploy request to the MAD: "DEPLOY ID XML_DRV_MSG"
* @param oid the virtual machine id.
@ -287,7 +282,6 @@ private:
const string& drv_msg) const
{
write_drv("POLL", oid, drv_msg);
}
/**

View File

@ -22,6 +22,8 @@
#include "ObjectCollection.h"
#include "VirtualMachineTemplate.h"
#include "AuthRequest.h"
#include "History.h"
#include "ActionSet.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -131,18 +133,27 @@ public:
AuthRequest& ar,
Template *tmpl);
/**
* Checks if the given action is supported for Virtual Router VMs
* @param action VM action to check
* @return true if the action is supported for Virtual Router VMs
*/
static bool is_action_supported(History::VMAction action)
{
return SUPPORTED_ACTIONS.is_set(action);
}
private:
// -------------------------------------------------------------------------
// Friends
// -------------------------------------------------------------------------
friend class VirtualRouterPool;
static const ActionSet<History::VMAction> SUPPORTED_ACTIONS;
// *************************************************************************
// Attributes
// *************************************************************************
ObjectCollection vms;
// *************************************************************************

View File

@ -1217,7 +1217,8 @@ DATASTORE_DRIVER_CEPH_SCRIPTS="src/datastore_mad/remotes/ceph/cp \
src/datastore_mad/remotes/ceph/snap_revert \
src/datastore_mad/remotes/ceph/snap_flatten \
src/datastore_mad/remotes/ceph/ceph.conf \
src/datastore_mad/remotes/ceph/ceph_utils.sh"
src/datastore_mad/remotes/ceph/ceph_utils.sh \
src/datastore_mad/remotes/ceph/export"
DATASTORE_DRIVER_DEV_SCRIPTS="src/datastore_mad/remotes/dev/cp \
src/datastore_mad/remotes/dev/mkfs \

View File

@ -1078,19 +1078,26 @@ DS_MAD_CONF = [
# name : name of the market driver
# required_attrs : comma separated list of required attributes in the Market
# template
# app_actions: List of actions allowed for a MarketPlaceApp
# - monitor The apps of the marketplace will be monitored
# - create, the app in the marketplace
# - delete, the app from the marketplace
#*******************************************************************************
MARKET_MAD_CONF = [
NAME = "one",
REQUIRED_ATTRS = ""
REQUIRED_ATTRS = "",
APP_ACTIONS = "create, monitor"
]
MARKET_MAD_CONF = [
NAME = "http",
REQUIRED_ATTRS = "BASE_URL,PUBLIC_DIR"
REQUIRED_ATTRS = "BASE_URL,PUBLIC_DIR",
APP_ACTIONS = "create, delete, monitor"
]
MARKET_MAD_CONF = [
NAME = "s3",
REQUIRED_ATTRS = "ACCESS_KEY_ID,SECRET_ACCESS_KEY,REGION,BUCKET"
REQUIRED_ATTRS = "ACCESS_KEY_ID,SECRET_ACCESS_KEY,REGION,BUCKET",
APP_ACTIONS = "create, delete, monitor"
]

View File

@ -1,11 +1,11 @@
---
:ID:
:desc: ONE identifier for the Marketplace
:desc: ONE identifier for the Marketplace
:size: 4
:NAME:
:desc: Name of the Marketplace
:size: 30
:size: 20
:left: true
:SIZE:
@ -28,8 +28,8 @@
:default:
- :ID
- :NAME
- :SIZE
- :AVAIL
- :APPS
- :MAD
- :NAME

View File

@ -1,19 +1,19 @@
---
:ID:
:desc: ONE identifier for the marketplace app
:desc: ONE identifier for the MarketPlaceApp
:size: 4
:NAME:
:desc: Name of the marketplace app
:size: 15
:desc: Name of the MarketPlaceApp
:size: 25
:left: true
:VERSION:
:desc: Version of the marketplace app
:size: 7
:desc: Version of the MarketPlaceApp
:size: 10
:SIZE:
:desc: Marketplace app size (M)
:desc: MarketPlaceApp size (M)
:size: 5
:STAT:
@ -21,22 +21,16 @@
:size: 4
:TYPE:
:desc: Marketplace app type
:desc: MarketPlaceApp type
:size: 4
:DATE:
:desc: Publishing date for the marketplace app
:REGTIME:
:desc: Registration time of the MarketplaceApp
:size: 8
:MARKET:
:desc: ID of the marketplace
:size: 6
:PUBLISHER:
:desc: Publisher of the marketplace app
:size: 25
:left: true
:desc: Name of the MarketPlace
:size: 20
:default:
- :ID
@ -45,6 +39,5 @@
- :SIZE
- :STAT
- :TYPE
- :DATE
- :REGTIME
- :MARKET
- :PUBLISHER

View File

@ -43,10 +43,6 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
d["NAME"]
end
column :PUBLISHER, "Publisher of the App", :left, :size=>25 do |d|
d["PUBLISHER"]
end
column :VERSION, "Version of the app", :size=>7 do |d|
d["VERSION"]
end
@ -59,8 +55,8 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
OneMarketPlaceAppHelper.state_to_str(d["STATE"])
end
column :DATE, "Publishing date of the app", :size=>8 do |d|
Time.at(d['DATE'].to_i).strftime("%D")
column :REGTIME, "Registration time of the app", :size=>8 do |d|
Time.at(d['REGTIME'].to_i).strftime("%D")
end
column :TYPE, "Marketplace app type", :size=>4 do |d|
@ -68,11 +64,11 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
MarketPlaceApp::SHORT_MARKETPLACEAPP_TYPES[type]
end
column :MARKET, "ID of the marketplace", :size=>6 do |d|
d["MARKETPLACE_ID"]
column :MARKET, "Name of the MarketPlace", :size=>6 do |d|
d["MARKETPLACE"]
end
default :ID,:NAME,:VERSION,:SIZE,:STAT,:TYPE,:DATE,:MARKET,:PUBLISHER
default :ID,:NAME,:VERSION,:SIZE,:STAT,:TYPE,:REGTIME,:MARKET
end
table
@ -125,7 +121,7 @@ class OneMarketPlaceAppHelper < OpenNebulaHelper::OneHelper
puts str % ["SOURCE", app['SOURCE']]
puts str % ["MD5", app['MD5']]
puts str % ["PUBLISHER", app['PUBLISHER']]
puts str % ["PUB. DATE", Time.at(app['DATE'].to_i).strftime("%c") ]
puts str % ["REGISTER TIME", Time.at(app['REGTIME'].to_i).strftime("%c") ]
puts str % ["VERSION", app['VERSION']]
puts str % ["DESCRIPTION", app['DESCRIPTION']]
puts str % ["SIZE", OpenNebulaHelper.unit_to_str(app['SIZE'].to_i,{},'M')]

View File

@ -650,6 +650,31 @@ cmd=CommandParser::CmdParser.new(ARGV) do
}
end
rename_desc = <<-EOT.unindent
Renames the Service
EOT
command :rename, rename_desc, :service_id, :name do
client = Service::Client.new(
:username => options[:username],
:password => options[:password],
:url => options[:server],
:user_agent => USER_AGENT)
params = Hash.new
params['name'] = args[1]
json_action = Service.build_json_action('rename', params)
response = client.post("#{RESOURCE_PATH}/#{args[0]}/action", json_action)
if CloudClient::is_error?(response)
[response.code.to_i, response.to_s]
else
response.code.to_i
end
end
action_desc = <<-EOT.unindent
Perform an action on all the Virtual Machines of a given role.
Actions supported: #{Role::SCHEDULE_ACTIONS.join(",")}

View File

@ -399,6 +399,62 @@ cmd=CommandParser::CmdParser.new(ARGV) do
}
end
clone_desc = <<-EOT.unindent
Creates a new Service Template from an existing one
EOT
command :clone, clone_desc, :templateid, :name do
client = Service::Client.new(
:username => options[:username],
:password => options[:password],
:url => options[:server],
:user_agent => USER_AGENT)
params = Hash.new
params['name'] = args[1]
json_action = Service.build_json_action('clone', params)
response = client.post("#{RESOURCE_PATH}/#{args[0]}/action", json_action)
if CloudClient::is_error?(response)
[response.code.to_i, response.to_s]
else
if options[:json]
[0, response.body]
else
template = JSON.parse(response.body)
puts "ID: #{template['DOCUMENT']['ID']}"
0
end
end
end
rename_desc = <<-EOT.unindent
Renames the Service Template
EOT
command :rename, rename_desc, :templateid, :name do
client = Service::Client.new(
:username => options[:username],
:password => options[:password],
:url => options[:server],
:user_agent => USER_AGENT)
params = Hash.new
params['name'] = args[1]
json_action = Service.build_json_action('rename', params)
response = client.post("#{RESOURCE_PATH}/#{args[0]}/action", json_action)
if CloudClient::is_error?(response)
[response.code.to_i, response.to_s]
else
response.code.to_i
end
end
update_desc = <<-EOT.unindent
Update the template contents. If a path is not provided the editor will
be launched to modify the current content.

View File

@ -512,9 +512,19 @@ post '/service_template/:id/action' do
status 204
service_template.rename(opts['name'])
when 'clone'
status 204
service_template.clone(opts['name'])
# TODO return id of the new template
rc = service_template.clone(opts['name'])
if OpenNebula.is_error?(rc)
error CloudServer::HTTP_ERROR_CODE[rc.errno], rc.message
end
new_stemplate = OpenNebula::ServiceTemplate.new_with_id(rc, @client)
new_stemplate.info
if OpenNebula.is_error?(new_stemplate)
error CloudServer::HTTP_ERROR_CODE[new_stemplate.errno], new_stemplate.message
end
status 201
body new_stemplate.to_json
else
OpenNebula::Error.new("Action #{action['perform']} not supported")
end

View File

@ -146,7 +146,7 @@ int MarketPlace::insert(SqlDB *db, string& error_str)
//MarketPlacePool::allocate checks NAME
erase_template_attribute("NAME", name);
erase_template_attribute("MARKET_MAD", market_mad);
get_template_attribute("MARKET_MAD", market_mad);
if ( market_mad.empty() == true )
{
@ -290,6 +290,31 @@ std::string& MarketPlace::to_xml(std::string& xml) const
/* --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------- */
static void set_supported_actions(ActionSet<MarketPlaceApp::Action>& as,
const string& astr)
{
std::vector<std::string> actions;
std::vector<std::string>::iterator vit;
std::string action;
MarketPlaceApp::Action id;
actions = one_util::split(astr, ',');
for (vit = actions.begin() ; vit != actions.end() ; ++vit)
{
action = one_util::trim(*vit);
if ( MarketPlaceApp::action_from_str(action, id) != 0 )
{
NebulaLog::log("MKP", Log::ERROR, "Wrong action: " + action);
continue;
}
as.set(id);
}
}
int MarketPlace::from_xml(const std::string &xml_str)
{
int rc = 0;
@ -346,6 +371,29 @@ int MarketPlace::from_xml(const std::string &xml_str)
return -1;
}
// ------ SUPPORTED ACTIONS, regenerated from oned.conf ------
const VectorAttribute* vatt;
string actions;
if (Nebula::instance().get_market_conf_attribute(market_mad, vatt) == 0)
{
actions = vatt->vector_value("APP_ACTIONS");
}
if (actions.empty())
{
if (market_mad == "http" || market_mad == "s3")
{
actions = "create, monitor, delete";
}
else if ( market_mad == "one" )
{
actions = "create, monitor";
}
}
set_supported_actions(supported_actions, actions);
return 0;
}
@ -360,6 +408,12 @@ int MarketPlace::post_update_template(std::string& error)
if (!new_market_mad.empty())
{
if (set_market_mad(new_market_mad, error) != 0)
{
add_template_attribute("MARKET_MAD", market_mad);
return -1;
}
market_mad = new_market_mad;
}

View File

@ -49,7 +49,6 @@ MarketPlaceApp::MarketPlaceApp(
md5(""),
size_mb(0),
description(""),
publisher(""),
version(""),
apptemplate64(""),
market_id(-1),
@ -100,8 +99,9 @@ int MarketPlaceApp::insert(SqlDB *db, string& error_str)
remove_template_attribute("SIZE");
remove_template_attribute("MD5");
remove_template_attribute("FORMAT");
remove_template_attribute("REGTIME");
date = time(NULL);
regtime = time(NULL);
type = IMAGE;
@ -109,7 +109,6 @@ int MarketPlaceApp::insert(SqlDB *db, string& error_str)
//ORIGIN_ID
//DESCRIPTION
//APPTEMPLATE64
//PUBLISHER
//VERSION
if (!get_template_attribute("ORIGIN_ID", origin_id))
{
@ -122,13 +121,6 @@ int MarketPlaceApp::insert(SqlDB *db, string& error_str)
get_template_attribute("APPTEMPLATE64", apptemplate64);
get_template_attribute("PUBLISHER", publisher);
if (publisher.empty())
{
publisher = uname;
}
get_template_attribute("VERSION", version);
if (version.empty())
@ -246,14 +238,13 @@ std::string& MarketPlaceApp::to_xml(std::string& xml) const
"<GID>" << gid << "</GID>" <<
"<UNAME>" << uname << "</UNAME>" <<
"<GNAME>" << gname << "</GNAME>" <<
"<DATE>" << date << "</DATE>" <<
"<REGTIME>" << regtime << "</REGTIME>" <<
"<NAME>" << name << "</NAME>" <<
"<ORIGIN_ID>" << origin_id << "</ORIGIN_ID>" <<
"<SOURCE>" << source << "</SOURCE>" <<
"<MD5>" << md5 << "</MD5>" <<
"<SIZE>" << size_mb << "</SIZE>" <<
"<DESCRIPTION>" << description << "</DESCRIPTION>" <<
"<PUBLISHER>" << publisher << "</PUBLISHER>" <<
"<VERSION>" << version << "</VERSION>" <<
"<FORMAT>" << format << "</FORMAT>" <<
"<APPTEMPLATE64>" << apptemplate64 << "</APPTEMPLATE64>" <<
@ -290,7 +281,7 @@ int MarketPlaceApp::from_xml(const std::string &xml_str)
rc += xpath(uname, "/MARKETPLACEAPP/UNAME", "not_found");
rc += xpath(gname, "/MARKETPLACEAPP/GNAME", "not_found");
rc += xpath(name, "/MARKETPLACEAPP/NAME", "not_found");
rc += xpath<time_t>(date, "/MARKETPLACEAPP/DATE", -1);
rc += xpath<time_t>(regtime,"/MARKETPLACEAPP/REGTIME", -1);
rc += xpath(source, "/MARKETPLACEAPP/SOURCE", "not_found");
rc += xpath(origin_id, "/MARKETPLACEAPP/ORIGIN_ID", -1);
rc += xpath(istate, "/MARKETPLACEAPP/STATE", -1);
@ -299,14 +290,13 @@ int MarketPlaceApp::from_xml(const std::string &xml_str)
rc += xpath<long long>(size_mb, "/MARKETPLACEAPP/SIZE", -1);
rc += xpath(version, "/MARKETPLACEAPP/VERSION", "not_found");
rc += xpath(md5, "/MARKETPLACEAPP/MD5", "not_found");
rc += xpath(publisher, "/MARKETPLACEAPP/PUBLISHER", "not_found");
rc += xpath(format, "/MARKETPLACEAPP/FORMAT", "not_found");
rc += xpath(apptemplate64,"/MARKETPLACEAPP/APPTEMPLATE64", "not_found");
rc += xpath(market_name, "/MARKETPLACEAPP/MARKETPLACE", "not_found");
rc += xpath(market_id, "/MARKETPLACEAPP/MARKETPLACE_ID", -1);
state = static_cast<MarketPlaceAppState>(istate);
type = static_cast<MarketPlaceAppType>(itype);
state = static_cast<State>(istate);
type = static_cast<Type>(itype);
// ----- Permissions -----
rc += perms_from_xml();
@ -338,21 +328,24 @@ int MarketPlaceApp::post_update_template(string& error)
{
std::string n_description;
std::string n_apptemplate64;
std::string n_publisher;
std::string n_version;
// -------------------------------------------------------------------------
// Update well known attributes
// -------------------------------------------------------------------------
get_template_attribute("DESCRIPTION", n_description);
get_template_attribute("APPTEMPLATE64", n_apptemplate64);
get_template_attribute("PUBLISHER", n_publisher);
get_template_attribute("VERSION", n_version);
get_template_attribute("DESCRIPTION", description);
get_template_attribute("APPTEMPLATE64", apptemplate64);
get_template_attribute("VERSION", version);
description = n_description;
apptemplate64 = n_apptemplate64;
publisher = n_publisher;
version = n_version;
// -------------------------------------------------------------------------
// Remove non-update attributes
// -------------------------------------------------------------------------
remove_template_attribute("SOURCE");
remove_template_attribute("SIZE");
remove_template_attribute("MD5");
remove_template_attribute("FORMAT");
remove_template_attribute("REGTIME");
remove_template_attribute("ORIGIN_ID");
return 0;
}
@ -360,7 +353,7 @@ int MarketPlaceApp::post_update_template(string& error)
/* --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------- */
MarketPlaceApp::MarketPlaceAppType MarketPlaceApp::str_to_type(string& str_type)
MarketPlaceApp::Type MarketPlaceApp::str_to_type(string& str_type)
{
one_util::toupper(str_type);
@ -425,7 +418,6 @@ void MarketPlaceApp::to_template(Template * tmpl) const
int MarketPlaceApp::from_template64(const std::string &info64, std::string& err)
{
std::string * info = one_util::base64_decode(info64);
std::string sdate;
if (info == 0)
{
@ -456,24 +448,17 @@ int MarketPlaceApp::from_template64(const std::string &info64, std::string& err)
erase_template_attribute("NAME", name);
erase_template_attribute("SOURCE", source);
erase_template_attribute("DESCRIPTION", description);
erase_template_attribute("SIZE", size_mb);
erase_template_attribute("VERSION", version);
erase_template_attribute("MD5", md5);
erase_template_attribute("PUBLISHER", publisher);
erase_template_attribute("FORMAT", format);
erase_template_attribute("APPTEMPLATE64", apptemplate64);
erase_template_attribute("REGTIME", regtime);
erase_template_attribute("DATE", sdate);
std::istringstream iss(sdate);
iss >> date;
get_template_attribute("DESCRIPTION", description);
get_template_attribute("VERSION", version);
get_template_attribute("APPTEMPLATE64", apptemplate64);
if ( date == 0 )
{
date = time(NULL);
}
replace_template_attribute("IMPORTED", "YES");
replace_template_attribute("IMPORTED", "YES");
return 0;
return 0;
}

View File

@ -144,7 +144,7 @@ int MarketPlaceAppPool::import(const std::string& t64, int mp_id,
{
//Marketplace app already imported
delete app;
return 0;
return -2;
}
return PoolSQL::allocate(app, error_str);

View File

@ -263,10 +263,20 @@ void MarketPlaceManager::monitor_market(int mp_id)
return;
}
mp->to_xml(mp_data);
mp_name = mp->get_name();
if ( !mp->is_action_supported(MarketPlaceApp::MONITOR) )
{
NebulaLog::log("MKP", Log::DEBUG, "Monitoring disabled for market: " +
mp_name);
mp->unlock();
return;
}
mp->to_xml(mp_data);
mp->unlock();
drv_msg = MarketPlaceManager::format_message("", mp_data, "");

View File

@ -61,7 +61,7 @@ int MarketPlaceManager::import_app(
app->to_xml(app_data);
MarketPlaceApp::MarketPlaceAppType type = app->get_type();
MarketPlaceApp::Type type = app->get_type();
int app_id = app->get_oid();
int origin_id = app->get_origin_id();
@ -131,7 +131,7 @@ void MarketPlaceManager::release_app_resources(int appid)
return;
}
MarketPlaceApp::MarketPlaceAppType type = app->get_type();
MarketPlaceApp::Type type = app->get_type();
int iid = app->get_origin_id();
@ -180,8 +180,8 @@ int MarketPlaceManager::delete_app(int appid, const std::string& market_data,
app->to_xml(app_data);
MarketPlaceApp::MarketPlaceAppType type = app->get_type();
MarketPlaceApp::MarketPlaceAppState state = app->get_state();
MarketPlaceApp::Type type = app->get_type();
MarketPlaceApp::State state = app->get_state();
int market_id = app->get_market_id();

View File

@ -143,10 +143,22 @@ static void monitor_action(
for (int i=0; i< num ; i++)
{
if ( apppool->import(apps[i]->value(), id, name, err) == -1 )
int rc = apppool->import(apps[i]->value(), id, name, err);
if ( rc == -1 )
{
NebulaLog::log("MKP", Log::ERROR, "Error importing app: " + err);
}
else if ( rc >= 0 ) //-2 means app already imported
{
MarketPlace * market = marketpool->get(id, true);
market->add_marketapp(rc);
marketpool->update(market);
market->unlock();
}
}
oss << "Marketplace " << name << " (" << id << ") successfully monitored.";

View File

@ -20,20 +20,21 @@ require 'net/http'
require 'uri'
require 'json'
require 'base64'
require 'rexml/document'
class OneMarket
ONE_MARKET_URL = 'http://marketplace.opennebula.systems/'
AGENT = 'Market Driver'
VERSION = File.dirname(__FILE__) + '/../../VERSION'
def initialize(url=ONE_MARKET_URL)
@url = url
def initialize(url)
@url = url || ONE_MARKET_URL
@agent = "OpenNebula #{File.read(VERSION)} (#{AGENT})"
end
def get(path)
uri = URI(@url + path)
req = Net::HTTP::Get.new(uri)
req = Net::HTTP::Get.new(uri.request_uri)
req['User-Agent'] = @agent
@ -74,7 +75,7 @@ class OneMarket
print_var(tmpl, "DESCRIPTION", app["short_description"])
print_var(tmpl, "VERSION", app["version"])
print_var(tmpl, "TAGS", app["tags"].join(', '))
print_var(tmpl, "DATE", app["creation_time"])
print_var(tmpl, "REGTIME", app["creation_time"])
if !app["files"].nil? && !app["files"][0].nil?
file = app["files"][0]
@ -143,6 +144,14 @@ end
################################################################################
# Main Program. Outpust the list of marketplace appliances
################################################################################
begin
drv_message = Base64::decode64(ARGV[0])
doc = REXML::Document.new(drv_message).root
url = doc.elements['MARKETPLACE/TEMPLATE/ENDPOINT'].text rescue nil
rescue Exception
end
#TODO get marketplace URL from MARKETPLACE Templace for other markets
one_market = OneMarket.new
puts one_market.get_appliances()
one_market = OneMarket.new(url)
puts one_market.get_appliances

View File

@ -1107,23 +1107,3 @@ int Nebula::get_conf_attribute(
return -1;
};
int Nebula::get_ds_conf_attribute(
const std::string& name,
const VectorAttribute* &value) const
{
return get_conf_attribute("DS_MAD_CONF", name, value);
};
int Nebula::get_tm_conf_attribute(
const std::string& name,
const VectorAttribute* &value) const
{
return get_conf_attribute("TM_MAD_CONF", name, value);
};
int Nebula::get_market_conf_attribute(
const std::string& name,
const VectorAttribute* &value) const
{
return get_conf_attribute("MARKET_MAD_CONF", name, value);
};

View File

@ -912,6 +912,14 @@ int MarketPlaceAppAllocate::pool_allocate(
std::string mp_name = mp->get_name();
std::string mp_data;
if ( !mp->is_action_supported(MarketPlaceApp::CREATE) )
{
att.resp_msg = "Create disabled for market: " + mp_name;
mp->unlock();
return -1;
}
mp->to_xml(mp_data);
mp->unlock();

View File

@ -518,6 +518,14 @@ int MarketPlaceAppDelete::drop(int oid, PoolObjectSQL * object, string& emsg)
std::string mp_name = mp->get_name();
std::string mp_data;
if ( !mp->is_action_supported(MarketPlaceApp::DELETE) )
{
emsg = "Delete disabled for market: " + mp_name;
mp->unlock();
return -1;
}
mp->to_xml(mp_data);
mp->unlock();

View File

@ -544,7 +544,7 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
if (vm->is_vrouter() && !vm->is_vrouter_action_supported(action))
if (vm->is_vrouter() && !VirtualRouter::is_action_supported(action))
{
bool failure = true;
@ -1029,7 +1029,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
if (vm->is_vrouter() && !vm->is_vrouter_action_supported(action))
if (vm->is_vrouter() && !VirtualRouter::is_action_supported(action))
{
att.resp_msg = "Migration is not supported for virtual router VMs";
failure_response(ACTION, att);
@ -1580,7 +1580,7 @@ void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
volatile_disk = vm->volatile_disk_extended_info(&tmpl);
if (vm->is_vrouter() && !vm->is_vrouter_action_supported(History::DISK_ATTACH_ACTION))
if (vm->is_vrouter() && !VirtualRouter::is_action_supported(History::DISK_ATTACH_ACTION))
{
att.resp_msg = "Action is not supported for virtual router VMs";
failure_response(ACTION, att);
@ -1663,7 +1663,7 @@ void VirtualMachineDetach::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
if (vm->is_vrouter() && !vm->is_vrouter_action_supported(History::NIC_DETACH_ACTION))
if (vm->is_vrouter() && !VirtualRouter::is_action_supported(History::NIC_DETACH_ACTION))
{
att.resp_msg = "Action is not supported for virtual router VMs";
failure_response(ACTION, att);
@ -2115,7 +2115,7 @@ void VirtualMachineAttachNic::request_execute(
return;
}
if (vm->is_vrouter() && !vm->is_vrouter_action_supported(History::NIC_ATTACH_ACTION))
if (vm->is_vrouter() && !VirtualRouter::is_action_supported(History::NIC_ATTACH_ACTION))
{
att.resp_msg = "Action is not supported for virtual router VMs";
failure_response(Request::ACTION, att);
@ -2252,7 +2252,7 @@ void VirtualMachineDetachNic::request_execute(
return;
}
if (vm->is_vrouter() && !vm->is_vrouter_action_supported(History::NIC_DETACH_ACTION))
if (vm->is_vrouter() && !VirtualRouter::is_action_supported(History::NIC_DETACH_ACTION))
{
att.resp_msg = "Action is not supported for virtual router VMs";
failure_response(Request::ACTION, att);

View File

@ -268,6 +268,7 @@ tabs:
actions:
Image.refresh: true
Image.create_dialog: true
Image.export_dialog: true
Image.rename: true
Image.chown: true
Image.chgrp: true
@ -588,8 +589,8 @@ tabs:
User.quotas_dialog: false
marketplaces-tab:
panel_tabs:
#marketplaces_info_tab: true
#marketplaces_apps_tab: true
marketplace_info_tab: true
marketplace_apps_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
@ -611,8 +612,8 @@ tabs:
MarketPlace.delete: true
marketplaceapps-tab:
panel_tabs:
#marketplaces_info_tab: true
#marketplaces_apps_tab: true
marketplaceapp_info_tab: true
marketplaceapp_templates_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
@ -629,8 +630,11 @@ tabs:
actions:
MarketPlaceApp.refresh: true
MarketPlaceApp.create_dialog: true
MarketPlaceApp.export_dialog: true
MarketPlaceApp.rename: true
MarketPlaceApp.chown: true
MarketPlaceApp.chgrp: true
MarketPlaceApp.chmod: true
MarketPlaceApp.enable: true
MarketPlaceApp.disable: true
MarketPlaceApp.delete: true

View File

@ -268,6 +268,7 @@ tabs:
actions:
Image.refresh: true
Image.create_dialog: true
Image.export_dialog: true
Image.rename: true
Image.chown: false
Image.chgrp: false
@ -583,8 +584,8 @@ tabs:
User.quotas_dialog: false
marketplaces-tab:
panel_tabs:
#marketplaces_info_tab: true
#marketplaces_apps_tab: true
marketplace_info_tab: true
marketplaces_app_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
@ -606,8 +607,8 @@ tabs:
MarketPlace.delete: true
marketplaceapps-tab:
panel_tabs:
#marketplaces_info_tab: true
#marketplaces_apps_tab: true
marketplaceapp_info_tab: true
marketplaceapp_templates_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
@ -623,9 +624,12 @@ tabs:
#- 11 # Labels
actions:
MarketPlaceApp.refresh: true
#MarketPlaceApp.create_dialog: true
MarketPlaceApp.create_dialog: true
MarketPlaceApp.export_dialog: true
MarketPlaceApp.rename: true
MarketPlaceApp.chown: true
MarketPlaceApp.chgrp: true
MarketPlaceApp.chmod: true
MarketPlaceApp.enable: true
MarketPlaceApp.disable: true
MarketPlaceApp.delete: true

View File

@ -37,7 +37,7 @@ module OpenNebulaJSON
template = template_to_str(mp_hash)
end
self.allocate(template)
self.allocate(template, mp_id.to_i)
end
def perform_action(template_json)
@ -48,6 +48,7 @@ module OpenNebulaJSON
rc = case action_hash['perform']
when "update" then self.update(action_hash['params'])
when "export" then self.export(action_hash['params'])
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'])
@ -61,7 +62,17 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
super(params['template_raw'])
if !params['append'].nil?
super(params['template_raw'], params['append'])
else
super(params['template_raw'])
end
end
def export(params=Hash.new)
dsid = params['dsid'] ? params['dsid'].to_i : params['dsid']
name = params['name']
super({:dsid => dsid, :name => name})
end
def chown(params=Hash.new)

View File

@ -32,5 +32,5 @@ module OpenNebulaJSON
class VdcPoolJSON < OpenNebula::VdcPool; include JSONUtils; end
class VirtualRouterPoolJSON < OpenNebula::VirtualRouterPool; include JSONUtils; end
class MarketPlacePoolJSON < OpenNebula::MarketPlacePool; include JSONUtils; end
class MarketpPlaceAppPoolJSON < OpenNebula::MarketPlaceAppPool; include JSONUtils; end
class MarketPlaceAppPoolJSON < OpenNebula::MarketPlaceAppPool; include JSONUtils; end
end

View File

@ -112,7 +112,7 @@ require.config({
'spice-filexfer': '../bower_components/spice-html5/filexfer',
/* vis.js */
'vis': '../bower_components/vis/dist/vis'
'vis': '../bower_components/vis/dist/vis.min'
},
shim: {
/* Tabs */

View File

@ -97,6 +97,10 @@ define(function(require) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "rename", action_obj);
},
"export" : function(params) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "export", action_obj);
},
"enable": function(params) {
OpenNebulaAction.simple_action(params, RESOURCE, "enable");
},

View File

@ -24,8 +24,11 @@ define(function(require) {
var RESOURCE = "Image";
var XML_ROOT = "IMAGE";
var TAB_ID = require('./tabId');
var MARKETPLACEAPPS_TAB_ID = require('tabs/marketplaceapps-tab/tabId');
var CREATE_DIALOG_ID = require('./form-panels/create/formPanelId');
var CLONE_DIALOG_ID = require('./dialogs/clone/dialogId');
var CREATE_APP_DIALOG_ID = require('tabs/marketplaceapps-tab/form-panels/create/formPanelId');
var _commonActions = new CommonActions(OpenNebulaResource, RESOURCE, TAB_ID, XML_ROOT);
@ -50,6 +53,23 @@ define(function(require) {
"Image.snapshot_flatten": _commonActions.singleAction("snapshot_flatten"),
"Image.snapshot_revert": _commonActions.singleAction("snapshot_revert"),
"Image.snapshot_delete": _commonActions.singleAction("snapshot_delete"),
"Image.export_dialog" : {
type: "custom",
call: function() {
Sunstone.showTab(MARKETPLACEAPPS_TAB_ID);
Sunstone.showFormPanel(MARKETPLACEAPPS_TAB_ID, CREATE_APP_DIALOG_ID, "export",
function(formPanelInstance, context) {
var selectedNodes = Sunstone.getDataTable(TAB_ID).elements();
if (selectedNodes.length !== 1) {
Notifier.notifyMessage('Please select one (and just one) Image to export.');
return false;
}
var resourceId = '' + selectedNodes[0];
formPanelInstance.setImageId(resourceId);
});
}
},
"Image.clone_dialog" : {
type: "custom",

View File

@ -27,6 +27,10 @@ define(function(require) {
type: "create_dialog",
layout: "create"
},
"Image.export_dialog" : {
type: "action",
text: '<i class="fa fa-share-alt"/>'
},
"Image.chown" : {
type: "confirm_with_select",
text: Locale.tr("Change owner"),

View File

@ -27,7 +27,8 @@ define(function(require) {
];
var _panels = [
//require('./marketplaceapps-tab/panels/info')
require('./marketplaceapps-tab/panels/info'),
require('./marketplaceapps-tab/panels/templates')
];
var _panelsHooks = [
@ -35,7 +36,8 @@ define(function(require) {
];
var _formPanels = [
//require('./datastores-tab/form-panels/create')
require('./marketplaceapps-tab/form-panels/create'),
require('./marketplaceapps-tab/form-panels/export')
];
var Tab = {
@ -44,7 +46,7 @@ define(function(require) {
listHeader: '<i class="fa fa-fw fa-shopping-cart"></i>&emsp;'+Locale.tr("Apps"),
infoHeader: '<i class="fa fa-fw fa-shopping-cart"></i>&emsp;'+Locale.tr("App"),
subheader: '<span/> <small></small>&emsp;',
resource: 'MarketPlace',
resource: 'MarketPlaceApp',
buttons: Buttons,
actions: Actions,
dataTable: new Table(DATATABLE_ID, {actions: true, info: true, oneSelection: true}),

View File

@ -24,13 +24,38 @@ define(function(require) {
var RESOURCE = "MarketPlaceApp";
var XML_ROOT = "MARKETPLACEAPP";
var TAB_ID = require('./tabId');
//var CREATE_DIALOG_ID = require('./form-panels/create/formPanelId');
var CREATE_DIALOG_ID = require('./form-panels/create/formPanelId');
var EXPORT_DIALOG_ID = require('./form-panels/export/formPanelId');
var _commonActions = new CommonActions(OpenNebulaResource, RESOURCE, TAB_ID, XML_ROOT);
var _actions = {
//"MarketPlaceApp.create" : _commonActions.create(CREATE_DIALOG_ID),
//"MarketPlaceApp.create_dialog" : _commonActions.showCreate(CREATE_DIALOG_ID),
"MarketPlaceApp.create" : _commonActions.create(CREATE_DIALOG_ID),
"MarketPlaceApp.create_dialog" : _commonActions.showCreate(CREATE_DIALOG_ID),
"MarketPlaceApp.export_dialog" : {
type: "custom",
call: function() {
Sunstone.showFormPanel(TAB_ID, EXPORT_DIALOG_ID, "export");
}
},
"MarketPlaceApp.export" : {
type: "multiple",
call: OpenNebulaResource.export,
callback: function(req) {
Sunstone.hideFormPanel(TAB_ID);
OpenNebulaAction.clear_cache("IMAGE");
OpenNebulaAction.clear_cache("VMTEMPLATE");
},
elements: function() {
return Sunstone.getDataTable(TAB_ID).elements();
},
error: function(request, response){
// without tab id param to work for both templates and vms tab
Sunstone.hideFormPanelLoading();
Notifier.onError(request, response);
},
notify: true
},
"MarketPlaceApp.list" : _commonActions.list(),
"MarketPlaceApp.show" : _commonActions.show(),
"MarketPlaceApp.refresh" : _commonActions.refresh(),
@ -38,9 +63,11 @@ define(function(require) {
"MarketPlaceApp.chown": _commonActions.multipleAction('chown'),
"MarketPlaceApp.chgrp": _commonActions.multipleAction('chgrp'),
"MarketPlaceApp.chmod": _commonActions.singleAction('chmod'),
"MarketPlaceApp.enable": _commonActions.multipleAction('enable'),
"MarketPlaceApp.disable": _commonActions.multipleAction('disable'),
//"MarketPlaceApp.update" : _commonActions.updateTemplate(),
//"MarketPlaceApp.update_template" : _commonActions.updateTemplate(),
//"MarketPlaceApp.append_template" : _commonActions.appendTemplate(),
"MarketPlaceApp.update_template" : _commonActions.updateTemplate(),
"MarketPlaceApp.append_template" : _commonActions.appendTemplate(),
"MarketPlaceApp.rename": _commonActions.singleAction('rename')
}

View File

@ -23,10 +23,14 @@ define(function(require) {
layout: "refresh",
alwaysActive: true
},
//"MarketPlaceApp.create_dialog" : {
// type: "create_dialog",
// layout: "create"
//},
"MarketPlaceApp.create_dialog" : {
type: "create_dialog",
layout: "create"
},
"MarketPlaceApp.export_dialog" : {
type: "action",
text: '<i class="fa fa-download"/>'
},
"MarketPlaceApp.chown" : {
type: "confirm_with_select",
text: Locale.tr("Change owner"),
@ -41,6 +45,16 @@ define(function(require) {
layout: "user_select",
tip: Locale.tr("Select the new group") + ":"
},
"MarketPlaceApp.enable" : {
type: "action",
layout: "more_select",
text: Locale.tr("Enable")
},
"MarketPlaceApp.disable" : {
type: "action",
layout: "more_select",
text: Locale.tr("Disable")
},
"MarketPlaceApp.delete" : {
type: "confirm",
text: Locale.tr("Delete"),

View File

@ -129,7 +129,7 @@ define(function(require) {
OpenNebulaMarketPlaceApp.stateStr(element.STATE),
OpenNebulaMarketPlaceApp.typeStr(element.TYPE),
Humanize.prettyTime(element.REGTIME),
OpenNebulaMarketPlace.getName(element.MARKETPLACE_ID),
element.MARKETPLACE,
(LabelsUtils.labelsStr(element[TEMPLATE_ATTR])||'')
];
}

View File

@ -24,8 +24,10 @@ define(function(require) {
var Locale = require('utils/locale');
var Notifier = require('utils/notifier');
var Tips = require('utils/tips');
var ResourceSelect = require('utils/resource-select');
var ImagesTable = require('tabs/images-tab/datatable');
var MarketPlacesTable = require('tabs/marketplaces-tab/datatable');
var Config = require('sunstone-config');
var WizardFields = require('utils/wizard-fields');
/*
TEMPLATES
@ -50,12 +52,29 @@ define(function(require) {
this.tabId = TAB_ID;
this.actions = {
'create': {
'title': Locale.tr("Create MarketPlace"),
'title': Locale.tr("Create MarketPlace App"),
'buttonText': Locale.tr("Create"),
'resetButton': true
},
'export': {
'title': Locale.tr("Create MarketPlace App from Image"),
'buttonText': Locale.tr("Create"),
'resetButton': true
}
};
this.imagesTable = new ImagesTable(
FORM_PANEL_ID + 'imagesTable',
{'select': true});
this.marketPlacesTable = new MarketPlacesTable(
FORM_PANEL_ID + 'marketPlacesTable',
{'select': true});
this.marketPlacesTableAdvanced = new MarketPlacesTable(
FORM_PANEL_ID + 'marketPlacesTableAdvanced',
{'select': true});
BaseFormPanel.call(this);
}
@ -66,6 +85,7 @@ define(function(require) {
FormPanel.prototype.htmlAdvanced = _htmlAdvanced;
FormPanel.prototype.submitWizard = _submitWizard;
FormPanel.prototype.submitAdvanced = _submitAdvanced;
FormPanel.prototype.setImageId = _setImageId;
FormPanel.prototype.onShow = _onShow;
FormPanel.prototype.setup = _setup;
@ -78,245 +98,87 @@ define(function(require) {
function _htmlWizard() {
return TemplateWizardHTML({
'formPanelId': this.formPanelId,
'imagesTableHTML': this.imagesTable.dataTableHTML,
'marketPlacesTableHTML': this.marketPlacesTable.dataTableHTML
});
}
function _htmlAdvanced() {
return TemplateAdvancedHTML({formPanelId: this.formPanelId});
return TemplateAdvancedHTML({
'formPanelId': this.formPanelId,
'marketPlacesTableAdvancedHTML': this.marketPlacesTableAdvanced.dataTableHTML
});
}
function _onShow(dialog) {
$("#name", dialog).focus();
function _onShow(context) {
this.imagesTable.resetResourceTableSelect();
this.marketPlacesTable.resetResourceTableSelect();
this.marketPlacesTableAdvanced.resetResourceTableSelect();
// var cluster_id = $("div#cluster_id .resource_list_select", dialog).val();
// if (!cluster_id) cluster_id = "-1";
//
// var cluster_id_raw = $("div#datastore_cluster_raw .resource_list_select", dialog).val();
// if (!cluster_id_raw) cluster_id_raw = "-1";
//
// ResourceSelect.insert({
// context: $('#cluster_id', dialog),
// resourceName: 'Cluster',
// initValue: cluster_id,
// includeDefaultCluster: true
// });
//
// ResourceSelect.insert({
// context: $('#datastore_cluster_raw', dialog),
// resourceName: 'Cluster',
// initValue: cluster_id_raw,
// includeDefaultCluster: true
// });
$("#NAME", context).focus();
return false;
}
// Set up the create datastore dialog
function _setup(dialog) {
Tips.setup(dialog);
function _setImageId(imageId) {
var selectedResources = {
ids : imageId
}
this.imagesTable.selectResourceTableSelect(selectedResources);
}
// Show custom driver input only when custom is selected in selects
// $('input[name="ds_tab_custom_ds_mad"],' +
// 'input[name="ds_tab_custom_tm_mad"]', dialog).parent().hide();
//
// $('select#ds_mad', dialog).change(function() {
// if ($(this).val() == "custom") {
// $('input[name="ds_tab_custom_ds_mad"]', dialog).parent().show();
// } else {
// _setRequiredFields(dialog, $(this).val());
// $('input[name="ds_tab_custom_ds_mad"]', dialog).parent().hide();
// }
// });
//
// $('select#tm_mad', dialog).change(function() {
// if ($(this).val() == "custom")
// $('input[name="ds_tab_custom_tm_mad"]', dialog).parent().show();
// else
// $('input[name="ds_tab_custom_tm_mad"]', dialog).parent().hide();
// });
//
// $('#presets', dialog).change(function() {
// _hideAll(dialog);
// var choice_str = $(this).val();
//
// switch (choice_str)
// {
// case 'fs':
// _selectFilesystem(dialog);
// break;
// case 'vmware_vmfs':
// _selectVmwareVmfs(dialog);
// break;
// case 'block_lvm':
// _selectBlockLvm(dialog);
// break;
// case 'fs_lvm':
// _selectFsLvm(dialog);
// break;
// case 'ceph':
// _selectCeph(dialog);
// break;
// case 'gluster':
// _selectGluster(dialog);
// break;
// case 'dev':
// _selectDevices(dialog);
// break;
// case 'iscsi':
// _selectISCSI(dialog);
// break;
// case 'custom':
// _selectCustom(dialog);
// break;
// }
// });
//
// $('#presets', dialog).change();
//
// // Hide disk_type
// $('select#disk_type', dialog).parent().hide();
//
// _hideAll(dialog);
// _selectFilesystem(dialog);
// Set up the create datastore context
function _setup(context) {
Tips.setup(context);
this.imagesTable.initialize();
this.marketPlacesTable.initialize();
this.marketPlacesTableAdvanced.initialize();
this.imagesTable.idInput().
attr('required', '').
attr('wizard_field', 'ORIGIN_ID');
this.marketPlacesTable.idInput().attr('required', '');
this.marketPlacesTableAdvanced.idInput().attr('required', '');
}
function _submitWizard(dialog) {
// var name = $('#name', dialog).val();
// var cluster_id = $(".resource_list_select", $('#cluster_id', dialog)).val();
// var ds_type = $('input[name=ds_type]:checked', dialog).val();
// var ds_mad = $('#ds_mad', dialog).val();
// ds_mad = ds_mad == "custom" ? $('input[name="ds_tab_custom_ds_mad"]', dialog).val() : ds_mad;
// var tm_mad = $('#tm_mad', dialog).val();
// tm_mad = tm_mad == "custom" ? $('input[name="ds_tab_custom_tm_mad"]', dialog).val() : tm_mad;
// var type = $('#disk_type', dialog).val();
//
// var safe_dirs = $('#safe_dirs', dialog).val();
// var base_path = $('#base_path', dialog).val();
// var restricted_dirs = $('#restricted_dirs', dialog).val();
// var limit_transfer_bw = $('#limit_transfer_bw', dialog).val();
// var datastore_capacity_check = $('#datastore_capacity_check', dialog).is(':checked');
// var no_decompress = $('#no_decompress', dialog).is(':checked');
//
// var bridge_list = $('#bridge_list', dialog).val();
// var ds_tmp_dir = $('#ds_tmp_dir', dialog).val();
// var vg_name = $('#vg_name', dialog).val();
// var limit_mb = $('#limit_mb', dialog).val();
// var gluster_host = $('#gluster_host', dialog).val();
// var gluster_volume = $('#gluster_volume', dialog).val();
// var pool_name = $('#pool_name', dialog).val();
// var ceph_host = $('#ceph_host', dialog).val();
// var ceph_secret = $('#ceph_secret', dialog).val();
// var ceph_user = $('#ceph_user', dialog).val();
// var rbd_format = $('#rbd_format', dialog).val();
// var staging_dir = $('#staging_dir', dialog).val();
// var ceph_conf = $('#ceph_conf', dialog).val();
// var iscsi_host = $('#iscsi_host', dialog).val();
// var iscsi_user = $('#iscsi_user', dialog).val();
// var iscsi_usage = $('#iscsi_usage', dialog).val();
//
// var ds_obj = {
// "datastore" : {
// "name" : name,
// "tm_mad" : tm_mad,
// "disk_type" : type,
// "type" : ds_type
// },
// "cluster_id" : cluster_id
// };
//
// // If we are adding a system datastore then
// // we do not use ds_mad
// if (ds_type != "SYSTEM_DS")
// ds_obj.datastore.ds_mad = ds_mad;
//
// if (base_path)
// ds_obj.datastore.base_path = base_path;
//
// if (safe_dirs)
// ds_obj.datastore.safe_dirs = safe_dirs;
//
// if (restricted_dirs)
// ds_obj.datastore.restricted_dirs = restricted_dirs;
//
// if (limit_transfer_bw)
// ds_obj.datastore.limit_transfer_bw = limit_transfer_bw;
//
// if (no_decompress)
// ds_obj.datastore.no_decompress = "YES";
//
// if (datastore_capacity_check)
// ds_obj.datastore.datastore_capacity_check = "YES";
//
// if (bridge_list)
// ds_obj.datastore.bridge_list = bridge_list;
//
// if (ds_tmp_dir)
// ds_obj.datastore.ds_tmp_dir = ds_tmp_dir;
//
// if (vg_name)
// ds_obj.datastore.vg_name = vg_name;
//
// if (limit_mb)
// ds_obj.datastore.limit_mb = limit_mb;
//
// if (gluster_host)
// ds_obj.datastore.gluster_host = gluster_host;
//
// if (gluster_volume)
// ds_obj.datastore.gluster_volume = gluster_volume;
//
// if (pool_name)
// ds_obj.datastore.pool_name = pool_name;
//
// if (ceph_host)
// ds_obj.datastore.ceph_host = ceph_host;
//
// if (ceph_secret)
// ds_obj.datastore.ceph_secret = ceph_secret;
//
// if (ceph_user)
// ds_obj.datastore.ceph_user = ceph_user;
//
// if (rbd_format)
// ds_obj.datastore.rbd_format = rbd_format;
//
// if (staging_dir)
// ds_obj.datastore.staging_dir = staging_dir;
//
// if (ceph_conf)
// ds_obj.datastore.ceph_conf = ceph_conf;
//
// if (iscsi_host)
// ds_obj.datastore.iscsi_host = iscsi_host;
//
// if (iscsi_user)
// ds_obj.datastore.iscsi_user = iscsi_user;
//
// if (iscsi_usage)
// ds_obj.datastore.iscsi_usage = iscsi_usage;
function _submitWizard(context) {
var marketPlaceJSON = {};
$.extend(marketPlaceJSON, WizardFields.retrieve(context));
// Sunstone.runAction("Datastore.create", ds_obj);
var vmTemplate = $('#VMTEMPLATE', context).val();
if (vmTemplate) {
marketPlaceJSON['VMTEMPLATE64'] = btoa(vmTemplate);
}
var appTemplate = $('#APPTEMPLATE', context).val();
if (appTemplate) {
marketPlaceJSON['APPTEMPLATE64'] = btoa(appTemplate);
}
var marketPlaceAppObj = {
"marketplaceapp" : marketPlaceJSON,
"mp_id" : this.marketPlacesTable.idInput().val()
};
Sunstone.runAction("MarketPlaceApp.create", marketPlaceAppObj);
return false;
}
function _submitAdvanced(dialog) {
// var template = $('#template', dialog).val();
// var cluster_id = $(".resource_list_select", $('#datastore_cluster_raw', dialog)).val();
//
// if (!cluster_id) {
// Notifier.notifyError(Locale.tr("Please select a cluster for this datastore"));
// return false;
// }
//
// var ds_obj = {
// "datastore" : {
// "datastore_raw" : template
// },
// "cluster_id" : cluster_id
// };
//
// Sunstone.runAction("Datastore.create", ds_obj);
function _submitAdvanced(context) {
var template = $('#template', context).val();
var marketPlaceAppObj = {
"marketplaceapp" : {
"marketplaceapp_raw" : template
},
"mp_id" : this.marketPlacesTableAdvanced.idInput().val()
};
Sunstone.runAction("MarketPlaceApp.create", marketPlaceAppObj);
return false;
}
});

View File

@ -15,6 +15,10 @@
{{! -------------------------------------------------------------------------- }}
<form data-abide="ajax" id="{{formPanelId}}Advanced" class="custom creation">
<fieldset>
<legend>{{tr "Select the Marketplace where the App will be created"}}</legend>
{{{marketPlacesTableAdvancedHTML}}}
</fieldset>
<div class="row">
<div class="large-12 columns">
<p>{{tr "Write the MarketPlace Appliance template here"}}</p>

View File

@ -0,0 +1,84 @@
{{! -------------------------------------------------------------------------- }}
{{! 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. }}
{{! -------------------------------------------------------------------------- }}
<form data-abide="ajax" id="{{formPanelId}}Wizard" class="custom creation">
<div class="row">
<div class="medium-6 columns">
<label for="NAME">
{{tr "Name"}}:
<span class="tip">
{{tr "Name that the Marketplace App will get for description purposes."}}
</span>
</label>
<input id="NAME" type="text" wizard_field="NAME" required/>
</div>
<div class="medium-3 columns hidden">
<label for="TYPE">{{tr "Type"}}</label>
<select id="TYPE" wizard_field="TYPE" required>
<option value="image">{{tr "Image"}}</option>
</select>
</div>
</div>
<div class="row">
<div class="medium-6 columns">
<label for="DESCRIPTION">
{{tr "Description"}}
<span class="tip">
{{tr "Human readable description of the MarketPlace App for other users."}}
</span>
</label>
<textarea id="DESCRIPTION" wizard_field="DESCRIPTION" rows="1"></textarea>
</div>
<div class="medium-3 columns">
<label for="VERSION">
{{tr "Version"}}:
<span class="tip">
{{tr "Version of the App"}}
</span>
</label>
<input id="VERSION" type="text" wizard_field="VERSION"/>
</div>
<div class="medium-3 columns">
</div>
</div>
<fieldset>
<legend>{{tr "Select the Image to be exported"}}</legend>
{{{imagesTableHTML}}}
</fieldset>
<fieldset>
<legend>{{tr "Select the Marketplace where the App will be created"}}</legend>
{{{marketPlacesTableHTML}}}
</fieldset>
<div class="row">
<div class="medium-6 columns">
<label for="VMTEMPLATE">
{{tr "VM Template"}}
<span class="tip">
{{tr "VM Template"}}
</span>
</label>
<textarea id="VMTEMPLATE" rows="2"></textarea>
</div>
<div class="medium-6 columns">
<label for="APPTEMPLATE">
{{tr "App Template"}}
<span class="tip">
{{tr "App Template"}}
</span>
</label>
<textarea id="APPTEMPLATE" rows="2"></textarea>
</div>
</div>
</form>

View File

@ -0,0 +1,119 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
define(function(require) {
/*
DEPENDENCIES
*/
var BaseFormPanel = require('utils/form-panels/form-panel');
var Sunstone = require('sunstone');
var Locale = require('utils/locale');
var Notifier = require('utils/notifier');
var Tips = require('utils/tips');
var DataStoresTable = require('tabs/datastores-tab/datatable');
var DataStore = require('opennebula/datastore');
var Config = require('sunstone-config');
var WizardFields = require('utils/wizard-fields');
/*
TEMPLATES
*/
var TemplateWizardHTML = require('hbs!./export/wizard');
/*
CONSTANTS
*/
var FORM_PANEL_ID = require('./export/formPanelId');
var TAB_ID = require('../tabId');
/*
CONSTRUCTOR
*/
function FormPanel() {
this.formPanelId = FORM_PANEL_ID;
this.tabId = TAB_ID;
this.actions = {
'export': {
'title': Locale.tr("Export App To OpenNebula"),
'buttonText': Locale.tr("Export"),
'resetButton': true
}
};
this.datastoresTable = new DataStoresTable(
FORM_PANEL_ID + 'datastoresTable', {
'select': true,
'selectOptions': {
'filter_fn': function(ds) { return ds.TYPE == DataStore.TYPES.IMAGE_DS; } // Show system DS only
}
});
BaseFormPanel.call(this);
}
FormPanel.FORM_PANEL_ID = FORM_PANEL_ID;
FormPanel.prototype = Object.create(BaseFormPanel.prototype);
FormPanel.prototype.constructor = FormPanel;
FormPanel.prototype.htmlWizard = _htmlWizard;
FormPanel.prototype.submitWizard = _submitWizard;
FormPanel.prototype.onShow = _onShow;
FormPanel.prototype.setup = _setup;
return FormPanel;
/*
FUNCTION DEFINITIONS
*/
function _htmlWizard() {
return TemplateWizardHTML({
'formPanelId': this.formPanelId,
'datastoresTableHTML': this.datastoresTable.dataTableHTML
});
}
function _onShow(context) {
this.datastoresTable.resetResourceTableSelect();
$("#NAME", context).focus();
return false;
}
// Set up the create datastore context
function _setup(context) {
Tips.setup(context);
this.datastoresTable.initialize();
this.datastoresTable.idInput().attr('required', '');
}
function _submitWizard(context) {
var marketPlaceAppObj = {
"name" : $("#NAME", context).val(),
"dsid" : this.datastoresTable.idInput().val()
};
Sunstone.runAction("MarketPlaceApp.export", Sunstone.getDataTable(TAB_ID).elements(), marketPlaceAppObj);
return false;
}
});

View File

@ -0,0 +1,19 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
define(function(require){
return 'exportMarketPlaceAppForm';
})

View File

@ -0,0 +1,32 @@
{{! -------------------------------------------------------------------------- }}
{{! 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. }}
{{! -------------------------------------------------------------------------- }}
<form data-abide="ajax" id="{{formPanelId}}Wizard" class="custom creation">
<div class="row">
<div class="medium-6 columns">
<label for="NAME">
{{tr "Name"}}:
<span class="tip">
{{tr "Name that the resource will get for description purposes."}}
</span>
</label>
<input id="NAME" type="text" wizard_field="NAME"/>
</div>
</div>
<fieldset>
<legend>{{tr "Select the Datastore to store the resource"}}</legend>
{{{datastoresTableHTML}}}
</fieldset>
</form>

View 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. */
/* -------------------------------------------------------------------------- */
define(function(require) {
/*
DEPENDENCIES
*/
var Locale = require('utils/locale');
var Humanize = require('utils/humanize');
var RenameTr = require('utils/panel/rename-tr');
var TemplateTable = require('utils/panel/template-table');
var PermissionsTable = require('utils/panel/permissions-table');
var OpenNebulaMarketPlaceApp = require('opennebula/marketplaceapp');
var Sunstone = require('sunstone');
/*
TEMPLATES
*/
var TemplateInfo = require('hbs!./info/html');
/*
CONSTANTS
*/
var TAB_ID = require('../tabId');
var PANEL_ID = require('./info/panelId');
var RESOURCE = "MarketPlaceApp"
var XML_ROOT = "MARKETPLACEAPP"
/*
CONSTRUCTOR
*/
function Panel(info) {
this.title = Locale.tr("Info");
this.icon = "fa-info-circle";
this.element = info[XML_ROOT];
return this;
};
Panel.PANEL_ID = PANEL_ID;
Panel.prototype.html = _html;
Panel.prototype.setup = _setup;
return Panel;
/*
FUNCTION DEFINITIONS
*/
function _html() {
var strippedTemplate = $.extend({}, this.element.TEMPLATE);
delete strippedTemplate["VMTEMPLATE64"];
delete strippedTemplate["APPTEMPLATE64"];
var templateTableHTML = TemplateTable.html(
strippedTemplate, RESOURCE,
Locale.tr("Attributes"));
var renameTrHTML = RenameTr.html(TAB_ID, RESOURCE, this.element.NAME);
var permissionsTableHTML = PermissionsTable.html(TAB_ID, RESOURCE, this.element);
var prettyRegTime = Humanize.prettyTime(this.element.REGTIME);
var stateStr = OpenNebulaMarketPlaceApp.stateStr(this.element.STATE);
var typeStr = OpenNebulaMarketPlaceApp.typeStr(this.element.TYPE);
var sizeStr = Humanize.sizeFromMB(this.element.SIZE);
return TemplateInfo({
'element': this.element,
'renameTrHTML': renameTrHTML,
'templateTableHTML': templateTableHTML,
'permissionsTableHTML': permissionsTableHTML,
'prettyRegTime': prettyRegTime,
'stateStr': stateStr,
'typeStr': typeStr,
'sizeStr': sizeStr
});
}
function _setup(context) {
var strippedTemplate = $.extend({}, this.element.TEMPLATE);
delete strippedTemplate["VMTEMPLATE64"];
delete strippedTemplate["APPTEMPLATE64"];
var hiddenValues = {};
if (this.element.TEMPLATE.VMTEMPLATE64 !== undefined) {
hiddenValues.VMTEMPLATE64 = this.element.TEMPLATE.VMTEMPLATE64;
}
if (this.element.TEMPLATE.APPTEMPLATE64 !== undefined) {
hiddenValues.APPTEMPLATE64 = this.element.TEMPLATE.APPTEMPLATE64;
}
TemplateTable.setup(strippedTemplate, RESOURCE, this.element.ID, context, hiddenValues);
RenameTr.setup(TAB_ID, RESOURCE, this.element.ID, context);
PermissionsTable.setup(TAB_ID, RESOURCE, this.element, context);
return false;
}
});

View 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. }}
{{! -------------------------------------------------------------------------- }}
<div class="row">
<div class="large-6 columns">
<table class="dataTable">
<thead>
<tr>
<th colspan="3">{{tr "Information"}}</th>
</tr>
</thead>
<tbody>
<tr>
<td class="key_td">{{tr "ID"}}</td>
<td class="value_td" colspan="2">{{element.ID}}</td>
</tr>
{{{renameTrHTML}}}
<tr>
<td class="key_td">{{tr "MarketPlace"}}</td>
<td class="value_td">{{element.MARKETPLACE}}</td>
<td></td>
</tr>
<tr>
<td class="key_td">{{tr "Register time"}}</td>
<td class="value_td">{{prettyRegTime}}</td>
<td></td>
</tr>
<tr>
<td class="key_td">{{tr "Type"}}</td>
<td class="value_td">{{typeStr}}</td>
<td></td>
</tr>
<tr>
<td class="key_td">{{tr "Size"}}</td>
<td class="value_td" colspan="2">{{sizeStr}}</td>
</tr>
<tr>
<td class="key_td">{{tr "State"}}</td>
<td class="value_td">{{stateStr}}</td>
<td></td>
</tr>
<tr>
<td class="key_td">{{tr "Format"}}</td>
<td class="value_td">{{element.FORMAT}}</td>
<td></td>
</tr>
<tr>
<td class="key_td">{{tr "Version"}}</td>
<td class="value_td">{{element.VERSION}}</td>
<td></td>
</tr>
</tbody>
</table>
</div>
<div class="large-6 columns">
{{{permissionsTableHTML}}}
</div>
</div>
<div class="row">
<div class="large-9 columns">
{{{templateTableHTML}}}
</div>
</div>

View File

@ -0,0 +1,19 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
define(function(require){
return 'marketplaceapp_info_tab';
});

View File

@ -0,0 +1,121 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
define(function(require) {
/*
DEPENDENCIES
*/
var Locale = require('utils/locale');
var Humanize = require('utils/humanize');
var RenameTr = require('utils/panel/rename-tr');
var TemplateTable = require('utils/panel/template-table');
var PermissionsTable = require('utils/panel/permissions-table');
var OpenNebulaMarketPlaceApp = require('opennebula/marketplaceapp');
var Sunstone = require('sunstone');
/*
TEMPLATES
*/
var TemplateInfo = require('hbs!./templates/html');
/*
CONSTANTS
*/
var TAB_ID = require('../tabId');
var PANEL_ID = require('./templates/panelId');
var RESOURCE = "MarketPlaceApp"
var XML_ROOT = "MARKETPLACEAPP"
/*
CONSTRUCTOR
*/
function Panel(info) {
this.title = Locale.tr("Templates");
this.icon = "fa-file-o";
this.element = info[XML_ROOT];
return this;
};
Panel.PANEL_ID = PANEL_ID;
Panel.prototype.html = _html;
Panel.prototype.setup = _setup;
return Panel;
/*
FUNCTION DEFINITIONS
*/
function _html() {
var vmTemplate = atob(this.element.TEMPLATE.VMTEMPLATE64 || '');
var appTemplate = atob(this.element.TEMPLATE.APPTEMPLATE64 || '');
return TemplateInfo({
'element': this.element,
'vmTemplate': vmTemplate,
'appTemplate': appTemplate
});
}
function _setup(context) {
var that = this;
context.off("click", ".vmTemplate_edit");
context.on("click", ".vmTemplate_edit", function() {
$("#vmTemplate_text", context).hide();
$("#vmTemplate_textarea", context).show().focus();
});
context.off("change", "#vmTemplate_textarea");
context.on("change", "#vmTemplate_textarea", function() {
var templateStr = 'VMTEMPLATE64 = "' + btoa($(this).val()) + '"';
Sunstone.runAction("MarketPlaceApp.append_template", that.element.ID, templateStr);
});
context.off("focusout", "#vmTemplate_textarea");
context.on("focusout", "#vmTemplate_textarea", function() {
$("#vmTemplate_text", context).show();
$("#vmTemplate_textarea", context).hide();
});
context.off("click", ".appTemplate_edit");
context.on("click", ".appTemplate_edit", function() {
$("#appTemplate_text", context).hide();
$("#appTemplate_textarea", context).show().focus();
});
context.off("change", "#appTemplate_textarea");
context.on("change", "#appTemplate_textarea", function() {
var templateStr = 'APPTEMPLATE64 = "' + btoa($(this).val()) + '"';
Sunstone.runAction("MarketPlaceApp.append_template", that.element.ID, templateStr);
});
context.off("focusout", "#appTemplate_textarea");
context.on("focusout", "#appTemplate_textarea", function() {
$("#appTemplate_text", context).show();
$("#appTemplate_textarea", context).hide();
});
return false;
}
});

View File

@ -0,0 +1,62 @@
{{! -------------------------------------------------------------------------- }}
{{! 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. }}
{{! -------------------------------------------------------------------------- }}
<div class="row">
<div class="large-6 columns">
<table class="dataTable" cellpadding="0" cellspacing="0" border="0">
<thead>
<tr>
<th>{{tr "App Template"}}</th>
<th>
<a class="appTemplate_edit right" href="#"><i class="fa fa-pencil-square-o"></i></a>
</th>
</tr>
</thead>
</table>
<textarea rows="6" type="text" id="appTemplate_textarea" class="hidden">{{appTemplate}}</textarea>
{{#if appTemplate}}
<pre id="appTemplate_text" class="info_text">
{{~htmlDecode appTemplate~}}
</pre>
{{else}}
<p id="appTemplate_text" class="info_text">
{{~tr "You can provide a template for the resource that will be created in OpenNebula"~}}
</p>
{{/if}}
</div>
<div class="large-6 columns">
<table class="dataTable" cellpadding="0" cellspacing="0" border="0">
<thead>
<tr>
<th>{{tr "VM Template"}}</th>
<th>
<a class="vmTemplate_edit right" href="#"><i class="fa fa-pencil-square-o"></i></a>
</th>
</tr>
</thead>
</table>
<textarea rows="6" type="text" id="vmTemplate_textarea" class="hidden">{{vmTemplate}}</textarea>
{{#if vmTemplate}}
<pre id="vmTemplate_text" class="info_text">
{{~htmlDecode vmTemplate~}}
</pre>
{{else}}
<p id="vmTemplate_text" class="info_text">
{{~tr "You can provide a VM template associated to the resource that will be created in OpenNebula"~}}
</p>
{{/if}}
</div>
</div>

View File

@ -0,0 +1,19 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
define(function(require){
return 'marketplaceapp_templates_tab';
});

View File

@ -27,7 +27,8 @@ define(function(require) {
];
var _panels = [
//require('./marketplaces-tab/panels/info')
require('./marketplaces-tab/panels/info'),
require('./marketplaces-tab/panels/apps')
];
var _panelsHooks = [

View File

@ -22,9 +22,7 @@ define(function(require) {
var BaseFormPanel = require('utils/form-panels/form-panel');
var Sunstone = require('sunstone');
var Locale = require('utils/locale');
var Notifier = require('utils/notifier');
var Tips = require('utils/tips');
var ResourceSelect = require('utils/resource-select');
var Config = require('sunstone-config');
var WizardFields = require('utils/wizard-fields');
var TemplateUtils = require('utils/template-utils');
@ -43,70 +41,76 @@ define(function(require) {
var FORM_PANEL_ID = require('./create/formPanelId');
var TAB_ID = require('../tabId');
var MARKET_MAD_ATTRS = [
{
name: 'ENDPOINT',
label: Locale.tr("Endpoint"),
tooltip: Locale.tr("URL of AppMarket."),
driver: 'one'
},
{
name: 'BASE_URL',
label: Locale.tr("Base URL"),
tooltip: Locale.tr("URL base to generate app end points"),
tooltip: Locale.tr("URL base to generate app end points, where the PUBLIC_DIR is accessible."),
driver: 'http'
},
{
name: 'PUBLIC_DIR',
label: Locale.tr("Public Directory"),
tooltip: Locale.tr("Directory path to place images, the document root for http server"),
tooltip: Locale.tr("Absolute directory path to place images, the document root for http server, in the frontend or in the hosts pointed at by the BRIDGE_LIST directive."),
driver: 'http'
},
{
name: 'BRIDGE_LIST',
label: Locale.tr("Bridge List"),
tooltip: Locale.tr("Separated list of servers to access the public directory. If not defined, public directory will be local"),
tooltip: Locale.tr("Comma separated list of servers to access the public directory. If not defined, public directory will be local"),
driver: 'http'
},
{
name: 'ACCESS_KEY_ID',
label: Locale.tr("Access Key Id"),
tooltip: Locale.tr("Access Key Id"),
tooltip: Locale.tr("The access key of the S3 user."),
driver: 's3'
},
{
name: 'SECRET_ACCESS_KEY',
label: Locale.tr("Secret Access Key"),
tooltip: Locale.tr("Secret Access Key"),
tooltip: Locale.tr("The secret key of the S3 user."),
driver: 's3'
},
{
name: 'BUCKET',
label: Locale.tr("Bucket"),
tooltip: Locale.tr("Bucket"),
tooltip: Locale.tr("The bucket where the files will be stored."),
driver: 's3'
},
{
name: 'REGION',
label: Locale.tr("Region"),
tooltip: Locale.tr("Region"),
tooltip: Locale.tr("The region to connect to. If you are using Ceph-S3 any value here will work."),
driver: 's3'
},
{
name: 'TOTAL_MB',
label: Locale.tr("Total MB"),
tooltip: Locale.tr("Total MB"),
tooltip: Locale.tr("This parameter defines the Total size of the MarketPlace in MB. It defaults to 1024 GB."),
driver: 's3'
},
{
name: 'SIGNATURE_VERSION',
label: Locale.tr("Signature Version"),
tooltip: Locale.tr("Signature Version"),
tooltip: Locale.tr("Leave blank for Amazon AWS S3 service. If connecting to Ceph S3 it **must** be 's3'."),
driver: 's3'
},
{
name: 'ENDPOINT',
label: Locale.tr("Endpoint"),
tooltip: Locale.tr("Endpoint"),
tooltip: Locale.tr("The URL of AppMarket."),
driver: 's3'
},
{
name: 'FORCE_PATH_STYLE',
label: Locale.tr("Force Path Style"),
tooltip: Locale.tr("Force Path Style"),
tooltip: Locale.tr("Leave blank for Amazon AWS S3 service. If connecting to Ceph S3 it **must** be 'YES'."),
driver: 's3'
}
]
@ -173,29 +177,8 @@ define(function(require) {
function _onShow(dialog) {
$("#NAME", dialog).focus();
$('#MARKET_MAD', dialog).change();
// var cluster_id = $("div#cluster_id .resource_list_select", dialog).val();
// if (!cluster_id) cluster_id = "-1";
//
// var cluster_id_raw = $("div#datastore_cluster_raw .resource_list_select", dialog).val();
// if (!cluster_id_raw) cluster_id_raw = "-1";
//
// ResourceSelect.insert({
// context: $('#cluster_id', dialog),
// resourceName: 'Cluster',
// initValue: cluster_id,
// includeDefaultCluster: true
// });
//
// ResourceSelect.insert({
// context: $('#datastore_cluster_raw', dialog),
// resourceName: 'Cluster',
// initValue: cluster_id_raw,
// includeDefaultCluster: true
// });
return false;
}
@ -220,70 +203,6 @@ define(function(require) {
dialog.on('change', '#MARKET_MAD', function() {
_setRequiredFields(dialog, this.value);
});
// Show custom driver input only when custom is selected in selects
// $('input[name="ds_tab_custom_ds_mad"],' +
// 'input[name="ds_tab_custom_tm_mad"]', dialog).parent().hide();
//
// $('select#ds_mad', dialog).change(function() {
// if ($(this).val() == "custom") {
// $('input[name="ds_tab_custom_ds_mad"]', dialog).parent().show();
// } else {
// _setRequiredFields(dialog, $(this).val());
// $('input[name="ds_tab_custom_ds_mad"]', dialog).parent().hide();
// }
// });
//
// $('select#tm_mad', dialog).change(function() {
// if ($(this).val() == "custom")
// $('input[name="ds_tab_custom_tm_mad"]', dialog).parent().show();
// else
// $('input[name="ds_tab_custom_tm_mad"]', dialog).parent().hide();
// });
//
// $('#presets', dialog).change(function() {
// _hideAll(dialog);
// var choice_str = $(this).val();
//
// switch (choice_str)
// {
// case 'fs':
// _selectFilesystem(dialog);
// break;
// case 'vmware_vmfs':
// _selectVmwareVmfs(dialog);
// break;
// case 'block_lvm':
// _selectBlockLvm(dialog);
// break;
// case 'fs_lvm':
// _selectFsLvm(dialog);
// break;
// case 'ceph':
// _selectCeph(dialog);
// break;
// case 'gluster':
// _selectGluster(dialog);
// break;
// case 'dev':
// _selectDevices(dialog);
// break;
// case 'iscsi':
// _selectISCSI(dialog);
// break;
// case 'custom':
// _selectCustom(dialog);
// break;
// }
// });
//
// $('#presets', dialog).change();
//
// // Hide disk_type
// $('select#disk_type', dialog).parent().hide();
//
// _hideAll(dialog);
// _selectFilesystem(dialog);
}

View File

@ -32,11 +32,7 @@
{{/each}}
</select>
</div>
<div class="medium-6 columns hidden">
<label for="TYPE">{{tr "Type"}}</label>
<select id="TYPE" wizard_field="TYPE" required>
<option value="image">{{tr "Image"}}</option>
</select>
<div class="medium-6 columns">
</div>
</div>
<div class="row">
@ -47,9 +43,9 @@
{{tr "Human readable description of the MarketPlace for other users."}}
</span>
</label>
<textarea id="DESCRIPTION" wizard_field="DESCRIPTION" rows="2"></textarea>
<textarea id="DESCRIPTION" wizard_field="DESCRIPTION" rows="1"></textarea>
</div>
<div class="small-8 medium-8 columns">
<div class="medium-6 columns">
</div>
</div>
<div class="row">

View 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. */
/* -------------------------------------------------------------------------- */
define(function(require){
/*
DEPENDENCIES
*/
var Locale = require('utils/locale');
var MarketPlaceAppsTable = require('tabs/marketplaceapps-tab/datatable');
/*
CONSTANTS
*/
var PANEL_ID = require('./apps/panelId');
var MARKETPLACEAPPS_TABLE_ID = PANEL_ID + "MarketPlaceAppsTable"
var XML_ROOT = "MARKETPLACE"
/*
CONSTRUCTOR
*/
function Panel(info) {
this.title = Locale.tr("Apps");
this.icon = "fa-shopping-cart";
this.element = info[XML_ROOT.toUpperCase()];
return this;
};
Panel.PANEL_ID = PANEL_ID;
Panel.prototype.html = _html;
Panel.prototype.setup = _setup;
return Panel;
/*
FUNCTION DEFINITIONS
*/
function _html() {
var marketPlaceApps = [];
if (this.element.MARKETPLACEAPPS.ID != undefined){
marketPlaceApps = this.element.MARKETPLACEAPPS.ID;
if (!$.isArray(marketPlaceApps)){
marketPlaceApps = [marketPlaceApps];
}
}
var opts = {
info: true,
select: true,
selectOptions: {
read_only: true,
fixed_ids: marketPlaceApps
}
};
this.marketPlaceAppsDataTable = new MarketPlaceAppsTable(MARKETPLACEAPPS_TABLE_ID, opts);
return this.marketPlaceAppsDataTable.dataTableHTML;
}
function _setup(context) {
this.marketPlaceAppsDataTable.initialize();
this.marketPlaceAppsDataTable.refreshResourceTableSelect();
return false;
}
})

View File

@ -0,0 +1,19 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
define(function(require){
return 'marketplace_apps_tab';
});

View File

@ -0,0 +1,90 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
define(function(require) {
/*
DEPENDENCIES
*/
var Locale = require('utils/locale');
var Humanize = require('utils/humanize');
var RenameTr = require('utils/panel/rename-tr');
var TemplateTable = require('utils/panel/template-table');
var PermissionsTable = require('utils/panel/permissions-table');
var DatastoreCapacityBar = require('tabs/datastores-tab/utils/datastore-capacity-bar');
/*
TEMPLATES
*/
var TemplateInfo = require('hbs!./info/html');
/*
CONSTANTS
*/
var TAB_ID = require('../tabId');
var PANEL_ID = require('./info/panelId');
var RESOURCE = "MarketPlace"
/*
CONSTRUCTOR
*/
function Panel(info) {
this.title = Locale.tr("Info");
this.icon = "fa-info-circle";
this.element = info[RESOURCE.toUpperCase()];
return this;
};
Panel.PANEL_ID = PANEL_ID;
Panel.prototype.html = _html;
Panel.prototype.setup = _setup;
return Panel;
/*
FUNCTION DEFINITIONS
*/
function _html() {
var renameTrHTML = RenameTr.html(TAB_ID, RESOURCE, this.element.NAME);
var templateTableHTML = TemplateTable.html(
this.element.TEMPLATE, RESOURCE,
Locale.tr("Attributes"));
var permissionsTableHTML = PermissionsTable.html(TAB_ID, RESOURCE, this.element);
var capacityBar = DatastoreCapacityBar.html(this.element);
return TemplateInfo({
'element': this.element,
'renameTrHTML': renameTrHTML,
'templateTableHTML': templateTableHTML,
'permissionsTableHTML': permissionsTableHTML,
'capacityBar': capacityBar
});
}
function _setup(context) {
RenameTr.setup(TAB_ID, RESOURCE, this.element.ID, context);
TemplateTable.setup(this.element.TEMPLATE, RESOURCE, this.element.ID, context);
PermissionsTable.setup(TAB_ID, RESOURCE, this.element, context);
return false;
}
});

View File

@ -0,0 +1,49 @@
{{! -------------------------------------------------------------------------- }}
{{! 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. }}
{{! -------------------------------------------------------------------------- }}
<div class="row">
<div class="large-6 columns">
<table class="dataTable">
<thead>
<tr>
<th colspan="3">{{tr "Information"}}</th>
</tr>
</thead>
<tbody>
<tr>
<td class="key_td">{{tr "ID"}}</td>
<td class="value_td" colspan="2">{{element.ID}}</td>
</tr>
{{{renameTrHTML}}}
<tr>
<td class="key_td">{{tr "Driver"}}</td>
<td class="value_td">{{element.MARKET_MAD}}</td>
<td></td>
</tr>
<tr>
<td class="key_td">{{tr "Capacity"}}</td>
<td class="value_td" colspan="2">{{{capacityBar}}}</td>
</tr>
</tbody>
</table>
</div>
<div class="large-6 columns">
{{{permissionsTableHTML}}}
</div>
</div>
<div class="row">
<div class="large-9 columns">{{{templateTableHTML}}}</div>
</div>

View File

@ -0,0 +1,19 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
define(function(require){
return 'marketplace_info_tab';
});

View File

@ -35,13 +35,13 @@ define(function(require) {
}
//replace the text with an icon and spans
//obj.html('<span data-tooltip class="' + tip_classes.join(' ') + '" data-width="210" title="' + tip + '"><i class="fa fa-question-circle"></i></span>');
obj.html('<span title="' + tip + '"><i class="fa fa-question-circle"></i></span>');
obj.html('<span title="' + $.trim(tip) + '"><i class="fa fa-question-circle"></i></span>');
});
}
var _html = function(str) {
//return '<span data-tooltip class="" data-width="210" title="' + str + '"><i class="fa fa-question-circle"></i></span>'
return '<span title="' + str + '"><i class="fa fa-question-circle"></i></span>';
return '<span title="' + $.trim(str) + '"><i class="fa fa-question-circle"></i></span>';
}
return {

View File

@ -19,11 +19,11 @@
"resumablejs": "git://github.com/23/resumable.js.git#420cd351c5",
"spice-html5": "git://anongit.freedesktop.org/spice/spice-html5#spice-html5-0.1.6",
"require-handlebars-plugin": "0.11.2",
"requirejs": "2.1.17",
"almond": "0.3.1",
"datatables": "1.10.7",
"foundation": "5.5.2",
"vis": "4.12.0"
"vis": "4.12.0",
"requirejs": "2.1.22"
},
"version": "4.14",
"authors": [

View File

@ -1185,13 +1185,19 @@ hr {
}
}
#user_ssh_public_key_text, #config_ssh_public_key_text {
#user_ssh_public_key_text,
#config_ssh_public_key_text {
font-size: 0.875rem;
color: #777;
padding: 0px 10px;
overflow-x:hidden;
text-overflow:
ellipsis; height: 120px;
text-overflow: ellipsis;
height: 120px;
}
.info_text {
color: #777;
padding: 0px 10px;
}
.vm-action-disabled {

View File

@ -3204,24 +3204,6 @@ bool VirtualMachine::is_vrouter()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool VirtualMachine::is_vrouter_action_supported(History::VMAction action)
{
return (action == History::MIGRATE_ACTION ||
action == History::LIVE_MIGRATE_ACTION ||
action == History::HOLD_ACTION ||
action == History::RELEASE_ACTION ||
action == History::RESUME_ACTION ||
action == History::BOOT_ACTION ||
action == History::REBOOT_ACTION ||
action == History::REBOOT_HARD_ACTION ||
action == History::RESCHED_ACTION ||
action == History::UNRESCHED_ACTION ||
action == History::DISK_SNAPSHOT_CREATE_ACTION ||
action == History::DISK_SNAPSHOT_DELETE_ACTION);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::generate_context(string &files, int &disk_id,
const string& token_password)

View File

@ -206,8 +206,8 @@ int LibVirtDriver::deployment_description_kvm(
string hyperv_options = "";
vector<const VectorAttribute *> raw;
string default_raw;
string data;
string default_raw = "";
string data = "";
// ------------------------------------------------------------------------
@ -928,7 +928,7 @@ int LibVirtDriver::deployment_description_kvm(
{
get_default("SPICE_OPTIONS", spice_options);
if ( spice_options != "" )
if (spice_options.empty())
{
file << "\t\t" << spice_options << endl;
}

View File

@ -22,19 +22,30 @@
#include "NebulaUtil.h"
#include <sstream>
const string VirtualMachineManagerDriver::imported_actions_default =
"shutdown, shutdown-hard, hold, release, suspend, resume, delete, reboot, "
"reboot-hard, resched, unresched, disk-attach, disk-detach, nic-attach, "
"nic-detach, snap-create, snap-delete";
const string VirtualMachineManagerDriver::imported_actions_default_public =
"shutdown, shutdown-hard, hold, release, suspend, resume, delete, reboot, "
"reboot-hard, resched, unresched, disk-attach, disk-detach, nic-attach, "
"nic-detach, snap-create, snap-delete, poweroff, poweroff-hard";
VirtualMachineManagerDriver::VirtualMachineManagerDriver(
int userid,
const map<string,string>& attrs,
bool sudo,
VirtualMachinePool * pool):
Mad(userid,attrs,sudo), driver_conf(true), imported_vm_actions(0),
vmpool(pool)
Mad(userid,attrs,sudo), driver_conf(true), vmpool(pool)
{
map<string,string>::const_iterator it;
char * error_msg = 0;
const char * cfile;
string file;
int rc;
string action_defaults;
it = attrs.find("DEFAULT");
@ -78,26 +89,7 @@ VirtualMachineManagerDriver::VirtualMachineManagerDriver(
if (it != attrs.end())
{
vector<string> actions;
vector<string>::iterator vit;
string action;
History::VMAction id;
actions = one_util::split(it->second, ',');
for (vit = actions.begin() ; vit != actions.end() ; ++vit)
{
action = one_util::trim(*vit);
if ( History::action_from_str(action, id) != 0 )
{
NebulaLog::log("VMM", Log::ERROR, "Wrong action: " + action);
continue;
}
imported_vm_actions += 1 << static_cast<int>(id);
}
action_defaults = it->second;
}
else
{
@ -107,85 +99,39 @@ VirtualMachineManagerDriver::VirtualMachineManagerDriver(
if (it != attrs.end())
{
if ( it->second == "kvm" )
if ( it->second == "kvm" || it->second == "xen3" ||
it->second == "xen" || it->second == "vmware" )
{
imported_vm_actions = 132623768;
action_defaults = imported_actions_default;
}
else if ( it->second == "xen3" )
else if ( it->second == "sl" || it->second == "ec2" ||
it->second == "az" || it->second == "vcenter" )
{
imported_vm_actions = 132623768;
}
else if ( it->second == "xen" )
{
imported_vm_actions = 132623768;
}
else if ( it->second == "vmware" )
{
imported_vm_actions = 132623768;
}
else if ( it->second == "vcenter" )
{
imported_vm_actions = 134196632;
}
else if ( it->second == "ec2" )
{
imported_vm_actions = 134196632;
}
else if ( it->second == "az" )
{
imported_vm_actions = 134196632;
}
else if ( it->second == "sl" )
{
imported_vm_actions = 134196632;
action_defaults = imported_actions_default_public;
}
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
vector<string> actions;
vector<string>::iterator vit;
void VirtualMachineManagerDriver::get_default(
const char * name,
const char * vname,
string& value) const
{
const VectorAttribute * vattr = driver_conf.get(name);
string action;
History::VMAction id;
if ( vattr == 0 )
actions = one_util::split(action_defaults, ',');
for (vit = actions.begin() ; vit != actions.end() ; ++vit)
{
value.clear();
action = one_util::trim(*vit);
if ( History::action_from_str(action, id) != 0 )
{
NebulaLog::log("VMM", Log::ERROR, "Wrong action: " + action);
continue;
}
imported_actions.set(id);
}
else
{
value = vattr->vector_value(vname);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool VirtualMachineManagerDriver::get_default(
const char * name,
const char * vname,
bool& value) const
{
string st;
get_default(name, vname, st);
if ( st == "" )
{
value = false;
return false;
}
one_util::toupper(st);
value = ( st == "YES" );
return true;
}
/* ************************************************************************** */

View File

@ -35,10 +35,10 @@ int XenDriver::deployment_description(
int num;
string credits;
string cpu;
string memory;
string vcpu;
string credits = "";
string cpu = "";
string memory = "";
string vcpu = "";
float base_credit = 1.0;
float cpu_units = 1.0;
@ -102,8 +102,8 @@ int XenDriver::deployment_description(
int localtime_found = -1;
vector<const VectorAttribute *> raw;
string data;
string default_raw;
string data = "";
string default_raw = "";
// ------------------------------------------------------------------------
@ -624,17 +624,17 @@ int XenDriver::deployment_description(
}
}
if ( pae_found != 0 && get_default("FEATURES", "PAE", pae) )
if ( pae_found != 0 && get_default("FEATURES", "PAE", pae) == 0 )
{
pae_found = 0;
}
if ( acpi_found != 0 && get_default("FEATURES", "ACPI", acpi) )
if ( acpi_found != 0 && get_default("FEATURES", "ACPI", acpi) == 0 )
{
acpi_found = 0;
}
if ( apic_found != 0 && get_default("FEATURES", "APIC", apic) )
if ( apic_found != 0 && get_default("FEATURES", "APIC", apic) == 0 )
{
apic_found = 0;
}
@ -653,22 +653,22 @@ int XenDriver::deployment_description(
get_default("FEATURES", "LOCALTIME", localtime);
}
if ( pae_found == 0)
if ( pae_found == 0 )
{
file << "pae = " << on_off_string(pae) << endl;
}
if ( acpi_found == 0)
if ( acpi_found == 0 )
{
file << "acpi = " << on_off_string(acpi) << endl;
}
if ( apic_found == 0)
if ( apic_found == 0 )
{
file << "apic = " << on_off_string(apic) << endl;
}
if ( device_model_found == 0)
if ( device_model_found == 0 )
{
file << "device_model = '" << device_model << "'" << endl;
}

View File

@ -17,6 +17,24 @@
#include "VirtualRouter.h"
#include "VirtualNetworkPool.h"
#include "Nebula.h"
#include "VirtualMachine.h"
static const History::VMAction action[12] = {
History::MIGRATE_ACTION,
History::LIVE_MIGRATE_ACTION,
History::HOLD_ACTION,
History::RELEASE_ACTION,
History::RESUME_ACTION,
History::BOOT_ACTION,
History::REBOOT_ACTION,
History::REBOOT_HARD_ACTION,
History::RESCHED_ACTION,
History::UNRESCHED_ACTION,
History::DISK_SNAPSHOT_CREATE_ACTION,
History::DISK_SNAPSHOT_DELETE_ACTION
};
const ActionSet<History::VMAction> VirtualRouter::SUPPORTED_ACTIONS(action, 12);
/* ************************************************************************ */
/* VirtualRouter :: Constructor/Destructor */
@ -728,3 +746,4 @@ void VirtualRouter::set_auth_request(int uid,
vnpool->authorize_nic(PoolObjectSQL::VROUTER, *nics_it, uid, &ar);
}
}