def test_update_interfaces_removed_raises(self): rec = {"MAC": "00:11:22:33:44:55"} interfaces = [xapi.VIF("device_id1", rec, "opaque_vif1")] dom_id = "1" vif_index = "0" vif_rec = {"device": vif_index, "VM": "opaqueref"} vm_rec = {"domid": dom_id} expected_args = dict(dom_id=dom_id, vif_index=vif_index) self.session.xenapi.VIF.get_record.return_value = vif_rec self.session.xenapi.VM.get_record.return_value = vm_rec xenapi_VIF = self.session.xenapi.VIF # Without the try/except in _unset, this raises and the test fails xenapi_VIF.remove_from_other_config.side_effect = XenAPI.Failure( "HANDLE_INVALID") self.xclient.update_interfaces([], [], interfaces) self.assertEqual(xenapi_VIF.add_to_other_config.call_count, 0) xenapi_VIF.remove_from_other_config.assert_called_once_with( "opaque_vif1", "security_groups") self.session.xenapi.host.call_plugin.assert_called_once_with( self.session.xenapi.session.get_this_host.return_value, "neutron_vif_flow", "online_instance_flows", expected_args)
async def xenapi_task_handler(cls, session, task, ignore_timeout=False, show_progress=False): """A pseudo-xenapi asyncio-ifier via implementing event loop by myself.""" cycle_passed = 0 while session.xenapi.task.get_status(task) == "pending" and ( cycle_passed <= cls.TIMEOUT or ignore_timeout): await asyncio.sleep(1) if show_progress: progress = round(session.xenapi.task.get_progress(task), 2) * 100 print(str(progress) + "% Complete!", flush=True) cycle_passed += 1 if cycle_passed > cls.TIMEOUT: raise XenGardenAsyncTimeoutException() session.xenapi.task.get_record(task) result = session.xenapi.task.get_result(task) error = session.xenapi.task.get_error_info(task) result = result.replace("<value>", "") result = result.replace("</value>", "") if len(error) > 0: raise XenAPI.Failure(error) return result
def test_update_interfaces_removed_vm_removed(self): rec = {"MAC": "00:11:22:33:44:55"} interfaces = [xapi.VIF("device_id1", rec, "opaque_vif1")] self.session.xenapi.VIF.get_record.side_effect = XenAPI.Failure( "HANDLE_INVALID") self.session.xenapi.VM.get_record.return_value = XenAPI.Failure( "HANDLE_INVALID") self.xclient.update_interfaces([], [], interfaces) xenapi_VIF = self.session.xenapi.VIF self.assertEqual(xenapi_VIF.add_to_other_config.call_count, 0) xenapi_VIF.remove_from_other_config.assert_called_once_with( "opaque_vif1", "security_groups") self.assertEqual(self.session.xenapi.host.call_plugin.call_count, 0)
def check_resp_status_and_retry(resp, image_id, url): # Note(Jesse): This branch sorts errors into those that are permanent, # those that are ephemeral, and those that are unexpected. if resp.status in ( httplib.BAD_REQUEST, # 400 httplib.UNAUTHORIZED, # 401 httplib.PAYMENT_REQUIRED, # 402 httplib.FORBIDDEN, # 403 httplib.METHOD_NOT_ALLOWED, # 405 httplib.NOT_ACCEPTABLE, # 406 httplib.PROXY_AUTHENTICATION_REQUIRED, # 407 httplib.CONFLICT, # 409 httplib.GONE, # 410 httplib.LENGTH_REQUIRED, # 411 httplib.PRECONDITION_FAILED, # 412 httplib.REQUEST_ENTITY_TOO_LARGE, # 413 httplib.REQUEST_URI_TOO_LONG, # 414 httplib.UNSUPPORTED_MEDIA_TYPE, # 415 httplib.REQUESTED_RANGE_NOT_SATISFIABLE, # 416 httplib.EXPECTATION_FAILED, # 417 httplib.UNPROCESSABLE_ENTITY, # 422 httplib.LOCKED, # 423 httplib.FAILED_DEPENDENCY, # 424 httplib.UPGRADE_REQUIRED, # 426 httplib.NOT_IMPLEMENTED, # 501 httplib.HTTP_VERSION_NOT_SUPPORTED, # 505 httplib.NOT_EXTENDED, # 510 ): raise PluginError("Got Permanent Error response [%i] while " "uploading image [%s] to glance [%s]" % (resp.status, image_id, url)) # Nova service would process the exception elif resp.status == httplib.NOT_FOUND: # 404 exc = XenAPI.Failure('ImageNotFound') raise exc # NOTE(nikhil): Only a sub-set of the 500 errors are retryable. We # optimistically retry on 500 errors below. elif resp.status in ( httplib.REQUEST_TIMEOUT, # 408 httplib.INTERNAL_SERVER_ERROR, # 500 httplib.BAD_GATEWAY, # 502 httplib.SERVICE_UNAVAILABLE, # 503 httplib.GATEWAY_TIMEOUT, # 504 httplib.INSUFFICIENT_STORAGE, # 507 ): raise RetryableError("Got Ephemeral Error response [%i] while " "uploading image [%s] to glance [%s]" % (resp.status, image_id, url)) else: # Note(Jesse): Assume unexpected errors are retryable. If you are # seeing this error message, the error should probably be added # to either the ephemeral or permanent error list. raise RetryableError("Got Unexpected Error response [%i] while " "uploading image [%s] to glance [%s]" % (resp.status, image_id, url))
def wait_for_task_success(session, task_ref): status = wait_for_task_complete(session, task_ref) if status == 'success': return session.xenapi.task.get_result(task_ref) elif status == 'cancelled': log.debug('Task %s cancelled', task_ref) raise TaskCancelled() else: error_info = session.xenapi.task.get_error_info(task_ref) log.debug('Task %s failed: %s', task_ref, error_info) raise XenAPI.Failure(error_info)
def main(session, iteration): # Find a non-template VM object all_vms = session.xenapi.VM.get_all_records() vms = [] hosts = [] for vm in all_vms: record = all_vms[vm] if not (record["is_a_template"]) and not (record[ "is_control_domain"]) and record["power_state"] == "Running": vms.append(vm) hosts.append(record["resident_on"]) print "%d: Found %d suitable running VMs" % (iteration, len(vms)) # use a rotation as a permutation hosts = [hosts[-1]] + hosts[:(len(hosts) - 1)] tasks = [] for j in range(0, len(vms)): vm = vms[j] host = hosts[j] task = session.xenapi.Async.VM.pool_migrate(vm, host, {"live": "true"}) tasks.append(task) finished = False records = {} while not finished: finished = True for task in tasks: record = session.xenapi.task.get_record(task) records[task] = record if record["status"] == "pending": finished = False time.sleep(1) allok = True for task in tasks: record = records[task] if record["status"] != "success": allok = False if not allok: print "One of the tasks didn't succeed at", time.strftime( "%F:%HT%M:%SZ", time.gmtime()) idx = 0 for task in tasks: record = records[task] vm_name = session.xenapi.VM.get_name_label(vms[idx]) host_name = session.xenapi.host.get_name_label(hosts[idx]) print "%s : %12s %s -> %s [ status: %s; result = %s; error = %s ]" % ( record["uuid"], record["name_label"], vm_name, host_name, record["status"], record["result"], repr(record["error_info"])) idx += 1 raise XenAPI.Failure("Task failed") else: for task in tasks: session.xenapi.task.destroy(task)
def call_plugin(self, host_ref, plugin, method, *arg): if self.session.fail_plugin: m = mock.Mock( side_effect=XenAPI.Failure("raised by Mock(): plugin failed")) m() h = self.__getHost(host_ref) if plugin in h.supportedPlugins: obj = h.supportedPlugins[plugin] func = getattr(obj, method, None) if callable(func): return func(*arg) return ""
def unwrap_plugin_exceptions(func, *args, **kwargs): try: return func(*args, **kwargs) except XenAPI.Failure, exn: log.debug("Got exception: %s", exn) if (len(exn.details) == 4 and exn.details[0] == 'XENAPI_PLUGIN_EXCEPTION' and exn.details[2] == 'Failure'): params = None try: params = eval(exn.details[3]) except: raise exn raise XenAPI.Failure(params) else: raise
def test_session_raises_exception(self, mock_ref, mock_uuid, mock_verify, mock_version, create_session, mock_timeout): import XenAPI self.flags(connection_concurrent=2, group='xenserver') sess = mock.Mock() create_session.return_value = sess # First login fails, second login in except block succeeds, # third login for the pool succeeds sess.login_with_password.side_effect = [ XenAPI.Failure(['HOST_IS_SLAVE', 'master']), None, None ] mock_version.return_value = ('version', 'brand') session.XenAPISession('http://slave', 'username', 'password') self.assertEqual(3, sess.login_with_password.call_count) self.assertEqual(3, mock_timeout.call_count)
def get_api_session(): if not api: raise ImportError('XenAPI not installed') url = CONF.xenapi.connection_url username = CONF.xenapi.connection_username password = CONF.xenapi.connection_password if not url or password is None: raise XenapiException('Must specify connection_url, and ' 'connection_password to use') exception = api.Failure("Unable to log in to XenAPI " "(is the Dom0 disk full?)") try: session = api.Session(url) with timeout.Timeout(CONF.xenapi.login_timeout, exception): session.login_with_password(username, password) except api.Failure as e: msg = "Could not connect to XenAPI: %s" % e.details[0] raise XenapiException(msg) return session
def test_sessioned_exception_handling(self, xapi_session): xapi_session.side_effect = XenAPI.Failure("HANDLE_INVALID") with self.assertRaises(XenAPI.Failure): xapi.XapiClient() self.session.logout.assert_called_once()