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 ...@@ -31,6 +31,7 @@ import tempfile
import re import re
import platform import platform
import logging import logging
import copy
from ganeti import ssh from ganeti import ssh
from ganeti import logger from ganeti import logger
...@@ -3139,6 +3140,36 @@ def _ComputeDiskSize(disk_template, disk_size, swap_size): ...@@ -3139,6 +3140,36 @@ def _ComputeDiskSize(disk_template, disk_size, swap_size):
return req_size_dict[disk_template] 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): class LUCreateInstance(LogicalUnit):
"""Create an instance. """Create an instance.
...@@ -3449,18 +3480,7 @@ class LUCreateInstance(LogicalUnit): ...@@ -3449,18 +3480,7 @@ class LUCreateInstance(LogicalUnit):
" %d MB available, %d MB required" % " %d MB available, %d MB required" %
(node, info['vg_free'], req_size)) (node, info['vg_free'], req_size))
# hypervisor parameter validation _CheckHVParams(self, nodenames, self.op.hypervisor, self.op.hvparams)
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])
# os verification # os verification
os_obj = self.rpc.call_os_get(pnode.name, self.op.os_type) os_obj = self.rpc.call_os_get(pnode.name, self.op.os_type)
...@@ -4450,11 +4470,18 @@ class LUSetInstanceParams(LogicalUnit): ...@@ -4450,11 +4470,18 @@ class LUSetInstanceParams(LogicalUnit):
""" """
HPATH = "instance-modify" HPATH = "instance-modify"
HTYPE = constants.HTYPE_INSTANCE HTYPE = constants.HTYPE_INSTANCE
_OP_REQP = ["instance_name"] _OP_REQP = ["instance_name", "hvparams"]
REQ_BGL = False REQ_BGL = False
def ExpandNames(self): def ExpandNames(self):
self._ExpandAndLockInstance() 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): def BuildHooksEnv(self):
"""Build hooks env. """Build hooks env.
...@@ -4502,19 +4529,9 @@ class LUSetInstanceParams(LogicalUnit): ...@@ -4502,19 +4529,9 @@ class LUSetInstanceParams(LogicalUnit):
self.bridge = getattr(self.op, "bridge", None) self.bridge = getattr(self.op, "bridge", None)
self.kernel_path = getattr(self.op, "kernel_path", None) self.kernel_path = getattr(self.op, "kernel_path", None)
self.initrd_path = getattr(self.op, "initrd_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) self.force = getattr(self.op, "force", None)
all_parms = [self.mem, self.vcpus, self.ip, self.bridge, self.mac, all_parms = [self.mem, self.vcpus, self.ip, self.bridge, self.mac]
self.kernel_path, self.initrd_path, self.hvm_boot_order, if all_parms.count(None) == len(all_parms) and not self.op.hvparams:
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):
raise errors.OpPrereqError("No changes submitted") raise errors.OpPrereqError("No changes submitted")
if self.mem is not None: if self.mem is not None:
try: try:
...@@ -4543,65 +4560,36 @@ class LUSetInstanceParams(LogicalUnit): ...@@ -4543,65 +4560,36 @@ class LUSetInstanceParams(LogicalUnit):
if not utils.IsValidMac(self.mac): if not utils.IsValidMac(self.mac):
raise errors.OpPrereqError('Invalid MAC address %s' % self.mac) raise errors.OpPrereqError('Invalid MAC address %s' % self.mac)
if self.kernel_path is not None: # checking the new params on the primary/secondary nodes
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)
instance = self.instance = self.cfg.GetInstanceInfo(self.op.instance_name) instance = self.instance = self.cfg.GetInstanceInfo(self.op.instance_name)
assert self.instance is not None, \ assert self.instance is not None, \
"Cannot retrieve locked instance %s" % self.op.instance_name "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 = [] self.warn = []
if self.mem is not None and not self.force: 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_info = self.rpc.call_instance_info(pnode, instance.name,
instance.hypervisor) instance.hypervisor)
nodeinfo = self.rpc.call_node_info(nodelist, self.cfg.GetVGName(), nodeinfo = self.rpc.call_node_info(nodelist, self.cfg.GetVGName(),
...@@ -4628,19 +4616,8 @@ class LUSetInstanceParams(LogicalUnit): ...@@ -4628,19 +4616,8 @@ class LUSetInstanceParams(LogicalUnit):
if node not in nodeinfo or not isinstance(nodeinfo[node], dict): if node not in nodeinfo or not isinstance(nodeinfo[node], dict):
self.warn.append("Can't get info from secondary node %s" % node) self.warn.append("Can't get info from secondary node %s" % node)
elif self.mem > nodeinfo[node]['memory_free']: elif self.mem > nodeinfo[node]['memory_free']:
self.warn.append("Not enough memory to failover instance to secondary" self.warn.append("Not enough memory to failover instance to"
" node %s" % node) " 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)
return return
...@@ -4671,39 +4648,10 @@ class LUSetInstanceParams(LogicalUnit): ...@@ -4671,39 +4648,10 @@ class LUSetInstanceParams(LogicalUnit):
if self.mac: if self.mac:
instance.nics[0].mac = self.mac instance.nics[0].mac = self.mac
result.append(("mac", self.mac)) result.append(("mac", self.mac))
if self.do_kernel_path: if self.op.hvparams:
instance.kernel_path = self.kernel_path instance.hvparams = self.hv_new
result.append(("kernel_path", self.kernel_path)) for key, val in self.op.hvparams.iteritems():
if self.do_initrd_path: result.append(("hv/%s" % key, val))
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))
self.cfg.Update(instance) self.cfg.Update(instance)
......
...@@ -424,9 +424,7 @@ class OpSetInstanceParams(OpCode): ...@@ -424,9 +424,7 @@ class OpSetInstanceParams(OpCode):
OP_DSC_FIELD = "instance_name" OP_DSC_FIELD = "instance_name"
__slots__ = [ __slots__ = [
"instance_name", "mem", "vcpus", "ip", "bridge", "mac", "instance_name", "mem", "vcpus", "ip", "bridge", "mac",
"kernel_path", "initrd_path", "hvm_boot_order", "hvm_acpi", "hvparams", "force",
"hvm_pae", "hvm_cdrom_image_path", "vnc_bind_address",
"hvm_nic_type", "hvm_disk_type", "force"
] ]
......
...@@ -771,51 +771,14 @@ def SetInstanceParams(opts, args): ...@@ -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 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.hypervisor):
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):
logger.ToStdout("Please give at least one of the parameters.") logger.ToStdout("Please give at least one of the parameters.")
return 1 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, op = opcodes.OpSetInstanceParams(instance_name=args[0], mem=opts.mem,
vcpus=opts.vcpus, ip=opts.ip, vcpus=opts.vcpus, ip=opts.ip,
bridge=opts.bridge, mac=opts.mac, bridge=opts.bridge, mac=opts.mac,
kernel_path=opts.kernel_path, hvparams=opts.hypervisor,
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,
force=opts.force) force=opts.force)
# even if here we process the result, we allow submit only # even if here we process the result, we allow submit only
...@@ -1037,48 +1000,9 @@ commands = { ...@@ -1037,48 +1000,9 @@ commands = {
make_option("--mac", dest="mac", make_option("--mac", dest="mac",
help="MAC address", default=None, help="MAC address", default=None,
type="string", metavar="<MACADDRESS>"), type="string", metavar="<MACADDRESS>"),
make_option("--kernel", dest="kernel_path", keyval_option("-H", "--hypervisor", type="keyval",
help="Path to the instances' kernel (or" default={}, dest="hypervisor",
" 'default')", default=None, help="Change hypervisor parameters"),
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>"),
SUBMIT_OPT, SUBMIT_OPT,
], ],
"<instance>", "Alters the parameters of an instance"), "<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