Commit 74409b12 authored by Iustin Pop's avatar Iustin Pop
Browse files

Change gnt-instance modify to the hvparams model

Reviewed-by: imsnah
parent 5018a335
......@@ -31,6 +31,7 @@ import tempfile
import re
import platform
import logging
import copy
from ganeti import ssh
from ganeti import logger
......@@ -3139,6 +3140,36 @@ def _ComputeDiskSize(disk_template, disk_size, swap_size):
return req_size_dict[disk_template]
def _CheckHVParams(lu, nodenames, hvname, hvparams):
"""Hypervisor parameter validation.
This function abstract the hypervisor parameter validation to be
used in both instance create and instance modify.
@type lu: L{LogicalUnit}
@param lu: the logical unit for which we check
@type nodenames: list
@param nodenames: the list of nodes on which we should check
@type hvname: string
@param hvname: the name of the hypervisor we should use
@type hvparams: dict
@param hvparams: the parameters which we need to check
@raise errors.OpPrereqError: if the parameters are not valid
"""
hvinfo = lu.rpc.call_hypervisor_validate_params(nodenames,
hvname,
hvparams)
for node in nodenames:
info = hvinfo.get(node, None)
if not info or not isinstance(info, (tuple, list)):
raise errors.OpPrereqError("Cannot get current information"
" from node '%s' (%s)" % (node, info))
if not info[0]:
raise errors.OpPrereqError("Hypervisor parameter validation failed:"
" %s" % info[1])
class LUCreateInstance(LogicalUnit):
"""Create an instance.
......@@ -3449,18 +3480,7 @@ class LUCreateInstance(LogicalUnit):
" %d MB available, %d MB required" %
(node, info['vg_free'], req_size))
# hypervisor parameter validation
hvinfo = self.rpc.call_hypervisor_validate_params(nodenames,
self.op.hypervisor,
self.op.hvparams)
for node in nodenames:
info = hvinfo.get(node, None)
if not info or not isinstance(info, (tuple, list)):
raise errors.OpPrereqError("Cannot get current information"
" from node '%s' (%s)" % (node, info))
if not info[0]:
raise errors.OpPrereqError("Hypervisor parameter validation failed:"
" %s" % info[1])
_CheckHVParams(self, nodenames, self.op.hypervisor, self.op.hvparams)
# os verification
os_obj = self.rpc.call_os_get(pnode.name, self.op.os_type)
......@@ -4450,11 +4470,18 @@ class LUSetInstanceParams(LogicalUnit):
"""
HPATH = "instance-modify"
HTYPE = constants.HTYPE_INSTANCE
_OP_REQP = ["instance_name"]
_OP_REQP = ["instance_name", "hvparams"]
REQ_BGL = False
def ExpandNames(self):
self._ExpandAndLockInstance()
self.needed_locks[locking.LEVEL_NODE] = []
self.recalculate_locks[locking.LEVEL_NODE] = constants.LOCKS_REPLACE
def DeclareLocks(self, level):
if level == locking.LEVEL_NODE:
self._LockInstancesNodes()
def BuildHooksEnv(self):
"""Build hooks env.
......@@ -4502,19 +4529,9 @@ class LUSetInstanceParams(LogicalUnit):
self.bridge = getattr(self.op, "bridge", None)
self.kernel_path = getattr(self.op, "kernel_path", None)
self.initrd_path = getattr(self.op, "initrd_path", None)
self.hvm_boot_order = getattr(self.op, "hvm_boot_order", None)
self.hvm_acpi = getattr(self.op, "hvm_acpi", None)
self.hvm_pae = getattr(self.op, "hvm_pae", None)
self.hvm_nic_type = getattr(self.op, "hvm_nic_type", None)
self.hvm_disk_type = getattr(self.op, "hvm_disk_type", None)
self.hvm_cdrom_image_path = getattr(self.op, "hvm_cdrom_image_path", None)
self.vnc_bind_address = getattr(self.op, "vnc_bind_address", None)
self.force = getattr(self.op, "force", None)
all_parms = [self.mem, self.vcpus, self.ip, self.bridge, self.mac,
self.kernel_path, self.initrd_path, self.hvm_boot_order,
self.hvm_acpi, self.hvm_pae, self.hvm_cdrom_image_path,
self.vnc_bind_address, self.hvm_nic_type, self.hvm_disk_type]
if all_parms.count(None) == len(all_parms):
all_parms = [self.mem, self.vcpus, self.ip, self.bridge, self.mac]
if all_parms.count(None) == len(all_parms) and not self.op.hvparams:
raise errors.OpPrereqError("No changes submitted")
if self.mem is not None:
try:
......@@ -4543,65 +4560,36 @@ class LUSetInstanceParams(LogicalUnit):
if not utils.IsValidMac(self.mac):
raise errors.OpPrereqError('Invalid MAC address %s' % self.mac)
if self.kernel_path is not None:
self.do_kernel_path = True
if self.kernel_path == constants.VALUE_NONE:
raise errors.OpPrereqError("Can't set instance to no kernel")
if self.kernel_path != constants.VALUE_DEFAULT:
if not os.path.isabs(self.kernel_path):
raise errors.OpPrereqError("The kernel path must be an absolute"
" filename")
else:
self.do_kernel_path = False
if self.initrd_path is not None:
self.do_initrd_path = True
if self.initrd_path not in (constants.VALUE_NONE,
constants.VALUE_DEFAULT):
if not os.path.isabs(self.initrd_path):
raise errors.OpPrereqError("The initrd path must be an absolute"
" filename")
else:
self.do_initrd_path = False
# boot order verification
if self.hvm_boot_order is not None:
if self.hvm_boot_order != constants.VALUE_DEFAULT:
if len(self.hvm_boot_order.strip("acdn")) != 0:
raise errors.OpPrereqError("invalid boot order specified,"
" must be one or more of [acdn]"
" or 'default'")
# hvm_cdrom_image_path verification
if self.op.hvm_cdrom_image_path is not None:
if not (os.path.isabs(self.op.hvm_cdrom_image_path) or
self.op.hvm_cdrom_image_path.lower() == "none"):
raise errors.OpPrereqError("The path to the HVM CDROM image must"
" be an absolute path or None, not %s" %
self.op.hvm_cdrom_image_path)
if not (os.path.isfile(self.op.hvm_cdrom_image_path) or
self.op.hvm_cdrom_image_path.lower() == "none"):
raise errors.OpPrereqError("The HVM CDROM image must either be a"
" regular file or a symlink pointing to"
" an existing regular file, not %s" %
self.op.hvm_cdrom_image_path)
# vnc_bind_address verification
if self.op.vnc_bind_address is not None:
if not utils.IsValidIP(self.op.vnc_bind_address):
raise errors.OpPrereqError("given VNC bind address '%s' doesn't look"
" like a valid IP address" %
self.op.vnc_bind_address)
# checking the new params on the primary/secondary nodes
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
pnode = self.instance.primary_node
nodelist = [pnode]
nodelist.extend(instance.secondary_nodes)
if self.op.hvparams:
i_hvdict = copy.deepcopy(instance.hvparams)
for key, val in self.op.hvparams.iteritems():
if val is None:
try:
del i_hvdict[key]
except KeyError:
pass
else:
i_hvdict[key] = val
cluster = self.cfg.GetClusterInfo()
hv_new = cluster.FillDict(cluster.hvparams[instance.hypervisor],
i_hvdict)
# local check
hypervisor.GetHypervisor(
instance.hypervisor).CheckParameterSyntax(hv_new)
_CheckHVParams(self, nodelist, instance.hypervisor, hv_new)
self.hv_new = hv_new
self.warn = []
if self.mem is not None and not self.force:
pnode = self.instance.primary_node
nodelist = [pnode]
nodelist.extend(instance.secondary_nodes)
instance_info = self.rpc.call_instance_info(pnode, instance.name,
instance.hypervisor)
nodeinfo = self.rpc.call_node_info(nodelist, self.cfg.GetVGName(),
......@@ -4628,19 +4616,8 @@ class LUSetInstanceParams(LogicalUnit):
if node not in nodeinfo or not isinstance(nodeinfo[node], dict):
self.warn.append("Can't get info from secondary node %s" % node)
elif self.mem > nodeinfo[node]['memory_free']:
self.warn.append("Not enough memory to failover instance to secondary"
" node %s" % node)
# Xen HVM device type checks
if instance.hypervisor == constants.HT_XEN_HVM:
if self.op.hvm_nic_type is not None:
if self.op.hvm_nic_type not in constants.HT_HVM_VALID_NIC_TYPES:
raise errors.OpPrereqError("Invalid NIC type %s specified for Xen"
" HVM hypervisor" % self.op.hvm_nic_type)
if self.op.hvm_disk_type is not None:
if self.op.hvm_disk_type not in constants.HT_HVM_VALID_DISK_TYPES:
raise errors.OpPrereqError("Invalid disk type %s specified for Xen"
" HVM hypervisor" % self.op.hvm_disk_type)
self.warn.append("Not enough memory to failover instance to"
" secondary node %s" % node)
return
......@@ -4671,39 +4648,10 @@ class LUSetInstanceParams(LogicalUnit):
if self.mac:
instance.nics[0].mac = self.mac
result.append(("mac", self.mac))
if self.do_kernel_path:
instance.kernel_path = self.kernel_path
result.append(("kernel_path", self.kernel_path))
if self.do_initrd_path:
instance.initrd_path = self.initrd_path
result.append(("initrd_path", self.initrd_path))
if self.hvm_boot_order:
if self.hvm_boot_order == constants.VALUE_DEFAULT:
instance.hvm_boot_order = None
else:
instance.hvm_boot_order = self.hvm_boot_order
result.append(("hvm_boot_order", self.hvm_boot_order))
if self.hvm_acpi is not None:
instance.hvm_acpi = self.hvm_acpi
result.append(("hvm_acpi", self.hvm_acpi))
if self.hvm_pae is not None:
instance.hvm_pae = self.hvm_pae
result.append(("hvm_pae", self.hvm_pae))
if self.hvm_nic_type is not None:
instance.hvm_nic_type = self.hvm_nic_type
result.append(("hvm_nic_type", self.hvm_nic_type))
if self.hvm_disk_type is not None:
instance.hvm_disk_type = self.hvm_disk_type
result.append(("hvm_disk_type", self.hvm_disk_type))
if self.hvm_cdrom_image_path:
if self.hvm_cdrom_image_path == constants.VALUE_NONE:
instance.hvm_cdrom_image_path = None
else:
instance.hvm_cdrom_image_path = self.hvm_cdrom_image_path
result.append(("hvm_cdrom_image_path", self.hvm_cdrom_image_path))
if self.vnc_bind_address:
instance.vnc_bind_address = self.vnc_bind_address
result.append(("vnc_bind_address", self.vnc_bind_address))
if self.op.hvparams:
instance.hvparams = self.hv_new
for key, val in self.op.hvparams.iteritems():
result.append(("hv/%s" % key, val))
self.cfg.Update(instance)
......
......@@ -424,9 +424,7 @@ class OpSetInstanceParams(OpCode):
OP_DSC_FIELD = "instance_name"
__slots__ = [
"instance_name", "mem", "vcpus", "ip", "bridge", "mac",
"kernel_path", "initrd_path", "hvm_boot_order", "hvm_acpi",
"hvm_pae", "hvm_cdrom_image_path", "vnc_bind_address",
"hvm_nic_type", "hvm_disk_type", "force"
"hvparams", "force",
]
......
......@@ -771,51 +771,14 @@ def SetInstanceParams(opts, args):
"""
if not (opts.mem or opts.vcpus or opts.ip or opts.bridge or opts.mac or
opts.kernel_path or opts.initrd_path or opts.hvm_boot_order or
opts.hvm_acpi or opts.hvm_pae or opts.hvm_cdrom_image_path or
opts.vnc_bind_address or opts.hvm_nic_type or opts.hvm_disk_type):
opts.hypervisor):
logger.ToStdout("Please give at least one of the parameters.")
return 1
kernel_path = _TransformPath(opts.kernel_path)
initrd_path = _TransformPath(opts.initrd_path)
if opts.hvm_boot_order == 'default':
hvm_boot_order = constants.VALUE_DEFAULT
else:
hvm_boot_order = opts.hvm_boot_order
if opts.hvm_acpi is None:
hvm_acpi = opts.hvm_acpi
else:
hvm_acpi = opts.hvm_acpi == _VALUE_TRUE
if opts.hvm_pae is None:
hvm_pae = opts.hvm_pae
else:
hvm_pae = opts.hvm_pae == _VALUE_TRUE
if opts.hvm_nic_type == constants.VALUE_NONE:
hvm_nic_type = None
else:
hvm_nic_type = opts.hvm_nic_type
if opts.hvm_disk_type == constants.VALUE_NONE:
hvm_disk_type = None
else:
hvm_disk_type = opts.hvm_disk_type
op = opcodes.OpSetInstanceParams(instance_name=args[0], mem=opts.mem,
vcpus=opts.vcpus, ip=opts.ip,
bridge=opts.bridge, mac=opts.mac,
kernel_path=opts.kernel_path,
initrd_path=opts.initrd_path,
hvm_boot_order=hvm_boot_order,
hvm_acpi=hvm_acpi, hvm_pae=hvm_pae,
hvm_cdrom_image_path=
opts.hvm_cdrom_image_path,
vnc_bind_address=opts.vnc_bind_address,
hvm_nic_type=hvm_nic_type,
hvm_disk_type=hvm_disk_type,
hvparams=opts.hypervisor,
force=opts.force)
# even if here we process the result, we allow submit only
......@@ -1037,48 +1000,9 @@ commands = {
make_option("--mac", dest="mac",
help="MAC address", default=None,
type="string", metavar="<MACADDRESS>"),
make_option("--kernel", dest="kernel_path",
help="Path to the instances' kernel (or"
" 'default')", default=None,
type="string", metavar="<FILENAME>"),
make_option("--initrd", dest="initrd_path",
help="Path to the instances' initrd (or 'none', or"
" 'default')", default=None,
type="string", metavar="<FILENAME>"),
make_option("--hvm-boot-order", dest="hvm_boot_order",
help="boot device order for HVM"
"(either one or more of [acdn] or 'default')",
default=None, type="string", metavar="<BOOTORDER>"),
make_option("--hvm-acpi", dest="hvm_acpi",
help="ACPI support for HVM (true|false)",
metavar="<BOOL>", choices=["true", "false"]),
make_option("--hvm-pae", dest="hvm_pae",
help="PAE support for HVM (true|false)",
metavar="<BOOL>", choices=["true", "false"]),
make_option("--hvm-cdrom-image-path",
dest="hvm_cdrom_image_path",
help="CDROM image path for HVM"
"(absolute path or None)",
default=None, type="string", metavar="<CDROMIMAGE>"),
make_option("--hvm-nic-type", dest="hvm_nic_type",
help="Type of virtual NIC for HVM "
"(rtl8139,ne2k_pci,ne2k_isa,paravirtual)",
metavar="NICTYPE",
choices=[constants.HT_HVM_NIC_RTL8139,
constants.HT_HVM_NIC_NE2K_PCI,
constants.HT_HVM_NIC_NE2K_ISA,
constants.HT_HVM_DEV_PARAVIRTUAL],
default=None),
make_option("--hvm-disk-type", dest="hvm_disk_type",
help="Type of virtual disks for HVM "
"(ioemu,paravirtual)",
metavar="DISKTYPE",
choices=[constants.HT_HVM_DEV_IOEMU,
constants.HT_HVM_DEV_PARAVIRTUAL],
default=None),
make_option("--vnc-bind-address", dest="vnc_bind_address",
help="bind address for VNC (IP address)",
default=None, type="string", metavar="<VNCADDRESS>"),
keyval_option("-H", "--hypervisor", type="keyval",
default={}, dest="hypervisor",
help="Change hypervisor parameters"),
SUBMIT_OPT,
],
"<instance>", "Alters the parameters of an instance"),
......
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