Commit 67fc3042 authored by Iustin Pop's avatar Iustin Pop
Browse files

Export more instance information in hooks



Currently we miss in hooks the instance's hypervisor, hypervisor
parameters and backend parameters. This forces hooks to query back into
ganeti, which is dangerous due to possible luxi sockets exhaustion.

This patch adds these three as INSTANCE_HYPERVISOR, INSTANCE_HV_*,
INSTANCE_BE_*. The hook environment prefixes all keys with “GANETI”, so
a default settings for a xen-pvm instance would be:

  GANETI_INSTANCE_HV_initrd_path=
  GANETI_INSTANCE_HV_kernel_args=ro
  GANETI_INSTANCE_HV_kernel_path=/boot/vmlinuz-2.6-xenU
  GANETI_INSTANCE_HV_root_path=/dev/sda1

Any dashes in parameter names are changed to underscores, since
variables with dashes are not easy to access from the shell
(alternatively we could deny those via an unittest for constants.py).
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent f226f085
...@@ -1690,6 +1690,10 @@ def OSEnvironment(instance, debug=0): ...@@ -1690,6 +1690,10 @@ def OSEnvironment(instance, debug=0):
result['NIC_%d_FRONTEND_TYPE' % idx] = \ result['NIC_%d_FRONTEND_TYPE' % idx] = \
instance.hvparams[constants.HV_NIC_TYPE] instance.hvparams[constants.HV_NIC_TYPE]
for source, kind in [(instance.beparams, "BE"), (instance.hvparams, "HV")]:
for key, value in source.items():
env["INSTANCE_%s_%s" % (kind, key)] = value
return result return result
def BlockdevGrow(disk, amount): def BlockdevGrow(disk, amount):
......
...@@ -453,7 +453,8 @@ def _CheckNodeNotDrained(lu, node): ...@@ -453,7 +453,8 @@ def _CheckNodeNotDrained(lu, node):
def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status, def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status,
memory, vcpus, nics, disk_template, disks): memory, vcpus, nics, disk_template, disks,
bep, hvp, hypervisor):
"""Builds instance related env variables for hooks """Builds instance related env variables for hooks
This builds the hook environment from individual variables. This builds the hook environment from individual variables.
...@@ -479,6 +480,12 @@ def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status, ...@@ -479,6 +480,12 @@ def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status,
@param disk_template: the distk template of the instance @param disk_template: the distk template of the instance
@type disks: list @type disks: list
@param disks: the list of (size, mode) pairs @param disks: the list of (size, mode) pairs
@type bep: dict
@param bep: the backend parameters for the instance
@type hvp: dict
@param hvp: the hypervisor parameters for the instance
@type hypervisor: string
@param hypervisor: the hypervisor for the instance
@rtype: dict @rtype: dict
@return: the hook environment for this instance @return: the hook environment for this instance
...@@ -497,6 +504,7 @@ def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status, ...@@ -497,6 +504,7 @@ def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status,
"INSTANCE_MEMORY": memory, "INSTANCE_MEMORY": memory,
"INSTANCE_VCPUS": vcpus, "INSTANCE_VCPUS": vcpus,
"INSTANCE_DISK_TEMPLATE": disk_template, "INSTANCE_DISK_TEMPLATE": disk_template,
"INSTANCE_HYPERVISOR": hypervisor,
} }
if nics: if nics:
...@@ -522,6 +530,10 @@ def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status, ...@@ -522,6 +530,10 @@ def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status,
env["INSTANCE_DISK_COUNT"] = disk_count env["INSTANCE_DISK_COUNT"] = disk_count
for source, kind in [(bep, "BE"), (hvp, "HV")]:
for key, value in source.items():
env["INSTANCE_%s_%s" % (kind, key)] = value
return env return env
...@@ -540,7 +552,9 @@ def _BuildInstanceHookEnvByObject(lu, instance, override=None): ...@@ -540,7 +552,9 @@ def _BuildInstanceHookEnvByObject(lu, instance, override=None):
@return: the hook environment dictionary @return: the hook environment dictionary
""" """
bep = lu.cfg.GetClusterInfo().FillBE(instance) cluster = lu.cfg.GetClusterInfo()
bep = cluster.FillBE(instance)
hvp = cluster.FillHV(instance)
args = { args = {
'name': instance.name, 'name': instance.name,
'primary_node': instance.primary_node, 'primary_node': instance.primary_node,
...@@ -552,6 +566,9 @@ def _BuildInstanceHookEnvByObject(lu, instance, override=None): ...@@ -552,6 +566,9 @@ def _BuildInstanceHookEnvByObject(lu, instance, override=None):
'nics': [(nic.ip, nic.bridge, nic.mac) for nic in instance.nics], 'nics': [(nic.ip, nic.bridge, nic.mac) for nic in instance.nics],
'disk_template': instance.disk_template, 'disk_template': instance.disk_template,
'disks': [(disk.size, disk.mode) for disk in instance.disks], 'disks': [(disk.size, disk.mode) for disk in instance.disks],
'bep': bep,
'hvp': hvp,
'hypervisor': instance.hypervisor,
} }
if override: if override:
args.update(override) args.update(override)
...@@ -4341,6 +4358,7 @@ class LUCreateInstance(LogicalUnit): ...@@ -4341,6 +4358,7 @@ class LUCreateInstance(LogicalUnit):
self.op.hvparams) self.op.hvparams)
hv_type = hypervisor.GetHypervisor(self.op.hypervisor) hv_type = hypervisor.GetHypervisor(self.op.hypervisor)
hv_type.CheckParameterSyntax(filled_hvp) hv_type.CheckParameterSyntax(filled_hvp)
self.hv_full = filled_hvp
# fill and remember the beparams dict # fill and remember the beparams dict
utils.ForceDictType(self.op.beparams, constants.BES_PARAMETER_TYPES) utils.ForceDictType(self.op.beparams, constants.BES_PARAMETER_TYPES)
...@@ -4518,6 +4536,9 @@ class LUCreateInstance(LogicalUnit): ...@@ -4518,6 +4536,9 @@ class LUCreateInstance(LogicalUnit):
nics=[(n.ip, n.bridge, n.mac) for n in self.nics], nics=[(n.ip, n.bridge, n.mac) for n in self.nics],
disk_template=self.op.disk_template, disk_template=self.op.disk_template,
disks=[(d["size"], d["mode"]) for d in self.disks], disks=[(d["size"], d["mode"]) for d in self.disks],
bep=self.be_full,
hvp=self.hv_full,
hypervisor=self.op.hypervisor,
)) ))
nl = ([self.cfg.GetMasterNode(), self.op.pnode] + nl = ([self.cfg.GetMasterNode(), self.op.pnode] +
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
import unittest import unittest
import re
from ganeti import constants from ganeti import constants
...@@ -54,5 +55,17 @@ class TestConstants(unittest.TestCase): ...@@ -54,5 +55,17 @@ class TestConstants(unittest.TestCase):
constants.CONFIG_REVISION)) constants.CONFIG_REVISION))
class TestParameterNames(unittest.TestCase):
"""HV/BE parameter tests"""
VALID_NAME = re.compile("^[a-zA-Z_][a-zA-Z0-9_]*$")
def testNoDashes(self):
for kind, source in [('hypervisor', constants.HVS_PARAMETER_TYPES),
('backend', constants.BES_PARAMETER_TYPES)]:
for key in source:
self.failUnless(self.VALID_NAME.match(key),
"The %s parameter '%s' contains invalid characters" %
(kind, key))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
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