1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

F #1147: Permit to rename disk snapshot names in Sunstone

Author:  Abel Coronado <acoronado@opennebula.systems>
 Author: Christian González <cgonzalez@opennebula.systems>
This commit is contained in:
Abel Coronado 2018-10-11 17:01:36 +02:00 committed by Ruben S. Montero
parent c3af68655b
commit 2e410af2ce
39 changed files with 469 additions and 2 deletions

View File

@ -76,7 +76,8 @@ public:
DISK_SNAPSHOT_REVERT_ACTION = 41, // "one.vm.disksnapshotrevert"
RECOVER_ACTION = 42, // "one.vm.recover"
RETRY_ACTION = 43, // "one.vm.recover"
MONITOR_ACTION = 44 // internal, monitoring process
MONITOR_ACTION = 44, // internal, monitoring process
DISK_SNAPSHOT_RENAME_ACTION = 45 // "one.vm.disksnapshotrename"
};
static string action_to_str(VMAction action);

View File

@ -523,6 +523,28 @@ private:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class VirtualMachineDiskSnapshotRename: public RequestManagerVirtualMachine
{
public:
VirtualMachineDiskSnapshotRename():
RequestManagerVirtualMachine("one.vm.disksnapshotrename",
"Rename a disk snapshot",
"A:siiis"){
Nebula& nd = Nebula::instance();
//All VM disk snapshot operations are set to the same auth value
auth_op = nd.get_vm_auth_op(History::DISK_SNAPSHOT_RENAME_ACTION);
};
~VirtualMachineDiskSnapshotRename(){};
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class VirtualMachineUpdateConf: public RequestManagerVirtualMachine
{
public:

View File

@ -101,6 +101,12 @@ public:
*/
int active_snapshot(int id);
/**
* Rename the given snapshot by the given name
*/
int rename_snapshot(int id, const string& name, string& str_error);
/**
* Clear all the snapshots in the list
*/

View File

@ -1491,6 +1491,19 @@ public:
disks.delete_snapshot(disk_id, snap_id, ds_quotas, vm_quotas, io, vo);
}
/**
* Renames the snap_id from the list
* @param disk_id of the disk
* @param snap_id of the snapshot
* @param new_name of the snapshot
* @return 0 on success
*/
int rename_disk_snapshot(int disk_id, int snap_id, const string& new_name,
string& error_str)
{
return disks.rename_snapshot(disk_id, snap_id, new_name, error_str);
}
/**
* Deletes all the disk snapshots for non-persistent disks and for persistent
* disks in no shared system ds.

View File

@ -256,6 +256,24 @@ public:
return (snapshots != 0);
}
/**
* Renames a snapshot
*
* @param id_snap of the snapshot
* @param new_name of the snapshot
* @return 0 on success
*/
int rename_snapshot(int snap_id, const string& new_name, string& str_error)
{
if (!snapshots)
{
str_error = "The VM does not have any snapshot";
return -1;
}
return snapshots->rename_snapshot(snap_id, new_name, str_error);
}
/**
* Creates a new snapshot of the disk
* @param name a description for this snapshot
@ -740,6 +758,15 @@ public:
void delete_snapshot(int disk_id, int snap_id, Template **ds_quota,
Template **vm_quota, bool& io, bool& vo);
/**
* Renames a given snapshot
* @param disk_id of the disk
* @param snap_id of the snapshot
* @param new_name of the snapshot
* @return 0 on success
*/
int rename_snapshot(int disk_id, int snap_id, const string& new_name, string& str_error);
/**
* Deletes all the disk snapshots for non-persistent disks and for persistent
* disks in no shared system ds.

View File

@ -76,6 +76,7 @@
RECOVER_ACTION = 42
RETRY_ACTION = 43
MONITOR_ACTION = 44
DISK_SNAPSHOT_RENAME_ACTION = 45
-->
<xs:element name="ACTION" type="xs:integer"/>
<xs:element name="UID" type="xs:integer"/>

View File

@ -181,6 +181,7 @@
RECOVER_ACTION = 42
RETRY_ACTION = 43
MONITOR_ACTION = 44
DISK_SNAPSHOT_RENAME_ACTION = 45
-->
<xs:element name="ACTION" type="xs:integer"/>
<xs:element name="UID" type="xs:integer"/>

View File

@ -876,6 +876,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
States: RUNNING, POWEROFF, SUSPENDED
EOT
command :"disk-snapshot-delete", disk_snapshot_delete_desc,
:vmid, :diskid, :disk_snapshot_id do
helper.perform_action(args[0],options,"disk snapshot deleted") do |o|
@ -883,6 +884,23 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
end
disk_snapshot_rename_desc = <<-EOT.unindent
Renames a disk snapshot.
EOT
command :"disk-snapshot-rename", disk_snapshot_rename_desc,
:vmid, :diskid, :disk_snapshot_id, :new_snapshot_name do
helper.perform_action(args[0],options,"disk snapshot rename") do |o|
is_num = true if Integer(args[2]) rescue false
if !is_num
OpenNebula::Error.new("The disk snapshot ID must be an integer")
else
o.disk_snapshot_rename(args[1].to_i, args[2].to_i, args[3].to_s)
end
end
end
disk_resize_desc = <<-EOT.unindent
Resizes a VM disk. The new size should be larger than the old one.
The valid units are:

View File

@ -794,6 +794,7 @@ static int _set_vm_auth_ops(const std::string& ops_str,
ops_set.set(History::DISK_SNAPSHOT_CREATE_ACTION);
ops_set.set(History::DISK_SNAPSHOT_DELETE_ACTION);
ops_set.set(History::DISK_SNAPSHOT_REVERT_ACTION);
ops_set.set(History::DISK_SNAPSHOT_RENAME_ACTION);
}
else if ( the_op == "terminate" )
{

View File

@ -691,6 +691,12 @@ func (vm *VM) SnapshotRevert(snapID int) error {
return err
}
// DiskSnapshotRename renames a snapshot
func (vm *VM) DiskSnapshotRename(diskID, snapID int, newName string) error {
_, err := client.Call("one.vm.disksnapshotrename", vm.ID, diskID, snapID, newName)
return err
}
// Attach a new disk to the virtual machine. diskTemplate is a string containing
// a single DISK vector attribute. Syntax can be the usual attribute=value or
// XML

View File

@ -51,6 +51,7 @@ public class VirtualMachine extends PoolElement{
private static final String DISKSNAPSHOTCREATE = METHOD_PREFIX + "disksnapshotcreate";
private static final String DISKSNAPSHOTREVERT = METHOD_PREFIX + "disksnapshotrevert";
private static final String DISKSNAPSHOTDELETE = METHOD_PREFIX + "disksnapshotdelete";
private static final String DISKSNAPSHOTRENAME = METHOD_PREFIX + "disksnapshotrename";
private static final String DISKRESIZE = METHOD_PREFIX + "diskresize";
private static final String UPDATECONF = METHOD_PREFIX + "updateconf";
@ -575,6 +576,23 @@ public class VirtualMachine extends PoolElement{
return client.call(DISKSNAPSHOTDELETE, id, diskId, snapId);
}
/**
* Deletes a disk snapshot
*
* @param client XML-RPC Client.
* @param id The VM id of the target VM.
* @param diskId Id of the disk
* @param snapId Id of the snapshot
* @param new_name New name of the snapshot
* @return If an error occurs the error message contains the reason.
*/
public static OneResponse diskSnapshotRename(Client client, int id,
int diskId, int snapId, String new_name)
{
return client.call(DISKSNAPSHOTRENAME, id, diskId, snapId, new_name);
}
/**
* Resize VM disk
*

View File

@ -46,6 +46,7 @@ module OpenNebula
:disksnapshotcreate => "vm.disksnapshotcreate",
:disksnapshotrevert => "vm.disksnapshotrevert",
:disksnapshotdelete => "vm.disksnapshotdelete",
:disksnapshotrename => "vm.disksnapshotrename",
:diskresize => "vm.diskresize",
:updateconf => "vm.updateconf",
:lock => "vm.lock",
@ -211,7 +212,7 @@ module OpenNebula
disk-snapshot-create disk-snapshot-delete terminate terminate-hard
disk-resize deploy chown chmod updateconf rename resize update
snapshot-resize snapshot-delete snapshot-revert disk-saveas
disk-snapshot-revert recover retry monitor}
disk-snapshot-revert recover retry monitor disk-snapshot-rename}
EXTERNAL_IP_ATTRS = [
'GUEST_IP',
@ -651,6 +652,18 @@ module OpenNebula
return call(VM_METHODS[:disksnapshotdelete], @pe_id, disk_id, snap_id)
end
# Renames a disk snapshot
#
# @param disk_id [Integer] Id of the disk
# @param snap_id [Integer] Id of the snapshot
# @param new_name [String] New name for the snapshot
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def disk_snapshot_rename(disk_id, snap_id, new_name)
return call(VM_METHODS[:disksnapshotrename], @pe_id, disk_id, snap_id, new_name)
end
# Changes the size of a disk
#
# @param disk_id [Integer] Id of the disk

View File

@ -376,6 +376,7 @@ void RequestManager::register_xml_methods()
xmlrpc_c::methodPtr vm_dsnap_create(new VirtualMachineDiskSnapshotCreate());
xmlrpc_c::methodPtr vm_dsnap_revert(new VirtualMachineDiskSnapshotRevert());
xmlrpc_c::methodPtr vm_dsnap_delete(new VirtualMachineDiskSnapshotDelete());
xmlrpc_c::methodPtr vm_dsnap_rename(new VirtualMachineDiskSnapshotRename());
xmlrpc_c::methodPtr vm_recover(new VirtualMachineRecover());
xmlrpc_c::methodPtr vm_updateconf(new VirtualMachineUpdateConf());
xmlrpc_c::methodPtr vm_disk_resize(new VirtualMachineDiskResize());
@ -577,6 +578,7 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.vm.disksnapshotcreate", vm_dsnap_create);
RequestManagerRegistry.addMethod("one.vm.disksnapshotrevert", vm_dsnap_revert);
RequestManagerRegistry.addMethod("one.vm.disksnapshotdelete", vm_dsnap_delete);
RequestManagerRegistry.addMethod("one.vm.disksnapshotrename", vm_dsnap_rename);
RequestManagerRegistry.addMethod("one.vm.recover", vm_recover);
RequestManagerRegistry.addMethod("one.vm.updateconf", vm_updateconf);
RequestManagerRegistry.addMethod("one.vm.lock", vm_lock);

View File

@ -2978,6 +2978,72 @@ void VirtualMachineDiskSnapshotDelete::request_execute(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineDiskSnapshotRename::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
VirtualMachine * vm;
ostringstream oss;
const VirtualMachineDisk * disk;
int rc;
int id = xmlrpc_c::value_int(paramList.getInt(1));
int did = xmlrpc_c::value_int(paramList.getInt(2));
int snap_id = xmlrpc_c::value_int(paramList.getInt(3));
string new_snap_name = xmlrpc_c::value_string(paramList.getString(4));
if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false )
{
return;
}
if ((vm = get_vm(id, att)) == 0)
{
oss << "Could not rename the snapshot for VM " << id
<< ", VM does not exist";
att.resp_msg = oss.str();
return;
}
disk = (const_cast<const VirtualMachine *>(vm))->get_disk(did);
if (disk == 0)
{
att.resp_msg = "VM disk does not exist";
failure_response(ACTION, att);
vm->unlock();
return;
}
rc = vm->rename_disk_snapshot(did, snap_id, new_snap_name, att.resp_msg);
if ( rc != 0 )
{
failure_response(ACTION, att);
vm->unlock();
return;
}
success_response(id, att);
pool->update(vm);
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineUpdateConf::request_execute(
xmlrpc_c::paramList const& paramList, RequestAttributes& att)
{

View File

@ -395,6 +395,7 @@ tabs:
VM.snapshot_delete: true
VM.disk_snapshot_create: true
VM.disk_snapshot_revert: true
VM.disk_snapshot_rename: true
VM.disk_snapshot_delete: true
VM.resched: true
VM.unresched: true

View File

@ -84,6 +84,7 @@ tabs:
VM.snapshot_delete: true
VM.disk_snapshot_create: true
VM.disk_snapshot_revert: true
VM.disk_snapshot_rename: true
VM.disk_snapshot_delete: true
VM.save_as_template: true
VM.lockU: true

View File

@ -394,6 +394,7 @@ tabs:
VM.snapshot_delete: false
VM.disk_snapshot_create: false
VM.disk_snapshot_revert: false
VM.disk_snapshot_rename: false
VM.disk_snapshot_delete: false
VM.resched: false
VM.unresched: false

View File

@ -387,6 +387,7 @@ tabs:
VM.snapshot_delete: true
VM.disk_snapshot_create: true
VM.disk_snapshot_revert: true
VM.disk_snapshot_rename: true
VM.disk_snapshot_delete: true
VM.resched: false
VM.unresched: false

View File

@ -395,6 +395,7 @@ tabs:
VM.snapshot_delete: true
VM.disk_snapshot_create: true
VM.disk_snapshot_revert: true
VM.disk_snapshot_rename: true
VM.disk_snapshot_delete: true
VM.resched: true
VM.unresched: true

View File

@ -84,6 +84,7 @@ tabs:
VM.snapshot_delete: true
VM.disk_snapshot_create: true
VM.disk_snapshot_revert: true
VM.disk_snapshot_rename: true
VM.disk_snapshot_delete: true
VM.save_as_template: true
VM.lockU: true

View File

@ -394,6 +394,7 @@ tabs:
VM.snapshot_delete: false
VM.disk_snapshot_create: false
VM.disk_snapshot_revert: false
VM.disk_snapshot_rename: false
VM.disk_snapshot_delete: false
VM.resched: false
VM.unresched: false

View File

@ -387,6 +387,7 @@ tabs:
VM.snapshot_delete: true
VM.disk_snapshot_create: true
VM.disk_snapshot_revert: true
VM.disk_snapshot_rename: true
VM.disk_snapshot_delete: true
VM.resched: false
VM.unresched: false

View File

@ -393,6 +393,7 @@ tabs:
VM.snapshot_delete: true
VM.disk_snapshot_create: false
VM.disk_snapshot_revert: false
VM.disk_snapshot_rename: false
VM.disk_snapshot_delete: false
VM.resched: true
VM.unresched: true

View File

@ -85,6 +85,7 @@ tabs:
VM.snapshot_delete: true
VM.disk_snapshot_create: true
VM.disk_snapshot_revert: true
VM.disk_snapshot_rename: true
VM.disk_snapshot_delete: true
VM.save_as_template: true
VM.lockU: true

View File

@ -394,6 +394,7 @@ tabs:
VM.snapshot_delete: false
VM.disk_snapshot_create: false
VM.disk_snapshot_revert: false
VM.disk_snapshot_rename: false
VM.disk_snapshot_delete: false
VM.resched: false
VM.unresched: false

View File

@ -387,6 +387,7 @@ tabs:
VM.snapshot_delete: true
VM.disk_snapshot_create: true
VM.disk_snapshot_revert: true
VM.disk_snapshot_rename: true
VM.disk_snapshot_delete: true
VM.resched: false
VM.unresched: false

View File

@ -57,6 +57,7 @@ module OpenNebulaJSON
when "snapshot_delete" then self.snapshot_delete(action_hash['params'])
when "disk_snapshot_create" then self.disk_snapshot_create(action_hash['params'])
when "disk_snapshot_revert" then self.disk_snapshot_revert(action_hash['params'])
when "disk_snapshot_rename" then self.disk_snapshot_rename(action_hash['params'])
when "disk_snapshot_delete" then self.disk_snapshot_delete(action_hash['params'])
when "terminate" then self.terminate(action_hash['params'])
when "reboot" then self.reboot(action_hash['params'])
@ -139,6 +140,10 @@ module OpenNebulaJSON
super(params['disk_id'].to_i, params['snapshot_id'].to_i)
end
def disk_snapshot_rename(params=Hash.new)
super(params['disk_id'].to_i, params['snapshot_id'].to_i, params['new_name'])
end
def disk_snapshot_delete(params=Hash.new)
super(params['disk_id'].to_i, params['snapshot_id'].to_i)
end

View File

@ -471,6 +471,10 @@ define(function(require) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "disk_snapshot_revert", action_obj);
},
"disk_snapshot_rename": function(params) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "disk_snapshot_rename", action_obj);
},
"disk_snapshot_delete": function(params) {
var action_obj = params.data.extra_param;
OpenNebulaAction.simple_action(params, RESOURCE, "disk_snapshot_delete", action_obj);

View File

@ -736,6 +736,7 @@ define(function(require) {
require("./vms-tab/dialogs/attach-disk"),
require("./vms-tab/dialogs/disk-snapshot"),
require("./vms-tab/dialogs/disk-saveas"),
require("./vms-tab/dialogs/disk-snapshot-rename"),
require("./vms-tab/dialogs/attach-nic"),
require("./vms-tab/dialogs/revert"),
require("./vms-tab/dialogs/snapshot"),

View File

@ -30,6 +30,7 @@ define(function(require) {
require('./vms-tab/dialogs/attach-disk'),
require('./vms-tab/dialogs/disk-snapshot'),
require('./vms-tab/dialogs/disk-saveas'),
require('./vms-tab/dialogs/disk-snapshot-rename'),
require('./vms-tab/dialogs/disk-resize'),
require('./vms-tab/dialogs/attach-nic'),
require('./vms-tab/dialogs/snapshot'),

View File

@ -98,6 +98,7 @@ define(function(require) {
"VM.snapshot_delete": _commonActions.singleAction('snapshot_delete'),
"VM.disk_snapshot_create": _commonActions.singleAction('disk_snapshot_create'),
"VM.disk_snapshot_revert": _commonActions.singleAction('disk_snapshot_revert'),
"VM.disk_snapshot_rename": _commonActions.singleAction('disk_snapshot_rename'),
"VM.disk_snapshot_delete": _commonActions.singleAction('disk_snapshot_delete'),
"VM.disk_saveas" : _commonActions.singleAction('disk_saveas'),

View File

@ -0,0 +1,108 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2018, 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!./disk-snapshot-rename/html');
var Sunstone = require('sunstone');
var Tips = require('utils/tips');
/*
CONSTANTS
*/
var DIALOG_ID = require('./disk-snapshot-rename/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.setParams = _setParams;
return Dialog;
/*
FUNCTION DEFINITIONS
*/
function _html() {
return TemplateHTML({
'dialogId': this.dialogId
});
}
function _setup(context) {
var that = this;
$('#' + DIALOG_ID + 'Form', context).submit(function() {
var new_name = $('#snapshot_new_name', this).val();
var obj = {
"disk_id" : that.diskId,
"new_name": new_name,
"snapshot_id": that.snapshotId,
};
Sunstone.runAction('VM.disk_snapshot_rename', that.element.ID, obj);
Sunstone.getDialog(DIALOG_ID).hide();
Sunstone.getDialog(DIALOG_ID).reset();
return false;
});
return false;
}
function _onShow(context) {
this.setNames( {tabId: TAB_ID} );
$("#disk_id", context).val(this.diskId);
$("#snapshot_id", context).val(this.snapshotId);
$("#disk_rename", context).focus();
return false;
}
/**
* @param {object} params
* - params.element : VM element
* - params.diskId : Disk ID to save as
* - params.snapshotId : Disk snapshot ID to save as. Can be undefined
*/
function _setParams(params) {
this.element = params.element;
this.diskId = params.diskId;
this.snapshotId = -1;
if(params.snapshotId){
this.snapshotId = params.snapshotId;
}
}
});

View File

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

View File

@ -0,0 +1,50 @@
{{! -------------------------------------------------------------------------- }}
{{! Copyright 2002-2018, 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">
<div class="large-12 columns">
<h3 class="subheader" id="">{{tr "Rename"}}</h3>
</div>
</div>
<div class="confirm-resources-header"></div>
<div class="reveal-body">
<form id="{{dialogId}}Form" action="">
<div class="row">
<div class="large-6 columns">
<label for="disk_id">{{tr "Disk ID"}}</label>
<input style="border-style: inset; background-color: lightgrey" type="text" name="disk_id" id="disk_id" disabled/>
</div>
<div class="large-6 columns snapshot_id_row">
<label for="snapshot_id">{{tr "Snapshot ID"}}</label>
<input style="border-style: inset; background-color: lightgrey" type="text" name="snapshot_id" id="snapshot_id" disabled/>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<label for="snapshot_new_name">{{tr "New name"}}</label>
<input type="text" name="snapshot_new_name" id="snapshot_new_name" />
</div>
</div>
<div class="form_buttons">
<button class="button radius right success" type="submit">{{tr "Rename"}}</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

@ -43,6 +43,7 @@ define(function(require) {
var ATTACH_DISK_DIALOG_ID = require('../dialogs/attach-disk/dialogId');
var DISK_SNAPSHOT_DIALOG_ID = require('../dialogs/disk-snapshot/dialogId');
var DISK_SAVEAS_DIALOG_ID = require('../dialogs/disk-saveas/dialogId');
var DISK_SNAPSHOT_RENAME_DIALOG_ID = require('../dialogs/disk-snapshot-rename/dialogId');
var CONFIRM_DIALOG_ID = require('utils/dialogs/generic-confirm/dialogId');
var DISK_RESIZE_DIALOG_ID = require('../dialogs/disk-resize/dialogId');
var RESOURCE = "VM"
@ -524,10 +525,12 @@ define(function(require) {
// Enable/disable buttons
if ($(this).is(":checked")) {
$(".disk_snapshot_saveas", snapshotsSection).prop('disabled', false);
$(".disk_snapshot_rename", snapshotsSection).prop('disabled', false);
$(".disk_snapshot_revert", snapshotsSection).prop('disabled', false);
$(".disk_snapshot_delete", snapshotsSection).prop('disabled', false);
} else {
$(".disk_snapshot_saveas", snapshotsSection).prop('disabled', true);
$(".disk_snapshot_rename", snapshotsSection).prop('disabled', true);
$(".disk_snapshot_revert", snapshotsSection).prop('disabled', true);
$(".disk_snapshot_delete", snapshotsSection).prop('disabled', true);
}
@ -554,6 +557,27 @@ define(function(require) {
});
}
if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_rename")) {
context.off('click', '.disk_snapshot_rename');
context.on('click', '.disk_snapshot_rename', function() {
var snapshotsSection = $(this).closest('.snapshots');
var disk_id = snapshotsSection.attr('disk_id');
var snapshot_id = $(".snapshot_check_item:checked", snapshotsSection).attr('snapshot_id');
var dialog = Sunstone.getDialog(DISK_SNAPSHOT_RENAME_DIALOG_ID);
dialog.setParams(
{ element: that.element,
diskId: disk_id,
snapshotId: snapshot_id
});
dialog.reset();
dialog.show();
return false;
});
}
if (Config.isTabActionEnabled("vms-tab", "VM.disk_snapshot_revert")) {
context.off('click', '.disk_snapshot_revert');
context.on('click', '.disk_snapshot_revert', function() {

View File

@ -22,6 +22,11 @@
<span class="fas fa-save fa-fw"></span>{{tr "Save as"}}
</button>
{{/isTabActionEnabled}}
{{#isTabActionEnabled "vms-tab" "VM.disk_snapshot_rename"}}
<button class="disk_snapshot_rename button secondary small radius" disabled="disabled">
<span class="fas fa-edit fa-fw"></span>{{tr "Rename"}}
</button>
{{/isTabActionEnabled}}
{{#isTabActionEnabled "vms-tab" "VM.disk_snapshot_revert"}}
<button class="disk_snapshot_revert button secondary small radius" disabled="disabled">
<span class="fas fa-reply fa-fw"></span>{{tr "Revert"}}

View File

@ -512,6 +512,9 @@ string History::action_to_str(VMAction action)
case DISK_SNAPSHOT_DELETE_ACTION:
st = "disk-snapshot-delete";
break;
case DISK_SNAPSHOT_RENAME_ACTION:
st = "disk-snapshot-rename";
break;
case DISK_RESIZE_ACTION:
st = "disk-resize";
break;
@ -670,6 +673,10 @@ int History::action_from_str(const string& st, VMAction& action)
{
action = DISK_SNAPSHOT_DELETE_ACTION;
}
else if (st == "disk-snapshot-rename")
{
action = DISK_SNAPSHOT_RENAME_ACTION;
}
else if (st == "disk-resize")
{
action = DISK_RESIZE_ACTION;

View File

@ -274,6 +274,24 @@ int Snapshots::active_snapshot(int id)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Snapshots::rename_snapshot(int id, const string& name, string& str_error)
{
VectorAttribute * snapshot = get_snapshot(id);
if (snapshot == 0)
{
str_error = "Snapshot does not exist";
return -1;
}
snapshot->replace("NAME", name);
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
const VectorAttribute * Snapshots::get_snapshot(int id) const
{
map<int, VectorAttribute *>::const_iterator it;

View File

@ -1403,6 +1403,23 @@ void VirtualMachineDisks::delete_snapshot(int disk_id, int snap_id,
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachineDisks::rename_snapshot(int disk_id, int snap_id, const string& new_name,
string& error_str)
{
VirtualMachineDisk * disk = get_disk(disk_id);
if (disk == 0)
{
error_str = "VM disk does not exist";
return -1;
}
return disk->rename_snapshot(snap_id, new_name, error_str);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineDisks::delete_non_persistent_snapshots(Template **vm_quotas,
vector<Template *> &ds_quotas)
{