diff --git a/include/History.h b/include/History.h index 63c713c1e6..d5e6bcc43e 100644 --- a/include/History.h +++ b/include/History.h @@ -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); diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 8ce375420f..ef864da558 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -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: diff --git a/include/Snapshots.h b/include/Snapshots.h index a17339bbc2..6166a57470 100644 --- a/include/Snapshots.h +++ b/include/Snapshots.h @@ -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 */ diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 9f382bbbbe..588279955b 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -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. diff --git a/include/VirtualMachineDisk.h b/include/VirtualMachineDisk.h index 120877d01b..f8cbc66fd5 100644 --- a/include/VirtualMachineDisk.h +++ b/include/VirtualMachineDisk.h @@ -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. diff --git a/share/doc/xsd/acct.xsd b/share/doc/xsd/acct.xsd index 8fee77f6e1..8f45cf13e5 100644 --- a/share/doc/xsd/acct.xsd +++ b/share/doc/xsd/acct.xsd @@ -76,6 +76,7 @@ RECOVER_ACTION = 42 RETRY_ACTION = 43 MONITOR_ACTION = 44 + DISK_SNAPSHOT_RENAME_ACTION = 45 --> diff --git a/share/doc/xsd/vm.xsd b/share/doc/xsd/vm.xsd index a2d980da68..9c9f5979e0 100644 --- a/share/doc/xsd/vm.xsd +++ b/share/doc/xsd/vm.xsd @@ -181,6 +181,7 @@ RECOVER_ACTION = 42 RETRY_ACTION = 43 MONITOR_ACTION = 44 + DISK_SNAPSHOT_RENAME_ACTION = 45 --> diff --git a/src/cli/onevm b/src/cli/onevm index c295f8efba..04e9060118 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -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: diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index d4034aee28..415b093610 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -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" ) { diff --git a/src/oca/go/src/goca/vm.go b/src/oca/go/src/goca/vm.go index 174d0b369b..81ba09770d 100644 --- a/src/oca/go/src/goca/vm.go +++ b/src/oca/go/src/goca/vm.go @@ -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 diff --git a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java index 0ad4a3b9d1..e50f50203e 100644 --- a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java +++ b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java @@ -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 * diff --git a/src/oca/ruby/opennebula/virtual_machine.rb b/src/oca/ruby/opennebula/virtual_machine.rb index dc2991c886..d927b0bfc7 100644 --- a/src/oca/ruby/opennebula/virtual_machine.rb +++ b/src/oca/ruby/opennebula/virtual_machine.rb @@ -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 diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 068d601580..326144a075 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -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); diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 3b1673b2dc..e2f049007c 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -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(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) { diff --git a/src/sunstone/etc/sunstone-views/kvm/admin.yaml b/src/sunstone/etc/sunstone-views/kvm/admin.yaml index 3f12a0beab..d051cedc92 100644 --- a/src/sunstone/etc/sunstone-views/kvm/admin.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/admin.yaml @@ -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 diff --git a/src/sunstone/etc/sunstone-views/kvm/cloud.yaml b/src/sunstone/etc/sunstone-views/kvm/cloud.yaml index ad0c760fe5..35df83c14d 100644 --- a/src/sunstone/etc/sunstone-views/kvm/cloud.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/cloud.yaml @@ -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 diff --git a/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml b/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml index 0821c8c532..aa895cabc8 100644 --- a/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/groupadmin.yaml @@ -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 diff --git a/src/sunstone/etc/sunstone-views/kvm/user.yaml b/src/sunstone/etc/sunstone-views/kvm/user.yaml index 2cd4d51446..23d7165d89 100644 --- a/src/sunstone/etc/sunstone-views/kvm/user.yaml +++ b/src/sunstone/etc/sunstone-views/kvm/user.yaml @@ -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 diff --git a/src/sunstone/etc/sunstone-views/mixed/admin.yaml b/src/sunstone/etc/sunstone-views/mixed/admin.yaml index 441f17dbe2..e7500c2277 100644 --- a/src/sunstone/etc/sunstone-views/mixed/admin.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/admin.yaml @@ -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 diff --git a/src/sunstone/etc/sunstone-views/mixed/cloud.yaml b/src/sunstone/etc/sunstone-views/mixed/cloud.yaml index ad0c760fe5..35df83c14d 100644 --- a/src/sunstone/etc/sunstone-views/mixed/cloud.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/cloud.yaml @@ -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 diff --git a/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml b/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml index 0821c8c532..aa895cabc8 100644 --- a/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/groupadmin.yaml @@ -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 diff --git a/src/sunstone/etc/sunstone-views/mixed/user.yaml b/src/sunstone/etc/sunstone-views/mixed/user.yaml index 2cd4d51446..23d7165d89 100644 --- a/src/sunstone/etc/sunstone-views/mixed/user.yaml +++ b/src/sunstone/etc/sunstone-views/mixed/user.yaml @@ -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 diff --git a/src/sunstone/etc/sunstone-views/vcenter/admin.yaml b/src/sunstone/etc/sunstone-views/vcenter/admin.yaml index d178ab2265..800e04560d 100644 --- a/src/sunstone/etc/sunstone-views/vcenter/admin.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter/admin.yaml @@ -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 diff --git a/src/sunstone/etc/sunstone-views/vcenter/cloud.yaml b/src/sunstone/etc/sunstone-views/vcenter/cloud.yaml index 1bbf4a7e06..2d40b8e3ec 100644 --- a/src/sunstone/etc/sunstone-views/vcenter/cloud.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter/cloud.yaml @@ -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 diff --git a/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml b/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml index 8c8fed6b86..4b9c45e861 100644 --- a/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter/groupadmin.yaml @@ -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 diff --git a/src/sunstone/etc/sunstone-views/vcenter/user.yaml b/src/sunstone/etc/sunstone-views/vcenter/user.yaml index 2cd4d51446..23d7165d89 100644 --- a/src/sunstone/etc/sunstone-views/vcenter/user.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter/user.yaml @@ -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 diff --git a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb index aeee8750ed..7f54955db5 100644 --- a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb @@ -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 diff --git a/src/sunstone/public/app/opennebula/vm.js b/src/sunstone/public/app/opennebula/vm.js index 5b01a885d0..b807148ea2 100644 --- a/src/sunstone/public/app/opennebula/vm.js +++ b/src/sunstone/public/app/opennebula/vm.js @@ -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); diff --git a/src/sunstone/public/app/tabs/provision-tab.js b/src/sunstone/public/app/tabs/provision-tab.js index d471d629b8..77e589a382 100644 --- a/src/sunstone/public/app/tabs/provision-tab.js +++ b/src/sunstone/public/app/tabs/provision-tab.js @@ -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"), diff --git a/src/sunstone/public/app/tabs/vms-tab.js b/src/sunstone/public/app/tabs/vms-tab.js index ae247d9c7f..b8c6524fa0 100644 --- a/src/sunstone/public/app/tabs/vms-tab.js +++ b/src/sunstone/public/app/tabs/vms-tab.js @@ -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'), diff --git a/src/sunstone/public/app/tabs/vms-tab/actions.js b/src/sunstone/public/app/tabs/vms-tab/actions.js index 049554064f..20ff661c35 100644 --- a/src/sunstone/public/app/tabs/vms-tab/actions.js +++ b/src/sunstone/public/app/tabs/vms-tab/actions.js @@ -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'), diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/disk-snapshot-rename.js b/src/sunstone/public/app/tabs/vms-tab/dialogs/disk-snapshot-rename.js new file mode 100644 index 0000000000..f2526a4fa2 --- /dev/null +++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/disk-snapshot-rename.js @@ -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; + } + } + }); diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/disk-snapshot-rename/dialogId.js b/src/sunstone/public/app/tabs/vms-tab/dialogs/disk-snapshot-rename/dialogId.js new file mode 100644 index 0000000000..2a7a917f69 --- /dev/null +++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/disk-snapshot-rename/dialogId.js @@ -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'; +}); diff --git a/src/sunstone/public/app/tabs/vms-tab/dialogs/disk-snapshot-rename/html.hbs b/src/sunstone/public/app/tabs/vms-tab/dialogs/disk-snapshot-rename/html.hbs new file mode 100644 index 0000000000..9227fc0358 --- /dev/null +++ b/src/sunstone/public/app/tabs/vms-tab/dialogs/disk-snapshot-rename/html.hbs @@ -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. }} +{{! -------------------------------------------------------------------------- }} + + + + + {{tr "Rename"}} + + + + + + + + {{tr "Disk ID"}} + + + + {{tr "Snapshot ID"}} + + + + + + {{tr "New name"}} + + + + + {{tr "Rename"}} + + + × + + + + diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/storage.js b/src/sunstone/public/app/tabs/vms-tab/panels/storage.js index 93b3418d21..9ae11238f6 100644 --- a/src/sunstone/public/app/tabs/vms-tab/panels/storage.js +++ b/src/sunstone/public/app/tabs/vms-tab/panels/storage.js @@ -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() { diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/storage/disk-details.hbs b/src/sunstone/public/app/tabs/vms-tab/panels/storage/disk-details.hbs index 741a325ff2..211865b388 100644 --- a/src/sunstone/public/app/tabs/vms-tab/panels/storage/disk-details.hbs +++ b/src/sunstone/public/app/tabs/vms-tab/panels/storage/disk-details.hbs @@ -22,6 +22,11 @@ {{tr "Save as"}} {{/isTabActionEnabled}} + {{#isTabActionEnabled "vms-tab" "VM.disk_snapshot_rename"}} + + {{tr "Rename"}} + + {{/isTabActionEnabled}} {{#isTabActionEnabled "vms-tab" "VM.disk_snapshot_revert"}} {{tr "Revert"}} diff --git a/src/vm/History.cc b/src/vm/History.cc index 455e5f5e13..70b7592afb 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -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; diff --git a/src/vm/Snapshots.cc b/src/vm/Snapshots.cc index c23cc65129..5697a00809 100644 --- a/src/vm/Snapshots.cc +++ b/src/vm/Snapshots.cc @@ -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::const_iterator it; diff --git a/src/vm/VirtualMachineDisk.cc b/src/vm/VirtualMachineDisk.cc index 42b4a61d1c..d9b66075b8 100644 --- a/src/vm/VirtualMachineDisk.cc +++ b/src/vm/VirtualMachineDisk.cc @@ -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 &ds_quotas) {