def test_socket_error_on_create(self, m_socket): '''create_bound_netlink_socket catches socket creation exception''' """NetlinkCreateSocketError is raised when socket creation errors.""" m_socket.side_effect = socket.error("Fake socket failure") with self.assertRaises(NetlinkCreateSocketError) as ctx_mgr: create_bound_netlink_socket() self.assertEqual( 'Exception during netlink socket create: Fake socket failure', str(ctx_mgr.exception))
def _poll_imds(self): """Poll IMDS for the new provisioning data until we get a valid response. Then return the returned JSON object.""" url = IMDS_URL + "reprovisiondata?api-version=2017-04-02" headers = {"Metadata": "true"} nl_sock = None report_ready = bool(not os.path.isfile(REPORTED_READY_MARKER_FILE)) def exc_cb(msg, exception): if isinstance(exception, UrlError) and exception.code == 404: return True # If we get an exception while trying to call IMDS, we # call DHCP and setup the ephemeral network to acquire the new IP. return False LOG.debug("Wait for vnetswitch to happen") while True: try: # Save our EphemeralDHCPv4 context so we avoid repeated dhcp self._ephemeral_dhcp_ctx = EphemeralDHCPv4() lease = self._ephemeral_dhcp_ctx.obtain_lease() if report_ready: try: nl_sock = netlink.create_bound_netlink_socket() except netlink.NetlinkCreateSocketError as e: LOG.warning(e) self._ephemeral_dhcp_ctx.clean_network() return path = REPORTED_READY_MARKER_FILE LOG.info("Creating a marker file to report ready: %s", path) util.write_file( path, "{pid}: {time}\n".format(pid=os.getpid(), time=time())) self._report_ready(lease=lease) report_ready = False try: netlink.wait_for_media_disconnect_connect( nl_sock, lease['interface']) except AssertionError as error: LOG.error(error) return self._ephemeral_dhcp_ctx.clean_network() else: return readurl(url, timeout=1, headers=headers, exception_cb=exc_cb, infinite=True, log_req_resp=False).contents except UrlError: # Teardown our EphemeralDHCPv4 context on failure as we retry self._ephemeral_dhcp_ctx.clean_network() pass finally: if nl_sock: nl_sock.close()