예제 #1
0
def handle_set_thermal_ambient(kwargs):
    """Configure thermal properties for room temperature"""

    if kwargs["event"] and kwargs["pause_at"] and kwargs["rate"]:
        ISystemEnvironment.set_ambient_props(kwargs)
    elif kwargs["event"] or kwargs["pause_at"] or kwargs["rate"]:
        raise argparse.ArgumentTypeError(
            "Event, pause-at and rate must be supplied")
    else:
        StateClient.set_ambient(kwargs["degrees"])
예제 #2
0
def handle_voltage_set(args):
    """Action callback for handling voltage set command"""
    if args["value"] is not None:
        StateClient.set_voltage(args["value"])

    del args["value"]

    # set voltage fluctuation properties if any are provided
    if [arg_value for _, arg_value in args.items() if arg_value is not None]:
        ISystemEnvironment.set_voltage_props(args)
예제 #3
0
def cv_command(cv_group):
    """Endpoints for CacheVault properties"""
    cv_group = cv_group.add_subparsers()

    # CLI PD setter
    set_cv_action = cv_group.add_parser("set",
                                        help="Configure CacheVault",
                                        parents=[get_ctrl_storage_args()])

    set_cv_action.add_argument(
        "-r",
        "--replacement-required",
        help="Correctable RAM errors on disk data",
        choices=["Yes", "No"],
        required=True,
    )

    set_cv_action.add_argument(
        "-w",
        "--write-through-fail",
        help=
        "Virtual drive endpoint will fail to report its cache mode as WT (WriteThrough)",
        action="store_false",
    )

    set_cv_action.set_defaults(func=lambda args: process_cmd_result(
        StateClient(args["asset_key"]).set_cv_replacement(
            args["controller"], args)))
예제 #4
0
def pd_command(pd_group):
    """Endpoints for setting storage props (pd, vd, controller etc.)"""

    pd_subp = pd_group.add_subparsers()

    # group a few args into a common parent element
    server_controller_parent = get_ctrl_storage_args()

    # CLI PD setter
    set_pd_action = pd_subp.add_parser(
        "set",
        help="Configure a physical drive (error count, state etc.)",
        parents=[server_controller_parent],
    )

    set_pd_action.add_argument("-d",
                               "--drive-id",
                               help="Physical Drive id (DID)",
                               type=int,
                               required=True)

    set_pd_action.add_argument(
        "-m",
        "--media-error-count",
        help="Update media error count for the drive",
        type=int,
    )

    set_pd_action.add_argument(
        "-o",
        "--other-error-count",
        help="Update other error count for the drive",
        type=int,
    )

    set_pd_action.add_argument(
        "-p",
        "--predictive-error-count",
        help="Update error prediction value for the drive",
        type=int,
    )

    set_pd_action.add_argument(
        "-r",
        "--rebuild-time",
        help=
        "Time (in seconds) required to complete rebuild process for a drive",
        type=int,
    )

    set_pd_action.add_argument(
        "-s",
        "--state",
        help="Update state if the physical drive",
        choices=["Onln", "Offln"],
    )

    set_pd_action.set_defaults(func=lambda args: process_cmd_result(
        StateClient(args["asset_key"]).set_physical_drive_prop(
            args["controller"], args["drive_id"], args)))
예제 #5
0
def manage_state(asset_key, mng_action):
    """Perform action for a node/asset with a certain key
    Args:
        asset_key (int): supplied asset identifier
        mng_action (func): callable object (lambda/function etc) that identifies action
    """
    state_manager = StateClient(asset_key)
    mng_action(state_manager)
예제 #6
0
def dry_run_actions(args):
    """Do a dry run of action replay without changing of affecting assets' states"""
    action_slc = get_action_slice(args["start"], args["end"])
    action_details = StateClient.list_actions(action_slc)
    try:
        Recorder.perform_dry_run(action_details, action_slc)
    except KeyboardInterrupt:
        print("Dry-run was interrupted by the user", file=sys.stderr)
예제 #7
0
def controller_command(ctrl_group):
    """Endpoints for setting storage props (pd, vd, controller etc.)"""

    ctrl_subp = ctrl_group.add_subparsers()
    server_controller_parent = get_ctrl_storage_args()

    # CLI controller setter
    set_ctrl_action = ctrl_subp.add_parser(
        "set",
        help="Configure a specific RAID controller",
        parents=[server_controller_parent],
    )

    set_ctrl_action.add_argument(
        "-e",
        "--memory-correctable-errors",
        help="Correctable RAM errors on disk data",
        type=int,
        required=False,
        dest="mem_c_errors",
    )

    set_ctrl_action.add_argument(
        "-u",
        "--memory-uncorrectable-errors",
        help="Uncorrectable RAM errors on disk data",
        type=int,
        required=False,
        dest="mem_uc_errors",
    )

    set_ctrl_action.add_argument(
        "-a",
        "--alarm-state",
        help="Controller alarm state",
        choices=["missing", "off", "on"],
        required=False,
        dest="alarm",
    )

    set_ctrl_action.set_defaults(func=lambda args: process_cmd_result(
        StateClient(args["asset_key"]).set_controller_prop(
            args["controller"], args)))
예제 #8
0
def get_action_slice(start, end):
    """Parse start & end range specifiers
    Args:
        start: start index or starting datestring or time string
                in a format "%H:%M:%S" or "%Y-%m-%d %H:%M:%S"
        end: end index or end date/time in a format "%H:%M:%S" or "%Y-%m-%d %H:%M:%S"
    Returns:
        slice: range of actions
    """

    try:
        return slice(int(start), int(end))
    except (ValueError, TypeError):

        # attemp to parse dates if one/both of the range options are non digits
        all_actions = StateClient.list_actions(slice(None, None))

        start = get_index_from_range_opt(start, all_actions)
        end = get_index_from_range_opt(end, all_actions, start_opt=False)

        return slice(start, end)
예제 #9
0
def power_command(power_group):
    """CLI endpoints for managing assets' power states & wallpower"""
    power_subp = power_group.add_subparsers()

    # Manage power of individual assets
    power_up_action = power_subp.add_parser(
        "up", help="Power up a particular component/asset"
    )
    power_up_action.add_argument("-k", "--asset-key", type=int, required=True)

    power_down_action = power_subp.add_parser(
        "down", help="Power down a particular component/asset"
    )
    power_down_action.add_argument("-k", "--asset-key", type=int, required=True)
    power_down_action.add_argument(
        "--hard",
        help="Enable abrupt poweroff instead of shutdown",
        dest="hard",
        action="store_true",
    )

    # Wallpower management
    power_outage_action = power_subp.add_parser(
        "outage", help="Simulate complete power loss"
    )
    power_restore_action = power_subp.add_parser(
        "restore", help="Restore mains power after outage"
    )

    # Voltage system-wide
    voltage_action_group = power_subp.add_parser(
        "voltage", help="Manage systems voltage behavior"
    )

    voltage_subp = voltage_action_group.add_subparsers()

    get_voltage_action = voltage_subp.add_parser(
        "get", help="Query current voltage configurations"
    )
    get_voltage_action.add_argument(
        "--value-only",
        help="Return voltage value only (omit details of voltage behaviour)",
        action="store_true",
    )

    set_voltage_action = voltage_subp.add_parser(
        "set", help="Update voltage value/voltage settings"
    )

    set_voltage_action.add_argument(
        "--value", type=float, help="Update voltage value (in Volts)"
    )

    set_voltage_action.add_argument(
        "--mu",
        type=float,
        help="Mean for gaussian random method for voltage fluctuations",
    )

    set_voltage_action.add_argument(
        "--sigma",
        type=float,
        help="Standard deviation for gaussian random method for voltage fluctuations",
    )

    set_voltage_action.add_argument(
        "--min",
        type=float,
        help="Min volt value for uniform random method for voltage fluctuations",
    )

    set_voltage_action.add_argument(
        "--max",
        type=float,
        help="Max volt value for uniform random method for voltage fluctuations",
    )

    set_voltage_action.add_argument(
        "--method",
        choices=ISystemEnvironment.voltage_random_methods(),
        help="Max volt value for uniform random method for voltage fluctuations",
    )

    set_voltage_action.add_argument(
        "--enable-fluctuation", dest="enabled", action="store_true"
    )
    set_voltage_action.add_argument(
        "--disable-fluctuation", dest="enabled", action="store_false"
    )

    # CLI action callbacks

    power_outage_action.set_defaults(func=lambda _: StateClient.power_outage())
    power_restore_action.set_defaults(func=lambda _: StateClient.power_restore())
    power_up_action.set_defaults(
        func=lambda args: manage_state(args["asset_key"], lambda a: a.power_up())
    )
    power_down_action.set_defaults(
        hard=False,  # abrupt shutdown if False by default
        func=lambda args: manage_state(
            args["asset_key"],
            lambda a: a.power_off() if args["hard"] else a.shut_down(),
        ),
    )

    set_voltage_action.set_defaults(func=handle_voltage_set)
    get_voltage_action.set_defaults(func=handle_voltage_get)
예제 #10
0
def actions_command(actions_group):
    """Action command can be used to manage/replay recorded
    actions performed by SimEngine users"""

    play_subp = actions_group.add_subparsers()

    # replay commands
    replay_action = play_subp.add_parser(
        "replay",
        help="Replay actions, will replay all history if range is not provided",
        parents=[range_args()],
    )
    replay_action.add_argument("-l",
                               "--list",
                               action="store_true",
                               help="List re-played actions")

    #  clear action history
    clear_action = play_subp.add_parser("clear",
                                        help="Purge action history",
                                        parents=[range_args()])
    clear_action.add_argument("-l",
                              "--list",
                              action="store_true",
                              help="List deleted actions")

    # misc
    disable_action = play_subp.add_parser(
        "disable",
        help="Disable recorder (recorder will ignore incoming commands)")
    enable_action = play_subp.add_parser(
        "enable", help="Enable recorder registering incoming actions")
    status_action = play_subp.add_parser(
        "status",
        help="Returns recorder status indicating if recorder is enabled \
            and if it is in-process of replaying",
    )
    list_action = play_subp.add_parser("list",
                                       help="List action history",
                                       parents=[range_args()])
    dry_run_action = play_subp.add_parser(
        "dry-run",
        help="Perform a dry run of actions replay",
        parents=[range_args()])

    save_action = play_subp.add_parser("save",
                                       help="Save action history to a file",
                                       parents=[range_args()])

    save_action.add_argument("-l",
                             "--list",
                             action="store_true",
                             help="Explicitly list saved actions")

    save_action.add_argument("-f",
                             "--filename",
                             type=str,
                             required=True,
                             help="Target file name")

    load_action = play_subp.add_parser(
        "load",
        help=
        "Load action history from a file (will override the existing actions)",
        parents=[range_args()],
    )

    load_action.add_argument("-f",
                             "--filename",
                             type=str,
                             required=True,
                             help="Will load from this file")

    rand_action = play_subp.add_parser(
        "random", help="Perform random actions associated with assets")
    rand_action.add_argument("-c",
                             "--count",
                             type=int,
                             help="Number of actions to be performed",
                             default=1)
    rand_action.add_argument(
        "-k",
        "--asset-keys",
        nargs="+",
        type=int,
        help="Include only these assets when picking a random component,\
            defaults to all if not provided",
    )
    rand_action.add_argument(
        "-s",
        "--seconds",
        type=int,
        help="Perform actions for 'n' seconds (alternative to 'count')",
    )
    rand_action.add_argument(
        "-n",
        "--nap-time",
        type=float,
        help=
        "Pause between each random action or max nap time if --min-nap is present",
    )

    rand_action.add_argument(
        "-m",
        "--min-nap",
        type=float,
        help="Minimum sleep time, pauses between actions will be set to random\
            if this value is provided",
    )

    # cli actions/callbacks
    replay_action.set_defaults(func=lambda args: [
        print_action_list(
            StateClient.list_actions(
                get_action_slice(args["start"], args["end"])))
        if args["list"] else None,
        StateClient.replay_actions(get_action_slice(args["start"], args["end"])
                                   ),
    ])

    clear_action.set_defaults(func=lambda args: [
        print_action_list(
            StateClient.list_actions(
                get_action_slice(args["start"], args["end"])))
        if args["list"] else None,
        StateClient.clear_actions(get_action_slice(args["start"], args["end"])
                                  ),
    ])

    list_action.set_defaults(func=lambda args: print_action_list(
        StateClient.list_actions(get_action_slice(args["start"], args["end"])))
                             )

    disable_action.set_defaults(
        func=lambda _: StateClient.set_recorder_status(enabled=False))

    enable_action.set_defaults(
        func=lambda _: StateClient.set_recorder_status(enabled=True))
    status_action.set_defaults(
        func=lambda _: print("Enabled: {enabled}\nReplaying: {replaying}".
                             format(**StateClient.get_recorder_status())))
    dry_run_action.set_defaults(func=dry_run_actions)

    save_action.set_defaults(
        func=lambda args: handle_file_command(args, StateClient.save_actions))
    load_action.set_defaults(
        func=lambda args: handle_file_command(args, StateClient.load_actions))

    rand_action.set_defaults(func=StateClient.rand_actions)
예제 #11
0
def configure_command(configure_state_group):
    """Update some runtime values of the system components"""

    conf_state_subp = configure_state_group.add_subparsers()
    conf_ups_action = conf_state_subp.add_parser(
        "ups", help="Update UPS runtime properties"
    )
    conf_ups_action.add_argument(
        "-k", "--asset-key", type=int, required=True, help="Unique asset key of the UPS"
    )

    conf_ups_action.add_argument(
        "-d",
        "--drain-speed",
        type=float,
        help="Update factor of the battery drain (1 sets to regular speed)",
        choices=range(1, 10001),
        metavar="[1-10001]",
    )

    conf_ups_action.add_argument(
        "-c",
        "--charge-speed",
        type=float,
        help="Update factor of the battery charge (1 sets to regular speed)",
        choices=range(1, 10001),
        metavar="[1-10001]",
    )

    conf_sensor_action = conf_state_subp.add_parser(
        "sensor", help="Update sensor runtime properties"
    )
    conf_sensor_action.add_argument(
        "-k",
        "--asset-key",
        type=int,
        required=True,
        help="Unique asset key of the server sensor belongs to",
    )

    conf_sensor_action.add_argument(
        "-s", "--sensor-name", type=str, required=True, help="Name of the sensor"
    )

    conf_sensor_action.add_argument(
        "-r",
        "--runtime-value",
        required=True,
        help="New sensor value (will be reflected on ipmi)",
    )

    conf_ups_action.set_defaults(
        func=lambda args: configure_battery(args["asset_key"], args)
    )
    conf_sensor_action.set_defaults(
        func=lambda args: StateClient(args["asset_key"]).set_sensor_status(
            args["sensor_name"], args["runtime_value"]
        )
    )

    conf_rand_action = conf_state_subp.add_parser(
        "randomizer", help="Configure randomized options for actions"
    )

    conf_rand_action.add_argument(
        "-k",
        "--asset-key",
        type=int,
        help="Unique asset key (Required if randomized \
             options are associated with an asset)",
    )

    conf_rand_action.add_argument(
        "-s", "--start", type=int, help="Start range value for randomized option"
    )

    conf_rand_action.add_argument(
        "-e", "--end", type=int, help="End range value for randomized option"
    )

    conf_rand_action.add_argument(
        "-l",
        "--list",
        action="store_true",
        help="List randranges for ranomizable options",
    )

    conf_rand_arguments = [
        "pd-media-error-count",
        "pd-other-error-count",
        "pd-predictive-error-count",
        "ctrl-memory-correctable-errors",
        "ctrl-memory-uncorrectable-errors",
        "ambient",
    ]

    conf_rand_action.add_argument(
        "-o",
        "--option",
        help="Option/Argument to be configured",
        choices=conf_rand_arguments,
    )

    conf_rand_action.set_defaults(validate=validate_randomizer_options)

    conf_rand_action.set_defaults(
        func=lambda args: handle_configure_randomizer(args, conf_rand_arguments)
    )