50 |
50 |
"""Logical Unit base class.
|
51 |
51 |
|
52 |
52 |
Subclasses must follow these rules:
|
53 |
|
- implement CheckPrereq which also fills in the opcode instance
|
54 |
|
with all the fields (even if as None)
|
|
53 |
- implement ExpandNames
|
|
54 |
- implement CheckPrereq
|
55 |
55 |
- implement Exec
|
56 |
56 |
- implement BuildHooksEnv
|
57 |
57 |
- redefine HPATH and HTYPE
|
... | ... | |
82 |
82 |
self.cfg = context.cfg
|
83 |
83 |
self.sstore = sstore
|
84 |
84 |
self.context = context
|
|
85 |
self.needed_locks = None
|
85 |
86 |
self.__ssh = None
|
86 |
87 |
|
87 |
88 |
for attr_name in self._OP_REQP:
|
... | ... | |
109 |
110 |
|
110 |
111 |
ssh = property(fget=__GetSSH)
|
111 |
112 |
|
|
113 |
def ExpandNames(self):
|
|
114 |
"""Expand names for this LU.
|
|
115 |
|
|
116 |
This method is called before starting to execute the opcode, and it should
|
|
117 |
update all the parameters of the opcode to their canonical form (e.g. a
|
|
118 |
short node name must be fully expanded after this method has successfully
|
|
119 |
completed). This way locking, hooks, logging, ecc. can work correctly.
|
|
120 |
|
|
121 |
LUs which implement this method must also populate the self.needed_locks
|
|
122 |
member, as a dict with lock levels as keys, and a list of needed lock names
|
|
123 |
as values. Rules:
|
|
124 |
- Use an empty dict if you don't need any lock
|
|
125 |
- If you don't need any lock at a particular level omit that level
|
|
126 |
- Don't put anything for the BGL level
|
|
127 |
- If you want all locks at a level use None as a value
|
|
128 |
(this reflects what LockSet does, and will be replaced before
|
|
129 |
CheckPrereq with the full list of nodes that have been locked)
|
|
130 |
|
|
131 |
Examples:
|
|
132 |
# Acquire all nodes and one instance
|
|
133 |
self.needed_locks = {
|
|
134 |
locking.LEVEL_NODE: None,
|
|
135 |
locking.LEVEL_INSTANCES: ['instance1.example.tld'],
|
|
136 |
}
|
|
137 |
# Acquire just two nodes
|
|
138 |
self.needed_locks = {
|
|
139 |
locking.LEVEL_NODE: ['node1.example.tld', 'node2.example.tld'],
|
|
140 |
}
|
|
141 |
# Acquire no locks
|
|
142 |
self.needed_locks = {} # No, you can't leave it to the default value None
|
|
143 |
|
|
144 |
"""
|
|
145 |
# The implementation of this method is mandatory only if the new LU is
|
|
146 |
# concurrent, so that old LUs don't need to be changed all at the same
|
|
147 |
# time.
|
|
148 |
if self.REQ_BGL:
|
|
149 |
self.needed_locks = {} # Exclusive LUs don't need locks.
|
|
150 |
else:
|
|
151 |
raise NotImplementedError
|
|
152 |
|
112 |
153 |
def CheckPrereq(self):
|
113 |
154 |
"""Check prerequisites for this LU.
|
114 |
155 |
|
... | ... | |
121 |
162 |
not fulfilled. Its return value is ignored.
|
122 |
163 |
|
123 |
164 |
This method should also update all the parameters of the opcode to
|
124 |
|
their canonical form; e.g. a short node name must be fully
|
125 |
|
expanded after this method has successfully completed (so that
|
126 |
|
hooks, logging, etc. work correctly).
|
|
165 |
their canonical form if it hasn't been done by ExpandNames before.
|
127 |
166 |
|
128 |
167 |
"""
|
129 |
168 |
raise NotImplementedError
|