From 007a2f3e50e20aa187eff32807c221afb0227986 Mon Sep 17 00:00:00 2001
From: Alexander Schreiber <als@google.com>
Date: Wed, 17 Oct 2007 15:00:59 +0000
Subject: [PATCH] Patch series for reboot feature, part 1

This patch series implements the reboot command for gnt-instance. It
supports three types of reboot: soft (hypervisor reboot), hard (instance
config rebuild and reboot) and full (full instance shutdown and startup
again).

This patch contains the backend and rpc part of the patch.


Reviewed-by: iustinp
---
 daemons/ganeti-noded | 10 ++++++++++
 lib/backend.py       | 35 +++++++++++++++++++++++++++++++++++
 lib/constants.py     |  5 +++++
 lib/rpc.py           | 12 ++++++++++++
 4 files changed, 62 insertions(+)

diff --git a/daemons/ganeti-noded b/daemons/ganeti-noded
index 454bc8c35..12f6b7a48 100755
--- a/daemons/ganeti-noded
+++ b/daemons/ganeti-noded
@@ -324,6 +324,16 @@ class ServerObject(pb.Avatar):
     extra_args = params[1]
     return backend.StartInstance(instance, extra_args)
 
+  @staticmethod
+  def perspective_instance_reboot(params):
+    """Reboot an instance.
+
+    """
+    instance = objects.Instance.FromDict(params[0])
+    reboot_type = params[1]
+    extra_args = params[2]
+    return backend.RebootInstance(instance, reboot_type, extra_args)
+
   @staticmethod
   def perspective_instance_info(params):
     """Query instance information.
diff --git a/lib/backend.py b/lib/backend.py
index 5df65a574..d2c154ae1 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -585,6 +585,41 @@ def ShutdownInstance(instance):
   return True
 
 
+def RebootInstance(instance, reboot_type, extra_args):
+  """Reboot an instance.
+
+  Args:
+    instance    - name of instance to reboot
+    reboot_type - how to reboot [soft,hard,full]
+
+  """
+  running_instances = GetInstanceList()
+
+  if instance.name not in running_instances:
+    logger.Error("Cannot reboot instance that is not running")
+    return False
+
+  hyper = hypervisor.GetHypervisor()
+  if reboot_type == constants.INSTANCE_REBOOT_SOFT:
+    try:
+      hyper.RebootInstance(instance)
+    except errors.HypervisorError, err:
+      logger.Error("Failed to soft reboot instance: %s" % err)
+      return False
+  elif reboot_type == constants.INSTANCE_REBOOT_HARD:
+    try:
+      ShutdownInstance(instance)
+      StartInstance(instance, extra_args)
+    except errors.HypervisorError, err:
+      logger.Error("Failed to hard reboot instance: %s" % err)
+      return False
+  else:
+    raise errors.ParameterError("reboot_type invalid")
+
+
+  return True
+
+
 def CreateBlockDevice(disk, size, on_primary, info):
   """Creates a block device for an instance.
 
diff --git a/lib/constants.py b/lib/constants.py
index e7b33d573..d1237de90 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -117,3 +117,8 @@ SSH_HOST_DSA_PRIV = SSH_CONFIG_DIR + "ssh_host_dsa_key"
 SSH_HOST_DSA_PUB = SSH_HOST_DSA_PRIV + ".pub"
 SSH_HOST_RSA_PRIV = SSH_CONFIG_DIR + "ssh_host_rsa_key"
 SSH_HOST_RSA_PUB = SSH_HOST_RSA_PRIV + ".pub"
+
+# reboot types
+INSTANCE_REBOOT_SOFT = "soft"
+INSTANCE_REBOOT_HARD = "hard"
+INSTANCE_REBOOT_FULL = "full"
diff --git a/lib/rpc.py b/lib/rpc.py
index efe847c5c..f545e79d0 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -311,6 +311,18 @@ def call_instance_shutdown(node, instance):
   return c.getresult().get(node, False)
 
 
+def call_instance_reboot(node, instance, reboot_type, extra_args):
+  """Reboots an instance.
+
+  This is a single-node call.
+
+  """
+  c = Client("instance_reboot", [instance.ToDict(), reboot_type, extra_args])
+  c.connect(node)
+  c.run()
+  return c.getresult().get(node, False)
+
+
 def call_instance_os_add(node, inst, osdev, swapdev):
   """Installs an OS on the given instance.
 
-- 
GitLab