Skip to content

Commit 66e81bb

Browse files
FuzailBrcmabdosi
authored andcommitted
Platform Driver Development Framework (PDDF): Adding PDDF CLI utils (sonic-net#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.
1 parent 1f4e3a0 commit 66e81bb

File tree

14 files changed

+795
-0
lines changed

14 files changed

+795
-0
lines changed
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
_pddf_fanutil_completion() {
2+
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
3+
COMP_CWORD=$COMP_CWORD \
4+
_PDDF_FANUTIL_COMPLETE=complete $1 ) )
5+
return 0
6+
}
7+
8+
complete -F _pddf_fanutil_completion -o default pddf_fanutil;
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
_pddf_ledutil_completion() {
2+
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
3+
COMP_CWORD=$COMP_CWORD \
4+
_PDDF_LEDUTIL_COMPLETE=complete $1 ) )
5+
return 0
6+
}
7+
8+
complete -F _pddf_ledutil_completion -o default pddf_ledutil;
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
_pddf_psuutil_completion() {
2+
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
3+
COMP_CWORD=$COMP_CWORD \
4+
_PDDF_PSUUTIL_COMPLETE=complete $1 ) )
5+
return 0
6+
}
7+
8+
complete -F _pddf_psuutil_completion -o default pddf_psuutil;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
_pddf_thermalutil_completion() {
2+
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
3+
COMP_CWORD=$COMP_CWORD \
4+
_PDDF_THERMALUTIL_COMPLETE=complete $1 ) )
5+
return 0
6+
}
7+
8+
complete -F _pddf_thermalutil_completion -o default pddf_thermalutil;

pddf_fanutil/__init__.py

Whitespace-only changes.

pddf_fanutil/main.py

+193
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
#!/usr/bin/env python
2+
#
3+
# main.py
4+
#
5+
# Command-line utility for interacting with FAN Controller in PDDF mode in SONiC
6+
#
7+
8+
try:
9+
import sys
10+
import os
11+
import subprocess
12+
import click
13+
import imp
14+
import syslog
15+
import types
16+
import traceback
17+
from tabulate import tabulate
18+
from utilities_common import util_base
19+
from utilities_common.util_base import UtilLogger
20+
from utilities_common.util_base import UtilHelper
21+
except ImportError as e:
22+
raise ImportError("%s - required module not found" % str(e))
23+
24+
VERSION = '1.0'
25+
26+
SYSLOG_IDENTIFIER = "fanutil"
27+
PLATFORM_SPECIFIC_MODULE_NAME = "fanutil"
28+
PLATFORM_SPECIFIC_CLASS_NAME = "FanUtil"
29+
30+
# Global platform-specific fanutil class instance
31+
platform_fanutil = None
32+
33+
#logger = UtilLogger(SYSLOG_IDENTIFIER)
34+
35+
# This is our main entrypoint - the main 'fanutil' command
36+
@click.group()
37+
def cli():
38+
"""pddf_fanutil - Command line utility for providing FAN information"""
39+
40+
if os.geteuid() != 0:
41+
click.echo("Root privileges are required for this operation")
42+
sys.exit(1)
43+
44+
# Load the helper class
45+
helper = UtilHelper()
46+
47+
if not helper.check_pddf_mode():
48+
click.echo("PDDF mode should be supported and enabled for this platform for this operation")
49+
sys.exit(1)
50+
51+
# Load platform-specific fanutil class
52+
global platform_fanutil
53+
try:
54+
platform_fanutil = helper.load_platform_util(PLATFORM_SPECIFIC_MODULE_NAME, PLATFORM_SPECIFIC_CLASS_NAME)
55+
except Exception as e:
56+
click.echo("Failed to load {}: {}".format(PLATFORM_SPECIFIC_MODULE_NAME, str(e)))
57+
sys.exit(2)
58+
59+
# 'version' subcommand
60+
@cli.command()
61+
def version():
62+
"""Display version info"""
63+
click.echo("PDDF fanutil version {0}".format(VERSION))
64+
65+
# 'numfans' subcommand
66+
@cli.command()
67+
def numfans():
68+
"""Display number of FANs installed on device"""
69+
click.echo(str(platform_fanutil.get_num_fans()))
70+
71+
# 'status' subcommand
72+
@cli.command()
73+
@click.option('-i', '--index', default=-1, type=int, help="the index of FAN")
74+
def status(index):
75+
"""Display FAN status"""
76+
supported_fan = range(1, platform_fanutil.get_num_fans() + 1)
77+
fan_ids = []
78+
if (index < 0):
79+
fan_ids = supported_fan
80+
else:
81+
fan_ids = [index]
82+
83+
header = ['FAN', 'Status']
84+
status_table = []
85+
86+
for fan in fan_ids:
87+
msg = ""
88+
fan_name = "FAN {}".format(fan)
89+
if fan not in supported_fan:
90+
click.echo("Error! The {} is not available on the platform.\n" \
91+
"Number of supported FAN - {}.".format(fan_name, platform_fanutil.get_num_fans()))
92+
continue
93+
presence = platform_fanutil.get_presence(fan)
94+
if presence:
95+
oper_status = platform_fanutil.get_status(fan)
96+
msg = 'OK' if oper_status else "NOT OK"
97+
else:
98+
msg = 'NOT PRESENT'
99+
status_table.append([fan_name, msg])
100+
101+
if status_table:
102+
click.echo(tabulate(status_table, header, tablefmt="simple"))
103+
104+
# 'direction' subcommand
105+
@cli.command()
106+
@click.option('-i', '--index', default=-1, type=int, help="the index of FAN")
107+
def direction(index):
108+
"""Display FAN airflow direction"""
109+
supported_fan = range(1, platform_fanutil.get_num_fans() + 1)
110+
fan_ids = []
111+
if (index < 0):
112+
fan_ids = supported_fan
113+
else:
114+
fan_ids = [index]
115+
116+
header = ['FAN', 'Direction']
117+
status_table = []
118+
119+
for fan in fan_ids:
120+
msg = ""
121+
fan_name = "FAN {}".format(fan)
122+
if fan not in supported_fan:
123+
click.echo("Error! The {} is not available on the platform.\n" \
124+
"Number of supported FAN - {}.".format(fan_name, platform_fanutil.get_num_fans()))
125+
continue
126+
direction = platform_fanutil.get_direction(fan)
127+
status_table.append([fan_name, direction])
128+
129+
if status_table:
130+
click.echo(tabulate(status_table, header, tablefmt="simple"))
131+
132+
# 'speed' subcommand
133+
@cli.command()
134+
@click.option('-i', '--index', default=-1, type=int, help="the index of FAN")
135+
def getspeed(index):
136+
"""Display FAN speed in RPM"""
137+
supported_fan = range(1, platform_fanutil.get_num_fans() + 1)
138+
fan_ids = []
139+
if (index < 0):
140+
fan_ids = supported_fan
141+
else:
142+
fan_ids = [index]
143+
144+
header = ['FAN', 'Front Fan RPM', 'Rear Fan RPM']
145+
status_table = []
146+
147+
for fan in fan_ids:
148+
msg = ""
149+
fan_name = "FAN {}".format(fan)
150+
if fan not in supported_fan:
151+
click.echo("Error! The {} is not available on the platform.\n" \
152+
"Number of supported FAN - {}.".format(fan_name, platform_fanutil.get_num_fans()))
153+
continue
154+
front = platform_fanutil.get_speed(fan)
155+
rear = platform_fanutil.get_speed_rear(fan)
156+
status_table.append([fan_name, front, rear])
157+
158+
if status_table:
159+
click.echo(tabulate(status_table, header, tablefmt="simple"))
160+
161+
# 'setspeed' subcommand
162+
@cli.command()
163+
@click.argument('speed', type=int)
164+
def setspeed(speed):
165+
"""Set FAN speed in percentage"""
166+
if speed is None:
167+
click.echo("speed value is required")
168+
raise click.Abort()
169+
170+
status = platform_fanutil.set_speed(speed)
171+
if status:
172+
click.echo("Successful")
173+
else:
174+
click.echo("Failed")
175+
176+
@cli.group()
177+
def debug():
178+
"""pddf_fanutil debug commands"""
179+
pass
180+
181+
@debug.command()
182+
def dump_sysfs():
183+
"""Dump all Fan related SysFS paths"""
184+
status = platform_fanutil.dump_sysfs()
185+
186+
if status:
187+
for i in status:
188+
click.echo(i)
189+
190+
191+
192+
if __name__ == '__main__':
193+
cli()

pddf_ledutil/__init__.py

Whitespace-only changes.

pddf_ledutil/main.py

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env python
2+
#
3+
# main.py
4+
#
5+
# Command-line utility for interacting with FAN Controller in PDDF mode in SONiC
6+
#
7+
8+
try:
9+
import sys
10+
import os
11+
import subprocess
12+
import click
13+
import imp
14+
import syslog
15+
import types
16+
import traceback
17+
from tabulate import tabulate
18+
from utilities_common import util_base
19+
from utilities_common.util_base import UtilLogger
20+
from utilities_common.util_base import UtilHelper
21+
except ImportError as e:
22+
raise ImportError("%s - required module not found" % str(e))
23+
24+
VERSION = '1.0'
25+
26+
SYSLOG_IDENTIFIER = "ledutil"
27+
PLATFORM_SPECIFIC_MODULE_NAME = "ledutil"
28+
PLATFORM_SPECIFIC_CLASS_NAME = "LedUtil"
29+
30+
# Global platform-specific ledutil class instance
31+
platform_ledutil = None
32+
33+
#logger = UtilLogger(SYSLOG_IDENTIFIER)
34+
35+
# ==================== CLI commands and groups ====================
36+
37+
38+
# This is our main entrypoint - the main 'ledutil' command
39+
@click.group()
40+
def cli():
41+
"""pddf_ledutil - Command line utility for providing FAN information"""
42+
43+
if os.geteuid() != 0:
44+
click.echo("Root privileges are required for this operation")
45+
sys.exit(1)
46+
47+
# Load the helper class
48+
helper = UtilHelper()
49+
50+
if not helper.check_pddf_mode():
51+
click.echo("PDDF mode should be supported and enabled for this platform for this operation")
52+
sys.exit(1)
53+
54+
# Load platform-specific fanutil class
55+
global platform_ledutil
56+
try:
57+
platform_ledutil = helper.load_platform_util(PLATFORM_SPECIFIC_MODULE_NAME, PLATFORM_SPECIFIC_CLASS_NAME)
58+
except Exception as e:
59+
click.echo("Failed to load {}: {}".format(PLATFORM_SPECIFIC_MODULE_NAME, str(e)))
60+
sys.exit(2)
61+
62+
# 'version' subcommand
63+
@cli.command()
64+
def version():
65+
"""Display version info"""
66+
click.echo("PDDF ledutil version {0}".format(VERSION))
67+
68+
# 'getstatusled' subcommand
69+
@cli.command()
70+
@click.argument('device_name', type=click.STRING)
71+
@click.argument('index', type=click.STRING)
72+
def getstatusled(device_name, index):
73+
if device_name is None:
74+
click.echo("device_name is required")
75+
raise click.Abort()
76+
77+
outputs = platform_ledutil.get_status_led(device_name, index)
78+
click.echo(outputs)
79+
80+
81+
# 'setstatusled' subcommand
82+
@cli.command()
83+
@click.argument('device_name', type=click.STRING)
84+
@click.argument('index', type=click.STRING)
85+
@click.argument('color', type=click.STRING)
86+
@click.argument('color_state', type=click.STRING)
87+
def setstatusled(device_name, index, color, color_state):
88+
if device_name is None:
89+
click.echo("device_name is required")
90+
raise click.Abort()
91+
92+
outputs = platform_ledutil.set_status_led(device_name, index, color, color_state)
93+
click.echo(outputs)
94+
95+
if __name__ == '__main__':
96+
cli()

pddf_psuutil/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)