Skip to content

Commit

Permalink
Merge pull request #59 from Hui-Zhi/main
Browse files Browse the repository at this point in the history
Enhancements
  • Loading branch information
Hui-Zhi committed Jul 2, 2022
2 parents 53eb18c + c943664 commit 01b3a88
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 93 deletions.
4 changes: 2 additions & 2 deletions src/soliddriver_checks/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ def run(check_target, output, out_format, query, version):
\b
CHECK_TARGET can be:
rpm file
directory containing rpm files
KMP file
directory containing KMP files
"system" to check locally installed kernel modules
a config file listing remote systems to check (Please
ensure your remote systems are scp command accessable)
Expand Down
27 changes: 8 additions & 19 deletions src/soliddriver_checks/config/templates/driver-checks.html.jinja
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>checking result from soliddriver-checks</title>
<title>Kernel Module Check Report</title>
<style>body {
font-family: 'Poppins';
font-size: 18px;
Expand Down Expand Up @@ -66,26 +66,15 @@
</style>
</head>
<body>
<div><div>
<h1 style="text-align: center; font-size:x-large;background-color: #30BA78;">Solid driver check result (Drivers)</h1>
</dev>
<p style="font-size:large;">soliddriver-checks is a tool for parnter(s) and customer(s) to check their drivers installed and RPMs to ensure these are meet basic SUSE requirements.</p>
<p>What do we check for drivers?</p>
<ul style="font-size:x-small">
<li>supported flag:
<ul>
<li>'yes' means this package is built by SUSE and supported by SUSE</li>
<li>'external' means this package is built by vendor and supported by both SUSE and vendor</li>
<li>'Missing' or others means this package does not contain 'supported' flag or unrecognizable 'supported' flag</li>
Please contact your IHV or who provide this package to you if it's highlighted, we don't recommend you install it.
</ul>
</li>
<li>RPM information: means which RPM have this driver installed</li>
<li>SUSE Release: this driver was built for which SUSE OS version</li>
</ul></div>
<div style="background-color:#30BA78">
<h3 style="text-align: center; font-size:x-large;">Kernel Modules Check Report</h3>
</div>
<p style="font-size:small;"><strong>soliddriver-checks</strong> is a tool for parnter and customer to check their <strong>KMPs(Kernel Module Packages)</strong> or <strong>installed/running kernel modules</strong> whether can meet basic SUSE requirements. More information can be found <a href="https://github.com/SUSE/soliddriver-checks" style="background-color: #30BA78;">here</a></p>
<p style="font-size:small;"><strong style="background-color:yellow; color:red;">Notice: </strong> Only kernel modules provided by third parties can be list in this report, for full report please use json output.</p>
<p style="font-size:small;text-align:center">{{version}} {{timestamp}}</p>
{% for detail in details -%}
<div>
<p style="text-align: center; font-size:large;background-color: #30BA78;">Solid Driver Checking Result: {{detail.name}}</p>
<p style="text-align: center; font-size:large;background-color: #30BA78;">soliddriver check report: {{detail.name}}</p>
</div>
<div style="background-color: #30BA78;;">
<table style="width: 600px; margin-left: auto;margin-right: auto; border-collapse: collapse; border:hidden">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>checking result from soliddriver-checks</title>
<title>Kernel Module Packages Check Report</title>
<style>body {
font-family: 'Poppins';
font-size: 18px;
Expand All @@ -26,6 +26,13 @@
th.summary_vendor{
width:240px;
}
th.detail_rpm{
width:auto;
}
th.detail_kernel_module{
width:auto;
background-color:#90EBCD;
}
th.detail_0{
width:120px;
}
Expand All @@ -46,6 +53,10 @@
}
th.detail_6{
width:240px;
background-color:#90EBCD;
}th.detail_7{
width:240px;
background-color:#90EBCD;
}
td{
text-align:left;
Expand Down Expand Up @@ -94,26 +105,51 @@
td.warning_row_border{
border: 2px solid #FE7C3F
}
.tooltip {
position: relative;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 180px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -60px;
opacity: 0;
transition: opacity 0.3s;
}
.tooltiptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
</style>
</head>
<body>
<div><div>
<h1 style="text-align: center; font-size:x-large;background-color: #30BA78;">Solid driver check result (RPMs)</h1>
<div><div style="background-color:#30BA78">
<h3 style="text-align: center; font-size:x-large;">Kernel Module Packages Check Report</h3>
</div>
<p style="font-size:small;">soliddriver-checks is a tool for parnter(s) and customer(s) to check their RPMs to ensure these are meet basic SUSE requirements.</p>
<p style="font-size:x-small">Please refer to <a href="https://drivers.suse.com/doc/kmpm/" style="background-color: #30BA78;">Kernel Module Packages Manual</a> to learn how to build a KMP(Kernel Module Package).</p>
<p>What do we check?</p>
<ul style="font-size:x-small">
<li>supported flag: <ul>
<li>'yes' means this package is built by SUSE and supported by SUSE</li>
<li>'external' means this package is built by vendor and supported by both SUSE and vendor</li>
<li>'Missing' or others means this package does not contain 'supported' flag or unrecognizable 'supported' flag</li>
</ul>Please contact your IHV or who provide this package to you if it's highlighted, we don't recommend you install it. </li>
<li>symbol check: For all KMP packages, the symbols needed by the drivers in this packages, should also have the requires in RPM and the checksum should match. Otherwise we don't recommend you install it.</li>
<li>signature: We list it here but not check if it's from the vendor in the list, please veirfy it by youself.</li>
<li>vendor: SUSE partner who provides and supports the kernel module code and packaging.</li>
</ul>
<div></div>
<p style="font-size:small;"><strong>soliddriver-checks</strong> is a tool for parnter and customer to check their <strong>KMPs(Kernel Module Packages)</strong> or <strong>installed/running kernel modules</strong> whether can meet basic SUSE requirements. More information can be found <a href="https://github.com/SUSE/soliddriver-checks" style="background-color: #30BA78;">here</a></p>
<p style="font-size:small;text-align:center">{{version}} {{timestamp}}</p>
<div>
<p style="text-align: center; font-size:large;background-color: #30BA78;">Summary of the result from vendor perspective: </p>
</div>
Expand Down
Binary file modified src/soliddriver_checks/config/templates/templates.xlsx
Binary file not shown.
105 changes: 69 additions & 36 deletions src/soliddriver_checks/utils/data_exporter.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from sqlite3 import Timestamp
import pdfkit
import pandas as pd
import os
Expand All @@ -23,6 +24,15 @@
from jinja2 import Environment, FileSystemLoader
import re
from copy import copy
from datetime import datetime
from ..version import __VERSION__


def _get_version():
return f"version: {__VERSION__}"

def _generate_timestamp():
return f"timestamp: {datetime.now()}"


class SDCConf:
Expand Down Expand Up @@ -124,10 +134,10 @@ def __init__(self):
self._cfg_path = f"{pkg_path}/../config/templates/templates.xlsx"

def set_driver_check_overview(self, ws):
self._copy_work_sheep("driver-check-summary", ws)
self._copy_work_sheep("km-report-overview", ws)

def set_rpm_check_overview(self, ws):
self._copy_work_sheep("rpm-check-summary", ws)
self._copy_work_sheep("kmp-report-overview", ws)

def _copy_work_sheep(self, title, ws):
tmpl = load_workbook(filename=self._cfg_path)
Expand All @@ -143,6 +153,8 @@ def _copy_work_sheep(self, title, ws):
ws[cell.coordinate].fill = copy(cell.fill)
ws[cell.coordinate].alignment = copy(cell.alignment)

ws["A5"].value = _get_version()
ws["A6"].value = _generate_timestamp()

class RPMsExporter:
def __init__(self):
Expand All @@ -156,17 +168,21 @@ def _summary_symbol_result(self, val):

result = ""
if unfound_no > 0:
result = "Can not find symbols like {} ... in RPM! ".format(
val["unfound"][0]
)
# result = "Can not find symbols like {} ... in RPM! ".format(
# val["unfound"][0]
# )

result = f"Number of symbols can not be found in KMP: {unfound_no}"

if cs_mm_no > 0:
result = (
result
+ "Symbols check sum like {} ... does not match in RPM!".format(
val["checksum-mismatch"][0]
)
)
# result = (
# result
# + "Symbols check sum like {} ... does not match in RPM!".format(
# val["checksum-mismatch"][0]
# )
# )

result = result + f" Number of symbols checksum does not match: {cs_mm_no}"

return result

Expand Down Expand Up @@ -214,7 +230,7 @@ def _get_summary_table(self, rpm_table):
df_summary = pd.DataFrame(
columns=[
"Vendor",
"Total rpms",
"Total KMPs",
"Driver Checks",
"License",
"Signature",
Expand Down Expand Up @@ -282,7 +298,7 @@ def license_check(vld_lics, rpm_licenses, driver_license):
df_summary = df_summary.append(
{
"Vendor": v,
"Total rpms": total,
"Total KMPs": total,
"Driver Checks": f"{dc} ({dc/total * 100:.2f}%)",
"License": f"{lic_check} ({lic_check/total * 100:.2f}%)",
"Signature": f"{no_sig} ({no_sig/total * 100:.2f}%)",
Expand Down Expand Up @@ -310,7 +326,7 @@ def _get_summary_table_html(self, rpm_table):

for i, row in df_summary.iterrows():
vendor = row["Vendor"]
total_rpms = row["Total rpms"]
total_rpms = row["Total KMPs"]
dc = row["Driver Checks"]
lic_check = row["License"]
signature = row["Signature"]
Expand Down Expand Up @@ -427,16 +443,17 @@ def _get_table_detail_html(self, rpm_table):
with tb:
tb.set_attribute("class", "table_center")
with tr():
th("Name", rowspan=2).set_attribute("class", f"detail_0")
th("Path", rowspan=2).set_attribute("class", f"detail_1")
th("Vendor", rowspan=2).set_attribute("class", f"detail_2")
th("Signature", rowspan=2).set_attribute("class", f"detail_3")
th("License", rowspan=2).set_attribute("class", f"detail_4")
th("Weak Module Invoked", rowspan=2).set_attribute("class", f"detail_5")
th("Driver Checks", colspan=2).set_attribute("class", f"detail_6")
th("KMP Checks", colspan=6).set_attribute("class", f"detail_rpm")
th("Kernel Module Checks", colspan=2).set_attribute("class", f"detail_kernel_module")
with tr():
th("Supported Flag/Signature").set_attribute("class", f"detail_6")
th("Symbols").set_attribute("class", f"detail_7")
th("Name").set_attribute("class", f"detail_0")
th("Path").set_attribute("class", f"detail_1")
th("Vendor").set_attribute("class", f"detail_2")
th(raw("Signature<span class=\"tooltiptext\">Only check there's a signature or not.</span>")).set_attribute("class", f"detail_3 tooltip")
th(raw("License<span class=\"tooltiptext\">KMP and it's kernel modules should use open source licenses.</span>")).set_attribute("class", f"detail_4 tooltip")
th(raw("Weak Module Invoked<span class=\"tooltiptext\">Weak Module is necessary to make 3rd party kernel modules installed for one kernel available to KABI-compatible kernels. </span>")).set_attribute("class", f"detail_5 tooltip")
th(raw("Supported Flag/Signature<span class=\"tooltiptext\">\"supported\" flag: <br/> \"yes\": Only supported by SUSE<br/> \"external\": supported by both SUSE and vendor</span>")).set_attribute("class", f"detail_6 tooltip")
th(raw("Symbols<span class=\"tooltiptext\">symbols check is to check whether the symbols in kernel modules matches the symbols in its package.</span>")).set_attribute("class", f"detail_7 tooltip")

for i, row in df.iterrows():
with tr() as r:
Expand Down Expand Up @@ -523,9 +540,9 @@ def to_html(self, rpm_table, file):
file_loader = FileSystemLoader(jinja_tmpl)
env = Environment(loader=file_loader)

rpm_tmpl = env.get_template("rpm-checks.html.jinja")
rpm_tmpl = env.get_template("kmp-checks.html.jinja")

rpm_checks = rpm_tmpl.render(
rpm_checks = rpm_tmpl.render(version=_get_version(), timestamp=_generate_timestamp(),
summary_table=self._get_summary_table_html(rpm_table),
rpm_details=self._get_table_detail_html(rpm_table),
)
Expand Down Expand Up @@ -644,7 +661,7 @@ def _xlsx_create_vendor_summary(self, wb, rpm_table):

def _xlsx_create_rpm_details(self, wb, rpm_table):
df = self._rename_rpm_detail_columns(rpm_table)
ws_rd = wb.create_sheet("RPMs details")
ws_rd = wb.create_sheet("KMPs details")
(
normal_font,
normal_border,
Expand All @@ -671,15 +688,30 @@ def _xlsx_create_rpm_details(self, wb, rpm_table):
) = self._style.get_rpm_xslx_table_header()

# Add headers
ws_rd.merge_cells('A1:G1')
ws_rd['A1'] = "KMP Checks"
ws_rd['A1'].font = header_font
ws_rd['A1'].fill = header_fill
ws_rd['A1'].border = header_border
ws_rd['A1'].alignment = center_align

ws_rd.merge_cells('H1:I1')
ws_rd['H1'] = "Kernel Module Checks"
ws_rd['H1'].font = header_font
ws_rd['H1'].fill = header_fill
ws_rd['H1'].border = header_border
ws_rd['H1'].alignment = center_align

cols = df.columns
xlsx_cols = list(string.ascii_lowercase[0:len(cols)])
for i in range(len(xlsx_cols)):
cell_no = xlsx_cols[i] + "1"
cell_no = xlsx_cols[i] + "2"
ws_rd[cell_no] = cols[i]
ws_rd[cell_no].font = header_font
ws_rd[cell_no].fill = header_fill
ws_rd[cell_no].border = header_border

ws_rd["H2"] = "Supported Flag/Signature" # rename the column name
# No need to show below volumns
ws_rd.column_dimensions["J"].hidden = True # Driver Licenses
ws_rd.column_dimensions["E"].hidden = True # Distribution
Expand All @@ -690,7 +722,7 @@ def _xlsx_create_rpm_details(self, wb, rpm_table):
for i, row in df.iterrows():
rpm_license = row["License"]
for col_idx in range(len(cols)):
cell_no = xlsx_cols[col_idx] + str(i+2)
cell_no = xlsx_cols[col_idx] + str(i+3)
val = row[cols[col_idx]]

ws_rd[cell_no].font = normal_font
Expand Down Expand Up @@ -770,15 +802,15 @@ def to_excel(self, rpm_table, file):
wb.save(file)

def to_pdf(self, rpm_table, file):
self.to_html(rpm_table, ".tmp.rpms.html")
pdfkit.from_file(".tmp.rpms.html", file)
os.remove(".tmp.rpms.html")
self.to_html(rpm_table, ".tmp.kmps.html")
pdfkit.from_file(".tmp.kmps.html", file)
os.remove(".tmp.kmps.html")

def to_all(self, rpm_table, directory):
excel_file = os.path.join(directory, "check_result.xlsx")
html_file = os.path.join(directory, "check_result.html")
pdf_file = os.path.join(directory, "check_result.pdf")
json_file = os.path.join(directory, "check_result.json")
excel_file = os.path.join(directory, "check_report.xlsx")
html_file = os.path.join(directory, "check_report.html")
pdf_file = os.path.join(directory, "check_report.pdf")
json_file = os.path.join(directory, "check_report.json")

if not os.path.exists(directory):
os.mkdir(directory)
Expand Down Expand Up @@ -1000,6 +1032,7 @@ def to_html(self, driver_tables, file):
df.loc[df["running"] == "False", "running"] = "&#9940;"
df = self._refmt_supported(df)
ts = (
# df.style.hide(axis='index')
df.style.hide_index()
.set_table_attributes('class="table_center"')
.apply(self._format_row_html, axis=1)
Expand All @@ -1015,7 +1048,7 @@ def to_html(self, driver_tables, file):
}
)

driver_checks = driver_tmpl.render(details=details)
driver_checks = driver_tmpl.render(version=_get_version(), timestamp=_generate_timestamp(), details=details)

with open(file, "w") as f:
f.write(driver_checks)
Expand Down
Loading

0 comments on commit 01b3a88

Please sign in to comment.