1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#
# Copyright (C) 2006-2009 Nexedi SA
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
from time import time
import logging
from neo import protocol
from neo.protocol import RUNNING_STATE, TEMPORARILY_DOWN_STATE, DOWN_STATE, \
BROKEN_STATE, PENDING_STATE, HIDDEN_STATE, MASTER_NODE_TYPE, \
STORAGE_NODE_TYPE, CLIENT_NODE_TYPE, ADMIN_NODE_TYPE, \
VALID_NODE_STATE_LIST, ADMIN_NODE_TYPE
from neo.util import dump
class Node(object):
"""This class represents a node."""
def __init__(self, server = None, uuid = None):
self.state = RUNNING_STATE
self.server = server
self.uuid = uuid
self.manager = None
self.last_state_change = time()
def setManager(self, manager):
self.manager = manager
def getLastStateChange(self):
return self.last_state_change
def getState(self):
return self.state
def setState(self, new_state):
assert new_state in VALID_NODE_STATE_LIST
if self.state != new_state:
self.state = new_state
self.last_state_change = time()
def setServer(self, server):
if self.server != server:
if self.server is not None and self.manager is not None:
self.manager.unregisterServer(self)
self.server = server
if server is not None and self.manager is not None:
self.manager.registerServer(self)
def getServer(self):
return self.server
def setUUID(self, uuid):
if self.uuid != uuid:
if self.uuid is not None and self.manager is not None:
self.manager.unregisterUUID(self)
self.uuid = uuid
if uuid is not None and self.manager is not None:
self.manager.registerUUID(self)
def getUUID(self):
return self.uuid
def getNodeType(self):
raise NotImplementedError
def __str__(self):
server = self.getServer()
if server is None:
address, port = None, None
else:
address, port = server
uuid = self.getUUID()
return '%s (%s:%s)' % (dump(uuid), address, port)
class MasterNode(Node):
"""This class represents a master node."""
def getNodeType(self):
return MASTER_NODE_TYPE
class StorageNode(Node):
"""This class represents a storage node."""
def getNodeType(self):
return STORAGE_NODE_TYPE
class ClientNode(Node):
"""This class represents a client node."""
def getNodeType(self):
return CLIENT_NODE_TYPE
class AdminNode(Node):
"""This class represents an admin node."""
def getNodeType(self):
return ADMIN_NODE_TYPE
class NodeManager(object):
"""This class manages node status."""
def __init__(self):
self.node_list = []
self.server_dict = {}
self.uuid_dict = {}
def add(self, node):
node.setManager(self)
self.node_list.append(node)
if node.getServer() is not None:
self.registerServer(node)
if node.getUUID() is not None:
self.registerUUID(node)
def remove(self, node):
self.node_list.remove(node)
self.unregisterServer(node)
self.unregisterUUID(node)
def registerServer(self, node):
self.server_dict[node.getServer()] = node
def unregisterServer(self, node):
try:
del self.server_dict[node.getServer()]
except KeyError:
pass
def registerUUID(self, node):
self.uuid_dict[node.getUUID()] = node
def unregisterUUID(self, node):
try:
del self.uuid_dict[node.getUUID()]
except KeyError:
pass
def getNodeList(self, filter = None):
if filter is None:
return list(self.node_list)
return [n for n in self.node_list if filter(n)]
def getMasterNodeList(self):
return self.getNodeList(filter = lambda node: node.getNodeType() == MASTER_NODE_TYPE)
def getStorageNodeList(self):
return self.getNodeList(filter = lambda node: node.getNodeType() == STORAGE_NODE_TYPE)
def getClientNodeList(self):
return self.getNodeList(filter = lambda node: node.getNodeType() == CLIENT_NODE_TYPE)
def getNodeByServer(self, server):
return self.server_dict.get(server)
def getNodeByUUID(self, uuid):
if uuid in (None, protocol.INVALID_UUID):
return None
return self.uuid_dict.get(uuid)
def clear(self, filter=None):
for node in self.getNodeList():
if filter is not None and filter(node):
self.remove(node)
def log(self):
node_state_dict = { RUNNING_STATE: 'R',
TEMPORARILY_DOWN_STATE: 'T',
DOWN_STATE: 'D',
BROKEN_STATE: 'B',
HIDDEN_STATE: 'H',
PENDING_STATE: 'P'}
node_type_dict = {
MASTER_NODE_TYPE: 'M',
STORAGE_NODE_TYPE: 'S',
CLIENT_NODE_TYPE: 'C',
ADMIN_NODE_TYPE: 'A',
}
for uuid, node in sorted(self.uuid_dict.items()):
args = (
dump(uuid),
node_type_dict[node.getNodeType()],
node_state_dict[node.getState()]
)
logging.debug('nm: %s : %s/%s' % args)