Skip to content

Commit

Permalink
Platform Driver Development Framework (PDDF): Adding PDDF CLI utils (#…
Browse files Browse the repository at this point in the history
…624)

This change is related to Platform Driver Development Framework (PDDF) which is being added to sonic-buildimage repo. More details can be found here, sonic-net/SONiC#406

PDDF supports its own CLI utilities, which use generic PDDF component plugins. I added these PDDF CLI utilities.
  • Loading branch information
FuzailBrcm authored and lguohan committed Dec 6, 2019
1 parent 771f468 commit 0e4fc9c
Show file tree
Hide file tree
Showing 14 changed files with 795 additions and 0 deletions.
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):
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

0 comments on commit 0e4fc9c

Please sign in to comment.