Commit b795a775 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Merge branch 'devel-2.4'



* devel-2.4:
  ht: Add new check for numbers
  Fix off-by-one bug in job serial generation
  Shorten some unbreakable lines in man pages
  Correct some spelling mistakes
  Fix bug in recreate-disks for DRBD instances
  Fix a lint warning
  KVM: configure bridged NICs at migration start
  Fix RAPI documentation regarding master role
  Fix bug in drbd8 replace disks on current nodes

Conflicts:
	lib/cmdlib.py: Trivial
	lib/opcodes.py: Trivial
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parents 7238edb5 697f49d5
......@@ -1685,7 +1685,7 @@ response body. Typical examples of queries would be: list of nodes,
instances, cluster info, etc.
In the case of job submission, the client receive a job ID, the
identifier which allows to query the job progress in the job queue
identifier which allows one to query the job progress in the job queue
(see `Job Queue`_).
Internally, each exported object has an version identifier, which is
......
......@@ -286,8 +286,8 @@ level only, allowing us to easily support non-DRBD instance moves.
Intra-cluster instance moves will re-use the existing export and import
scripts supplied by instance OS definitions. Unlike simply copying the
raw data, this allows to use filesystem-specific utilities to dump only
used parts of the disk and to exclude certain disks from the move.
raw data, this allows one to use filesystem-specific utilities to dump
only used parts of the disk and to exclude certain disks from the move.
Compression should be used to further reduce the amount of data
transferred.
......
......@@ -1225,11 +1225,14 @@ It supports the following commands: ``GET``, ``PUT``.
The role is always one of the following:
- drained
- master
- master-candidate
- offline
- regular
Note that the 'master' role is a special, and currently it can't be
modified via RAPI, only via the command line (``gnt-cluster
master-failover``).
``GET``
~~~~~~~
......
......@@ -122,11 +122,11 @@ only one available before Ganeti 2.1.2.
Under security model 'user' an instance is run as the user specified by
the hypervisor parameter 'security_domain'. This makes it easy to run
all instances as non privileged users, and allows to manually allocate
specific users to specific instances or sets of instances. If the
specified user doesn't have permissions a jail broken instance will need
some local privilege escalation before being able to take over the node
and the cluster. It's possible though for a jail broken instance to
all instances as non privileged users, and allows one to manually
allocate specific users to specific instances or sets of instances. If
the specified user doesn't have permissions a jail broken instance will
need some local privilege escalation before being able to take over the
node and the cluster. It's possible though for a jail broken instance to
affect other ones running under the same user.
Under security model 'pool' a global cluster-level uid pool is used to
......
......@@ -6062,31 +6062,44 @@ class LUInstanceRecreateDisks(LogicalUnit):
"""Recreate the disks.
"""
# change primary node, if needed
if self.op.nodes:
self.instance.primary_node = self.op.nodes[0]
self.LogWarning("Changing the instance's nodes, you will have to"
" remove any disks left on the older nodes manually")
instance = self.instance
to_skip = []
for idx, disk in enumerate(self.instance.disks):
mods = [] # keeps track of needed logical_id changes
for idx, disk in enumerate(instance.disks):
if idx not in self.op.disks: # disk idx has not been passed in
to_skip.append(idx)
continue
# update secondaries for disks, if needed
if self.op.nodes:
if disk.dev_type == constants.LD_DRBD8:
# need to update the nodes
# need to update the nodes and minors
assert len(self.op.nodes) == 2
logical_id = list(disk.logical_id)
logical_id[0] = self.op.nodes[0]
logical_id[1] = self.op.nodes[1]
disk.logical_id = tuple(logical_id)
assert len(disk.logical_id) == 6 # otherwise disk internals
# have changed
(_, _, old_port, _, _, old_secret) = disk.logical_id
new_minors = self.cfg.AllocateDRBDMinor(self.op.nodes, instance.name)
new_id = (self.op.nodes[0], self.op.nodes[1], old_port,
new_minors[0], new_minors[1], old_secret)
assert len(disk.logical_id) == len(new_id)
mods.append((idx, new_id))
# now that we have passed all asserts above, we can apply the mods
# in a single run (to avoid partial changes)
for idx, new_id in mods:
instance.disks[idx].logical_id = new_id
# change primary node, if needed
if self.op.nodes:
self.cfg.Update(self.instance, feedback_fn)
instance.primary_node = self.op.nodes[0]
self.LogWarning("Changing the instance's nodes, you will have to"
" remove any disks left on the older nodes manually")
if self.op.nodes:
self.cfg.Update(instance, feedback_fn)
_CreateDisks(self, self.instance, to_skip=to_skip)
_CreateDisks(self, instance, to_skip=to_skip)
class LUInstanceRename(LogicalUnit):
......@@ -9341,6 +9354,12 @@ class TLReplaceDisks(Tasklet):
(node_name, self.instance.name))
def _CreateNewStorage(self, node_name):
"""Create new storage on the primary or secondary node.
This is only used for same-node replaces, not for changing the
secondary node, hence we don't want to modify the existing disk.
"""
iv_names = {}
for idx, dev in enumerate(self.instance.disks):
......@@ -9362,7 +9381,7 @@ class TLReplaceDisks(Tasklet):
logical_id=(vg_meta, names[1]))
new_lvs = [lv_data, lv_meta]
old_lvs = dev.children
old_lvs = [child.Copy() for child in dev.children]
iv_names[dev.iv_name] = (dev, old_lvs, new_lvs)
# we pass force_create=True to force the LVM creation
......@@ -9400,7 +9419,7 @@ class TLReplaceDisks(Tasklet):
self.lu.LogWarning("Can't remove old LV: %s" % msg,
hint="remove unused LVs manually")
def _ExecDrbd8DiskOnly(self, feedback_fn):
def _ExecDrbd8DiskOnly(self, feedback_fn): # pylint: disable-msg=W0613
"""Replace a disk on the primary or secondary for DRBD 8.
The algorithm for replace is quite complicated:
......@@ -9483,10 +9502,14 @@ class TLReplaceDisks(Tasklet):
rename_new_to_old)
result.Raise("Can't rename new LVs on node %s" % self.target_node)
# Intermediate steps of in memory modifications
for old, new in zip(old_lvs, new_lvs):
new.logical_id = old.logical_id
self.cfg.SetDiskID(new, self.target_node)
# We need to modify old_lvs so that removal later removes the
# right LVs, not the newly added ones; note that old_lvs is a
# copy here
for disk in old_lvs:
disk.logical_id = ren_fn(disk, temp_suffix)
self.cfg.SetDiskID(disk, self.target_node)
......@@ -9506,10 +9529,6 @@ class TLReplaceDisks(Tasklet):
"volumes"))
raise errors.OpExecError("Can't add local storage to drbd: %s" % msg)
dev.children = new_lvs
self.cfg.Update(self.instance, feedback_fn)
cstep = 5
if self.early_release:
self.lu.LogStep(cstep, steps_total, "Removing old storage")
......
......@@ -296,6 +296,9 @@ TPositiveFloat = \
TJobId = TOr(TPositiveInt,
TRegex(re.compile("^%s$" % constants.JOB_ID_TEMPLATE)))
#: Number
TNumber = TOr(TInt, TFloat)
def TListOf(my_type):
"""Checks if a given value is a list with all elements of the same type.
......
......@@ -866,11 +866,13 @@ class KVMHypervisor(hv_base.BaseHypervisor):
utils.EnsureDirs([(self._InstanceChrootDir(name),
constants.SECURE_DIR_MODE)])
if not incoming:
# Configure the network now for starting instances, during
# FinalizeMigration for incoming instances
for nic_seq, nic in enumerate(kvm_nics):
self._ConfigureNIC(instance, nic_seq, nic, taps[nic_seq])
# Configure the network now for starting instances and bridged interfaces,
# during FinalizeMigration for incoming instances' routed interfaces
for nic_seq, nic in enumerate(kvm_nics):
if (incoming and
nic.nicparams[constants.NIC_MODE] != constants.NIC_MODE_BRIDGED):
continue
self._ConfigureNIC(instance, nic_seq, nic, taps[nic_seq])
if security_model == constants.HT_SM_POOL:
ss = ssconf.SimpleStore()
......@@ -1036,6 +1038,9 @@ class KVMHypervisor(hv_base.BaseHypervisor):
kvm_nics = kvm_runtime[1]
for nic_seq, nic in enumerate(kvm_nics):
if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
# Bridged interfaces have already been configured
continue
try:
tap = utils.ReadFile(self._InstanceNICFile(instance.name, nic_seq))
except EnvironmentError, err:
......
......@@ -1537,10 +1537,13 @@ class JobQueue(object):
"%s\n" % serial, True)
result = [self._FormatJobID(v)
for v in range(self._last_serial, serial + 1)]
for v in range(self._last_serial + 1, serial + 1)]
# Keep it only if we were able to write the file
self._last_serial = serial
assert len(result) == count
return result
@staticmethod
......
......@@ -1427,7 +1427,7 @@ class OpTestDelay(OpCode):
"""
OP_DSC_FIELD = "duration"
OP_PARAMS = [
("duration", ht.NoDefault, ht.TFloat, None),
("duration", ht.NoDefault, ht.TNumber, None),
("on_master", True, ht.TBool, None),
("on_nodes", ht.EmptyList, ht.TListOf(ht.TNonEmptyString), None),
("repeat", 0, ht.TPositiveInt, None),
......
......@@ -110,7 +110,7 @@ _VERIFY_FN = {
QFT_BOOL: ht.TBool,
QFT_NUMBER: ht.TInt,
QFT_UNIT: ht.TInt,
QFT_TIMESTAMP: ht.TOr(ht.TInt, ht.TFloat),
QFT_TIMESTAMP: ht.TNumber,
QFT_OTHER: lambda _: True,
}
......
......@@ -89,7 +89,9 @@ Run a command on a list of hosts::
Upload a script, some auxiliary files and run the script::
listrunner -l logdir -x runme.sh -a seed.dat -a golden.dat -h host1,host2,host3
listrunner -l logdir -x runme.sh \
-a seed.dat -a golden.dat \
-h host1,host2,host3
SEE ALSO
......
......@@ -225,12 +225,12 @@ script could be::
#!/bin/sh
case $OSP_DHCP in
""|yes|no)
;;
*)
echo "Invalid value '$OSP_DHCP' for the dhcp parameter" 1>&2
exit 1;
;;
""|yes|no)
;;
*)
echo "Invalid value '$OSP_DHCP' for the dhcp parameter" 1>&2
exit 1;
;;
esac
exit 0
......
......@@ -23,7 +23,7 @@ that runs on every node.
If the watcher is disabled at cluster level (via the
**gnt-cluster watcher pause** command), it will exit without doing
anything. The cluster-level pause can be overriden via the
anything. The cluster-level pause can be overridden via the
``--ignore-pause`` option, for example if during a maintenance the
watcher needs to be disabled in general, but the administrator
wants to run it just once.
......
......@@ -308,7 +308,7 @@ link
network script it is interpreted as a routing table number or
name.
The option ``--maintain-node-health`` allows to enable/disable
The option ``--maintain-node-health`` allows one to enable/disable
automatic maintenance actions on nodes. Currently these include
automatic shutdown of instances and deactivation of DRBD devices on
offline nodes; in the future it might be extended to automatic
......
......@@ -112,7 +112,7 @@ The available fields and their meaning are:
@QUERY_FIELDS_LOCK@
If the value of the option starts with the character ``+``, the new
fields will be added to the default list. This allows to quickly
fields will be added to the default list. This allows one to quickly
see the default list plus a few other fields, instead of retyping
the entire list of fields.
......
......@@ -107,7 +107,7 @@ special field states (see **ganeti(7)**).
The ``-o`` option takes a comma-separated list of output fields.
If the value of the option starts with the character ``+``, the new
fields will be added to the default list. This allows to quickly
fields will be added to the default list. This allows one to quickly
see the default list plus a few other fields, instead of retyping
the entire list of fields.
......
......@@ -182,8 +182,8 @@ boot\_order
blockdev\_prefix
Valid for the Xen HVM and PVM hypervisors.
Relevant to nonpvops guest kernels, in which the disk device names
are given by the host. Allows to specify 'xvd', which helps run
Relevant to non-pvops guest kernels, in which the disk device names
are given by the host. Allows one to specify 'xvd', which helps run
Red Hat based installers, driven by anaconda.
floppy\_image\_path
......@@ -670,8 +670,8 @@ fields. The available fields and their meaning are:
@QUERY_FIELDS_INSTANCE@
If the value of the option starts with the character ``+``, the new
field(s) will be added to the default list. This allows to quickly see
the default list plus a few other fields, instead of retyping the
field(s) will be added to the default list. This allows one to quickly
see the default list plus a few other fields, instead of retyping the
entire list of fields.
There is a subtle grouping about the available output fields: all
......
......@@ -124,7 +124,7 @@ oppriority
If the value of the option starts with the character ``+``, the new
fields will be added to the default list. This allows to quickly
fields will be added to the default list. This allows one to quickly
see the default list plus a few other fields, instead of retyping
the entire list of fields.
......
......@@ -183,7 +183,7 @@ fields. The available fields and their meaning are:
@QUERY_FIELDS_NODE@
If the value of the option starts with the character ``+``, the new
fields will be added to the default list. This allows to quickly
fields will be added to the default list. This allows one to quickly
see the default list plus a few other fields, instead of retyping
the entire list of fields.
......
......@@ -53,6 +53,7 @@ class TestTypeChecks(unittest.TestCase):
def testInt(self):
for val in [-100, -3, 0, 16, 128, 923874]:
self.assertTrue(ht.TInt(val))
self.assertTrue(ht.TNumber(val))
for val in [False, True, None, "", [], "Hello", 0.0, 0.23, -3818.163]:
self.assertFalse(ht.TInt(val))
......@@ -76,10 +77,19 @@ class TestTypeChecks(unittest.TestCase):
def testFloat(self):
for val in [-100.21, -3.0, 0.0, 16.12, 128.3433, 923874.928]:
self.assertTrue(ht.TFloat(val))
self.assertTrue(ht.TNumber(val))
for val in [False, True, None, "", [], "Hello", 0, 28, -1, -3281]:
self.assertFalse(ht.TFloat(val))
def testNumber(self):
for val in [-100, -3, 0, 16, 128, 923874,
-100.21, -3.0, 0.0, 16.12, 128.3433, 923874.928]:
self.assertTrue(ht.TNumber(val))
for val in [False, True, None, "", [], "Hello", "1"]:
self.assertFalse(ht.TNumber(val))
def testString(self):
for val in ["", "abc", "Hello World", "123",
u"", u"\u272C", u"abc"]:
......
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