X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/642339cfe809094985c6e56c6f38e6fad4128bb9..1a5c7281e4053d1e4108379adaea97e868c57dae:/lib/cmdlib.py diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 49a557c..1fa6be7 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -217,6 +217,28 @@ class LogicalUnit(object): """ return lu_result + def _ExpandAndLockInstance(self): + """Helper function to expand and lock an instance. + + Many LUs that work on an instance take its name in self.op.instance_name + and need to expand it and then declare the expanded name for locking. This + function does it, and then updates self.op.instance_name to the expanded + name. It also initializes needed_locks as a dict, if this hasn't been done + before. + + """ + if self.needed_locks is None: + self.needed_locks = {} + else: + assert locking.LEVEL_INSTANCE not in self.needed_locks, \ + "_ExpandAndLockInstance called with instance-level locks set" + expanded_name = self.cfg.ExpandInstanceName(self.op.instance_name) + if expanded_name is None: + raise errors.OpPrereqError("Instance '%s' not known" % + self.op.instance_name) + self.needed_locks[locking.LEVEL_INSTANCE] = expanded_name + self.op.instance_name = expanded_name + class NoHooksLU(LogicalUnit): """Simple LU which runs no hooks. @@ -3332,6 +3354,10 @@ class LUConnectConsole(NoHooksLU): """ _OP_REQP = ["instance_name"] + REQ_BGL = False + + def ExpandNames(self): + self._ExpandAndLockInstance() def CheckPrereq(self): """Check prerequisites. @@ -3339,12 +3365,9 @@ class LUConnectConsole(NoHooksLU): This checks that the instance is in the cluster. """ - instance = self.cfg.GetInstanceInfo( - self.cfg.ExpandInstanceName(self.op.instance_name)) - if instance is None: - raise errors.OpPrereqError("Instance '%s' not known" % - self.op.instance_name) - self.instance = instance + self.instance = self.cfg.GetInstanceInfo(self.op.instance_name) + assert self.instance is not None, \ + "Cannot retrieve locked instance %s" % self.op.instance_name def Exec(self, feedback_fn): """Connect to the console of an instance @@ -4074,6 +4097,10 @@ class LUSetInstanceParams(LogicalUnit): HPATH = "instance-modify" HTYPE = constants.HTYPE_INSTANCE _OP_REQP = ["instance_name"] + REQ_BGL = False + + def ExpandNames(self): + self._ExpandAndLockInstance() def BuildHooksEnv(self): """Build hooks env. @@ -4111,6 +4138,9 @@ class LUSetInstanceParams(LogicalUnit): This only checks the instance list against the existing names. """ + # FIXME: all the parameters could be checked before, in ExpandNames, or in + # a separate CheckArguments function, if we implement one, so the operation + # can be aborted without waiting for any lock, should it have an error... self.mem = getattr(self.op, "mem", None) self.vcpus = getattr(self.op, "vcpus", None) self.ip = getattr(self.op, "ip", None) @@ -4205,13 +4235,9 @@ class LUSetInstanceParams(LogicalUnit): " like a valid IP address" % self.op.vnc_bind_address) - instance = self.cfg.GetInstanceInfo( - self.cfg.ExpandInstanceName(self.op.instance_name)) - if instance is None: - raise errors.OpPrereqError("No such instance name '%s'" % - self.op.instance_name) - self.op.instance_name = instance.name - self.instance = instance + self.instance = self.cfg.GetInstanceInfo(self.op.instance_name) + assert self.instance is not None, \ + "Cannot retrieve locked instance %s" % self.op.instance_name return def Exec(self, feedback_fn): @@ -4261,7 +4287,7 @@ class LUSetInstanceParams(LogicalUnit): instance.vnc_bind_address = self.vnc_bind_address result.append(("vnc_bind_address", self.vnc_bind_address)) - self.cfg.AddInstance(instance) + self.cfg.Update(instance) return result