Commit 58774fb6 authored by Julien Muchembled's avatar Julien Muchembled

master: new option to automatically start a new cluster

parent 5a76664a
......@@ -100,3 +100,8 @@ class ConfigurationManager(object):
def getUpstreamMasters(self):
return util.parseMasterList(self.__get('upstream_masters'))
def getAutostart(self):
n = self.__get('autostart', True)
if n:
return int(n)
......@@ -56,6 +56,7 @@ class Application(object):
self.name = config.getCluster()
self.server = config.getBind()
self.autostart = config.getAutostart()
self.storage_readiness = set()
master_addresses, connector_name = config.getMasters()
......
......@@ -66,10 +66,12 @@ class RecoveryManager(MasterHandler):
node_list = [node for node in node_list if node.isPending()]
elif not all(node.isPending() for node in node_list):
continue
elif app._startup_allowed:
elif app._startup_allowed or app.autostart:
# No partition table and admin allowed startup, we are
# creating a new cluster out of all pending nodes.
node_list = app.nm.getStorageList(only_identified=True)
if not app._startup_allowed and len(node_list) < app.autostart:
continue
else:
continue
if node_list and not any(node.getConnection().isPending()
......
......@@ -33,6 +33,10 @@ parser.add_option('-p', '--partitions', help = 'partitions number')
parser.add_option('-l', '--logfile', help = 'specify a logging file')
parser.add_option('-D', '--dynamic-master-list', help='path of the file '
'containing dynamic master node list')
parser.add_option('-A', '--autostart',
help='minimum number of pending storage nodes to automatically start'
' new cluster (to avoid unwanted recreation of the cluster,'
' this should be the total number of storage nodes)')
parser.add_option('-C', '--upstream-cluster',
help='the name of cluster to backup')
parser.add_option('-M', '--upstream-masters',
......@@ -55,6 +59,7 @@ def main(args=None):
masters = options.masters,
replicas = options.replicas,
partitions = options.partitions,
autostart = options.autostart,
upstream_cluster = options.upstream_cluster,
upstream_masters = options.upstream_masters,
)
......
......@@ -561,7 +561,7 @@ class NEOCluster(object):
adapter=os.getenv('NEO_TESTS_ADAPTER', 'SQLite'),
storage_count=None, db_list=None, clear_databases=True,
db_user=DB_USER, db_password='', compress=True,
importer=None):
importer=None, autostart=None):
self.name = 'neo_%s' % self._allocate('name',
lambda: random.randint(0, 100))
master_list = [MasterApplication.newAddress()
......@@ -574,7 +574,8 @@ class NEOCluster(object):
self.upstream = weakref.proxy(upstream)
kw.update(getUpstreamCluster=upstream.name,
getUpstreamMasters=parseMasterList(upstream.master_nodes))
self.master_list = [MasterApplication(address=x, **kw)
self.master_list = [MasterApplication(getAutostart=autostart,
address=x, **kw)
for x in master_list]
if db_list is None:
if storage_count is None:
......@@ -647,20 +648,20 @@ class NEOCluster(object):
node.start()
self.tic()
if fast_startup:
self._startCluster()
self.startCluster()
if storage_list is None:
storage_list = self.storage_list
for node in storage_list:
node.start()
self.tic()
if not fast_startup:
self._startCluster()
self.startCluster()
self.tic()
state = self.neoctl.getClusterState()
assert state in (ClusterStates.RUNNING, ClusterStates.BACKINGUP), state
self.enableStorageList(storage_list)
def _startCluster(self):
def startCluster(self):
try:
self.neoctl.startCluster()
except RuntimeError:
......
......@@ -840,5 +840,17 @@ class Test(NEOThreadedTest):
finally:
cluster.stop()
def testAutostart(self):
def startCluster():
getClusterState = cluster.neoctl.getClusterState
self.assertEqual(ClusterStates.RECOVERING, getClusterState())
cluster.storage_list[2].start()
cluster = NEOCluster(storage_count=3, autostart=3)
try:
cluster.startCluster = startCluster
cluster.start(cluster.storage_list[:2])
finally:
cluster.stop()
if __name__ == "__main__":
unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment