diff options
| author | Johannes Erdfelt <johannes.erdfelt@rackspace.com> | 2011-06-15 22:28:32 +0000 |
|---|---|---|
| committer | Johannes Erdfelt <johannes.erdfelt@rackspace.com> | 2011-06-15 22:28:32 +0000 |
| commit | 7620db9454dd391ce3080e99cdb8237eaa9a4835 (patch) | |
| tree | fa71b98126bd37412b29f38e17980b3fc6cc287c /nova | |
| parent | 357556ce52af91cc4273597c6576bd9da8e5b388 (diff) | |
Windows instances will often take a few minutes setting up the image on first
boot and then reboot. We should be more patient for those systems as well
check if the domid changes so we can send agent requests to the current domid
Diffstat (limited to 'nova')
| -rw-r--r-- | nova/virt/xenapi/vmops.py | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 6b61ca9b5..190bf7c20 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -25,6 +25,7 @@ import M2Crypto import os import pickle import subprocess +import time import uuid from nova import context @@ -44,7 +45,10 @@ from nova.virt.xenapi.vm_utils import ImageType XenAPI = None LOG = logging.getLogger("nova.virt.xenapi.vmops") + FLAGS = flags.FLAGS +flags.DEFINE_integer('windows_version_timeout', 300, + 'time to wait for windows agent to be fully operational') def _cmp_version(a, b): @@ -244,7 +248,16 @@ class VMOps(object): 'architecture': instance.architecture}) def _check_agent_version(): - version = self.get_agent_version(instance) + if instance.os_type == 'windows': + # Windows will generally perform a setup process on first boot + # that can take a couple of minutes and then reboot. So we + # need to be more patient than normal as well as watch for + # domid changes + version = self.get_agent_version(instance, + timeout=FLAGS.windows_version_timeout, + check_domid_changes=True) + else: + version = self.get_agent_version(instance) if not version: LOG.info(_('No agent version returned by instance')) return @@ -500,18 +513,43 @@ class VMOps(object): task = self._session.call_xenapi('Async.VM.clean_reboot', vm_ref) self._session.wait_for_task(task, instance.id) - def get_agent_version(self, instance): + def get_agent_version(self, instance, timeout=None, + check_domid_changes=False): """Get the version of the agent running on the VM instance.""" - # Send the encrypted password - transaction_id = str(uuid.uuid4()) - args = {'id': transaction_id} - resp = self._make_agent_call('version', instance, '', args) - if resp is None: - # No response from the agent - return - resp_dict = json.loads(resp) - return resp_dict['message'] + def _call(): + # Send the encrypted password + transaction_id = str(uuid.uuid4()) + args = {'id': transaction_id} + resp = self._make_agent_call('version', instance, '', args) + if resp is None: + # No response from the agent + return + resp_dict = json.loads(resp) + return resp_dict['message'] + + if timeout: + vm_ref = self._get_vm_opaque_ref(instance) + vm_rec = self._session.get_xenapi().VM.get_record(vm_ref) + + domid = vm_rec['domid'] + + timeout = time.time() + timeout + while time.time() < timeout: + ret = _call() + if ret: + return ret + + if check_domid_changes: + vm_rec = self._session.get_xenapi().VM.get_record(vm_ref) + if vm_rec['domid'] != domid: + LOG.info(_('domid changed from %(olddomid)s to ' + '%(newdomid)s') % { + 'olddomid': domid, + 'newdomid': vm_rec['domid']}) + domid = vm_rec['domid'] + else: + return _call() def agent_update(self, instance, url, md5sum): """Update agent on the VM instance.""" |
