1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

F #4913: Merge branch 'master' into feature-4913

This commit is contained in:
Jaime Melis 2017-04-10 18:13:28 +02:00
commit 5eeb721e1c
39 changed files with 793 additions and 190 deletions

View File

@ -181,13 +181,32 @@ public:
quota_del(DATASTORE, uid, gid, tmpl);
}
/**
* Delete Datastore related usage from quota counters.
* for the given user and group
* @param uid of the user
* @param gid of the group
* @param tmpl template for the image, with usage
*/
static void ds_del(int uid, int gid, vector<Template *> tmpls)
{
vector<Template *>::iterator it;
for ( it = tmpls.begin(); it != tmpls.end() ; ++it )
{
quota_del(DATASTORE, uid, gid, *it);
delete *it;
}
}
/**
* Delete a set of Datastore usage attributes from quota counters. Each
* quota datastore is associate to a given image. NOTE: The templates
* *ARE FREED* by this function
* @param ds_quotas a map with image_id and a tmpl with usage attributes
*/
static void ds_del(map<int, Template *>& ds_quotas);
static void ds_del_recreate(int uid, int gid, vector<Template *>& ds_quotas);
/**
* Delete usage from the given quota counters.

View File

@ -243,6 +243,18 @@ public:
set(new SingleAttribute(name, value));
}
void add(const string& name, bool value)
{
if ( value )
{
set(new SingleAttribute(name, "YES"));
}
else
{
set(new SingleAttribute(name, "NO"));
}
}
/**
* Removes an attribute from the template. The attributes are returned. The
* attributes MUST be freed by the calling funtion

View File

@ -1041,7 +1041,7 @@ public:
* Releases all disk images taken by this Virtual Machine
* @param quotas disk space to free from image datastores
*/
void release_disk_images(map<int, Template *>& quotas);
void release_disk_images(vector<Template *>& quotas);
/**
* @return reference to the VirtualMachine disks
@ -1374,7 +1374,7 @@ public:
* @param ds_quotas The DS SIZE freed from image datastores.
*/
void delete_non_persistent_disk_resizes(Template **vm_quotas,
map<int, Template *>& ds_quotas)
vector<Template *>& ds_quotas)
{
disks.delete_non_persistent_resizes(vm_quotas, ds_quotas);
}
@ -1471,11 +1471,13 @@ public:
* @param snap_id of the snapshot
* @param ds_quotas template with snapshot usage for the DS quotas
* @param vm_quotas template with snapshot usage for the VM quotas
* @param io delete ds quotas from image owners
* @param vo delete ds quotas from vm owners
*/
void delete_disk_snapshot(int disk_id, int snap_id, Template **ds_quotas,
Template **vm_quotas)
Template **vm_quotas, bool& io, bool& vo)
{
disks.delete_snapshot(disk_id, snap_id, ds_quotas, vm_quotas);
disks.delete_snapshot(disk_id, snap_id, ds_quotas, vm_quotas, io, vo);
}
/**
@ -1485,7 +1487,7 @@ public:
* @param ds_quotas The DS SIZE freed from image datastores.
*/
void delete_non_persistent_disk_snapshots(Template **vm_quotas,
map<int, Template *>& ds_quotas)
vector<Template *>& ds_quotas)
{
disks.delete_non_persistent_snapshots(vm_quotas, ds_quotas);
}

View File

@ -244,8 +244,11 @@ public:
* @param snap_id of the snapshot
* @param ds_quotas template with snapshot usage for the DS quotas
* @param vm_quotas template with snapshot usage for the VM quotas
* @param io delete ds quotas from image owners
* @param vo delete ds quotas from vm owners
*/
void delete_snapshot(int snap_id, Template **ds_quota, Template **vm_quota);
void delete_snapshot(int snap_id, Template **ds_quota, Template **vm_quota,
bool& io, bool& vo);
/* ---------------------------------------------------------------------- */
/* Disk resize functions */
@ -261,8 +264,12 @@ public:
* @param new_size of disk
* @param dsdeltas increment in datastore usage
* @param vmdelta increment in system datastore usage
* @param do_img_owner quotas counter allocated for image uid/gid
* @param do_vm_owner quotas counter allocated for vm uid/gid
*
*/
void resize_quotas(long long new_size, Template& dsdelta, Template& vmdelta);
void resize_quotas(long long new_size, Template& dsdelta, Template& vmdelta,
bool& do_img_owner, bool& do_vm_owner);
/* ---------------------------------------------------------------------- */
/* Disk space usage functions */
@ -273,6 +280,11 @@ public:
*/
long long system_ds_size();
/**
* @return the space required by this disk in the image datastore
*/
long long image_ds_size();
/**
* Compute the storage needed by the disk in the system and/or image
* datastore
@ -408,6 +420,14 @@ public:
static void extended_info(int uid, Template * tmpl);
/**
* Computes the storage in the image DS needed for the disks in a VM
* template
* @param tmpl with DISK descriptions
* @param ds_quotas templates for quota updates
*/
static void image_ds_quotas(Template * tmpl, vector<Template *>& ds_quotas);
/**
* Sets Datastore information on volatile disks
*/
@ -446,7 +466,7 @@ public:
* @param img_error true if the image has to be set in error state
* @param quotas disk space usage to free from image datastores
*/
void release_images(int vmid, bool img_error, map<int, Template *>& quotas);
void release_images(int vmid, bool img_error, vector<Template *>& quotas);
/* ---------------------------------------------------------------------- */
/* DISK cloning functions */
@ -666,9 +686,11 @@ public:
* @param snap_id of the snapshot
* @param ds_quotas template with snapshot usage for the DS quotas
* @param vm_quotas template with snapshot usage for the VM quotas
* @param io delete ds quotas from image owners
* @param vo delete ds quotas from vm owners
*/
void delete_snapshot(int disk_id, int snap_id, Template **ds_quota,
Template **vm_quota);
Template **vm_quota, bool& io, bool& vo);
/**
* Deletes all the disk snapshots for non-persistent disks and for persistent
@ -677,7 +699,7 @@ public:
* @param ds_quotas The DS SIZE freed from image datastores.
*/
void delete_non_persistent_snapshots(Template **vm_quotas,
map<int, Template *>& ds_quotas);
vector<Template *> &ds_quotas);
/**
* Restores the disk original size for non-persistent and for persistent
@ -686,7 +708,7 @@ public:
* @param ds_quotas The DS SIZE freed from image datastores.
*/
void delete_non_persistent_resizes(Template **vm_quotas,
map<int, Template *>& ds_quotas);
vector<Template *> &ds_quotas);
protected:

View File

@ -212,7 +212,7 @@ error:
void DispatchManager::free_vm_resources(VirtualMachine * vm)
{
Template* tmpl;
map<int, Template *> ds_quotas;
vector<Template *> ds_quotas;
int uid;
int gid;
@ -247,7 +247,7 @@ void DispatchManager::free_vm_resources(VirtualMachine * vm)
if ( !ds_quotas.empty() )
{
Quotas::ds_del(ds_quotas);
Quotas::ds_del(uid, gid, ds_quotas);
}
if (vrid != -1)
@ -1052,8 +1052,8 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
Template * vm_quotas_snp = 0;
Template * vm_quotas_rsz = 0;
map<int, Template *> ds_quotas_snp;
map<int, Template *> ds_quotas_rsz;
vector<Template *> ds_quotas_snp;
vector<Template *> ds_quotas_rsz;
int vm_uid, vm_gid;
@ -1118,12 +1118,12 @@ int DispatchManager::delete_recreate(VirtualMachine * vm,
if ( !ds_quotas_snp.empty() )
{
Quotas::ds_del(ds_quotas_snp);
Quotas::ds_del_recreate(vm_uid, vm_gid, ds_quotas_snp);
}
if ( !ds_quotas_rsz.empty() )
{
Quotas::ds_del(ds_quotas_rsz);
Quotas::ds_del_recreate(vm_uid, vm_gid, ds_quotas_rsz);
}
if ( vm_quotas_snp != 0 )

View File

@ -204,7 +204,7 @@ void DispatchManager::done_action(int vid)
VirtualMachine * vm;
Template * tmpl;
map<int, Template *> ds_quotas;
vector<Template *> ds_quotas;
int uid;
int gid;
@ -264,7 +264,7 @@ void DispatchManager::done_action(int vid)
if ( !ds_quotas.empty() )
{
Quotas::ds_del(ds_quotas);
Quotas::ds_del(uid, gid, ds_quotas);
}
if (!deploy_id.empty())

View File

@ -820,8 +820,8 @@ void LifeCycleManager::delete_recreate_action(const LCMAction& la)
Template * vm_quotas_snp = 0;
Template * vm_quotas_rsz = 0;
map<int, Template *> ds_quotas_snp;
map<int, Template *> ds_quotas_rsz;
vector<Template *> ds_quotas_snp;
vector<Template *> ds_quotas_rsz;
int vm_uid, vm_gid;
@ -888,12 +888,12 @@ void LifeCycleManager::delete_recreate_action(const LCMAction& la)
if ( !ds_quotas_snp.empty() )
{
Quotas::ds_del(ds_quotas_snp);
Quotas::ds_del_recreate(vm_uid, vm_gid, ds_quotas_snp);
}
if ( !ds_quotas_rsz.empty() )
{
Quotas::ds_del(ds_quotas_rsz);
Quotas::ds_del_recreate(vm_uid, vm_gid, ds_quotas_rsz);
}
if ( vm_quotas_snp != 0 )

View File

@ -1865,6 +1865,8 @@ void LifeCycleManager::disk_snapshot_success(int vid)
Template *ds_quotas = 0;
Template *vm_quotas = 0;
bool img_owner, vm_owner;
const VirtualMachineDisk * disk;
Snapshots snaps(-1);
const Snapshots* tmp_snaps;
@ -1909,7 +1911,8 @@ void LifeCycleManager::disk_snapshot_success(int vid)
case VirtualMachine::DISK_SNAPSHOT_DELETE_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_DELETE_SUSPENDED:
vm->log("LCM", Log::INFO, "VM disk snapshot deleted.");
vm->delete_disk_snapshot(disk_id, snap_id, &ds_quotas, &vm_quotas);
vm->delete_disk_snapshot(disk_id, snap_id, &ds_quotas, &vm_quotas,
img_owner, vm_owner);
break;
default:
@ -1941,16 +1944,24 @@ void LifeCycleManager::disk_snapshot_success(int vid)
if ( ds_quotas != 0 )
{
Image* img = ipool->get(img_id, true);
if(img != 0)
if ( img_owner )
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
Image* img = ipool->get(img_id, true);
img->unlock();
if(img != 0)
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
Quotas::ds_del(img_uid, img_gid, ds_quotas);
img->unlock();
Quotas::ds_del(img_uid, img_gid, ds_quotas);
}
}
if ( vm_owner )
{
Quotas::ds_del(vm_uid, vm_gid, ds_quotas);
}
delete ds_quotas;
@ -2008,6 +2019,8 @@ void LifeCycleManager::disk_snapshot_failure(int vid)
bool has_snaps = false;
string error_str;
bool img_owner, vm_owner;
VirtualMachine * vm = vmpool->get(vid,true);
if ( vm == 0 )
@ -2036,7 +2049,8 @@ void LifeCycleManager::disk_snapshot_failure(int vid)
case VirtualMachine::DISK_SNAPSHOT_POWEROFF:
case VirtualMachine::DISK_SNAPSHOT_SUSPENDED:
vm->log("LCM", Log::ERROR, "Could not take disk snapshot.");
vm->delete_disk_snapshot(disk_id, snap_id, &ds_quotas, &vm_quotas);
vm->delete_disk_snapshot(disk_id, snap_id, &ds_quotas, &vm_quotas,
img_owner, vm_owner);
break;
case VirtualMachine::DISK_SNAPSHOT_DELETE:
@ -2077,16 +2091,24 @@ void LifeCycleManager::disk_snapshot_failure(int vid)
if ( ds_quotas != 0 )
{
Image* img = ipool->get(img_id, true);
if(img != 0)
if ( img_owner )
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
Image* img = ipool->get(img_id, true);
img->unlock();
if(img != 0)
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
Quotas::ds_del(img_uid, img_gid, ds_quotas);
img->unlock();
Quotas::ds_del(img_uid, img_gid, ds_quotas);
}
}
if ( vm_owner)
{
Quotas::ds_del(vm_uid, vm_gid, ds_quotas);
}
delete ds_quotas;
@ -2363,9 +2385,11 @@ void LifeCycleManager::disk_resize_failure(int vid)
int vm_uid = vm->get_uid();
int vm_gid = vm->get_gid();
bool img_quota, vm_quota;
disk->vector_value("IMAGE_ID", img_id);
disk->vector_value("SIZE_PREV", size_prev);
disk->resize_quotas(size_prev, ds_deltas, vm_deltas);
disk->resize_quotas(size_prev, ds_deltas, vm_deltas, img_quota, vm_quota);
disk->clear_resize(true);
@ -2374,7 +2398,7 @@ void LifeCycleManager::disk_resize_failure(int vid)
vm->unlock();
// Restore quotas
if ( !ds_deltas.empty() && img_id != -1 )
if ( img_quota && img_id != -1 )
{
Image* img = ipool->get(img_id, true);
@ -2389,6 +2413,11 @@ void LifeCycleManager::disk_resize_failure(int vid)
}
}
if ( vm_quota )
{
Quotas::ds_del(vm_uid, vm_gid, &ds_deltas);
}
if ( !vm_deltas.empty() )
{
Quotas::vm_del(vm_uid, vm_gid, &vm_deltas);

View File

@ -14,6 +14,18 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
# This patch changes the type of an AR to IP4_6_STATIC and also lets
# us add or change parameters. The AR must be specified in the extra
# option. For example, to change network 2, ar 1 and add ip6 and
# prefix_length you can use:
#
# onedb patch -s one.db ip4_6_static.rb \
# --extra vn=2;ar=1;ip6=2001::1;prefix_length=48
#
# You can also specify several ARs separated by ,:
#
# vn=3;ar=0;ip6=2001::1;prefix_length=48,vn=3;ar=1;ip6=2001::2;prefix_length=64
if !ONE_LOCATION
LOG_LOCATION = "/var/log/one"
else

View File

@ -121,7 +121,24 @@ bool VirtualMachineAllocate::allocate_authorization(
return false;
}
return true;
vector<Template *> ds_quotas;
vector<Template *>::iterator it;
bool ds_quota_auth = true;
VirtualMachineDisks::image_ds_quotas(&aux_tmpl, ds_quotas);
for ( it = ds_quotas.begin() ; it != ds_quotas.end() ; ++it )
{
if ( quota_authorization(*it, Quotas::DATASTORE, att) == false )
{
ds_quota_auth = false;
}
delete *it;
}
return ds_quota_auth;
}
/* -------------------------------------------------------------------------- */

View File

@ -2564,8 +2564,7 @@ void VirtualMachineDiskSnapshotCreate::request_execute(
PoolObjectAuth vm_perms;
const VirtualMachineDisk * disk;
VectorAttribute * delta_disk = 0;
VirtualMachineDisk * disk;
Template ds_deltas;
Template vm_deltas;
@ -2597,11 +2596,19 @@ void VirtualMachineDiskSnapshotCreate::request_execute(
return;
}
string disk_size = disk->vector_value("SIZE");
string ds_id = disk->vector_value("DATASTORE_ID");
/* ---------------------------------------------------------------------- */
/* Get disk information and quota usage deltas */
/* ---------------------------------------------------------------------- */
bool img_ds_quota, vm_ds_quota;
long long ssize;
disk->vector_value("SIZE", ssize);
ssize = 2 * ssize; //Sanpshot accounts as another disk of same size
disk->resize_quotas(ssize, ds_deltas, vm_deltas, img_ds_quota, vm_ds_quota);
bool is_volatile = disk->is_volatile();
bool is_system = disk->get_tm_target() == "SYSTEM";
bool do_ds_quota = disk->is_persistent() || !is_system;
int img_id = -1;
disk->vector_value("IMAGE_ID", img_id);
@ -2617,11 +2624,12 @@ void VirtualMachineDiskSnapshotCreate::request_execute(
return;
}
RequestAttributes ds_att_quota;
/* ---------- Attributes for quota update requests ---------------------- */
RequestAttributes img_att_quota;
RequestAttributes vm_att_quota;
//--------------------------- Persistent Images ----------------------------
if (do_ds_quota)
if (img_ds_quota)
{
PoolObjectAuth img_perms;
@ -2645,40 +2653,51 @@ void VirtualMachineDiskSnapshotCreate::request_execute(
return;
}
ds_att_quota = RequestAttributes(img_perms.uid, img_perms.gid, att);
ds_deltas.add("DATASTORE", ds_id);
ds_deltas.add("SIZE", disk_size);
ds_deltas.add("IMAGES", 0);
if (!quota_authorization(&ds_deltas, Quotas::DATASTORE, ds_att_quota))
{
return;
}
img_att_quota = RequestAttributes(img_perms.uid, img_perms.gid, att);
}
//--------------------- Account for System DS storage ----------------------
if (is_system)
if ( vm_ds_quota )
{
if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false )
{
return;
}
}
vm_att_quota = RequestAttributes(vm_perms.uid, vm_perms.gid, att);
vm_att_quota = RequestAttributes(vm_perms.uid, vm_perms.gid, att);
delta_disk = new VectorAttribute("DISK");
delta_disk->replace("TYPE", "FS");
delta_disk->replace("SIZE", disk_size);
/* ---------------------------------------------------------------------- */
/* Check quotas for the new size in image/system datastoress */
/* ---------------------------------------------------------------------- */
if ( img_ds_quota && !quota_authorization(&ds_deltas, Quotas::DATASTORE,
img_att_quota) )
{
return;
}
vm_deltas.add("VMS", 0);
vm_deltas.set(delta_disk);
if ( vm_ds_quota && !quota_authorization(&ds_deltas, Quotas::DATASTORE,
vm_att_quota) )
{
if ( img_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
return;
}
if ( !vm_deltas.empty() )
{
if (!quota_resize_authorization(id, &vm_deltas, vm_att_quota))
{
if (do_ds_quota)
if ( img_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, ds_att_quota);
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
if ( vm_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, vm_att_quota);
}
return;
@ -2692,12 +2711,17 @@ void VirtualMachineDiskSnapshotCreate::request_execute(
if ( rc != 0 )
{
if (do_ds_quota)
if ( img_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, ds_att_quota);
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
if (is_system)
if ( vm_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, vm_att_quota);
}
if ( !vm_deltas.empty() )
{
quota_rollback(&vm_deltas, Quotas::VM, vm_att_quota);
}
@ -2982,9 +3006,9 @@ void VirtualMachineDiskResize::request_execute(
}
/* ------------- Get information about the disk and image --------------- */
bool is_persistent = disk->is_persistent();
bool img_ds_quota, vm_ds_quota;
disk->resize_quotas(size, ds_deltas, vm_deltas);
disk->resize_quotas(size, ds_deltas, vm_deltas, img_ds_quota, vm_ds_quota);
int img_id = -1;
disk->vector_value("IMAGE_ID", img_id);
@ -2996,10 +3020,10 @@ void VirtualMachineDiskResize::request_execute(
/* ---------------------------------------------------------------------- */
/* Authorize the request for VM and IMAGE for persistent disks */
/* ---------------------------------------------------------------------- */
RequestAttributes ds_att_quota;
RequestAttributes img_att_quota;
RequestAttributes vm_att_quota;
if ( is_persistent )
if ( img_ds_quota )
{
PoolObjectAuth img_perms;
@ -3026,16 +3050,15 @@ void VirtualMachineDiskResize::request_execute(
return;
}
ds_att_quota = RequestAttributes(img_perms.uid, img_perms.gid, att);
img_att_quota = RequestAttributes(img_perms.uid, img_perms.gid, att);
}
else
if ( vm_ds_quota )
{
if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false )
{
return;
}
ds_att_quota = RequestAttributes(vm_perms.uid, vm_perms.gid, att);
}
vm_att_quota = RequestAttributes(vm_perms.uid, vm_perms.gid, att);
@ -3044,21 +3067,35 @@ void VirtualMachineDiskResize::request_execute(
/* Check quotas for the new size in image/system datastoress */
/* ---------------------------------------------------------------------- */
if ( !ds_deltas.empty() )
if ( img_ds_quota && !quota_authorization(&ds_deltas, Quotas::DATASTORE,
img_att_quota))
{
if (!quota_authorization(&ds_deltas, Quotas::DATASTORE, ds_att_quota))
return;
}
if ( vm_ds_quota && !quota_authorization(&ds_deltas, Quotas::DATASTORE,
vm_att_quota))
{
if ( img_ds_quota )
{
return;
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
return;
}
if ( !vm_deltas.empty() )
{
if (!quota_resize_authorization(id, &vm_deltas, vm_att_quota))
{
if (!ds_deltas.empty())
if ( img_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, ds_att_quota);
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
if ( vm_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, vm_att_quota);
}
return;
@ -3072,9 +3109,14 @@ void VirtualMachineDiskResize::request_execute(
if ( rc != 0 )
{
if ( !ds_deltas.empty() )
if ( img_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, ds_att_quota);
quota_rollback(&ds_deltas, Quotas::DATASTORE, img_att_quota);
}
if ( vm_ds_quota )
{
quota_rollback(&ds_deltas, Quotas::DATASTORE, vm_att_quota);
}
if ( !vm_deltas.empty() )

View File

@ -16,6 +16,8 @@
define(function(require) {
require('jquery');
require('jquery-ui');
require('foundation');
Foundation.Dropdown.defaults.positionClass = 'left';

View File

@ -21,6 +21,7 @@ require.config({
/* jQuery */
'jquery': '../bower_components/jquery/dist/jquery',
'jquery-ui': '../bower_components/jquery-ui/jquery-ui',
/* DataTables */
'datatables.net': '../bower_components/datatables/media/js/jquery.dataTables',

View File

@ -18,7 +18,7 @@ define(function(require) {
/*
DEPENDENCIES
*/
var Notifier = require('utils/notifier');
// require('foundation.tab');
var BaseFormPanel = require('utils/form-panels/form-panel');
var Sunstone = require('sunstone');
@ -229,23 +229,27 @@ define(function(require) {
json_template['ready_status_gate'] = ready_status_gate;
var templateStr = $('textarea#template', $("form#createServiceTemplateFormAdvanced")).val();
var template_final = TemplateUtils.mergeTemplates(templateJSON, templateStr);
if (this.action == "create") {
Sunstone.runAction("ServiceTemplate.create", json_template );
Sunstone.runAction("ServiceTemplate.create", template_final );
return false;
} else if (this.action == "update") {
Sunstone.runAction("ServiceTemplate.update",this.resourceId, JSON.stringify(json_template));
Sunstone.runAction("ServiceTemplate.update",this.resourceId, JSON.stringify(template_final));
return false;
}
}
function _submitAdvanced(context) {
var json_template = $('textarea#template', context).val();
var templateStr = $('textarea#template', context).val();
var templateJSON = this.retrieve($("form#createServiceTemplateFormWizard"));
var template_final = TemplateUtils.mergeTemplates(templateStr, templateJSON, true);
template_final = TemplateUtils.templateToString(template_final);
if (this.action == "create") {
Sunstone.runAction("ServiceTemplate.create", JSON.parse(json_template) );
Sunstone.runAction("ServiceTemplate.create", JSON.parse(template_final) );
return false;
} else if (this.action == "update") {
Sunstone.runAction("ServiceTemplate.update", this.resourceId, json_template);
Sunstone.runAction("ServiceTemplate.update", this.resourceId, template_final);
return false;
}
}
@ -399,7 +403,6 @@ define(function(require) {
$(".networks_role", role_section).show();
}
$(".vm_template_contents", role_section).val("");
$.each(selected_networks, function(){
$(".service_network_checkbox[value='"+this+"']", role_section).attr('checked', true).change();

View File

@ -300,6 +300,10 @@ define(function(require) {
if (Config.provision.dashboard.isEnabled("vms")) {
$("#provision_dashboard").append(TemplateDashboardVms());
if(!Config.isProvisionTabEnabled("provision-tab", "templates")){
$('.provision_create_vm_button').hide();
}
var start_time = Math.floor(new Date().getTime() / 1000);
// ms to s

View File

@ -1,4 +1,4 @@
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2016, OpenNebula Project, OpenNebula Systems */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
@ -18,7 +18,7 @@ define(function(require) {
/*
DEPENDENCIES
*/
var Notifier = require('utils/notifier');
var BaseFormPanel = require('utils/form-panels/form-panel');
var Sunstone = require('sunstone');
var Locale = require('utils/locale');
@ -188,24 +188,30 @@ define(function(require) {
function _submitWizard(context) {
var templateJSON = this.retrieve(context);
var templateStr = $('textarea#template', $("form#createVMTemplateFormAdvanced")).val();
var template_final = TemplateUtils.mergeTemplates(templateJSON, templateStr);
if (this.action == "create") {
Sunstone.runAction(this.resource+".create", {'vmtemplate': templateJSON});
Sunstone.runAction(this.resource+".create", {'vmtemplate': template_final});
return false;
} else if (this.action == "update") {
Sunstone.runAction(this.resource+".update", this.resourceId, TemplateUtils.templateToString(templateJSON));
Sunstone.runAction(this.resource+".update", this.resourceId, TemplateUtils.templateToString(template_final));
return false;
}
}
function _submitAdvanced(context) {
var template = $('textarea#template', context).val();
var templateStr = $('textarea#template', context).val();
var templateJSON = this.retrieve($("form#createVMTemplateFormWizard"));
var template_final = TemplateUtils.mergeTemplates(templateStr, templateJSON, true);
template_final = TemplateUtils.templateToString(template_final);
if (this.action == "create") {
Sunstone.runAction(this.resource+".create", {"vmtemplate": {"template_raw": template}});
Sunstone.runAction(this.resource+".create", {"vmtemplate": {"template_raw": template_final}});
return false;
} else if (this.action == "update") {
Sunstone.runAction(this.resource+".update", this.resourceId, template);
Sunstone.runAction(this.resource+".update", this.resourceId, template_final);
return false;
}
}

View File

@ -223,7 +223,7 @@ define(function(require) {
$.each(userInputsJSON, function(key,value){
var name = key.toUpperCase();
contextJSON[name] = "$" + name;
contextJSON[name.split("_")[2]] = "$" + name;
});
var start_script = WizardFields.retrieveInput($(".START_SCRIPT", context));

View File

@ -41,7 +41,7 @@
<li class="tabs-title is-active">
<a href="#netsshTab{{uniqueId}}">{{tr "Configuration"}}</a>
</li>
<li class="tabs-title">
<li class="tabs-title hypervisor only_kvm">
<a href="#filesTab{{uniqueId}}">{{tr "Files"}}</a>
</li>
<li class="tabs-title">
@ -109,7 +109,7 @@
{{{tip (tr "Text of the script executed when the machine starts up. It can contain shebang in case it is not shell script")}}}
<textarea rows="4" type="text" class="START_SCRIPT monospace" placeholder="yum upgrade"/>
</label>
<input type="checkbox" class="ENCODE_START_SCRIPT" id="ENCODE_START_SCRIPT{{uniqueId}}">
<input type="checkbox" class="ENCODE_START_SCRIPT" id="ENCODE_START_SCRIPT{{uniqueId}}" checked>
<label for="ENCODE_START_SCRIPT{{uniqueId}}">{{tr "Encode script in Base64"}}</label>
</div>
</div>

View File

@ -182,7 +182,7 @@ define(function(require) {
templateJSON["DISK_COST"] = templateJSON["DISK_COST"] * 1024;
}
else{
templateJSON["DISK_COST"] = "0";
delete templateJSON["MEMORY_UNIT_COST"];
}
if(templateJSON["MEMORY_UNIT_COST"] == "GB")
templateJSON["MEMORY_COST"] = templateJSON["MEMORY_COST"] * 1024;

View File

@ -113,10 +113,10 @@
<legend>{{tr "Override Network Values IPv6"}}</legend>
<div class="row">
<div class="medium-6 columns">
<label for="IP6_GLOBAL">
{{tr "Global address"}}
<label for="IP6">
{{tr "IP"}}
</label>
<input type="text" wizard_field="IP6_GLOBAL" id="IP6_GLOBAL" name="IP6_GLOBAL" size="3" />
<input type="text" wizard_field="IP6" id="IP6" name="IP6" size="3" />
</div>
<div class="medium-6 columns">
<label for="GATEWAY6">

View File

@ -33,6 +33,7 @@ define(function(require) {
require('./vms-tab/dialogs/disk-resize'),
require('./vms-tab/dialogs/attach-nic'),
require('./vms-tab/dialogs/snapshot'),
require('./vms-tab/dialogs/revert'),
require('./vms-tab/dialogs/vnc'),
require('./vms-tab/dialogs/spice'),
require('./vms-tab/dialogs/saveas-template')

View File

@ -141,9 +141,11 @@ define(function(require) {
custom_classes : "state-dependent"
},
"VM.terminate_hard" : {
type: text,
text: Locale.tr("Terminate") + ' <span class="label secondary radius">' + Locale.tr("hard") + '</span>',
type: "confirm",
icon: "<i class='fa fa-trash fa-3' style='color:#ec5840'/>",
text: Locale.tr(" Terminate") + ' <span class="label secondary radius">' + Locale.tr("hard") + '</span>',
layout: "vmsdelete_buttons",
tip: Locale.tr("This will remove information from non-persistent hard disks"),
custom_classes : "state-dependent"
},
"VM.resched" : {

View File

@ -0,0 +1,92 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2016, 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 BaseDialog = require('utils/dialogs/dialog');
var TemplateHTML = require('hbs!./revert/html');
var Sunstone = require('sunstone');
var Tips = require('utils/tips');
/*
CONSTANTS
*/
var DIALOG_ID = require('./revert/dialogId');
var TAB_ID = require('../tabId')
/*
CONSTRUCTOR
*/
function Dialog() {
this.dialogId = DIALOG_ID;
BaseDialog.call(this);
};
Dialog.DIALOG_ID = DIALOG_ID;
Dialog.prototype = Object.create(BaseDialog.prototype);
Dialog.prototype.constructor = Dialog;
Dialog.prototype.html = _html;
Dialog.prototype.onShow = _onShow;
Dialog.prototype.setup = _setup;
Dialog.prototype.setElement = _setElement;
return Dialog;
/*
FUNCTION DEFINITIONS
*/
function _html() {
return TemplateHTML({
'dialogId': this.dialogId
});
}
function _setup(context) {
var that = this;
Tips.setup(context);
$('#' + DIALOG_ID + 'Form', context).submit(function() {
var snapshot_id = $(this).parents('tr').attr('snapshot_id');
Sunstone.runAction('VM.snapshot_revert', that.element.ID, {"snapshot_id": snapshot_id});
Sunstone.getDialog(DIALOG_ID).hide();
Sunstone.getDialog(DIALOG_ID).reset();
return false;
});
return false;
}
function _onShow(context) {
this.setNames( {tabId: TAB_ID} );
return false;
}
function _setElement(element) {
this.element = element
}
});

View File

@ -0,0 +1,19 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2016, 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 'revertVMDialog';
});

View File

@ -0,0 +1,40 @@
{{! -------------------------------------------------------------------------- }}
{{! Copyright 2002-2016, 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 id="{{dialogId}}" class="reveal small" data-reveal>
<div class="row">
<h3 class="subheader">
{{tr "Revert"}}
</h3>
</div>
<div class="confirm-resources-header"></div>
<div class="reveal-body">
<form id="{{dialogId}}Form" action="">
<div class="row">
<div id="confirm_tip">{{tr "You have to confirm this action."}}</div>
<br/>
<div id="question">{{tr "Do you want to proceed?"}}</div>
<br />
</div>
<div class="form_buttons">
<button class="button radius right success" type="submit">{{tr "OK"}}</button>
</div>
<button class="close-button" data-close aria-label="{{tr "Close modal"}}" type="button">
<span aria-hidden="true">&times;</span>
</button>
</form>
</div>
</div>

View File

@ -34,6 +34,7 @@ define(function(require) {
var TAB_ID = require('../tabId');
var PANEL_ID = require('./snapshots/panelId');
var SNAPSHOT_DIALOG_ID = require('../dialogs/snapshot/dialogId');
var REVERT_DIALOG_ID = require('../dialogs/revert/dialogId');
var RESOURCE = "VM"
var XML_ROOT = "VM"
@ -165,8 +166,9 @@ define(function(require) {
if (Config.isTabActionEnabled("vms-tab", "VM.snapshot_revert")) {
context.off('click', '.snapshot_revert');
context.on('click', '.snapshot_revert', function() {
var snapshot_id = $(this).parents('tr').attr('snapshot_id');
Sunstone.runAction('VM.snapshot_revert', that.element.ID, {"snapshot_id": snapshot_id});
var dialog = Sunstone.getDialog(REVERT_DIALOG_ID);
dialog.setElement(that.element);
dialog.show();
return false;
});
}

View File

@ -44,7 +44,7 @@
<div class="row collapse ar_input type_ip4_6 type_ip6 switch left">
<label for="{{str_ar_tab_id}}_">{{tr "SLAAC"}}
</label>
<input class="switch-input slaac" wizard_field="SLAAC" name="SLAAC" id="{{str_ar_tab_id}}_slaac" type="checkbox">
<input class="switch-input slaac" id="{{str_ar_tab_id}}_slaac" type="checkbox">
<label class="switch-paddle" for="{{str_ar_tab_id}}_slaac">
</label>
</div>

View File

@ -91,6 +91,7 @@ define(function(require) {
NicsSection.insert({},
$(".nicsContext", context),
{ floatingIP: true,
forceIPv6:true,
forceIPv4:true,
management: true,
securityGroups: Config.isFeatureEnabled("secgroups")});

View File

@ -70,6 +70,7 @@ define(function(require) {
NicsSection.insert({},
$(".nicsContext", context),
{ floatingIP: true,
forceIPv6:true,
forceIPv4:true,
management: true,
securityGroups: Config.isFeatureEnabled("secgroups"),

View File

@ -145,6 +145,15 @@ define(function(require) {
}
}
var ip6 = $("input.manual_ip6", $(this)).val();
if (ip6 != undefined){
delete nic["IP6"];
if (ip6 != ""){
nic["IP6"] = ip6;
}
}
delete nic["VROUTER_MANAGEMENT"];
if ($("input.management", $(this)).prop("checked")){

View File

@ -63,6 +63,23 @@
</div>
{{/if}}
</div>
<div class="row">
{{#if options.forceIPv6}}
<div class="medium-6 columns">
<label>
{{tr "Force IPv6:"}}
<span class="tip">
{{tr "Optionally, you can force the IP assigned to the network interface."}}
</span>
{{#if options.nic.IP6}}
<input type="text" class="manual_ip6" value="{{options.nic.IP6}}"/>
{{else}}
<input type="text" class="manual_ip6"/>
{{/if}}
</label>
</div>
{{/if}}
</div>
{{#if options.securityGroups}}
<div class="row collapse">
<h6>

View File

@ -18,6 +18,7 @@ define(function(require) {
var Locale = require('utils/locale');
var Sunstone = require('sunstone');
var Notifier = require('utils/notifier');
//Escape doublequote in a string and return it
function _escapeDoubleQuotes(string) {
@ -92,7 +93,123 @@ define(function(require) {
return template_str;
}
function _merge_templates(template_master, template_slave, advanced){
if(!advanced)
template_slave = _convert_string_to_template(template_slave);
else
template_master = _convert_string_to_template(template_master);
if((advanced && template_master) || (!advanced && template_slave)){
var template_final = {};
$.extend(true, template_final, template_slave, template_master);
return template_final;
}else{
Notifier.notifyError(Locale.tr("Advanced template malformed"));
}
return template_master;
}
// Transforms an object to an opennebula template string
function _convert_string_to_template(string_json, unshown_values) {
string_json = string_json.split("\n").join(" ");
string_json = string_json.split(" ").join(" ");
string_json = string_json.split(" ").join(" ");
var match_symbols = "=[,]"
var template_json = {};
var array_string = string_json.split(" ");
var i = 0;
var array = false;
while(i < array_string.length-1){
if(!array_string[i].match('"') && !array_string[i].match(match_symbols)){ //is key
var key = array_string[i];
if(template_json[key]){ //exists key, generate Array
if(!Array.isArray(template_json[key])){
var obj = template_json[key];
template_json[key] = [];
template_json[key].push(obj);
}
array = true;
}
else{
array = false;
}
template_json[key];
i+=1;
if(array_string[i] == "="){
i+=1;
if(array_string[i] != "["){
var value = "";
if(key == "DESCRIPTION" && array_string[i][0] == '"' && array_string[i][array_string[i].length-1] != '"'){
while (array_string[i][array_string[i].length-1] != '"' && i < array_string.length-1){
value += array_string[i] + " ";
i+=1;
}
if(!value.match("="))
value = value.split('"').join("");
else{
value = value .slice(0,-1);
value = value .slice(1);
}
if(array){
template_json[key].push(value);
}else{
template_json[key] = value;
}
i+=1;
}
else if(array_string[i].match('"')){
value = array_string[i];
if(!value.match("="))
value = value.split('"').join("");
else{
value = value .slice(0,-1);
value = value .slice(1);
}
if(array){
template_json[key].push(value);
}else{
template_json[key] = value;
}
i+=1;
}
else return false;
}else{
var obj = {}
i+=1;
while(array_string[i] != ']' && i < array_string.length-1){
var sub_key;
if(!array_string[i].match('"') && !array_string[i].match(match_symbols)){
sub_key = array_string[i];
i+=1;
if(array_string[i] == "="){
i+=1;
if(array_string[i].match('"')){
if(array_string[i][array_string[i].length-1] == ","){
array_string[i] = array_string[i].slice(0,-1);
}
var value = array_string[i];
obj[sub_key] = value;
obj[sub_key] = obj[sub_key].split('"').join("");
i+=1;
}else return false;
}else return false;
}else return false;
}
if(array){
template_json[key].push(obj);
}else{
template_json[key] = {};
template_json[key] = obj;
}
i+=1;
}
}else return false;
}else return false;
}
return template_json;
}
return {
'mergeTemplates' : _merge_templates,
'stringToTemplate': _convert_string_to_template,
'templateToString': _convert_template_to_string,
'htmlDecode': _htmlDecode,
'htmlEncode': _htmlEncode,

View File

@ -55,11 +55,13 @@ define(function(require) {
function _setup(context){
context.on("click", ".add_user_input_attr", function() {
$(".user_input_attrs tbody", context).append(RowTemplateHTML());
$(".user_input_attrs tbody", context).append(RowTemplateHTML({'idInput': UniqueId.id()}));
$('tbody label').css('cursor', 'pointer');
$("select.user_input_type", context).change();
});
$('tbody').sortable();
context.on("change", "select.user_input_type", function() {
var row = $(this).closest("tr");
@ -74,12 +76,24 @@ define(function(require) {
function _retrieve(context){
var userInputsJSON = {};
var ids = [];
var index = 0;
$('.user_input_attrs tbody tr').each(function(key, value){
ids[index] = "_" + key + "_" + $(".user_input_name", $(this)).val();
index += 1;
});
index = 0;
$(".user_input_attrs tbody tr", context).each(function() {
if ($(".user_input_name", $(this)).val()) {
var attr = {};
attr.name = $(".user_input_name", $(this)).val();
attr.mandatory = true;
if($('.user_input_mandatory', $(this)).prop('checked')){
attr.mandatory = true;
} else {
attr.mandatory = false;
}
attr.type = $(".user_input_type", $(this)).val();
attr.description = $(".user_input_description", $(this)).val();
@ -89,7 +103,6 @@ define(function(require) {
case "fixed":
attr.initial = $("."+attr.type+" input.user_input_initial", $(this)).val();
break;
case "range":
case "range-float":
var min = $("."+attr.type+" input.user_input_params_min", $(this)).val();
@ -101,10 +114,15 @@ define(function(require) {
attr.params = $("."+attr.type+" input.user_input_params", $(this)).val();
attr.initial = $("."+attr.type+" input.user_input_initial", $(this)).val();
break;
case "boolean":
attr.initial = $('.user_input_initial:checked', $(this)).val();
break;
}
userInputsJSON[attr.name] = _marshall(attr);
userInputsJSON[ids[index]] = _marshall(attr);
index += 1;
}
});
return userInputsJSON;
@ -115,28 +133,51 @@ define(function(require) {
if (userInputsJSON) {
$.each(userInputsJSON, function(key, value) {
$(".add_user_input_attr", context).trigger("click");
var trcontext = $(".user_input_attrs tbody tr", context).last();
$(".user_input_name", trcontext).val(key);
var name = "";
var len = key.split("_");
for (i = 2; i < len.length; i++){
name += (len[i] + "_");
}
name = name.slice(0,-1);
$(".user_input_name", trcontext).val(name);
var attr = _unmarshall(value);
if (templateJSON[key] != undefined){
attr.initial = templateJSON[key];
}
$(".user_input_type", trcontext).val(attr.type).change();
$(".user_input_description", trcontext).val(attr.description);
if (attr.mandatory){
$('.user_input_mandatory', trcontext).attr("checked", "checked");
} else {
$('.user_input_mandatory', trcontext).removeAttr("checked");
}
switch(attr.type){
case "number":
case "number-float":
case "fixed":
$("."+attr.type+" input.user_input_initial", trcontext).val(attr.initial);
break;
case "boolean":
if(attr.initial == "YES"){
$('input#radio_yes', trcontext).attr("checked", "checked");
$('input#radio_no', trcontext).removeAttr('checked');
}
else {
$('input#radio_yes', trcontext).removeAttr("checked");
$('input#radio_no', trcontext).attr("checked", "checked");
}
break;
case "range":
case "range-float":
var values = attr.params.split(".."); // "2..8"
@ -343,6 +384,7 @@ define(function(require) {
switch (attr.type) {
case "number":
case "number-float":
case "boolean":
case "fixed":
st += ("| |" + (attr.initial != undefined ? attr.initial : "") );
@ -605,7 +647,11 @@ define(function(require) {
}
break;
case "password":
input = '<input type="password" value="'+value+'" '+wizard_field+' '+required+'/>';
input = '<br><input type="password" value="'+value+'" '+wizard_field+' '+required+'/>';
break;
case "boolean":
input = '<br>' + Locale.tr("YES ") + '<input type="radio" name="bool_' + attr.name + '" value="YES"' + wizard_field + ' ' + required + '/>';
input += Locale.tr("NO ") + '<input type="radio" name="bool_' + attr.name + '" value="NO"' + wizard_field + ' ' + required + '/>';
break;
case "number":
case "number-float":

View File

@ -1,4 +1,4 @@
<tr>
<tr style="border-style: groove; border-width: 0.5px 0">
<td>
<label>{{tr "Name"}}
<input class="user_input_name" type="text" pattern="^\w+$"/>
@ -16,6 +16,7 @@
<option value="range"> {{tr "range"}} </option>
<option value="range-float"> {{tr "range (float)"}} </option>
<option value="list"> {{tr "list"}} </option>
<option value="boolean"> {{tr "boolean"}} </option>
</select>
</label>
</td>
@ -33,6 +34,11 @@
<input type="number" step="any" class="user_input_initial" placeholder="42.5"/>
</label>
</div>
<div class="user_input_type_right boolean">
<label>{{tr "Default value"}}</label>
<input type="radio" step="any" name="bool_{{idInput}}" class="user_input_initial" id="radio_yes" value="YES"> {{tr "YES"}}
<input type="radio" step="any" name="bool_{{idInput}}" class="user_input_initial" id="radio_no" value="NO"> {{tr "NO"}}
</div>
<div class="user_input_type_right range">
<div class="row collapse">
<div class="small-6 columns">
@ -78,6 +84,11 @@
</label>
</div>
</td>
<td>
<label>{{tr "Mandatory"}}</label>
<input checked type="checkbox" name="user_input_mandatory_{{idInput}}" class="switch input user_input_mandatory slaac" id="user_input_mandatory_{{idInput}}" hidden/>
<label class="switch-paddle" for="user_input_mandatory_{{idInput}}"></label>
</td>
<td>
<br/>
<a href="#"><i class="fa fa-times-circle remove-tab"></i></a>

View File

@ -1,4 +1,4 @@
<table class="user_input_attrs policies_table dataTable">
<table class="user_input_attrs policies_table dataTable" style="cursor: pointer;">
<thead>
<tr>
<th style="width:30%"></th>

View File

@ -16,7 +16,8 @@
"jquery": "2.2.3",
"datatables": "1.10.12",
"navigo": "2.1.1",
"sprintf": "1.0.3"
"sprintf": "1.0.3",
"jquery-ui": "^1.12.1"
},
"authors": [
"Daniel Molina <dmolina@opennebula.org>",

View File

@ -295,33 +295,42 @@ void Quotas::quota_del(QuotaType type, int uid, int gid, Template * tmpl)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Quotas::ds_del(map<int, Template *>& ds_quotas)
void Quotas::ds_del_recreate(int uid, int gid, vector<Template *>& ds_quotas)
{
Nebula& nd = Nebula::instance();
ImagePool * ipool = nd.get_ipool();
map<int, Template *>::iterator it;
vector<Template *>::iterator it;
for (it = ds_quotas.begin(); it != ds_quotas.end(); it++)
{
int image_id = it->first;
Template * tmpl = it->second;
int image_id = -1;
Template * tmpl = *it;
if ( tmpl == 0 )
bool vm_owner, img_owner;
tmpl->get("IMAGE_ID", image_id);
tmpl->get("VM_QUOTA", vm_owner);
tmpl->get("IMG_QUOTA", img_owner);
if ( img_owner )
{
continue;
Image* img = ipool->get(image_id, true);
if(img != 0)
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
img->unlock();
quota_del(DATASTORE, img_uid, img_gid, tmpl);
}
}
Image* img = ipool->get(image_id, true);
if(img != 0)
if ( vm_owner )
{
int img_uid = img->get_uid();
int img_gid = img->get_gid();
img->unlock();
quota_del(DATASTORE, img_uid, img_gid, tmpl);
quota_del(DATASTORE, uid, gid, tmpl);
}
delete tmpl;

View File

@ -734,7 +734,7 @@ int VirtualMachine::insert(SqlDB * db, string& error_str)
int ivalue;
float fvalue;
set<int> cluster_ids;
map<int, Template *> quotas;
vector<Template *> quotas;
ostringstream oss;
@ -2653,7 +2653,7 @@ int VirtualMachine::get_disk_images(string& error_str)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachine::release_disk_images(map<int, Template *>& quotas)
void VirtualMachine::release_disk_images(vector<Template *>& quotas)
{
bool image_error = (state == ACTIVE && lcm_state != EPILOG) &&
state != PENDING && state != HOLD &&

View File

@ -270,8 +270,11 @@ int VirtualMachineDisk::revert_snapshot(int snap_id)
/* -------------------------------------------------------------------------- */
void VirtualMachineDisk::delete_snapshot(int snap_id, Template **ds_quotas,
Template **vm_quotas)
Template **vm_quotas, bool& img_owner, bool& vm_owner)
{
vm_owner = false;
img_owner = false;
if ( snapshots == 0 )
{
return;
@ -294,7 +297,10 @@ void VirtualMachineDisk::delete_snapshot(int snap_id, Template **ds_quotas,
string tm_target = get_tm_target();
if (is_persistent() || tm_target != "SYSTEM")
vm_owner = tm_target == "SELF";
img_owner = is_persistent() || tm_target == "NONE";
if ( img_owner || vm_owner )
{
*ds_quotas = new Template();
@ -345,11 +351,54 @@ long long VirtualMachineDisk::system_ds_size()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
long long VirtualMachineDisk::image_ds_size()
{
long long disk_sz, snapshot_sz = 0;
string tm_target = get_tm_target();
if ( get_tm_target() != "SELF" )
{
return 0;
}
if ( vector_value("SIZE", disk_sz) != 0 )
{
return 0;
}
if ( vector_value("DISK_SNAPSHOT_TOTAL_SIZE", snapshot_sz) == 0 )
{
disk_sz += snapshot_sz;
}
return disk_sz;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
// Owner to update ds usage quotas
//
// +--------+-------------------------------------+
// |LN/CLONE| PERSISTENT | NO PERSISTENT |
// | |---------+---------+-----------------+
// | TARGET | created | quota | created | quota |
// +--------+---------+---------+-----------------+
// | SYSTEM | system | IMG | system | - |
// | SELF | image | IMG+VM | image | VM |
// | NONE | image | IMG | image | IMG |
// +----------------------------------------------+
/* -------------------------------------------------------------------------- */
void VirtualMachineDisk::resize_quotas(long long new_size, Template& ds_deltas,
Template& vm_deltas)
Template& vm_deltas, bool& do_img_owner, bool& do_vm_owner)
{
long long current_size, delta_size;
do_vm_owner = false;
do_img_owner= false;
if ( vector_value("SIZE", current_size) != 0 )
{
return;
@ -363,10 +412,13 @@ void VirtualMachineDisk::resize_quotas(long long new_size, Template& ds_deltas,
delta_size = - delta_size;
}
bool is_system = get_tm_target() == "SYSTEM";
string ds_id = vector_value("DATASTORE_ID");
string tm = get_tm_target();
do_vm_owner = !is_volatile() && tm == "SELF";
do_img_owner = !is_volatile() && (is_persistent() || tm == "NONE");
bool is_system = tm == "SYSTEM";
string ds_id = vector_value("DATASTORE_ID");
if ( !is_volatile() && ( is_persistent() || !is_system ) )
if ( do_vm_owner || do_img_owner )
{
ds_deltas.add("DATASTORE", ds_id);
ds_deltas.add("SIZE", delta_size);
@ -482,33 +534,32 @@ long long VirtualMachineDisks::system_ds_size(Template * ds_tmpl)
return disks.system_ds_size();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*
void VirtualMachineDisks::image_ds_size(bool resize_snapshot, long long system,
std::map<int, long long>& ds_size) const
void VirtualMachineDisks::image_ds_quotas(Template * tmpl,
vector<Template *>& ds_quotas)
{
int ds_id;
long long system_sz, image_sz;
VirtualMachineDisks disks(tmpl, false);
for ( disk_iterator disk = begin() ; disk != end() ; ++disk )
for (disk_iterator it = disks.begin(); it != disks.end() ; ++it)
{
(*disk)->ds_size(resize_snapshot, ds_id, image_sz, system_sz);
long long ds_size = (*it)->image_ds_size();
system += system_sz;
if ( ds_size != 0 )
{
Template * d_ds = new Template();
if ( ds_id != -1 && image_sz > 0 )
{
if (ds_size.count(ds_id) == 0)
{
ds_size[ds_id] = 0;
}
d_ds->add("DATASTORE", (*it)->vector_value("DATASTORE_ID"));
d_ds->add("SIZE", ds_size);
d_ds->add("IMAGES", 0);
ds_size[ds_id] += image_sz;
}
ds_quotas.push_back(d_ds);
}
}
}
*/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -772,7 +823,7 @@ error_common:
/* -------------------------------------------------------------------------- */
void VirtualMachineDisks::release_images(int vmid, bool image_error,
map<int, Template *>& ds_quotas)
vector<Template *>& ds_quotas)
{
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
@ -796,23 +847,16 @@ void VirtualMachineDisks::release_images(int vmid, bool image_error,
imagem->set_image_size(iid, size);
}
/* ------- Update snapshots on source image if needed ---------- */
/* ------- Update snapshots on source image if needed ----------- */
if ( (*it)->has_snapshots() )
{
imagem->set_image_snapshots(iid, *(*it)->get_snapshots());
}
/* --------- Compute space to free on image datastore ----------- */
if ( !(*it)->is_persistent() && (*it)->get_tm_target() != "SYSTEM" )
if ( (*it)->get_tm_target() == "SELF" )
{
long long delta_size = 0;
if ( size > original_size )
{
delta_size = size - original_size;
}
delta_size += (*it)->get_total_snapshot_size();
long long delta_size = size + (*it)->get_total_snapshot_size();
Template * d_ds = new Template();
@ -820,7 +864,7 @@ void VirtualMachineDisks::release_images(int vmid, bool image_error,
d_ds->add("SIZE", delta_size);
d_ds->add("IMAGES", 0);
ds_quotas.insert(pair<int, Template *>(iid, d_ds));
ds_quotas.push_back(d_ds);
}
imagem->release_image(vmid, iid, image_error);
@ -1233,7 +1277,7 @@ int VirtualMachineDisks::revert_snapshot(int id, int snap_id)
/* -------------------------------------------------------------------------- */
void VirtualMachineDisks::delete_snapshot(int disk_id, int snap_id,
Template **ds_quota, Template **vm_quota)
Template **ds_quota, Template **vm_quota,bool& img_owner, bool& vm_owner)
{
VirtualMachineDisk * disk =
static_cast<VirtualMachineDisk *>(get_attribute(disk_id));
@ -1246,14 +1290,14 @@ void VirtualMachineDisks::delete_snapshot(int disk_id, int snap_id,
return;
}
disk->delete_snapshot(snap_id, ds_quota, vm_quota);
disk->delete_snapshot(snap_id, ds_quota, vm_quota, img_owner, vm_owner);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineDisks::delete_non_persistent_snapshots(Template **vm_quotas,
map<int, Template *>& ds_quotas)
vector<Template *> &ds_quotas)
{
long long system_disk = 0;
@ -1266,7 +1310,11 @@ void VirtualMachineDisks::delete_non_persistent_snapshots(Template **vm_quotas,
continue;
}
if ((*disk)->is_persistent() || tm_target != "SYSTEM" )
bool vm_owner = tm_target == "SELF";
bool img_owner = (*disk)->is_persistent();
// Decrement DS quota on disks that do not modify the original image
if ( vm_owner || img_owner )
{
int image_id;
@ -1280,8 +1328,11 @@ void VirtualMachineDisks::delete_non_persistent_snapshots(Template **vm_quotas,
d_ds->add("DATASTORE", (*disk)->vector_value("DATASTORE_ID"));
d_ds->add("SIZE", (*disk)->get_total_snapshot_size());
d_ds->add("IMAGES", 0);
d_ds->add("IMAGE_ID", image_id);
d_ds->add("VM_QUOTA", vm_owner);
d_ds->add("IMG_QUOTA", img_owner);
ds_quotas.insert(pair<int, Template *>(image_id, d_ds));
ds_quotas.push_back(d_ds);
}
if ( tm_target == "SYSTEM" )
@ -1426,7 +1477,7 @@ int VirtualMachineDisks::get_saveas_info(int& disk_id, string& source,
/* -------------------------------------------------------------------------- */
void VirtualMachineDisks::delete_non_persistent_resizes(Template **vm_quotas,
map<int, Template *>& ds_quotas)
vector<Template *>& ds_quotas)
{
long long original_size, size, delta_size, system_disk = 0;
@ -1447,7 +1498,17 @@ void VirtualMachineDisks::delete_non_persistent_resizes(Template **vm_quotas,
delta_size = original_size - size;
if ((*disk)->is_persistent() || tm_target != "SYSTEM" )
//Quotas uses del operation to substract counters, delta needs to be > 0
if ( delta_size < 0 )
{
delta_size = - delta_size;
}
bool vm_owner = tm_target == "SELF";
bool img_owner = (*disk)->is_persistent();
// Decrement DS quota on disks that do not modify the original image
if ( vm_owner || img_owner )
{
int image_id;
@ -1461,8 +1522,11 @@ void VirtualMachineDisks::delete_non_persistent_resizes(Template **vm_quotas,
d_ds->add("DATASTORE", (*disk)->vector_value("DATASTORE_ID"));
d_ds->add("SIZE", delta_size);
d_ds->add("IMAGES", 0);
d_ds->add("IMAGE_ID", image_id);
d_ds->add("VM_QUOTA", vm_owner);
d_ds->add("IMG_QUOTA", img_owner);
ds_quotas.insert(pair<int, Template *>(image_id, d_ds));
ds_quotas.push_back(d_ds);
}
if ( tm_target == "SYSTEM" )