Commit bcba4e01 authored by Michele Tartara's avatar Michele Tartara

Merge stable-2.7 into stable-2.8

Conflicts:
	INSTALL
	NEWS
	configure.ac
	src/Ganeti/Query/Group.hs
	test/hs/Test/Ganeti/Objects.hs
	test/hs/Test/Ganeti/Query/Query.hs
Signed-off-by: default avatarMichele Tartara <mtartara@google.com>
Reviewed-by: default avatarHelga Velroyen <helgav@google.com>
parents 25f8d59c 7d60c3b5
......@@ -56,9 +56,19 @@ packages, except for RBD, DRBD and Xen::
$ apt-get install lvm2 ssh bridge-utils iproute iputils-arping \
ndisc6 python python-pyopenssl openssl \
python-pyparsing python-simplejson \
python-pyinotify python-pycurl socat fping \
python-ipaddr python-bitarray
python-pyparsing python-simplejson python-bitarray \
python-pyinotify python-pycurl python-ipaddr socat fping
If bitarray is missing it can be installed from easy-install::
$ easy_install bitarray
Or on newer distributions (eg. Debian Wheezy) the above becomes::
$ apt-get install lvm2 ssh bridge-utils iproute iputils-arping \
ndisc6 python python-openssl openssl \
python-pyparsing python-simplejson python-bitarray \
python-pyinotify python-pycurl python-ipaddr socat fping
Note that this does not install optional packages::
......@@ -194,7 +204,7 @@ can use either apt::
or ``cabal``, after installing a required non-Haskell dependency::
$ apt-get install libpcre3-dev
$ cabal install hslogger Crypto text hinotify regex-pcre \
$ cabal install hslogger Crypto text hinotify==0.3.2 regex-pcre \
attoparsec vector snap-server
to install them.
......
......@@ -444,7 +444,11 @@ mandocrst = $(addprefix doc/man-,$(notdir $(manrst)))
HS_BIN_PROGS=src/htools
# Haskell programs to be installed in the MYEXECLIB dir
if ENABLE_MOND
HS_MYEXECLIB_PROGS=src/mon-collector
else
HS_MYEXECLIB_PROGS=
endif
# Haskell programs to be compiled by "make really-all"
HS_COMPILE_PROGS= \
......
......@@ -24,10 +24,10 @@ Version 2.8.0 beta1
configuration back to the previous stable version.
Version 2.7.0 beta3
-------------------
Version 2.7.0 rc1
-----------------
*(Released Mon, 22 Apr 2013)*
*(unreleased)*
Incompatible/important changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......@@ -87,7 +87,8 @@ New features
``plain`` disk template are supported.
- The KVM hypervisor has been updated with many new hypervisor
parameters, including a generic one for passing arbitrary command line
values. See a complete list in :manpage:`gnt-instance(8)`.
values. See a complete list in :manpage:`gnt-instance(8)`. It is now
compatible up to qemu 1.4.
- A new tool, called ``mon-collector``, is the stand-alone executor of
the data collectors for a monitoring system. As of this version, it
just includes the DRBD data collector, that can be executed by calling
......@@ -131,7 +132,31 @@ Misc changes
- The functionality for allocating multiple instances at once has been
overhauled and is now also available through :doc:`RAPI <rapi>`.
Since beta2:
Since beta3:
- Fix kvm compatibility with qemu 1.4 (Issue 389)
- Documentation updates (admin guide, upgrade notes, install
instructions) (Issue 372)
- Fix gnt-group list nodes and instances count (Issue 436)
- Fix compilation without non-mandatory libraries (Issue 441)
- Fix xen-hvm hypervisor forcing nics to type 'ioemu' (Issue 247)
- Make confd logging more verbose at INFO level (Issue 435)
- Improve "networks" documentation in :manpage:`gnt-instance(8)`
- Fix failure path for instance storage type conversion (Issue 229)
- Update htools text backend documentation
- Improve the renew-crypto section of :manpage:`gnt-cluster(8)`
- Disable inter-cluster instance move for file-based instances, because
it is dependant on instance export, which is not supported for
file-based instances. (Issue 414)
Version 2.7.0 beta3
-------------------
*(Released Mon, 22 Apr 2013)*
This was the third beta release of the 2.7 series. Since beta2:
- Fix hail to verify disk instance policies on a per-disk basis (Issue 418).
- Fix data loss on wrong usage of ``gnt-instance move``
......
......@@ -63,6 +63,12 @@ To run commands on all nodes, the `distributed shell (dsh)
$ gnt-cluster redist-conf
#. If you use file storage, check that the ``/etc/ganeti/file-storage-paths``
#. is correct on all nodes. For security reasons it's not copied
#. automatically, but it can be copied manually via::
$ gnt-cluster copyfile /etc/ganeti/file-storage-paths
#. Restart daemons again on all nodes::
$ /etc/init.d/ganeti restart
......
......@@ -566,8 +566,13 @@ if test "$enable_monitoring" != no; then
[MONITORING_PKG="$MONITORING_PKG attoparsec"])
AC_GHC_PKG_CHECK([snap-server], [],
[MONITORING_PKG="$MONITORING_PKG snap-server"])
MONITORING_DEP=
if test "$has_confd" = False; then
MONITORING_DEP="$MONITORING_DEP confd"
fi
has_monitoring_pkg=False
if test -z "$MONITORING_PKG"; then
has_monitoring=True
has_monitoring_pkg=True
elif test "$enable_monitoring" = check; then
AC_MSG_WARN(m4_normalize([The required extra libraries for the monitoring
daemon were not found ($MONITORING_PKG),
......@@ -577,9 +582,23 @@ if test "$enable_monitoring" != no; then
required libraries were not found:
$MONITORING_PKG]))
fi
has_monitoring_dep=False
if test -z "$MONITORING_DEP"; then
has_monitoring_dep=True
elif test "$enable_monitoring" = check; then
AC_MSG_WARN(m4_normalize([The optional Ganeti components required for the
monitoring agent were not enabled
($MONITORING_DEP), monitoring disabled]))
else
AC_MSG_FAILURE(m4_normalize([The monitoring functionality was requested, but
required optional Ganeti components were not
found: $MONITORING_DEP]))
fi
fi
if test "$has_monitoring" = True; then
AC_MSG_NOTICE([Enabling the monitoring daemon usage])
if test "$has_monitoring_pkg" = True -a "$has_monitoring_dep" = True; then
has_monitoring=True
AC_MSG_NOTICE([Enabling the monitoring agent usage])
fi
AC_SUBST(ENABLE_MOND, $has_monitoring)
AM_CONDITIONAL([ENABLE_MOND], [test "$has_monitoring" = True])
......
......@@ -124,7 +124,18 @@ diskless
file
The instance will use plain files as backend for its disks. No
redundancy is provided, and this is somewhat more difficult to
configure for high performance.
configure for high performance. Note that for security reasons the
file storage directory must be listed under
``/etc/ganeti/file-storage-paths``, and that file is not copied
automatically to all nodes by Ganeti.
sharedfile
The instance will use plain files as backend, but Ganeti assumes that
those files will be available and in sync automatically on all nodes.
This allows live migration and failover of instances using this
method. As for ``file`` the file storage directory must be listed under
``/etc/ganeti/file-storage-paths`` or ganeti will refuse to create
instances under it.
plain
The instance will use LVM devices as backend for its disks. No
......@@ -146,6 +157,11 @@ rbd
The instance will use Volumes inside a RADOS cluster as backend for its
disks. It will access them using the RADOS block device (RBD).
ext
The instance will use an external storage provider. See
:manpage:`ganeti-extstorage-interface(7)` for how to implement one.
IAllocator
~~~~~~~~~~
......@@ -263,7 +279,7 @@ can give include, among others:
instance is created. The IP and/or bridge of the NIC can be changed
via ``--net 0:ip=IP,link=BRIDGE``
See the manpage for gnt-instance for the detailed option list.
See :manpage:`ganeti-instance(8)` for the detailed option list.
For example if you want to create an highly available instance, with a
single disk of 50GB and the default memory size, having primary node
......
......@@ -301,6 +301,13 @@ instances on a node.
$ apt-get install drbd8-source drbd8-utils
$ m-a update
$ m-a a-i drbd8
Or on newer versions, if the kernel already has modules:
$ apt-get install drbd8-utils
Then to configure it for Ganeti::
$ echo drbd minor_count=128 usermode_helper=/bin/true >> /etc/modules
$ depmod -a
$ modprobe drbd minor_count=128 usermode_helper=/bin/true
......
......@@ -184,7 +184,9 @@ def _CheckFileStoragePath(path, allowed):
break
else:
raise errors.FileStoragePathError("Path '%s' is not acceptable for file"
" storage" % path)
" storage. A possible fix might be to add"
" it to /etc/ganeti/file-storage-paths"
" on all nodes." % path)
def _LoadAllowedFileStoragePaths(filename):
......
......@@ -4227,10 +4227,14 @@ class LUClusterSetParams(LogicalUnit):
node_list = self.owned_locks(locking.LEVEL_NODE)
vm_capable_nodes = [node.name
for node in self.cfg.GetAllNodesInfo().values()
if node.name in node_list and node.vm_capable]
# if vg_name not None, checks given volume group on all nodes
if self.op.vg_name:
vglist = self.rpc.call_vg_list(node_list)
for node in node_list:
vglist = self.rpc.call_vg_list(vm_capable_nodes)
for node in vm_capable_nodes:
msg = vglist[node].fail_msg
if msg:
# ignoring down node
......@@ -14152,11 +14156,22 @@ class LUInstanceSetParams(LogicalUnit):
feedback_fn("Initializing DRBD devices...")
# all child devices are in place, we can now create the DRBD devices
for disk in anno_disks:
for (node, excl_stor) in [(pnode, p_excl_stor), (snode, s_excl_stor)]:
f_create = node == pnode
_CreateSingleBlockDev(self, node, instance, disk, info, f_create,
excl_stor)
try:
for disk in anno_disks:
for (node, excl_stor) in [(pnode, p_excl_stor), (snode, s_excl_stor)]:
f_create = node == pnode
_CreateSingleBlockDev(self, node, instance, disk, info, f_create,
excl_stor)
except errors.GenericError, e:
feedback_fn("Initializing of DRBD devices failed;"
" renaming back original volumes...")
for disk in new_disks:
self.cfg.SetDiskID(disk, pnode)
rename_back_list = [(n.children[0], o.logical_id)
for (n, o) in zip(new_disks, instance.disks)]
result = self.rpc.call_blockdev_rename(pnode, rename_back_list)
result.Raise("Failed to rename LVs back after error %s" % str(e))
raise
# at this point, the instance has been modified
instance.disk_template = constants.DT_DRBD8
......@@ -17094,7 +17109,8 @@ def _CheckForConflictingIp(lu, ip, node):
"""
(conf_net, _) = lu.cfg.CheckIPInNodeGroup(ip, node)
if conf_net is not None:
raise errors.OpPrereqError(("Conflicting IP address found: '%s' != '%s'" %
raise errors.OpPrereqError(("The requested IP address (%s) belongs to"
" network %s, but the target NIC does not." %
(ip, conf_net)),
errors.ECODE_STATE)
......
......@@ -942,6 +942,7 @@ HV_VGA = "vga"
HV_KVM_EXTRA = "kvm_extra"
HV_KVM_MACHINE_VERSION = "machine_version"
HV_KVM_PATH = "kvm_path"
HV_VIF_TYPE = "vif_type"
HVS_PARAMETER_TYPES = {
......@@ -1011,6 +1012,7 @@ HVS_PARAMETER_TYPES = {
HV_VGA: VTYPE_STRING,
HV_KVM_EXTRA: VTYPE_STRING,
HV_KVM_MACHINE_VERSION: VTYPE_STRING,
HV_VIF_TYPE: VTYPE_STRING,
}
HVS_PARAMETERS = frozenset(HVS_PARAMETER_TYPES.keys())
......@@ -1407,6 +1409,15 @@ HT_KVM_VALID_NIC_TYPES = compat.UniqueFrozenset([
HT_NIC_PARAVIRTUAL,
])
# Vif types
# default vif type in xen-hvm
HT_HVM_VIF_IOEMU = "ioemu"
HT_HVM_VIF_VIF = "vif"
HT_HVM_VALID_VIF_TYPES = compat.UniqueFrozenset([
HT_HVM_VIF_IOEMU,
HT_HVM_VIF_VIF,
])
# Disk types
HT_DISK_IOEMU = "ioemu"
HT_DISK_IDE = "ide"
......@@ -2027,6 +2038,7 @@ HVC_DEFAULTS = {
HV_CPU_MASK: CPU_PINNING_ALL,
HV_CPU_CAP: 0,
HV_CPU_WEIGHT: 256,
HV_VIF_TYPE: HT_HVM_VIF_IOEMU,
},
HT_KVM: {
HV_KVM_PATH: KVM_PATH,
......
......@@ -564,6 +564,8 @@ class KVMHypervisor(hv_base.BaseHypervisor):
_ENABLE_KVM_RE = re.compile(r"^-enable-kvm\s", re.M)
_DISABLE_KVM_RE = re.compile(r"^-disable-kvm\s", re.M)
_NETDEV_RE = re.compile(r"^-netdev\s", re.M)
_DISPLAY_RE = re.compile(r"^-display\s", re.M)
_MACHINE_RE = re.compile(r"^-machine\s", re.M)
_NEW_VIRTIO_RE = re.compile(r"^name \"%s\"" % _VIRTIO_NET_PCI, re.M)
# match -drive.*boot=on|off on different lines, but in between accept only
# dashes not preceeded by a new line (which would mean another option
......@@ -1034,6 +1036,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
"""
# pylint: disable=R0912,R0914,R0915
hvp = instance.hvparams
self.ValidateParameters(hvp)
pidfile = self._InstancePidFile(instance.name)
kvm = hvp[constants.HV_KVM_PATH]
......@@ -1064,7 +1067,24 @@ class KVMHypervisor(hv_base.BaseHypervisor):
mversion = hvp[constants.HV_KVM_MACHINE_VERSION]
if not mversion:
mversion = self._GetDefaultMachineVersion(kvm)
kvm_cmd.extend(["-M", mversion])
if self._MACHINE_RE.search(kvmhelp):
# TODO (2.8): kernel_irqchip and kvm_shadow_mem machine properties, as
# extra hypervisor parameters. We should also investigate whether and how
# shadow_mem should be considered for the resource model.
if (hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_ENABLED):
specprop = ",accel=kvm"
else:
specprop = ""
machinespec = "%s%s" % (mversion, specprop)
kvm_cmd.extend(["-machine", machinespec])
else:
kvm_cmd.extend(["-M", mversion])
if (hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_ENABLED and
self._ENABLE_KVM_RE.search(kvmhelp)):
kvm_cmd.extend(["-enable-kvm"])
elif (hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_DISABLED and
self._DISABLE_KVM_RE.search(kvmhelp)):
kvm_cmd.extend(["-disable-kvm"])
kernel_path = hvp[constants.HV_KERNEL_PATH]
if kernel_path:
......@@ -1075,18 +1095,9 @@ class KVMHypervisor(hv_base.BaseHypervisor):
boot_floppy = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_FLOPPY
boot_network = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_NETWORK
self.ValidateParameters(hvp)
if startup_paused:
kvm_cmd.extend([_KVM_START_PAUSED_FLAG])
if (hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_ENABLED and
self._ENABLE_KVM_RE.search(kvmhelp)):
kvm_cmd.extend(["-enable-kvm"])
elif (hvp[constants.HV_KVM_FLAG] == constants.HT_KVM_DISABLED and
self._DISABLE_KVM_RE.search(kvmhelp)):
kvm_cmd.extend(["-disable-kvm"])
if boot_network:
kvm_cmd.extend(["-boot", "n"])
......@@ -1342,7 +1353,12 @@ class KVMHypervisor(hv_base.BaseHypervisor):
kvm_cmd.extend(["-spice", spice_arg])
else:
kvm_cmd.extend(["-nographic"])
# From qemu 1.4 -nographic is incompatible with -daemonize. The new way
# also works in earlier versions though (tested with 1.1 and 1.3)
if self._DISPLAY_RE.search(kvmhelp):
kvm_cmd.extend(["-display", "none"])
else:
kvm_cmd.extend(["-nographic"])
if hvp[constants.HV_USE_LOCALTIME]:
kvm_cmd.extend(["-localtime"])
......
......@@ -909,6 +909,8 @@ class XenHvmHypervisor(XenHypervisor):
constants.HV_CPU_CAP: hv_base.NO_CHECK,
constants.HV_CPU_WEIGHT:
(False, lambda x: 0 < x < 65535, "invalid weight", None, None),
constants.HV_VIF_TYPE:
hv_base.ParamInSet(False, constants.HT_HVM_VALID_VIF_TYPES),
}
def _GetConfig(self, instance, startup_memory, block_devices):
......@@ -980,14 +982,23 @@ class XenHvmHypervisor(XenHypervisor):
config.write("localtime = 1\n")
vif_data = []
# Note: what is called 'nic_type' here, is used as value for the xen nic
# vif config parameter 'model'. For the xen nic vif parameter 'type', we use
# the 'vif_type' to avoid a clash of notation.
nic_type = hvp[constants.HV_NIC_TYPE]
if nic_type is None:
vif_type_str = ""
if hvp[constants.HV_VIF_TYPE]:
vif_type_str = ", type=%s" % hvp[constants.HV_VIF_TYPE]
# ensure old instances don't change
nic_type_str = ", type=ioemu"
nic_type_str = vif_type_str
elif nic_type == constants.HT_NIC_PARAVIRTUAL:
nic_type_str = ", type=paravirtualized"
else:
nic_type_str = ", model=%s, type=ioemu" % nic_type
# parameter 'model' is only valid with type 'ioemu'
nic_type_str = ", model=%s, type=%s" % \
(nic_type, constants.HT_HVM_VIF_IOEMU)
for nic in instance.nics:
nic_str = "mac=%s%s" % (nic.mac, nic_type_str)
ip = getattr(nic, "ip", None)
......
......@@ -31,7 +31,8 @@ ADD
| {\--disk=*N*: {size=*VAL* \| adopt=*LV*}[,options...]
| \| {size=*VAL*,provider=*PROVIDER*}[,param=*value*... ][,options...]
| \| {-s|\--os-size} *SIZE*}
| [\--no-ip-check] [\--no-name-check] [\--no-start] [\--no-install]
| [\--no-ip-check] [\--no-name-check] [\--no-conflicts-check]
| [\--no-start] [\--no-install]
| [\--net=*N* [:options...] \| \--no-nics]
| [{-B|\--backend-parameters} *BEPARAMS*]
| [{-H|\--hypervisor-parameters} *HYPERVISOR* [: option=*value*... ]]
......@@ -124,7 +125,13 @@ mac
ip
specifies the IP address assigned to the instance from the Ganeti
side (this is not necessarily what the instance will use, but what
the node expects the instance to use)
the node expects the instance to use). Note that if an IP in the
range of a network configured with **gnt-network**\(8) is used,
and the NIC is not already connected to it, this network has to be
passed in the **network** parameter if this NIC is meant to be
connected to the said network. ``--no-conflicts-check`` can be used
to override this check. The special value **pool** causes Ganeti to
select an IP from the the network the NIC is or will be connected to.
mode
specifies the connection mode for this NIC: routed, bridged or
......@@ -278,6 +285,17 @@ nic\_type
- e1000 (KVM)
- paravirtual (default for KVM) (HVM & KVM)
vif\_type
Valid for the Xen HVM hypervisor.
This parameter specifies the vif type of the nic configuration
of the instance. Unsetting the value leads to no type being specified
in the configuration. Note that this parameter only takes effect when
the 'nic_type' is not set. The possible options are:
- ioemu
- vif
disk\_type
Valid for the Xen HVM and KVM hypervisors.
......
......@@ -177,7 +177,6 @@ handleCall _ op =
return . Bad $
GenericError ("Luxi call '" ++ strOfOp op ++ "' not implemented")
-- | Given a decoded luxi request, executes it and sends the luxi
-- response back to the client.
handleClientMsg :: Client -> ConfigReader -> LuxiOp -> IO Bool
......@@ -188,11 +187,13 @@ handleClientMsg client creader args = do
(!status, !rval) <-
case call_result of
Bad err -> do
logWarning $ "Failed to execute request: " ++ show err
logWarning $ "Failed to execute request " ++ show args ++ ": "
++ show err
return (False, showJSON err)
Ok result -> do
-- only log the first 2,000 chars of the result
logDebug $ "Result (truncated): " ++ take 2000 (J.encode result)
logInfo $ "Successfully handled " ++ strOfOp args
return (True, result)
sendMsg client $ buildResponse status rval
return True
......
......@@ -660,7 +660,7 @@ genStrOfKey = genConstrToStr ensureLower
-- | Generates the LuxiOp data type.
--
-- This takes a Luxi operation definition and builds both the
-- datatype and the function trnasforming the arguments to JSON.
-- datatype and the function transforming the arguments to JSON.
-- We can't use anything less generic, because the way different
-- operations are serialized differs on both parameter- and top-level.
--
......
......@@ -563,6 +563,9 @@ class MoveSourceExecutor(object):
logging.info("Retrieving instance information from source cluster")
instinfo = self._GetInstanceInfo(src_client, mrt.PollJob,
mrt.move.src_instance_name)
if instinfo["disk_template"] == constants.DT_FILE:
raise Error("Inter-cluster move of file-based instances is not"
" supported.")
logging.info("Preparing export on source cluster")
expinfo = self._PrepareExport(src_client, mrt.PollJob,
......
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