Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Platform Driver Development Framework (PDDF): Adding PDDF CLI utils #624

Merged
merged 3 commits into from
Dec 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions data/etc/bash_completion.d/pddf_fanutil
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
_pddf_fanutil_completion() {
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
_PDDF_FANUTIL_COMPLETE=complete $1 ) )
return 0
}

complete -F _pddf_fanutil_completion -o default pddf_fanutil;
8 changes: 8 additions & 0 deletions data/etc/bash_completion.d/pddf_ledutil
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
_pddf_ledutil_completion() {
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
_PDDF_LEDUTIL_COMPLETE=complete $1 ) )
return 0
}

complete -F _pddf_ledutil_completion -o default pddf_ledutil;
8 changes: 8 additions & 0 deletions data/etc/bash_completion.d/pddf_psuutil
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
_pddf_psuutil_completion() {
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
_PDDF_PSUUTIL_COMPLETE=complete $1 ) )
return 0
}

complete -F _pddf_psuutil_completion -o default pddf_psuutil;
8 changes: 8 additions & 0 deletions data/etc/bash_completion.d/pddf_thermalutil
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
_pddf_thermalutil_completion() {
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
_PDDF_THERMALUTIL_COMPLETE=complete $1 ) )
return 0
}

complete -F _pddf_thermalutil_completion -o default pddf_thermalutil;
Empty file added pddf_fanutil/__init__.py
Empty file.
193 changes: 193 additions & 0 deletions pddf_fanutil/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#!/usr/bin/env python
#
# main.py
#
# Command-line utility for interacting with FAN Controller in PDDF mode in SONiC
#

try:
import sys
import os
import subprocess
import click
import imp
import syslog
import types
import traceback
from tabulate import tabulate
from utilities_common import util_base
from utilities_common.util_base import UtilLogger
from utilities_common.util_base import UtilHelper
except ImportError as e:
raise ImportError("%s - required module not found" % str(e))

VERSION = '1.0'

SYSLOG_IDENTIFIER = "fanutil"
PLATFORM_SPECIFIC_MODULE_NAME = "fanutil"
PLATFORM_SPECIFIC_CLASS_NAME = "FanUtil"

# Global platform-specific fanutil class instance
platform_fanutil = None

#logger = UtilLogger(SYSLOG_IDENTIFIER)

# This is our main entrypoint - the main 'fanutil' command
@click.group()
def cli():
"""pddf_fanutil - Command line utility for providing FAN information"""

if os.geteuid() != 0:
click.echo("Root privileges are required for this operation")
sys.exit(1)

# Load the helper class
helper = UtilHelper()

if not helper.check_pddf_mode():
click.echo("PDDF mode should be supported and enabled for this platform for this operation")
sys.exit(1)

# Load platform-specific fanutil class
global platform_fanutil
try:
platform_fanutil = helper.load_platform_util(PLATFORM_SPECIFIC_MODULE_NAME, PLATFORM_SPECIFIC_CLASS_NAME)
except Exception as e:
click.echo("Failed to load {}: {}".format(PLATFORM_SPECIFIC_MODULE_NAME, str(e)))
sys.exit(2)

# 'version' subcommand
@cli.command()
def version():
"""Display version info"""
click.echo("PDDF fanutil version {0}".format(VERSION))

# 'numfans' subcommand
@cli.command()
def numfans():
"""Display number of FANs installed on device"""
click.echo(str(platform_fanutil.get_num_fans()))

# 'status' subcommand
@cli.command()
@click.option('-i', '--index', default=-1, type=int, help="the index of FAN")
def status(index):
"""Display FAN status"""
supported_fan = range(1, platform_fanutil.get_num_fans() + 1)
fan_ids = []
if (index < 0):
fan_ids = supported_fan
else:
fan_ids = [index]

header = ['FAN', 'Status']
status_table = []

for fan in fan_ids:
msg = ""
fan_name = "FAN {}".format(fan)
if fan not in supported_fan:
click.echo("Error! The {} is not available on the platform.\n" \
"Number of supported FAN - {}.".format(fan_name, platform_fanutil.get_num_fans()))
continue
presence = platform_fanutil.get_presence(fan)
if presence:
oper_status = platform_fanutil.get_status(fan)
msg = 'OK' if oper_status else "NOT OK"
else:
msg = 'NOT PRESENT'
status_table.append([fan_name, msg])

if status_table:
click.echo(tabulate(status_table, header, tablefmt="simple"))

# 'direction' subcommand
@cli.command()
@click.option('-i', '--index', default=-1, type=int, help="the index of FAN")
def direction(index):
"""Display FAN airflow direction"""
supported_fan = range(1, platform_fanutil.get_num_fans() + 1)
fan_ids = []
if (index < 0):
fan_ids = supported_fan
else:
fan_ids = [index]

header = ['FAN', 'Direction']
status_table = []

for fan in fan_ids:
msg = ""
fan_name = "FAN {}".format(fan)
if fan not in supported_fan:
click.echo("Error! The {} is not available on the platform.\n" \
"Number of supported FAN - {}.".format(fan_name, platform_fanutil.get_num_fans()))
continue
direction = platform_fanutil.get_direction(fan)
status_table.append([fan_name, direction])

if status_table:
click.echo(tabulate(status_table, header, tablefmt="simple"))

# 'speed' subcommand
@cli.command()
@click.option('-i', '--index', default=-1, type=int, help="the index of FAN")
def getspeed(index):
"""Display FAN speed in RPM"""
supported_fan = range(1, platform_fanutil.get_num_fans() + 1)
fan_ids = []
if (index < 0):
fan_ids = supported_fan
else:
fan_ids = [index]

header = ['FAN', 'Front Fan RPM', 'Rear Fan RPM']
status_table = []

for fan in fan_ids:
msg = ""
fan_name = "FAN {}".format(fan)
if fan not in supported_fan:
click.echo("Error! The {} is not available on the platform.\n" \
"Number of supported FAN - {}.".format(fan_name, platform_fanutil.get_num_fans()))
continue
front = platform_fanutil.get_speed(fan)
rear = platform_fanutil.get_speed_rear(fan)
status_table.append([fan_name, front, rear])

if status_table:
click.echo(tabulate(status_table, header, tablefmt="simple"))

# 'setspeed' subcommand
@cli.command()
@click.argument('speed', type=int)
def setspeed(speed):
"""Set FAN speed in percentage"""
if speed is None:
click.echo("speed value is required")
raise click.Abort()

status = platform_fanutil.set_speed(speed)
if status:
click.echo("Successful")
else:
click.echo("Failed")

@cli.group()
def debug():
"""pddf_fanutil debug commands"""
pass

@debug.command()
def dump_sysfs():
"""Dump all Fan related SysFS paths"""
status = platform_fanutil.dump_sysfs()

if status:
for i in status:
click.echo(i)



if __name__ == '__main__':
cli()
Empty file added pddf_ledutil/__init__.py
Empty file.
96 changes: 96 additions & 0 deletions pddf_ledutil/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env python
#
# main.py
#
# Command-line utility for interacting with FAN Controller in PDDF mode in SONiC
#

try:
import sys
import os
import subprocess
import click
import imp
import syslog
import types
import traceback
from tabulate import tabulate
from utilities_common import util_base
from utilities_common.util_base import UtilLogger
from utilities_common.util_base import UtilHelper
except ImportError as e:
raise ImportError("%s - required module not found" % str(e))

VERSION = '1.0'

SYSLOG_IDENTIFIER = "ledutil"
PLATFORM_SPECIFIC_MODULE_NAME = "ledutil"
PLATFORM_SPECIFIC_CLASS_NAME = "LedUtil"

# Global platform-specific ledutil class instance
platform_ledutil = None

#logger = UtilLogger(SYSLOG_IDENTIFIER)

# ==================== CLI commands and groups ====================


# This is our main entrypoint - the main 'ledutil' command
@click.group()
def cli():
"""pddf_ledutil - Command line utility for providing FAN information"""

if os.geteuid() != 0:
click.echo("Root privileges are required for this operation")
sys.exit(1)

# Load the helper class
helper = UtilHelper()

if not helper.check_pddf_mode():
click.echo("PDDF mode should be supported and enabled for this platform for this operation")
sys.exit(1)

# Load platform-specific fanutil class
global platform_ledutil
try:
platform_ledutil = helper.load_platform_util(PLATFORM_SPECIFIC_MODULE_NAME, PLATFORM_SPECIFIC_CLASS_NAME)
except Exception as e:
click.echo("Failed to load {}: {}".format(PLATFORM_SPECIFIC_MODULE_NAME, str(e)))
sys.exit(2)

# 'version' subcommand
@cli.command()
def version():
"""Display version info"""
click.echo("PDDF ledutil version {0}".format(VERSION))

# 'getstatusled' subcommand
@cli.command()
@click.argument('device_name', type=click.STRING)
@click.argument('index', type=click.STRING)
def getstatusled(device_name, index):
if device_name is None:
click.echo("device_name is required")
raise click.Abort()

outputs = platform_ledutil.get_status_led(device_name, index)
click.echo(outputs)


# 'setstatusled' subcommand
@cli.command()
@click.argument('device_name', type=click.STRING)
@click.argument('index', type=click.STRING)
@click.argument('color', type=click.STRING)
@click.argument('color_state', type=click.STRING)
def setstatusled(device_name, index, color, color_state):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the motivation to expose a CLI to set status led? Shouldn't it be controlled by the system itself?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some are but some are not. Usually PSU1/PSU2/FAN are controlled by system itself, But LOC are controlled by user. CPLD spec has R/W permission on the control register. DIAG led too, is not controlled by system sometimes.

if device_name is None:
click.echo("device_name is required")
raise click.Abort()

outputs = platform_ledutil.set_status_led(device_name, index, color, color_state)
click.echo(outputs)

if __name__ == '__main__':
cli()
Empty file added pddf_psuutil/__init__.py
Empty file.
Loading