def play_command(power_group): """CLI endpoints for managing assets' power states & wallpower""" play_subp = power_group.add_subparsers() folder_action = play_subp.add_parser( "folder", help="Update user-defined script folder") folder_action.add_argument( "-p", "--path", type=str, required=True, help="Path to the folder containing playback scripts", ) list_action = play_subp.add_parser( "list", help="List scripts available for execution") exec_action = play_subp.add_parser("execute", help="Execute a specific script") exec_action.add_argument("-p", "--play", type=str, required=True, help="Name of the play to be executed") # cli actions/callbacks folder_action.set_defaults(func=lambda args: IStateManager.set_play_path( os.path.abspath(os.path.expanduser(args["path"])))) list_action.set_defaults( func=lambda args: display_plays(IStateManager.plays())) exec_action.set_defaults(func=lambda args: IStateManager.execute_play( args["play"]) # TODO: handle invalid play )
def _handle_status_request(self, details): """Get overall system status/details including hardware assets; environment state & play details """ assets = IStateManager.get_system_status(flatten=False) graph_ref = GraphReference() with graph_ref.get_session() as session: stage_layout = GraphReference.get_stage_layout(session) # send system topology and assets' power-interconnections self._write_data( details["client"], ServerToClientRequests.sys_layout, {"assets": assets, "stageLayout": stage_layout}, ) self._write_data( details["client"], ServerToClientRequests.ambient_upd, {"ambient": ISystemEnvironment.get_ambient(), "rising": False}, ) self._write_data( details["client"], ServerToClientRequests.play_list, {"plays": list(itertools.chain(*IStateManager.plays()))}, ) self._write_data( details["client"], ServerToClientRequests.mains_upd, {"mains": ISystemEnvironment.mains_status()}, )
def _handle_sensor_state_request(self, details): """Update runtime value of a IPMI/BMC sensor""" server_sm = IStateManager.get_state_manager_by_key( details["payload"]["key"]) server_sm.update_sensor(details["payload"]["sensor_name"], details["payload"]["sensor_value"])
def _handle_ctrl_update_request(self, details): """Update RAID controller when requested""" payload = details["payload"] executed = IStateManager.get_state_manager_by_key( payload["key"]).set_controller_prop(payload["controller"], payload) self._cmd_executed_response(details["client"], executed)
def get_server_state_manager(asset_key): """Get server asset by key with type validation""" server_manager = IStateManager.get_state_manager_by_key(asset_key) if not isinstance(server_manager, IBMCServerStateManager): raise argparse.ArgumentTypeError( "Asset [{}] is not a server!".format(asset_key) ) return server_manager
def _handle_pd_update_request(self, details): """Update data related to physical drives when requested""" payload = details["payload"] executed = IStateManager.get_state_manager_by_key( payload["key"] ).set_physical_drive_prop(payload["controller"], payload["drive_id"], payload) self._cmd_executed_response(details["client"], executed)
def _handle_cv_repl_request(self, details): """Update cv details upon a request""" payload = details["payload"] executed = IStateManager.get_state_manager_by_key( payload["key"]).set_cv_replacement( payload["controller"], payload["replacement_required"], payload["write_through_fail"], ) self._cmd_executed_response(details["client"], executed)
def _handle_power_request(self, details): """Power up/down asset""" power_up = details["payload"]["status"] state_manager = IStateManager.get_state_manager_by_key( details["payload"]["key"]) if power_up: state_manager.power_up() elif "hard" in details["payload"] and details["payload"]["hard"]: state_manager.power_off() else: state_manager.shut_down()
def _handle_rand_act(self, details): """Handle perform random actions request""" rand_session_specs = details["payload"] assets = IStateManager.get_system_status(flatten=True) nap = None # filter out assets if range is provided if rand_session_specs["asset_keys"]: assets = list( filter(lambda x: x in rand_session_specs["asset_keys"], assets) ) if not assets and not 0 in rand_session_specs["asset_keys"]: logger.warning("No assets selected for random actions") return state_managers = list(map(IStateManager.get_state_manager_by_key, assets)) if ( not rand_session_specs["asset_keys"] or 0 in rand_session_specs["asset_keys"] ): state_managers.append(ISystemEnvironment()) if rand_session_specs["nap_time"]: def nap_calc(): nap_time = lambda: rand_session_specs["nap_time"] if rand_session_specs["min_nap"]: nap_time = lambda: random.randrange( rand_session_specs["min_nap"], rand_session_specs["nap_time"] ) time.sleep(nap_time()) nap = nap_calc rand_t = threading.Thread( target=Randomizer.randact, args=(state_managers,), kwargs={ "num_iter": rand_session_specs["count"], "seconds": rand_session_specs["seconds"], "nap": nap, }, name="[#] Randomizer", ) rand_t.daemon = True rand_t.start()
def configure_battery(key, kwargs): """Udpate runtime battery status""" state_manager = IStateManager.get_state_manager_by_key(key) if not isinstance(state_manager, IUPSStateManager): raise argparse.ArgumentTypeError("Asset [{}] is not a ups!".format(key)) if kwargs["drain_speed"] is None and kwargs["charge_speed"] is None: raise argparse.ArgumentTypeError( 'Must provide "--drain-speed" or "--charge-speed"' ) if kwargs["drain_speed"] is not None: state_manager.set_drain_speed_factor(kwargs["drain_speed"]) if kwargs["charge_speed"] is not None: state_manager.set_charge_speed_factor(kwargs["charge_speed"])
def get_status(**kwargs): """Retrieve power states of the assets Args: **kwargs: Command line options """ #### one asset #### if kwargs["asset_key"] and kwargs["load"]: state_manager = IStateManager.get_state_manager_by_key(kwargs["asset_key"]) if kwargs["value_only"]: print(state_manager.load) else: print( "{}-{} : {}".format( state_manager.key, state_manager.asset_type, state_manager.load ) ) return elif kwargs["asset_key"] and kwargs["agent"]: state_manager = IStateManager.get_state_manager_by_key(kwargs["asset_key"]) agent_info = state_manager.agent if agent_info: msg = "running" if agent_info[1] else "not running" if kwargs["value_only"]: print(int(agent_info[1])) else: print( "{}-{} : pid[{}] is {}".format( state_manager.key, state_manager.asset_type, agent_info[0], msg ) ) else: print( "{}-{} is not running any agents!".format( state_manager.key, state_manager.asset_type ) ) return elif kwargs["asset_key"]: state_manager = IStateManager.get_state_manager_by_key(kwargs["asset_key"]) if kwargs["value_only"]: print(state_manager.status) else: print( "{}-{} : {}".format( state_manager.key, state_manager.asset_type, state_manager.status ) ) return elif kwargs["mains"]: mains_status = ISystemEnvironment.mains_status() if kwargs["value_only"]: print(mains_status) else: print("Wallpower status:", mains_status) return ##### list states ##### assets = IStateManager.get_system_status() # json format if kwargs["json"]: print(json.dumps(assets, indent=4)) # monitor state with curses elif kwargs["monitor"]: stdscr = curses.initscr() curses.noecho() curses.cbreak() try: curses.start_color() curses.use_default_colors() for i in range(0, curses.COLORS): curses.init_pair(i, i, -1) while True: status_table_format(assets, stdscr) time.sleep(kwargs["watch_rate"]) assets = IStateManager.get_system_status() except KeyboardInterrupt: pass finally: curses.echo() curses.nocbreak() curses.endwin() # human-readable table else: status_table_format(assets)
def _handle_play_request(self, details): """Playback request""" IStateManager.execute_play(details["payload"]["name"])