Enable lockless node queries
[ganeti-local] / lib / backend.py
index 6147a46..8b19138 100644 (file)
@@ -260,8 +260,9 @@ def AddNode(dsa, dsapub, rsa, rsapub, sshkey, sshpub):
     priv_key, pub_key, auth_keys = ssh.GetUserFiles(constants.GANETI_RUNAS,
                                                     mkdir=True)
   except errors.OpExecError, err:
-    logging.exception("Error while processing user ssh files")
-    return False
+    msg = "Error while processing user ssh files"
+    logging.exception(msg)
+    return (False, "%s: %s" % (msg, err))
 
   for name, content in [(priv_key, sshkey), (pub_key, sshpub)]:
     utils.WriteFile(name, data=content, mode=0600)
@@ -270,7 +271,7 @@ def AddNode(dsa, dsapub, rsa, rsapub, sshkey, sshpub):
 
   utils.RunCmd([constants.SSH_INITD_SCRIPT, "restart"])
 
-  return True
+  return (True, "Node added successfully")
 
 
 def LeaveCluster():
@@ -426,7 +427,8 @@ def VerifyNode(what, cluster_name):
     result[constants.NV_VGLIST] = ListVolumeGroups()
 
   if constants.NV_VERSION in what:
-    result[constants.NV_VERSION] = constants.PROTOCOL_VERSION
+    result[constants.NV_VERSION] = (constants.PROTOCOL_VERSION,
+                                    constants.RELEASE_VERSION)
 
   if constants.NV_HVINFO in what:
     hyper = hypervisor.GetHypervisor(what[constants.NV_HVINFO])
@@ -435,7 +437,7 @@ def VerifyNode(what, cluster_name):
   if constants.NV_DRBDLIST in what:
     try:
       used_minors = bdev.DRBD8.GetUsedDevs().keys()
-    except errors.BlockDeviceErrors:
+    except errors.BlockDeviceError:
       logging.warning("Can't get used minors list", exc_info=True)
       used_minors = []
     result[constants.NV_DRBDLIST] = used_minors
@@ -689,7 +691,7 @@ def AddOSToInstance(instance):
     logging.error("os create command '%s' returned error: %s, logfile: %s,"
                   " output: %s", result.cmd, result.fail_reason, logfile,
                   result.output)
-    lines = [val.encode("string_escape")
+    lines = [utils.SafeEncode(val)
              for val in utils.TailFile(logfile, lines=20)]
     return (False, "OS create script failed (%s), last lines in the"
             " log file:\n%s" % (result.fail_reason, "\n".join(lines)))
@@ -723,7 +725,7 @@ def RunRenameInstance(instance, old_name):
   if result.failed:
     logging.error("os create command '%s' returned error: %s output: %s",
                   result.cmd, result.fail_reason, result.output)
-    lines = [val.encode("string_escape")
+    lines = [utils.SafeEncode(val)
              for val in utils.TailFile(logfile, lines=20)]
     return (False, "OS rename script failed (%s), last lines in the"
             " log file:\n%s" % (result.fail_reason, "\n".join(lines)))
@@ -909,7 +911,8 @@ def ShutdownInstance(instance):
     time.sleep(10)
   else:
     # the shutdown did not succeed
-    logging.error("shutdown of '%s' unsuccessful, using destroy", instance)
+    logging.error("Shutdown of '%s' unsuccessful, using destroy",
+                  instance.name)
 
     try:
       hyper.StopInstance(instance, force=True)
@@ -919,7 +922,7 @@ def ShutdownInstance(instance):
 
     time.sleep(1)
     if instance.name in GetInstanceList([hv_name]):
-      logging.error("could not shutdown instance '%s' even by destroy",
+      logging.error("Could not shutdown instance '%s' even by destroy",
                     instance.name)
       return False
 
@@ -980,7 +983,14 @@ def MigrationInfo(instance):
   @param instance: the instance definition
 
   """
-  return (True, '')
+  hyper = hypervisor.GetHypervisor(instance.hypervisor)
+  try:
+    info = hyper.MigrationInfo(instance)
+  except errors.HypervisorError, err:
+    msg = "Failed to fetch migration information"
+    logging.exception(msg)
+    return (False, '%s: %s' % (msg, err))
+  return (True, info)
 
 
 def AcceptInstance(instance, info, target):
@@ -994,6 +1004,13 @@ def AcceptInstance(instance, info, target):
   @param target: target host (usually ip), on this node
 
   """
+  hyper = hypervisor.GetHypervisor(instance.hypervisor)
+  try:
+    hyper.AcceptInstance(instance, info, target)
+  except errors.HypervisorError, err:
+    msg = "Failed to accept instance"
+    logging.exception(msg)
+    return (False, '%s: %s' % (msg, err))
   return (True, "Accept successfull")
 
 
@@ -1008,6 +1025,13 @@ def FinalizeMigration(instance, info, success):
   @param success: whether the migration was a success or a failure
 
   """
+  hyper = hypervisor.GetHypervisor(instance.hypervisor)
+  try:
+    hyper.FinalizeMigration(instance, info, success)
+  except errors.HypervisorError, err:
+    msg = "Failed to finalize migration"
+    logging.exception(msg)
+    return (False, '%s: %s' % (msg, err))
   return (True, "Migration Finalized")
 
 
@@ -1570,6 +1594,7 @@ def OSEnvironment(instance, debug=0):
   result = {}
   result['OS_API_VERSION'] = '%d' % constants.OS_API_VERSION
   result['INSTANCE_NAME'] = instance.name
+  result['INSTANCE_OS'] = instance.os
   result['HYPERVISOR'] = instance.hypervisor
   result['DISK_COUNT'] = '%d' % len(instance.disks)
   result['NIC_COUNT'] = '%d' % len(instance.nics)
@@ -1582,7 +1607,7 @@ def OSEnvironment(instance, debug=0):
     real_disk.Open()
     result['DISK_%d_PATH' % idx] = real_disk.dev_path
     # FIXME: When disks will have read-only mode, populate this
-    result['DISK_%d_ACCESS' % idx] = 'W'
+    result['DISK_%d_ACCESS' % idx] = disk.mode
     if constants.HV_DISK_TYPE in instance.hvparams:
       result['DISK_%d_FRONTEND_TYPE' % idx] = \
         instance.hvparams[constants.HV_DISK_TYPE]
@@ -2409,7 +2434,7 @@ class HooksRunner(object):
             #logging.exception("Error while closing fd %s", fd)
             pass
 
-    return result == 0, output
+    return result == 0, utils.SafeEncode(output.strip())
 
   def RunHooks(self, hpath, phase, env):
     """Run the scripts in the hooks directory.