From 7643153353a95bff61c03f515c3230d3a89d8eda Mon Sep 17 00:00:00 2001 From: Guido Trotter <ultrotter@google.com> Date: Mon, 19 Apr 2010 16:32:03 +0100 Subject: [PATCH] KVM: implement the HT_SM_POOL security model In order not to complicate to much the _ExecuteKVMRuntime function with nested try/except/finally/else constructs we move the actual runcmd+check call in a separate _RunKVMCmd function. Signed-off-by: Guido Trotter <ultrotter@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- lib/hypervisor/hv_kvm.py | 44 ++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py index a696a41fa..6b7483338 100644 --- a/lib/hypervisor/hv_kvm.py +++ b/lib/hypervisor/hv_kvm.py @@ -37,6 +37,8 @@ from ganeti import constants from ganeti import errors from ganeti import serializer from ganeti import objects +from ganeti import uidpool +from ganeti import ssconf from ganeti.hypervisor import hv_base @@ -559,6 +561,22 @@ class KVMHypervisor(hv_base.BaseHypervisor): kvm_nics = [objects.NIC.FromDict(snic) for snic in serialized_nics] return (kvm_cmd, kvm_nics, hvparams) + def _RunKVMCmd(self, name, kvm_cmd): + """Run the KVM cmd and check for errors + + @type name: string + @param name: instance name + @type kvm_cmd: list of strings + @param kvm_cmd: runcmd input for kvm + + """ + result = utils.RunCmd(kvm_cmd) + if result.failed: + raise errors.HypervisorError("Failed to start instance %s: %s (%s)" % + (name, result.fail_reason, result.output)) + if not self._InstancePidAlive(name)[2]: + raise errors.HypervisorError("Failed to start instance %s" % name) + def _ExecuteKVMRuntime(self, instance, kvm_runtime, incoming=None): """Execute a KVM cmd, after completing it with some last minute data @@ -607,13 +625,23 @@ class KVMHypervisor(hv_base.BaseHypervisor): raise errors.HypervisorError("Failed to open VNC password file %s: %s" % (vnc_pwd_file, err)) - result = utils.RunCmd(kvm_cmd) - if result.failed: - raise errors.HypervisorError("Failed to start instance %s: %s (%s)" % - (name, result.fail_reason, result.output)) - - if not self._InstancePidAlive(name)[2]: - raise errors.HypervisorError("Failed to start instance %s" % name) + if security_model == constants.HT_SM_POOL: + ss = ssconf.SimpleStore() + uid_pool = uidpool.ParseUidPool(ss.GetUidPool(), separator="\n") + all_uids = set(uidpool.ExpandUidPool(uid_pool)) + uid = uidpool.RequestUnusedUid(all_uids) + try: + username = pwd.getpwuid(uid.GetUid()).pw_name + kvm_cmd.extend(["-runas", username]) + self._RunKVMCmd(name, kvm_cmd) + except: + uidpool.ReleaseUid(uid) + raise + else: + uid.Unlock() + utils.WriteFile(self._InstanceUidFile(name), data=str(uid)) + else: + self._RunKVMCmd(name, kvm_cmd) if vnc_pwd: change_cmd = 'change vnc password %s' % vnc_pwd @@ -892,8 +920,6 @@ class KVMHypervisor(hv_base.BaseHypervisor): if hvparams[constants.HV_SECURITY_DOMAIN]: raise errors.HypervisorError("Cannot have a security domain when the" " security model is 'none' or 'pool'") - if security_model == constants.HT_SM_POOL: - raise errors.HypervisorError("Security model pool is not supported yet") @classmethod def ValidateParameters(cls, hvparams): -- GitLab