commit a530af1d88f608d10f613909d63e6fb342e0df56
Merge: 47f95a9 6e8f7fe
Author: Helga Velroyen <[email protected]>
Date: Wed Mar 18 16:23:52 2015 +0100
Merge branch 'stable-2.11' into stable-2.12
* stable-2.11
Renew crypto retries for non-master nodes
Retries for the master's SSL cert renewal
Unit tests for offline nodes
De-duplicate testing code regarding pathutils
Make LURenewCrypto handle unreachable nodes properly
Error handling on failed SSL cert renewal for master
Unit test for LURenewCrypto's valid case
Mock support for pathutils
Increase timeout of crypto token RPC
Conflicts:
lib/cmdlib/cluster.py
test/py/cmdlib/cluster_unittest.py
test/py/cmdlib/testsupport/__init__.py
Resolution:
for all affected files: update changes to
configuration handling
Signed-off-by: Helga Velroyen <[email protected]>
diff --cc Makefile.am
index a61755b,a384351..c9e64cd
--- a/Makefile.am
+++ b/Makefile.am
@@@ -1756,8 -1572,9 +1756,9 @@@ python_test_support =
test/py/cmdlib/testsupport/cmdlib_testcase.py \
test/py/cmdlib/testsupport/config_mock.py \
test/py/cmdlib/testsupport/iallocator_mock.py \
- test/py/cmdlib/testsupport/lock_manager_mock.py \
+ test/py/cmdlib/testsupport/livelock_mock.py \
test/py/cmdlib/testsupport/netutils_mock.py \
+ test/py/cmdlib/testsupport/pathutils_mock.py \
test/py/cmdlib/testsupport/processor_mock.py \
test/py/cmdlib/testsupport/rpc_runner_mock.py \
test/py/cmdlib/testsupport/ssh_mock.py \
diff --cc lib/cmdlib/cluster.py
index 5f6504a,0f4b2eb..828212f
--- a/lib/cmdlib/cluster.py
+++ b/lib/cmdlib/cluster.py
@@@ -110,8 -111,11 +110,10 @@@ class LUClusterRenewCrypto(NoHooksLU)
takes care of the renewal of the client SSL certificates.
"""
+ _MAX_NUM_RETRIES = 3
+
def Exec(self, feedback_fn):
master_uuid = self.cfg.GetMasterNode()
- cluster = self.cfg.GetClusterInfo()
server_digest = utils.GetCertificateDigest(
cert_filename=pathutils.NODED_CERT_FILE)
@@@ -125,21 -131,67 +127,60 @@@
except IOError:
logging.info("No old certificate available.")
- new_master_digest = _UpdateMasterClientCert(self, self.cfg,
master_uuid)
-
- self.cfg.AddNodeToCandidateCerts(master_uuid, new_master_digest)
+ for _ in range(self._MAX_NUM_RETRIES):
+ try:
+ # Technically it should not be necessary to set the cert
+ # paths. However, due to a bug in the mock library, we
+ # have to do this to be able to test the function properly.
+ _UpdateMasterClientCert(
- self, master_uuid, cluster, feedback_fn,
++ self, self.cfg, master_uuid,
+ client_cert=pathutils.NODED_CLIENT_CERT_FILE,
+ client_cert_tmp=pathutils.NODED_CLIENT_CERT_FILE_TMP)
+ break
+ except errors.OpExecError as e:
+ pass
+ else:
+ feedback_fn("Could not renew the master's client SSL certificate."
+ " Cleaning up. Error: %s." % e)
+ # Cleaning up temporary certificates
- utils.RemoveNodeFromCandidateCerts("%s-SERVER" % master_uuid,
- cluster.candidate_certs)
- utils.RemoveNodeFromCandidateCerts("%s-OLDMASTER" % master_uuid,
- cluster.candidate_certs)
++ self.cfg.RemoveNodeFromCandidateCerts("%s-SERVER" % master_uuid)
++ self.cfg.RemoveNodeFromCandidateCerts("%s-OLDMASTER" % master_uuid)
+ try:
+ utils.RemoveFile(pathutils.NODED_CLIENT_CERT_FILE_TMP)
+ except IOError:
+ pass
+ return
+
+ node_errors = {}
nodes = self.cfg.GetAllNodesInfo()
for (node_uuid, node_info) in nodes.items():
if node_info.offline:
feedback_fn("* Skipping offline node %s" % node_info.name)
continue
if node_uuid != master_uuid:
- new_digest = CreateNewClientCert(self, node_uuid)
- if node_info.master_candidate:
- self.cfg.AddNodeToCandidateCerts(node_uuid, new_digest)
+ for _ in range(self._MAX_NUM_RETRIES):
+ try:
+ new_digest = CreateNewClientCert(self, node_uuid)
+ if node_info.master_candidate:
- utils.AddNodeToCandidateCerts(node_uuid,
- new_digest,
- cluster.candidate_certs)
++ self.cfg.AddNodeToCandidateCerts(node_uuid,
++ new_digest)
+ break
+ except errors.OpExecError as last_exception:
+ pass
+ else:
+ if last_exception:
+ node_errors[node_uuid] = last_exception
+
+ if node_errors:
+ msg = ("Some nodes' SSL client certificates could not be renewed."
+ " Please make sure those nodes are reachable and rerun"
+ " the operation. The affected nodes and their errors are:\n")
+ for uuid, e in node_errors.items():
+ msg += "Node %s: %s\n" % (uuid, e)
+ feedback_fn(msg)
+
- utils.RemoveNodeFromCandidateCerts("%s-SERVER" % master_uuid,
- cluster.candidate_certs)
- utils.RemoveNodeFromCandidateCerts("%s-OLDMASTER" % master_uuid,
- cluster.candidate_certs)
- # Trigger another update of the config now with the new master cert
- self.cfg.Update(cluster, feedback_fn)
+ self.cfg.RemoveNodeFromCandidateCerts("%s-SERVER" % master_uuid)
+ self.cfg.RemoveNodeFromCandidateCerts("%s-OLDMASTER" % master_uuid)
- # Trigger another update of the config now with the new master cert
class LUClusterActivateMasterIp(NoHooksLU):
diff --cc test/py/cmdlib/cluster_unittest.py
index 1a90972,073b8de..eaed548
--- a/test/py/cmdlib/cluster_unittest.py
+++ b/test/py/cmdlib/cluster_unittest.py
@@@ -37,7 -37,8 +37,9 @@@ import OpenSS
import copy
import unittest
import operator
+import re
+ import shutil
+ import os
from ganeti.cmdlib import cluster
from ganeti import constants
diff --cc test/py/cmdlib/testsupport/__init__.py
index e25fc27,d121c37..a1f0678
--- a/test/py/cmdlib/testsupport/__init__.py
+++ b/test/py/cmdlib/testsupport/__init__.py
@@@ -36,10 -36,11 +36,11 @@@ from cmdlib.testsupport.cmdlib_testcas
withLockedLU
from cmdlib.testsupport.config_mock import ConfigMock
from cmdlib.testsupport.iallocator_mock import patchIAllocator
+from cmdlib.testsupport.livelock_mock import LiveLockMock
from cmdlib.testsupport.utils_mock import patchUtils
-from cmdlib.testsupport.lock_manager_mock import LockManagerMock
from cmdlib.testsupport.netutils_mock import patchNetutils, HostnameMock
from cmdlib.testsupport.processor_mock import ProcessorMock
+ from cmdlib.testsupport.pathutils_mock import patchPathutils
from cmdlib.testsupport.rpc_runner_mock import CreateRpcRunnerMock, \
RpcResultsBuilder
from cmdlib.testsupport.ssh_mock import patchSsh
@@@ -54,8 -54,8 +55,9 @@@ __all__ = ["CmdlibTestCase"
"patchUtils",
"patchNetutils",
"patchSsh",
+ "patchPathutils",
- "LockManagerMock",
"ProcessorMock",
"RpcResultsBuilder",
+ "LiveLockMock",
+ "WConfdMock",
]