commit a3514e86527a3369757a95418298b102c4abc0d5
Merge: 6b7ecdc 8351486
Author: Klaus Aehlig <[email protected]>
Date: Wed Apr 8 13:18:34 2015 +0200
Merge branch 'stable-2.11' into stable-2.12
* stable-2.11
(no changes)
* stable-2.10
fix typos in design-file-based-storage.rst doc
Switch to our osminor
Provide an alternative for os.minor working around its bug
Fix typo
CanTieredAlloc test: make instances big enough
After master-failover verify reachability of master IP
Report failure to deactivate old master IP in exit code
Expose warnings during master-failover
Fix manpage for gnt-cluster copyfile
Conflicts:
lib/bootstrap.py: adapt function to new IO specification
lib/utils/storage.py: trivial
Signed-off-by: Klaus Aehlig <[email protected]>
diff --cc lib/bootstrap.py
index a083f87,bb9b473..8a75548
--- a/lib/bootstrap.py
+++ b/lib/bootstrap.py
@@@ -1085,41 -1052,38 +1087,47 @@@ def MasterFailover(no_voting=False)
# this will also regenerate the ssconf files, since we updated the
# cluster info
cfg.Update(cluster_info, logging.error)
+
+ # if cfg.Update worked, then it means the old master daemon won't be
+ # able now to write its own config file (we rely on locking in both
+ # backend.UploadFile() and ConfigWriter._Write(); hence the next
+ # step is to kill the old master
+
+ logging.info("Stopping the master daemon on node %s", old_master)
+
+ runner = rpc.BootstrapRunner()
+ master_params = cfg.GetMasterNetworkParameters()
+ master_params.uuid = old_master_node.uuid
+ ems = cfg.GetUseExternalMipScript()
+ result = runner.call_node_deactivate_master_ip(old_master,
+ master_params, ems)
+
+ msg = result.fail_msg
+ if msg:
- logging.warning("Could not disable the master IP: %s", msg)
++ warning = "Could not disable the master IP: %s" % (msg,)
++ logging.warning("%s", warning)
++ warnings.append(warning)
+
+ result = runner.call_node_stop_master(old_master)
+ msg = result.fail_msg
+ if msg:
- logging.error("Could not disable the master role on the old master"
- " %s, please disable manually: %s", old_master, msg)
++ warning = ("Could not disable the master role on the old master"
++ " %s, please disable manually: %s" % (old_master, msg))
++ logging.error("%s", warning)
++ warnings.append(warning)
except errors.ConfigurationError, err:
logging.error("Error while trying to set the new master: %s",
str(err))
-- return 1
-
- # if cfg.Update worked, then it means the old master daemon won't be
- # able now to write its own config file (we rely on locking in both
- # backend.UploadFile() and ConfigWriter._Write(); hence the next
- # step is to kill the old master
-
- logging.info("Stopping the master daemon on node %s", old_master)
-
- runner = rpc.BootstrapRunner()
- master_params = cfg.GetMasterNetworkParameters()
- master_params.uuid = old_master_node.uuid
- ems = cfg.GetUseExternalMipScript()
- result = runner.call_node_deactivate_master_ip(old_master,
- master_params, ems)
-
- msg = result.fail_msg
- if msg:
- warning = "Could not disable the master IP: %s" % (msg,)
- logging.warning("%s", warning)
- warnings.append(warning)
-
- result = runner.call_node_stop_master(old_master)
- msg = result.fail_msg
- if msg:
- warning = ("Could not disable the master role on the old master"
- " %s, please disable manually: %s" % (old_master, msg))
- logging.error("%s", warning)
- warnings.append(warning)
++ return 1, warnings
+ finally:
+ # stop WConfd again:
+ result = utils.RunCmd([pathutils.DAEMON_UTIL, "stop", constants.WCONFD])
+ if result.failed:
- logging.error("Could not stop the configuration daemon,"
- " command %s had exitcode %s and error %s",
- result.cmd, result.exit_code, result.output)
++ warning = ("Could not stop the configuration daemon,"
++ " command %s had exitcode %s and error %s"
++ % (result.cmd, result.exit_code, result.output))
++ logging.error("%s", warning)
++ rcode = 1
logging.info("Checking master IP non-reachability...")
diff --cc lib/utils/storage.py
index 6e3ac87,ca488ed..e742d5e
--- a/lib/utils/storage.py
+++ b/lib/utils/storage.py
@@@ -184,34 -184,11 +184,44 @@@ def LookupSpaceInfoByStorageType(storag
return result
+def GetDiskLabels(prefix, num_disks, start=0):
+ """Generate disk labels for a number of disks
+
+ Note that disk labels are generated in the range [start..num_disks[
+ (e.g., as in range(start, num_disks))
+
+ @type prefix: string
+ @param prefix: disk label prefix (e.g., "/dev/sd")
+
+ @type num_disks: int
+ @param num_disks: number of disks (i.e., disk labels)
+
+ @type start: int
+ @param start: optional start index
+
+ @rtype: generator
+ @return: generator for the disk labels
+
+ """
+ def _GetDiskSuffix(i):
+ n = ord('z') - ord('a') + 1
+ if i < n:
+ return chr(ord('a') + i)
+ else:
+ mod = int(i % n)
+ pref = _GetDiskSuffix((i - mod) / (n + 1))
+ suf = _GetDiskSuffix(mod)
+ return pref + suf
+
+ for i in range(start, num_disks):
+ yield prefix + _GetDiskSuffix(i)
++
++
+ def osminor(dev):
+ """Return the device minor number from a raw device number.
+
+ This is a replacement for os.minor working around the issue that
+ Python's os.minor still has the old definition. See Ganeti issue
+ 1058 for more details.
+ """
+ return (dev & 0xff) | ((dev >> 12) & ~0xff)
--
Klaus Aehlig
Google Germany GmbH, Dienerstr. 12, 80331 Muenchen
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschaeftsfuehrer: Graham Law, Christine Elizabeth Flores