diff --git a/include/DispatchManager.h b/include/DispatchManager.h index 54631501ff..4eb2a7eb3e 100644 --- a/include/DispatchManager.h +++ b/include/DispatchManager.h @@ -46,6 +46,7 @@ public: { SUSPEND_SUCCESS,/**< Send by LCM when a VM is suspended*/ STOP_SUCCESS, /**< Send by LCM when a VM is stopped*/ + POWEROFF_SUCCESS, /**< Send by LCM when a VM is powered off */ DONE, /**< Send by LCM when a VM is shut down*/ FAILED, /**< Send by LCM when one of the execution steps fails*/ RESUBMIT, /**< Send by LCM when a VM is ready for resubmission*/ @@ -129,6 +130,15 @@ public: int shutdown ( int vid); + /** + * Powers off a VM. + * @param vid VirtualMachine identification + * @return 0 on success, -1 if the VM does not exits or -2 if the VM is + * in a wrong a state + */ + int poweroff ( + int vid); + /** * Holds a VM. * @param vid VirtualMachine identification @@ -317,6 +327,8 @@ private: void stop_success_action(int vid); + void poweroff_success_action(int vid); + void done_action(int vid); void failed_action(int vid); diff --git a/include/LifeCycleManager.h b/include/LifeCycleManager.h index 55664b63ca..5c280618aa 100644 --- a/include/LifeCycleManager.h +++ b/include/LifeCycleManager.h @@ -70,6 +70,7 @@ public: MIGRATE, /**< Sent by the DM to migrate a VM to other host */ LIVE_MIGRATE, /**< Sent by the DM to live-migrate a VM */ SHUTDOWN, /**< Sent by the DM to shutdown a running VM */ + POWEROFF, /**< Sent by the DM to power off a running VM */ RESTART, /**< Sent by the DM to restart a deployed VM */ DELETE, /**< Sent by the DM to delete a VM */ CLEAN, /**< Sent by the DM to cleanup a VM for resubmission*/ @@ -202,6 +203,8 @@ private: void shutdown_action(int vid); + void poweroff_action(int vid); + void failure_action(VirtualMachine * vm); void restart_action(int vid); diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 8902f58913..5fe8533b5d 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -56,7 +56,8 @@ public: STOPPED = 4, SUSPENDED = 5, DONE = 6, - FAILED = 7 + FAILED = 7, + POWEROFF = 8 }; /** @@ -81,7 +82,8 @@ public: FAILURE = 14, CLEANUP = 15, UNKNOWN = 16, - HOTPLUG = 17 + HOTPLUG = 17, + SHUTDOWN_POWEROFF = 18 }; // ------------------------------------------------------------------------- diff --git a/share/doc/states/states-complete.dot b/share/doc/states/states-complete.dot index 7f51deeba9..c1e01b4be2 100644 --- a/share/doc/states/states-complete.dot +++ b/share/doc/states/states-complete.dot @@ -24,7 +24,7 @@ digraph OpenNebula { color="white" } subgraph { rank = max; suspended; done; failure; - stopped;color="white" } + stopped; poweroff; color="white" } # create user -> pending [label="create"]; @@ -42,6 +42,10 @@ digraph OpenNebula { shutdown -> epilog [style="dashed"]; epilog -> done [style="dashed"]; +# poweroff + running -> shutdown_poweroff [label="poweroff"]; + shutdown_poweroff -> poweroff [style="dashed"]; + # livemigrate running -> migrate [label="livemigrate"]; migrate -> running [style="dashed"]; @@ -80,6 +84,7 @@ digraph OpenNebula { # restart unknown -> boot [label="restart"]; boot -> boot [label="restart"]; + poweroff -> boot [label="restart"]; # reboot, reset running -> running [label="reboot / reset"]; diff --git a/share/doc/states/states-simple.dot b/share/doc/states/states-simple.dot index 75f6801bc7..6a4b3aa517 100644 --- a/share/doc/states/states-simple.dot +++ b/share/doc/states/states-simple.dot @@ -23,7 +23,7 @@ digraph OpenNebula { subgraph { rank = same; prolog; boot; color="white" } subgraph { rank = same; migrate; save; shutdown; unknown; hotplug; color="white" } - subgraph { rank = max; suspended; done; failure; stopped; color="white" } + subgraph { rank = max; suspended; done; failure; stopped; poweroff; color="white" } # create user -> pending [label="create"]; @@ -35,9 +35,13 @@ digraph OpenNebula { # shutdown running -> shutdown [label="shutdown"]; - shutdown -> epilog [style="dashed"]; + shutdown -> epilog [label="shutdown", style="dashed"]; epilog -> done [style="dashed"]; +# poweroff + running -> shutdown [label="poweroff"]; + shutdown -> poweroff [label="poweroff", style="dashed"]; + # livemigrate running -> migrate [label="livemigrate"]; migrate -> running [label="livemigrate", style="dashed"]; @@ -75,6 +79,7 @@ digraph OpenNebula { # restart unknown -> boot [label="restart"]; boot -> boot [label="restart"]; + poweroff -> boot [label="restart"]; # reboot, reset running -> running [label="reboot / reset"]; diff --git a/src/cli/onevm b/src/cli/onevm index 082bc6ac97..4f95c39a8b 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -183,7 +183,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do end shutdown_desc = <<-EOT.unindent - Shuts down the given VM. + Shuts down the given VM. The VM life cycle will end. States: RUNNING EOT @@ -194,6 +194,19 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + poweroff_desc = <<-EOT.unindent + Powers off the given VM. The VM will remain in the poweroff state, and + can be powered on with the 'onevm restart' command. + + States: RUNNING + EOT + + command :poweroff, poweroff_desc, [:range,:vmid_list] do + helper.perform_actions(args[0],options,"shutting down") do |vm| + vm.poweroff + end + end + reboot_desc = <<-EOT.unindent Reboots the given VM, this is equivalent to execute the reboot command from the VM console. @@ -267,9 +280,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do end restart_desc = <<-EOT.unindent - Forces a re-deployment of the given VM, issuing a boot action. + Boots the given VM. - States: UNKNOWN, BOOT + States: UNKNOWN, BOOT, POWEROFF EOT command :restart, restart_desc, [:range,:vmid_list] do diff --git a/src/cloud/occi/lib/OCCIServer.rb b/src/cloud/occi/lib/OCCIServer.rb index 9c7ec17a92..ff68eb5fc9 100644 --- a/src/cloud/occi/lib/OCCIServer.rb +++ b/src/cloud/occi/lib/OCCIServer.rb @@ -58,7 +58,7 @@ class OCCIServer < CloudServer if config[:ssl_server] @base_url=config[:ssl_server] else - @base_url="http://#{config[:server]}:#{config[:port]}" + @base_url="http://#{config[:host]}:#{config[:port]}" end @client = client diff --git a/src/cloud/occi/lib/VirtualMachineOCCI.rb b/src/cloud/occi/lib/VirtualMachineOCCI.rb index eb8db6d926..0af7e05e2c 100644 --- a/src/cloud/occi/lib/VirtualMachineOCCI.rb +++ b/src/cloud/occi/lib/VirtualMachineOCCI.rb @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # -------------------------------------------------------------------------- # # Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # # # @@ -72,6 +73,9 @@ class VirtualMachineOCCI < VirtualMachine "REBOOT" => { :from => ["ACTIVE"], :action => :reboot}, "RESET" => { :from => ["ACTIVE"], :action => :reset}, "SHUTDOWN" => { :from => ["ACTIVE"], :action => :shutdown}, + "RESTART" => { :from => ["ACTIVE"], :action => :restart}, + "RESUBMIT" => { :from => ["ACTIVE", "FAILED"], :action => :resubmit}, + "POWEROFF" => { :from => ["ACTIVE"], :action => :poweroff}, "DONE" => { :from => VM_STATE, :action => :finalize} } diff --git a/src/cloud/occi/lib/ui/public/js/occi.js b/src/cloud/occi/lib/ui/public/js/occi.js index bdceef2429..8c4780455d 100644 --- a/src/cloud/occi/lib/ui/public/js/occi.js +++ b/src/cloud/occi/lib/ui/public/js/occi.js @@ -466,6 +466,18 @@ var OCCI = { params.data.body = { state : "RESUME" }; OCCI.Action.update(params,OCCI.VM.resource,"resume"); }, + "restart": function(params){ + params.data.body = { state : "RESTART" }; + OCCI.Action.update(params,OCCI.VM.resource,"restart"); + }, + "poweroff": function(params){ + params.data.body = { state : "POWEROFF" }; + OCCI.Action.update(params,OCCI.VM.resource,"poweroff"); + }, + "resubmit": function(params){ + params.data.body = { state : "RESUBMIT" }; + OCCI.Action.update(params,OCCI.VM.resource,"resubmit"); + }, "done": function(params){ params.data.body = { state : "DONE" }; OCCI.Action.update(params,OCCI.VM.resource,"done"); diff --git a/src/cloud/occi/lib/ui/public/js/plugins/compute.js b/src/cloud/occi/lib/ui/public/js/plugins/compute.js index ed11ac8e09..d4324aeedd 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -291,6 +291,33 @@ var vm_actions = { }, error: onError, notify: true + }, + + "VM.restart" : { + type: "multiple", + call: OCCI.VM.restart, + callback: updateVMachineElement, + elements: vmElements, + error: onError, + notify: true + }, + + "VM.resubmit" : { + type: "multiple", + call: OCCI.VM.resubmit, + callback: updateVMachineElement, + elements: vmElements, + error: onError, + notify: true + }, + + "VM.poweroff" : { + type: "multiple", + call: OCCI.VM.poweroff, + callback: updateVMachineElement, + elements: vmElements, + error: onError, + notify: true } /* @@ -363,6 +390,21 @@ var vm_buttons = { text: tr("Reset"), tip: "This will perform a hard reset on selected VMs" }, + "VM.restart" : { + type: "confirm", + text: tr("Restart"), + tip: tr("This will redeploy selected VMs") + }, + "VM.resubmit" : { + type: "confirm", + text: tr("Resubmit"), + tip: tr("This will resubmits VMs to PENDING state") + }, + "VM.poweroff" : { + type : "confirm", + text: tr("Power Off"), + tip: tr("This will send a power off signal to running VMs. They can be restarted later.") + }, "VM.cancel" : { type: "confirm", text: tr("Cancel"), @@ -513,6 +555,7 @@ function VMStateBulletStr(vm){ case "HOLD": case "STOPPED": case "SUSPENDED": + case "POWEROFF": state_html = ''+vm_state+''; break; case "ACTIVE": diff --git a/src/dm/DispatchManager.cc b/src/dm/DispatchManager.cc index 74657f580a..efdb55d3a2 100644 --- a/src/dm/DispatchManager.cc +++ b/src/dm/DispatchManager.cc @@ -77,6 +77,10 @@ void DispatchManager::trigger(Actions action, int _vid) aname = "STOP_SUCCESS"; break; + case POWEROFF_SUCCESS: + aname = "POWEROFF_SUCCESS"; + break; + case DONE: aname = "DONE"; break; @@ -126,6 +130,10 @@ void DispatchManager::do_action(const string &action, void * arg) { stop_success_action(vid); } + else if (action == "POWEROFF_SUCCESS") + { + poweroff_success_action(vid); + } else if (action == "DONE") { done_action(vid); diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index a58b14aa84..a52f715f73 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -209,6 +209,52 @@ error: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int DispatchManager::poweroff ( + int vid) +{ + ostringstream oss; + VirtualMachine * vm; + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return -1; + } + + oss << "Powering off VM " << vid; + NebulaLog::log("DiM",Log::DEBUG,oss); + + if (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::RUNNING ) + { + Nebula& nd = Nebula::instance(); + LifeCycleManager * lcm = nd.get_lcm(); + + lcm->trigger(LifeCycleManager::POWEROFF,vid); + } + else + { + goto error; + } + + vm->unlock(); + + return 0; + +error: + + oss.str(""); + oss << "Could not power off VM " << vid << ", wrong state."; + NebulaLog::log("DiM",Log::ERROR,oss); + + vm->unlock(); + return -2; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int DispatchManager::hold( int vid) { @@ -464,8 +510,6 @@ int DispatchManager::resume( Nebula& nd = Nebula::instance(); LifeCycleManager * lcm = nd.get_lcm(); - vm->set_state(VirtualMachine::ACTIVE); - vmpool->update(vm); vm->log("DiM", Log::INFO, "New VM state is ACTIVE."); @@ -508,9 +552,10 @@ int DispatchManager::restart(int vid) oss << "Restarting VM " << vid; NebulaLog::log("DiM",Log::DEBUG,oss); - if (vm->get_state() == VirtualMachine::ACTIVE && + if ((vm->get_state() == VirtualMachine::ACTIVE && (vm->get_lcm_state() == VirtualMachine::UNKNOWN || vm->get_lcm_state() == VirtualMachine::BOOT)) + || vm->get_state() == VirtualMachine::POWEROFF ) { Nebula& nd = Nebula::instance(); LifeCycleManager * lcm = nd.get_lcm(); @@ -739,6 +784,7 @@ int DispatchManager::finalize( switch (state) { case VirtualMachine::SUSPENDED: + case VirtualMachine::POWEROFF: int cpu, mem, disk; vm->get_requirements(cpu,mem,disk); @@ -799,6 +845,12 @@ int DispatchManager::resubmit(int vid) switch (vm->get_state()) { + case VirtualMachine::POWEROFF: + NebulaLog::log("DiM",Log::ERROR, + "Cannot resubmit a powered off VM. Restart it first"); + rc = -2; + break; + case VirtualMachine::SUSPENDED: NebulaLog::log("DiM",Log::ERROR, "Cannot resubmit a suspended VM. Resume it first"); diff --git a/src/dm/DispatchManagerStates.cc b/src/dm/DispatchManagerStates.cc index 6061820e1c..169741ea11 100644 --- a/src/dm/DispatchManagerStates.cc +++ b/src/dm/DispatchManagerStates.cc @@ -97,6 +97,45 @@ void DispatchManager::stop_success_action(int vid) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void DispatchManager::poweroff_success_action(int vid) +{ + VirtualMachine * vm; + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return; + } + + if ((vm->get_state() == VirtualMachine::ACTIVE) && + (vm->get_lcm_state() == VirtualMachine::SHUTDOWN_POWEROFF)) + { + vm->set_state(VirtualMachine::POWEROFF); + + vm->set_state(VirtualMachine::LCM_INIT); + + vmpool->update(vm); + + vm->log("DiM", Log::INFO, "New VM state is POWEROFF"); + } + else + { + ostringstream oss; + + oss << "poweroff_success action received but VM " << vid + << " not in ACTIVE state"; + NebulaLog::log("DiM",Log::ERROR,oss); + } + + vm->unlock(); + + return; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void DispatchManager::done_action(int vid) { VirtualMachine * vm; diff --git a/src/lcm/LifeCycleActions.cc b/src/lcm/LifeCycleActions.cc index adb4fd4d6b..02870ddda1 100644 --- a/src/lcm/LifeCycleActions.cc +++ b/src/lcm/LifeCycleActions.cc @@ -337,6 +337,52 @@ void LifeCycleManager::shutdown_action(int vid) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void LifeCycleManager::poweroff_action(int vid) +{ + VirtualMachine * vm; + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return; + } + + if (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::RUNNING) + { + Nebula& nd = Nebula::instance(); + VirtualMachineManager * vmm = nd.get_vmm(); + + //---------------------------------------------------- + // SHUTDOWN_POWEROFF STATE + //---------------------------------------------------- + + vm->set_state(VirtualMachine::SHUTDOWN_POWEROFF); + + vm->set_resched(false); + + vmpool->update(vm); + + vm->log("LCM",Log::INFO,"New VM state is SHUTDOWN_POWEROFF"); + + //---------------------------------------------------- + + vmm->trigger(VirtualMachineManager::SHUTDOWN,vid); + } + else + { + vm->log("LCM", Log::ERROR, "poweroff_action, VM in a wrong state."); + } + + vm->unlock(); + + return; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void LifeCycleManager::restore_action(int vid) { VirtualMachine * vm; @@ -349,7 +395,7 @@ void LifeCycleManager::restore_action(int vid) return; } - if (vm->get_state() == VirtualMachine::ACTIVE) + if (vm->get_state() == VirtualMachine::SUSPENDED) { Nebula& nd = Nebula::instance(); VirtualMachineManager * vmm = nd.get_vmm(); @@ -360,6 +406,7 @@ void LifeCycleManager::restore_action(int vid) //---------------------------------------------------- // BOOT STATE (FROM SUSPEND) //---------------------------------------------------- + vm->set_state(VirtualMachine::ACTIVE); vm->set_state(VirtualMachine::BOOT); @@ -449,9 +496,10 @@ void LifeCycleManager::restart_action(int vid) return; } - if (vm->get_state() == VirtualMachine::ACTIVE && + if ((vm->get_state() == VirtualMachine::ACTIVE && (vm->get_lcm_state() == VirtualMachine::UNKNOWN || - vm->get_lcm_state() == VirtualMachine::BOOT)) + vm->get_lcm_state() == VirtualMachine::BOOT )) + ||vm->get_state() == VirtualMachine::POWEROFF) { Nebula& nd = Nebula::instance(); VirtualMachineManager * vmm = nd.get_vmm(); @@ -460,12 +508,14 @@ void LifeCycleManager::restart_action(int vid) // RE-START THE VM IN THE SAME HOST //---------------------------------------------------- - if (vm->get_lcm_state() == VirtualMachine::BOOT) + if (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::BOOT) { vm->log("LCM", Log::INFO, "Sending BOOT command to VM again"); } else { + vm->set_state(VirtualMachine::ACTIVE); // Only needed by poweroff vm->set_state(VirtualMachine::BOOT); vmpool->update(vm); @@ -597,6 +647,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm) case VirtualMachine::RUNNING: case VirtualMachine::UNKNOWN: case VirtualMachine::SHUTDOWN: + case VirtualMachine::SHUTDOWN_POWEROFF: case VirtualMachine::CANCEL: case VirtualMachine::HOTPLUG: vm->set_running_etime(the_time); diff --git a/src/lcm/LifeCycleManager.cc b/src/lcm/LifeCycleManager.cc index c9603a54a5..d763b5dac8 100644 --- a/src/lcm/LifeCycleManager.cc +++ b/src/lcm/LifeCycleManager.cc @@ -193,6 +193,10 @@ void LifeCycleManager::trigger(Actions action, int _vid) aname = ACTION_FINALIZE; break; + case POWEROFF: + aname = "POWEROFF"; + break; + default: delete vid; return; @@ -338,6 +342,10 @@ void LifeCycleManager::do_action(const string &action, void * arg) { clean_action(vid); } + else if (action == "POWEROFF") + { + poweroff_action(vid); + } else if (action == ACTION_FINALIZE) { NebulaLog::log("LCM",Log::INFO,"Stopping Life-cycle Manager..."); diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index 6672f9b1fb..88d533d71f 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -367,6 +367,7 @@ void LifeCycleManager::shutdown_success_action(int vid) { Nebula& nd = Nebula::instance(); TransferManager * tm = nd.get_tm(); + DispatchManager * dm = nd.get_dm(); VirtualMachine * vm; time_t the_time = time(0); @@ -377,25 +378,52 @@ void LifeCycleManager::shutdown_success_action(int vid) return; } - //---------------------------------------------------- - // EPILOG STATE - //---------------------------------------------------- + if ( vm->get_lcm_state() == VirtualMachine::SHUTDOWN ) + { + //---------------------------------------------------- + // EPILOG STATE + //---------------------------------------------------- - vm->set_state(VirtualMachine::EPILOG); + vm->set_state(VirtualMachine::EPILOG); - vmpool->update(vm); + vmpool->update(vm); - vm->set_epilog_stime(the_time); + vm->set_epilog_stime(the_time); - vm->set_running_etime(the_time); + vm->set_running_etime(the_time); - vmpool->update_history(vm); + vmpool->update_history(vm); - vm->log("LCM", Log::INFO, "New VM state is EPILOG"); + vm->log("LCM", Log::INFO, "New VM state is EPILOG"); - //---------------------------------------------------- + //---------------------------------------------------- - tm->trigger(TransferManager::EPILOG,vid); + tm->trigger(TransferManager::EPILOG,vid); + } + else if (vm->get_lcm_state() == VirtualMachine::SHUTDOWN_POWEROFF) + { + //---------------------------------------------------- + // POWEROFF STATE + //---------------------------------------------------- + + vm->set_running_etime(the_time); + + vm->set_etime(the_time); + + vm->set_vm_info(); + + vm->set_reason(History::STOP_RESUME); + + vmpool->update_history(vm); + + //---------------------------------------------------- + + dm->trigger(DispatchManager::POWEROFF_SUCCESS,vid); + } + else + { + vm->log("LCM",Log::ERROR,"shutdown_success_action, VM in a wrong state"); + } vm->unlock(); } 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 35a15bf9ba..245de275ef 100644 --- a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java +++ b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java @@ -49,7 +49,8 @@ public class VirtualMachine extends PoolElement{ "STOPPED", "SUSPENDED", "DONE", - "FAILED" }; + "FAILED", + "POWEROFF" }; private static final String[] SHORT_VM_STATES = { @@ -60,7 +61,8 @@ public class VirtualMachine extends PoolElement{ "stop", "susp", "done", - "fail" }; + "fail", + "poff" }; private static final String[] LCM_STATE = { @@ -81,7 +83,8 @@ public class VirtualMachine extends PoolElement{ "FAILURE", "CLEANUP", "UNKNOWN", - "HOTPLUG" }; + "HOTPLUG", + "SHUTDOWN_POWEROFF" }; private static final String[] SHORT_LCM_STATES = { @@ -102,7 +105,8 @@ public class VirtualMachine extends PoolElement{ "fail", "clea", "unkn", - "hotp" }; + "hotp", + "poff" }; /** * Creates a new VM representation. @@ -123,7 +127,6 @@ public class VirtualMachine extends PoolElement{ super(xmlElement, client); } - // ================================= // Static XML-RPC methods // ================================= @@ -306,11 +309,12 @@ public class VirtualMachine extends PoolElement{ *
  • {@link VirtualMachine#resume()}
  • *
  • {@link VirtualMachine#finalizeVM()}
  • *
  • {@link VirtualMachine#restart()}
  • + *
  • {@link VirtualMachine#poweroff()}
  • * * * @param action The action name to be performed, can be:
    * "shutdown", "reboot", "hold", "release", "stop", "cancel", "suspend", - * "resume", "restart", "finalize". + * "resume", "restart", "finalize","poweroff". * @return If an error occurs the error message contains the reason. */ protected OneResponse action(String action) diff --git a/src/oca/ruby/OpenNebula/VirtualMachine.rb b/src/oca/ruby/OpenNebula/VirtualMachine.rb index 22936afa78..a9cb2c50d2 100644 --- a/src/oca/ruby/OpenNebula/VirtualMachine.rb +++ b/src/oca/ruby/OpenNebula/VirtualMachine.rb @@ -38,11 +38,12 @@ module OpenNebula :detach => "vm.detach" } - VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED} + VM_STATE=%w{INIT PENDING HOLD ACTIVE STOPPED SUSPENDED DONE FAILED + POWEROFF} LCM_STATE=%w{LCM_INIT PROLOG BOOT RUNNING MIGRATE SAVE_STOP SAVE_SUSPEND SAVE_MIGRATE PROLOG_MIGRATE PROLOG_RESUME EPILOG_STOP EPILOG - SHUTDOWN CANCEL FAILURE CLEANUP UNKNOWN HOTPLUG} + SHUTDOWN CANCEL FAILURE CLEANUP UNKNOWN HOTPLUG SHUTDOWN_POWEROFF} SHORT_VM_STATES={ "INIT" => "init", @@ -52,7 +53,8 @@ module OpenNebula "STOPPED" => "stop", "SUSPENDED" => "susp", "DONE" => "done", - "FAILED" => "fail" + "FAILED" => "fail", + "POWEROFF" => "poff" } SHORT_LCM_STATES={ @@ -72,7 +74,8 @@ module OpenNebula "FAILURE" => "fail", "CLEANUP" => "clea", "UNKNOWN" => "unkn", - "HOTPLUG" => "hotp" + "HOTPLUG" => "hotp", + "SHUTDOWN_POWEROFF" => "shut" } MIGRATE_REASON=%w{NONE ERROR STOP_RESUME USER CANCEL} @@ -148,6 +151,11 @@ module OpenNebula action('shutdown') end + # Powers off a running VM + def poweroff + action('poweroff') + end + # Reboots an already deployed VM def reboot action('reboot') diff --git a/src/ozones/Server/public/js/ozones.js b/src/ozones/Server/public/js/ozones.js index 8e76421896..e41a7206eb 100644 --- a/src/ozones/Server/public/js/ozones.js +++ b/src/ozones/Server/public/js/ozones.js @@ -44,81 +44,86 @@ var oZones = { "Helper": { "resource_state": function(type, value) { + var state; switch(type) { case "HOST": case "host": - return ["INIT", - "MONITORING_MONITORED", - "MONITORED", - "ERROR", - "DISABLED", - "MONITORING_ERROR"][value]; + state = tr(["INIT", + "MONITORING_MONITORED", + "MONITORED", + "ERROR", + "DISABLED", + "MONITORING_ERROR"][value]); break; case "HOST_SIMPLE": case "host_simple": - return ["INIT", - "UPDATE", - "ON", - "ERROR", - "OFF", - "RETRY"][value]; + state = tr(["INIT", + "UPDATE", + "ON", + "ERROR", + "OFF", + "RETRY"][value]); break; case "VM": case "vm": - return ["INIT", - "PENDING", - "HOLD", - "ACTIVE", - "STOPPED", - "SUSPENDED", - "DONE", - "FAILED"][value]; + state = tr(["INIT", + "PENDING", + "HOLD", + "ACTIVE", + "STOPPED", + "SUSPENDED", + "DONE", + "FAILED", + "POWEROFF"][value]); break; case "VM_LCM": case "vm_lcm": - return ["LCM_INIT", - "PROLOG", - "BOOT", - "RUNNING", - "MIGRATE", - "SAVE_STOP", - "SAVE_SUSPEND", - "SAVE_MIGRATE", - "PROLOG_MIGRATE", - "PROLOG_RESUME", - "EPILOG_STOP", - "EPILOG", - "SHUTDOWN", - "CANCEL", - "FAILURE", - "CLEANUP", - "UNKNOWN", - "HOTPLUG"][value]; + state = tr(["LCM_INIT", + "PROLOG", + "BOOT", + "RUNNING", + "MIGRATE", + "SAVE_STOP", + "SAVE_SUSPEND", + "SAVE_MIGRATE", + "PROLOG_MIGRATE", + "PROLOG_RESUME", + "EPILOG_STOP", + "EPILOG", + "SHUTDOWN", + "CANCEL", + "FAILURE", + "CLEANUP", + "UNKNOWN", + "HOTPLUG", + "SHUTDOWN_POWEROFF"][value]); break; case "IMAGE": case "image": - return ["INIT", - "READY", - "USED", - "DISABLED", - "LOCKED", - "ERROR", - "CLONE", - "DELETE", - "USED_PERS"][value]; + state = tr(["INIT", + "READY", + "USED", + "DISABLED", + "LOCKED", + "ERROR", + "CLONE", + "DELETE", + "USED_PERS"][value]); break; case "VM_MIGRATE_REASON": case "vm_migrate_reason": - return ["NONE", - "ERROR", - "STOP_RESUME", - "USER", - "CANCEL"][value]; + state = tr(["NONE", + "ERROR", + "STOP_RESUME", + "USER", + "CANCEL"][value]); break; default: - return; + return value; } + if (!state) state = value + return state; }, "image_type": function(value) diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 0f54a08ece..5d13a39ea8 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -328,6 +328,10 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, { rc = dm->reset(id); } + else if (action == "poweroff") + { + rc = dm->poweroff(id); + } switch (rc) { diff --git a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb index de4c6a4c1a..c44524b2d0 100644 --- a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb @@ -64,6 +64,7 @@ module OpenNebulaJSON when "saveas" then self.save_as(action_hash['params']) when "shutdown" then self.shutdown when "reboot" then self.reboot + when "poweroff" then self.poweroff when "resubmit" then self.resubmit when "chown" then self.chown(action_hash['params']) when "chmod" then self.chmod_octet(action_hash['params']) diff --git a/src/sunstone/public/js/opennebula.js b/src/sunstone/public/js/opennebula.js index 4f49bdc911..f1a90dc805 100644 --- a/src/sunstone/public/js/opennebula.js +++ b/src/sunstone/public/js/opennebula.js @@ -44,11 +44,12 @@ var OpenNebula = { "Helper": { "resource_state": function(type, value) { + var state; switch(type) { case "HOST": case "host": - return tr(["INIT", + state = tr(["INIT", "MONITORING_MONITORED", "MONITORED", "ERROR", @@ -57,7 +58,7 @@ var OpenNebula = { break; case "HOST_SIMPLE": case "host_simple": - return tr(["INIT", + state = tr(["INIT", "UPDATE", "ON", "ERROR", @@ -66,18 +67,19 @@ var OpenNebula = { break; case "VM": case "vm": - return tr(["INIT", + state = tr(["INIT", "PENDING", "HOLD", "ACTIVE", "STOPPED", "SUSPENDED", "DONE", - "FAILED"][value]); + "FAILED", + "POWEROFF"][value]); break; case "VM_LCM": case "vm_lcm": - return tr(["LCM_INIT", + state = tr(["LCM_INIT", "PROLOG", "BOOT", "RUNNING", @@ -94,11 +96,12 @@ var OpenNebula = { "FAILURE", "CLEANUP", "UNKNOWN", - "HOTPLUG"][value]); + "HOTPLUG", + "SHUTDOWN_POWEROFF"][value]); break; case "IMAGE": case "image": - return tr(["INIT", + state = tr(["INIT", "READY", "USED", "DISABLED", @@ -110,15 +113,17 @@ var OpenNebula = { break; case "VM_MIGRATE_REASON": case "vm_migrate_reason": - return tr(["NONE", + state = tr(["NONE", "ERROR", "STOP_RESUME", "USER", "CANCEL"][value]); break; default: - return; + return value; } + if (!state) state = value + return state; }, "image_type": function(value) @@ -622,6 +627,9 @@ var OpenNebula = { "resubmit": function(params){ OpenNebula.Action.simple_action(params,OpenNebula.VM.resource,"resubmit"); }, + "poweroff" : function(params){ + OpenNebula.Action.simple_action(params,OpenNebula.VM.resource,"poweroff"); + }, "reboot" : function(params){ OpenNebula.Action.simple_action(params,OpenNebula.VM.resource,"reboot"); }, diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index 96bafc0d76..34017aa233 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -1605,12 +1605,14 @@ function setupCreateTemplateDialog(){ $('#PORT',section_graphics).parent().show(); $('#PASSWD',section_graphics).parent().show(); $('#KEYMAP',section_graphics).parent().show(); + $('#LISTEN',section_graphics).parent().removeAttr('disabled'); $('#PORT',section_graphics).parent().removeAttr('disabled'); $('#PASSWD',section_graphics).parent().removeAttr('disabled'); $('#KEYMAP',section_graphics).parent().removeAttr('disabled'); break; case "sdl": $('#LISTEN',section_graphics).parent().show(); + $('#LISTEN',section_graphics).parent().removeAttr('disabled'); $('#PORT',section_graphics).parent().hide(); $('#PASSWD',section_graphics).parent().hide(); $('#KEYMAP',section_graphics).parent().hide(); @@ -1619,10 +1621,18 @@ function setupCreateTemplateDialog(){ $('#KEYMAP',section_graphics).parent().attr('disabled','disabled'); break; default: - $('#LISTEN',section_graphics).parent().hide(); - $('#PORT',section_graphics).parent().hide(); - $('#PASSWD',section_graphics).parent().hide(); - $('#KEYMAP',section_graphics).parent().hide(); + $('#LISTEN', + section_graphics).parent().hide().attr('disabled', + 'disabled'); + $('#PORT', + section_graphics).parent().hide().attr('disabled', + 'disabled'); + $('#PASSWD', + section_graphics).parent().hide().attr('disabled', + 'disabled'); + $('#KEYMAP', + section_graphics).parent().hide().attr('disabled', + 'disabled'); } }); diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index db851c66ef..96711d5ff0 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -343,6 +343,15 @@ var vm_actions = { notify: true }, + "VM.poweroff" : { + type: "multiple", + call: OpenNebula.VM.poweroff, + callback: vmShow, + elements: vmElements, + error: onError, + notify: true + }, + "VM.saveas" : { type: "single", call: OpenNebula.VM.saveas, @@ -582,6 +591,11 @@ var vm_buttons = { text: tr("Resubmit"), tip: tr("This will resubmits VMs to PENDING state") }, + "VM.poweroff" : { + type : "confirm", + text: tr("Power Off"), + tip: tr("This will send a power off signal to running VMs. They can be restarted later.") + }, "VM.reboot" : { type : "confirm", text: tr("Reboot"),