Commit 0c072225 authored by Thomas Thrainer's avatar Thomas Thrainer
Browse files

Merge branch 'stable-2.7' into stable-2.8



* stable-2.7
  Fix documentation of gnt-instance batch-create
  Support multi instance allocs without iallocator
  Document --no-conflicts-check for gnt-network
  Check disk template in right dict when copying
  ganeti.backend_unittest: chmod restricted cmd dir
  Fix formatting of tuple in error message
  Fix 'prcre' typo in INSTALL
  Format gnt-network info group output
  Add 2.7.2 NEWS entry

Conflicts:
	INSTALL
      (trivial)
	NEWS
      (added entry to unreleased 2.8 section with remark that it was
       merged from 2.7)
	lib/cmdlib.py
      (followed cmdlib split)
Signed-off-by: default avatarThomas Thrainer <thomasth@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parents 33b52bdc e3aa2b69
......@@ -206,7 +206,7 @@ can use either apt::
or ``cabal``, after installing a required non-Haskell dependency::
$ apt-get install libpcre3-dev
$ apt-get install libpcre3-dev libcurl4-openssl-dev
$ cabal install hslogger Crypto text hinotify==0.3.2 regex-pcre \
attoparsec vector snap-server
......
......@@ -102,6 +102,8 @@ Since 2.8.0 beta1
- Fix query compatibility between haskell and python implementations
- Add the ``vnet_hdr`` HV parameter for KVM
- Add ``--cleanup`` to instance failover
- Change the connected groups format in ``gnt-network info`` output; it
was previously displayed as a raw list by mistake. (Merged from 2.7)
Version 2.8.0 beta1
......
......@@ -240,8 +240,8 @@ def ShowNetworkConfig(_, args):
if group_list:
ToStdout(" connected to node groups:")
for group in group_list:
ToStdout(" %s", group)
for group, nic_mode, nic_link in group_list:
ToStdout(" %s (%s on %s)", group, nic_mode, nic_link)
else:
ToStdout(" not connected to any node group")
......
......@@ -1831,9 +1831,9 @@ class LUInstanceMultiAlloc(NoHooksLU):
" pnode/snode while others do not",
errors.ECODE_INVAL)
if self.op.iallocator is None:
if not has_nodes and self.op.iallocator is None:
default_iallocator = self.cfg.GetDefaultIAllocator()
if default_iallocator and has_nodes:
if default_iallocator:
self.op.iallocator = default_iallocator
else:
raise errors.OpPrereqError("No iallocator or nodes on the instances"
......@@ -1886,35 +1886,36 @@ class LUInstanceMultiAlloc(NoHooksLU):
"""Check prerequisite.
"""
cluster = self.cfg.GetClusterInfo()
default_vg = self.cfg.GetVGName()
ec_id = self.proc.GetECId()
if self.op.iallocator:
cluster = self.cfg.GetClusterInfo()
default_vg = self.cfg.GetVGName()
ec_id = self.proc.GetECId()
if self.op.opportunistic_locking:
# Only consider nodes for which a lock is held
node_whitelist = list(self.owned_locks(locking.LEVEL_NODE))
else:
node_whitelist = None
if self.op.opportunistic_locking:
# Only consider nodes for which a lock is held
node_whitelist = list(self.owned_locks(locking.LEVEL_NODE))
else:
node_whitelist = None
insts = [_CreateInstanceAllocRequest(op, ComputeDisks(op, default_vg),
_ComputeNics(op, cluster, None,
self.cfg, ec_id),
_ComputeFullBeParams(op, cluster),
node_whitelist)
for op in self.op.instances]
insts = [_CreateInstanceAllocRequest(op, ComputeDisks(op, default_vg),
_ComputeNics(op, cluster, None,
self.cfg, ec_id),
_ComputeFullBeParams(op, cluster),
node_whitelist)
for op in self.op.instances]
req = iallocator.IAReqMultiInstanceAlloc(instances=insts)
ial = iallocator.IAllocator(self.cfg, self.rpc, req)
req = iallocator.IAReqMultiInstanceAlloc(instances=insts)
ial = iallocator.IAllocator(self.cfg, self.rpc, req)
ial.Run(self.op.iallocator)
ial.Run(self.op.iallocator)
if not ial.success:
raise errors.OpPrereqError("Can't compute nodes using"
" iallocator '%s': %s" %
(self.op.iallocator, ial.info),
errors.ECODE_NORES)
if not ial.success:
raise errors.OpPrereqError("Can't compute nodes using"
" iallocator '%s': %s" %
(self.op.iallocator, ial.info),
errors.ECODE_NORES)
self.ia_result = ial.result
self.ia_result = ial.result
if self.op.dry_run:
self.dry_run_result = objects.FillDict(self._ConstructPartialResult(), {
......@@ -1925,34 +1926,43 @@ class LUInstanceMultiAlloc(NoHooksLU):
"""Contructs the partial result.
"""
(allocatable, failed) = self.ia_result
if self.op.iallocator:
(allocatable, failed_insts) = self.ia_result
allocatable_insts = map(compat.fst, allocatable)
else:
allocatable_insts = [op.instance_name for op in self.op.instances]
failed_insts = []
return {
opcodes.OpInstanceMultiAlloc.ALLOCATABLE_KEY:
map(compat.fst, allocatable),
opcodes.OpInstanceMultiAlloc.FAILED_KEY: failed,
opcodes.OpInstanceMultiAlloc.ALLOCATABLE_KEY: allocatable_insts,
opcodes.OpInstanceMultiAlloc.FAILED_KEY: failed_insts,
}
def Exec(self, feedback_fn):
"""Executes the opcode.
"""
op2inst = dict((op.instance_name, op) for op in self.op.instances)
(allocatable, failed) = self.ia_result
jobs = []
for (name, nodes) in allocatable:
op = op2inst.pop(name)
if self.op.iallocator:
op2inst = dict((op.instance_name, op) for op in self.op.instances)
(allocatable, failed) = self.ia_result
if len(nodes) > 1:
(op.pnode, op.snode) = nodes
else:
(op.pnode,) = nodes
for (name, nodes) in allocatable:
op = op2inst.pop(name)
jobs.append([op])
if len(nodes) > 1:
(op.pnode, op.snode) = nodes
else:
(op.pnode,) = nodes
jobs.append([op])
missing = set(op2inst.keys()) - set(failed)
assert not missing, \
"Iallocator did return incomplete result: %s" % utils.CommaJoin(missing)
missing = set(op2inst.keys()) - set(failed)
assert not missing, \
"Iallocator did return incomplete result: %s" % \
utils.CommaJoin(missing)
else:
jobs.extend([op] for op in self.op.instances)
return ResultWithJobs(jobs, **self._ConstructPartialResult())
......
......@@ -111,7 +111,7 @@ def RemoveFromUidPool(uid_pool, remove_uids):
if uid_range not in uid_pool:
raise errors.OpPrereqError(
"User-id range to be removed is not found in the current"
" user-id pool: %s" % uid_range, errors.ECODE_INVAL)
" user-id pool: %s" % str(uid_range), errors.ECODE_INVAL)
uid_pool.remove(uid_range)
......
......@@ -872,36 +872,42 @@ Example::
BATCH-CREATE
^^^^^^^^^^^^
**batch-create** {instances\_file.json}
| **batch-create**
| [{-I|\--iallocator} *instance allocator*]
| {instances\_file.json}
This command (similar to the Ganeti 1.2 **batcher** tool) submits
multiple instance creation jobs based on a definition file. The
instance configurations do not encompass all the possible options for
the **add** command, but only a subset.
multiple instance creation jobs based on a definition file. This
file can contain all options which are valid when adding an instance
with the exception of the ``iallocator`` field. The IAllocator is,
for optimization purposes, only allowed to be set for the whole batch
operation using the ``--iallocator`` parameter.
The instance file should be a valid-formed JSON file, containing a
dictionary with instance name and instance parameters. The accepted
parameters are:
The instance file must be a valid-formed JSON file, containing an
array of dictionaries with instance creation parameters. All parameters
(except ``iallocator``) which are valid for the instance creation
OP code are allowed. The most important ones are:
disk\_size
The size of the disks of the instance.
instance\_name
The FQDN of the new instance.
disk\_template
The disk template to use for the instance, the same as in the
**add** command.
backend
disks
Array of disk specifications. Each entry describes one disk as a
dictionary of disk parameters.
beparams
A dictionary of backend parameters.
hypervisor
A dictionary with a single key (the hypervisor name), and as value
the hypervisor options. If not passed, the default hypervisor and
hypervisor options will be inherited.
The hypervisor for the instance.
mac, ip, mode, link
Specifications for the one NIC that will be created for the
instance. 'bridge' is also accepted as a backwards compatible
key.
hvparams
A dictionary with the hypervisor options. If not passed, the default
hypervisor options will be inherited.
nics
List of NICs that will be created for the instance. Each entry
......@@ -909,13 +915,11 @@ nics
Please don't provide the "mac, ip, mode, link" parent keys if you
use this method for specifying NICs.
primary\_node, secondary\_node
pnode, snode
The primary and optionally the secondary node to use for the
instance (in case an iallocator script is not used).
iallocator
Instead of specifying the nodes, an iallocator script can be used
to automatically compute them.
instance (in case an iallocator script is not used). If those
parameters are given, they have to be given consistently for all
instances in the batch operation.
start
whether to start the instance
......@@ -936,30 +940,34 @@ file\_storage\_dir, file\_driver
A simple definition for one instance can be (with most of the
parameters taken from the cluster defaults)::
{
"instance3": {
"template": "drbd",
"os": "debootstrap",
"disk_size": ["25G"],
"iallocator": "dumb"
[
{
"mode": "create",
"instance_name": "instance1.example.com",
"disk_template": "drbd",
"os_type": "debootstrap",
"disks": [{"size":"1024"}],
"nics": [{}],
"hypervisor": "xen-pvm"
},
"instance5": {
"template": "drbd",
"os": "debootstrap",
"disk_size": ["25G"],
"iallocator": "dumb",
{
"mode": "create",
"instance_name": "instance2.example.com",
"disk_template": "drbd",
"os_type": "debootstrap",
"disks": [{"size":"4096", "mode": "rw", "vg": "xenvg"}],
"nics": [{}],
"hypervisor": "xen-hvm",
"hvparams": {"acpi": true},
"backend": {"maxmem": 512, "minmem": 256}
"beparams": {"maxmem": 512, "minmem": 256}
}
}
]
The command will display the job id for each submitted instance, as
follows::
# gnt-instance batch-create instances.json
instance3: 11224
instance5: 11225
Submitted jobs 37, 38
REMOVE
^^^^^^
......
......@@ -41,6 +41,7 @@ ADD
| [\--gateway6=*GATEWAY6*]
| [\--mac-prefix=*MACPREFIX*]
| [\--submit]
| [\--no-conflicts-check]
| {*network*}
Creates a new network with the given name. The network will be unused
......@@ -57,6 +58,9 @@ IPv6 semantics can be assigned to the network via the ``--network6`` and
``--gateway6`` options. IP pool is meaningless for IPV6 so those two
values can be used for EUI64 generation from a NIC's MAC address.
The ``--no-conflicts-check`` option can be used to skip the check for
conflicting IP addresses.
Note that a when connecting a network to a node group (see below) you
can specify also the NIC mode and link that will be used by instances on
that group to physically connect to this network. This allows the system
......@@ -141,12 +145,17 @@ Displays information about a given network.
CONNECT
~~~~~~~
| **connect** {*network*} {*mode*} {*link*} [*groups*...]
| **connect**
| [\--no-conflicts-check]
| {*network*} {*mode*} {*link*} [*groups*...]
Connect a network to given node groups (all if not specified) with the
network parameters *mode* and *link*. Every network interface will
inherit those parameters if assigned in a network.
The ``--no-conflicts-check`` option can be used to skip the check for
conflicting IP addresses.
DISCONNECT
~~~~~~~~~~
......
......@@ -168,6 +168,7 @@ class TestVerifyRestrictedCmdDirectory(unittest.TestCase):
def testNormal(self):
tmpname = utils.PathJoin(self.tmpdir, "foobar")
os.mkdir(tmpname)
os.chmod(tmpname, 0755)
self.assertTrue(os.path.isdir(tmpname))
(status, msg) = \
backend._VerifyRestrictedCmdDirectory(tmpname,
......
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