def navigation_prompt(self, prompt, forward_choices, forward, backward, banner=None): if hasattr(forward_choices, 'split'): forward_choices = forward_choices.split() lead_prompt = prompt if banner: lead_prompt = "%s%s" % (banner, prompt) self.fd.write("\r\n%s" % lead_prompt) self.fd.flush() recv_buf = [] while True: response = "" while True: # This was not my first choice, but it turns out that # we have to interpret telnet control sequences in order # to accommodate real fence agents. Sigh. c = self.socket.recv(1) if c in "\r\n": response = "".join(recv_buf) del (recv_buf[:]) # Eat the LF c = self.socket.recv(1) break recv_buf.append(c) if recv_buf == CTRL_C: for c in WONT_TIMING_MARK: self.socket.send(c) self.control_console() elif recv_buf == EOF: self.logout() elif recv_buf == ESC: backward(self.last_choice) if response in forward_choices: self.last_choice = response forward(response) elif response == "": self.fd.write("\r\n%s" % prompt) self.fd.flush() else: # i know it's a hack, so sue me. if forward == self.device_manager and response == "4": self.logout() else: import inspect caller = inspect.stack()[1][3] decoded_response = [ord(c) for c in response] log.error("Unhandled response in %s: '%s' (%s)" % (caller, response, decoded_response)) self.fd.write("\r\n%s" % prompt) self.fd.flush()
def stop_monitored_copytool(self, id): try: self.copytools[id].stop() except KeyError: log.error("Attempt to stop unknown copytool: %s" % id) try: self.copytool_monitors[id].stop() except KeyError: log.error("Attempt to stop unknown copytool monitor: %s" % id)
def poll_fake_controller(self, controller_id): """ For use by the simulator_controller storage plugin: query a particular fake controller """ try: controller = self.controllers[int(controller_id)] except KeyError: log.error("Controller '%s' not found in %s" % (controller_id, self.controllers.keys())) raise else: return controller.poll()
def register(self, fqdn, secret): try: log.debug("register %s" % fqdn) server = self.servers[fqdn] if server.agent_is_running: # e.g. if the server was added then force-removed then re-added server.shutdown_agent() if not server.is_worker and not self.power.server_has_power(fqdn): raise RuntimeError( "Not registering %s, none of its PSUs are powered" % fqdn) client = AgentClient(url=self.url + "register/%s/" % secret, action_plugins=FakeActionPlugins( self, server), device_plugins=FakeDevicePlugins(server), server_properties=server, crypto=server.crypto) try: registration_result = client.register() except ConnectionError as e: log.error("Registration connection failed for %s: %s" % (fqdn, e)) return except HttpError as e: log.error("Registration request failed for %s: %s" % (fqdn, e)) return server.crypto.install_certificate( registration_result['certificate']) # Immediately start the agent after registration, to pick up the # setup actions that will be waiting for us on the manager. self.start_server(fqdn) return registration_result except Exception: log.error(traceback.format_exc())
def create_pdu_entries(self, simulator, args): if not (args.username and args.password): sys.stderr.write( "Username and password required to create PDU entries\n") sys.exit(-1) session = self._get_authenticated_session(args.url, args.username, args.password) log.info( "Creating PDU entries and associating PDU outlets with servers...") outlet_count = len(simulator.servers) if outlet_count < 1: log.error("Skipping PDU creation (no servers)") return # Create a custom type to ensure that it has enough outlets. # NB: If more servers are added later this won't work correctly, # but it should handle most use cases for simulated clusters. response = session.post("%s/api/power_control_type/" % args.url, data=json.dumps({ 'agent': "fence_apc", 'make': "Fake", 'model': "PDU", 'default_username': "******", 'default_password': "******", 'max_outlets': outlet_count })) assert 200 <= response.status_code < 300, response.text fence_apc = json.loads(response.text) log.debug("Created power_control_type: %s" % fence_apc['name']) pdu_entries = [] for pdu_sim in simulator.power.pdu_sims.values(): response = session.post("%s/api/power_control_device/" % args.url, data=json.dumps({ 'device_type': fence_apc['resource_uri'], 'name': pdu_sim.name, 'address': pdu_sim.address, 'port': pdu_sim.port })) assert 200 <= response.status_code < 300, response.text pdu_entries.append(json.loads(response.text)) log.debug("Created power_control_device: %s" % pdu_entries[-1]['name']) response = session.get("%s/api/host/" % args.url, data=json.dumps({'limit': 0})) assert 200 <= response.status_code < 300, response.text servers = [ s for s in json.loads(response.text)['objects'] if 'posix_copytool_worker' not in s['server_profile'] ] for i, server in enumerate( sorted(servers, key=lambda server: server['fqdn'])): for pdu in pdu_entries: outlet = [ o for o in pdu['outlets'] if o['identifier'] == str(i + 1) ][0] response = session.patch( "%s/%s" % (args.url, outlet['resource_uri']), data=json.dumps({'host': server['resource_uri']})) assert 200 <= response.status_code < 300, response.text log.debug("Created association %s <=> %s:%s" % (server['fqdn'], pdu['name'], outlet['identifier']))