Revision d465bdc8

b/lib/cmdlib.py
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
b/lib/mcpu.py
150 150
    try:
151 151
      self.exclusive_BGL = lu_class.REQ_BGL
152 152
      lu = lu_class(self, op, self.context, sstore)
153
      lu.ExpandNames()
153 154
      result = self._ExecLU(lu)
154 155
    finally:
155 156
      self.context.glm.release(locking.LEVEL_CLUSTER)

Also available in: Unified diff