Files
yoctor-layers/meta-st/meta-st-openstlinux/classes/st-image-cve-summary.bbclass
2024-07-11 14:16:35 +02:00

631 lines
31 KiB
Plaintext

# To have tab on html file generated
CVE_IMAGE_CONTENT_WITH_TAB ?= "1"
# Configure on BSP side this var if you expect the summary to be generated
ENABLE_IMAGE_CVE_SUMMARY ??= "0"
ST_CVE_SUMMARY_DIR ?= "${WORKDIR}/cve-summary/"
ST_CVE_SUMMARY_DEPLOYDIR ?= "${DEPLOY_DIR}/images/${MACHINE}"
ST_CVE_SUMMARY_NAME ?= "${IMAGE_NAME}-cve_content.html"
ST_CVE_SUMMARY_LINK_NAME ?= "${IMAGE_LINK_NAME}-cve_content.html"
ST_MAIN_COMPONENTS ?= ""
def cve_create_summary(d):
import re
import json
tab = d.expand("${CVE_IMAGE_CONTENT_WITH_TAB}")
ref_image_name = d.expand("${IMAGE_LINK_NAME}")
deploy_image_dir = d.expand("${DEPLOY_DIR_IMAGE}")
temp_deploy_image_dir = d.expand("${IMGDEPLOYDIR}")
cve_deploy_dir = d.expand("${DEPLOY_DIR}/cve")
cve_summary_deploydir = d.getVar('ST_CVE_SUMMARY_DIR')
cve_summary_name = d.getVar('ST_CVE_SUMMARY_NAME')
cve_summary_link = d.getVar('ST_CVE_SUMMARY_LINK_NAME')
components_list = d.getVar('ST_MAIN_COMPONENTS')
datetime = d.getVar('DATETIME')
if tab.startswith("1"):
with_tab = 1
else:
with_tab = None
def private_open(filename):
result = None
if os.path.exists(filename):
try:
with open(filename, "r") as lic:
result = lic.readlines()
except IOError:
bb.warn("IMG LIC SUM: Cannot open file %s" % (filename))
result = ""
except:
bb.warn("IMG LIC SUM: Error with file %s" % (filename))
result = ""
else:
bb.warn("IMG LIC SUM: File does not exist with open file %s" % (filename))
result = ""
return result
class HTMLSummaryfile():
''' format definition '''
bold = "font-weight: bold; background-color: #cccccc;"
red = "background-color: #ff0000;"
center_format = "align: center;"
border_format = "border: 1;"
wrap_format = ""
wrap_red_format = "background-color: #ff0000;"
blue = "background-color: #0000ff;"
green = "background-color: #00ff00;"
opened_file = None
def openfile(self, file_name):
self.opened_file = open(file_name, 'w')
def closefile(self):
self.opened_file.close()
def startTable(self, style=None, classes=None):
if style:
if classes:
self.opened_file.write("<TABLE STYLE='%s' class='%s'>\n" % (style, classes))
else:
self.opened_file.write("<TABLE STYLE='%s'>\n" % style)
else:
if classes:
self.opened_file.write("<TABLE BORDER=1 class='%s'>\n" % classes)
else:
self.opened_file.write("<TABLE border=1>\n")
def stopTable(self):
self.opened_file.write("</TABLE>\n")
def startRow(self, style=None):
self.opened_file.write("<TR>\n")
def stopRow(self, style=None):
self.opened_file.write("</TR>\n")
def startColumn(self, style=None):
if style:
self.opened_file.write("<TD STYLE='%s'>\n")
else:
self.opened_file.write("<TD>\n")
def stopColumn(self, style=None):
self.opened_file.write("</TD>\n")
def addColumnHeaderContent(self, content, style=None):
if style:
self.opened_file.write("<TH STYLE='%s'>%s</TH>\n" % (style, content))
else:
self.opened_file.write("<TH><B>%s</B></TH>\n" % content)
def addColumnContent(self, content, style=None):
if style:
self.opened_file.write("<TD STYLE='%s'>%s</TD>\n" % (style, content))
else:
self.opened_file.write("<TD>%s</TD>\n" % content)
def addColumnURLOUTContent(self, content, url, style=None):
if style:
self.opened_file.write("<TD STYLE='%s'><A HREF='%s' TARGET='_blank'>%s</A></TD>\n" % (style, url, content))
else:
self.opened_file.write("<TD><A HREF='%s' TARGET='_blank'>%s</A></TD>\n" % (url, content))
def addColumnEmptyContent(self, style=None):
if style:
self.opened_file.write("<TD STYLE='%s'><BR/></TD>\n" % style)
else:
self.opened_file.write("<TD><BR/></TD>\n")
def addNewLine(self):
self.opened_file.write("<BR/>\n")
def addContent(self, content):
self.opened_file.write(content)
def addURLContent(self, content, url):
self.opened_file.write("<A HREF='%s'>%s</A>\n" %(url, content))
def startBlock(self):
self.opened_file.write("<UL>\n")
def stopBlock(self):
self.opened_file.write("</UL>\n")
def addTitle(self, title):
self.opened_file.write("<H1>{}</H1>\n".format(title))
def addAnchor(self, anchor):
self.opened_file.write("<A name='%s'/>\n" % anchor)
def startDiv(self, anchor, title, style=None):
self.opened_file.write("<div id='%s' class='tabcontent'>\n" % anchor)
self.opened_file.write("<H1>%s</H1>\n" % title)
def stopDiv(self):
self.opened_file.write("</div>\n")
def beginHtml(self):
self.opened_file.write("<HTML>\n")
self.opened_file.write('<HEAD>\n')
self.opened_file.write(" <STYLE TYPE='text/css'>\n")
self.opened_file.write("/* Style the tab buttons */\n")
self.opened_file.write(".tablink {\n")
self.opened_file.write(" background-color: #555;\n")
self.opened_file.write(" color: white;\n")
self.opened_file.write(" float: left;\n")
self.opened_file.write(" border: none;\n")
self.opened_file.write(" outline: none;\n")
self.opened_file.write(" cursor: pointer;\n")
self.opened_file.write(" padding: 14px 16px;\n")
self.opened_file.write(" font-size: 17px;\n")
self.opened_file.write(" width: 25%;\n")
self.opened_file.write("}\n")
self.opened_file.write("\n")
self.opened_file.write("/* Change background color of buttons on hover */\n")
self.opened_file.write(".tablink:hover {\n")
self.opened_file.write(" background-color: #777;\n")
self.opened_file.write("}\n")
self.opened_file.write("\n")
self.opened_file.write("/* Set default styles for tab content */\n")
self.opened_file.write(".tabcontent {\n")
self.opened_file.write(" color: black;\n")
self.opened_file.write(" display: none;\n")
self.opened_file.write(" padding: 50px;\n")
self.opened_file.write(" text-align: left;\n")
self.opened_file.write("}\n")
self.opened_file.write("\n")
self.opened_file.write("/* Style each tab content individually */\n")
self.opened_file.write("#statistic {background-color: white;}\n")
self.opened_file.write("#component {background-color: white;}\n")
self.opened_file.write("#images {background-color: white;}\n")
self.opened_file.write(" </STYLE>\n")
self.opened_file.write("</HEAD>\n")
def endHtml(self):
self.opened_file.write("</HTML>\n")
def beginBody(self, tab=None):
self.opened_file.write("<BODY>\n")
self.opened_file.write("<a name='top'/>\n")
def addApplicationTab(self):
if tab:
self.opened_file.write(' <button class="tablink" onclick="openTab(\'statistic\', this)" id="defaultOpen">Main Statistics</button>\n')
self.opened_file.write(' <button class="tablink" onclick="openTab(\'component\', this)">Main Components CVE / CVS</button>\n')
self.opened_file.write(' <button class="tablink" onclick="openTab(\'images\', this)">Image CVE / CVS</button>\n')
self.opened_file.write("\n")
def endBody(self, tab=None):
if tab:
self.opened_file.write('<SCRIPT TYPE="text/javascript">\n')
self.opened_file.write('function openTab(Name, elmnt) {\n')
self.opened_file.write(' // Hide all elements with class="tabcontent" by default */\n')
self.opened_file.write(' var i, tabcontent, tablinks;\n')
self.opened_file.write(' tabcontent = document.getElementsByClassName("tabcontent");\n')
self.opened_file.write(' for (i = 0; i < tabcontent.length; i++) {\n')
self.opened_file.write(' tabcontent[i].style.display = "none";\n')
self.opened_file.write(' }\n')
self.opened_file.write('\n')
self.opened_file.write(' // Remove the background color of all tablinks/buttons\n')
self.opened_file.write(' tablinks = document.getElementsByClassName("tablink");\n')
self.opened_file.write(' for (i = 0; i < tablinks.length; i++) {\n')
self.opened_file.write(' tablinks[i].style.backgroundColor = "";\n')
self.opened_file.write(' }\n')
self.opened_file.write('\n')
self.opened_file.write(' // Show the specific tab content\n')
self.opened_file.write(' document.getElementById(Name).style.display = "block";\n')
self.opened_file.write('\n')
self.opened_file.write(' // Add the specific color to the button used to open the tab content\n')
self.opened_file.write(' elmnt.style.backgroundColor = \'white\';\n')
self.opened_file.write(' elmnt.style.color = "black";\n')
self.opened_file.write('}\n')
self.opened_file.write('\n')
self.opened_file.write('function toggleunpatched(element) {\n')
self.opened_file.write(' patched = document.getElementsByClassName("patched");\n')
self.opened_file.write(' for (i = 0; i < patched.length; i++) {\n')
self.opened_file.write(' if (element.checked) {\n')
self.opened_file.write(' patched[i].style.display = "none";\n')
self.opened_file.write(' } else {\n')
self.opened_file.write(' patched[i].style.display = "block";\n')
self.opened_file.write(' }\n')
self.opened_file.write(' }\n')
self.opened_file.write('}\n')
self.opened_file.write('function toggleunscorev3(element) {\n')
self.opened_file.write(' score = document.getElementsByClassName("scorev3");\n')
self.opened_file.write(' for (i = 0; i < score.length; i++) {\n')
self.opened_file.write(' if (element.checked) {\n')
self.opened_file.write(' score[i].style.display = "none";\n')
self.opened_file.write(' } else {\n')
self.opened_file.write(' score[i].style.display = "block";\n')
self.opened_file.write(' }\n')
self.opened_file.write(' }\n')
self.opened_file.write(' if element.checked == false) {\n')
self.opened_file.write(' check = document.getElementsByName("check_unpatched")\n')
self.opened_file.write(' toggleunpatched(check[0])\n')
self.opened_file.write(' }\n')
self.opened_file.write('}\n')
self.opened_file.write('function toggleunscorev2(element) {\n')
self.opened_file.write(' score2 = document.getElementsByClassName("scorev2");\n')
self.opened_file.write(' for (i = 0; i < score2.length; i++) {\n')
self.opened_file.write(' if (element.checked) {\n')
self.opened_file.write(' score2[i].style.display = "none";\n')
self.opened_file.write(' } else {\n')
self.opened_file.write(' score2[i].style.display = "block";\n')
self.opened_file.write(' }\n')
self.opened_file.write(' }\n')
self.opened_file.write(' if element.checked == false) {\n')
self.opened_file.write(' check = document.getElementsByName("check_unpatched")\n')
self.opened_file.write(' toggleunpatched(check[0])\n')
self.opened_file.write(' }\n')
self.opened_file.write('}\n')
self.opened_file.write('// Get the element with id="defaultOpen" and click on it\n')
self.opened_file.write('document.getElementById("defaultOpen").click();\n')
self.opened_file.write('</SCRIPT>\n')
else:
self.opened_file.write('<SCRIPT TYPE="text/javascript">\n')
self.opened_file.write(' // display all elements with class="tabcontent" by default */\n')
self.opened_file.write(' var i, tabcontent, tablinks;\n')
self.opened_file.write(' tabcontent = document.getElementsByClassName("tabcontent");\n')
self.opened_file.write(' for (i = 0; i < tabcontent.length; i++) {\n')
self.opened_file.write(' tabcontent[i].style.display = "block";\n')
self.opened_file.write(' }\n')
self.opened_file.write('\n')
self.opened_file.write('</SCRIPT>\n')
self.opened_file.write("</BODY>\n")
def score_v2_table(score):
''' source : https://nvd.nist.gov/vuln-metrics/cvss '''
if float(score) < 4.0:
return "<SPAN STYLE='color: black; background-color: yellow;'> {} Low </SPAN>".format(score)
elif float(score) < 7.0:
return "<SPAN STYLE='color: black; background-color: #FFBF00;'> {} Medium </SPAN>".format(score)
else:
return "<SPAN STYLE='color: black; background-color: red;'> {} Hight </SPAN>".format(score)
def score_v3_table(score):
''' source : https://www.cert-ist.com/public/fr/SO_detail?code=cvss%20v3&format=html '''
if float(score) == 0.0:
return "<SPAN STYLE='color: black; background-color: darkgrey;'> {} None </SPAN>".format(score)
elif float(score) < 4.0:
return "<SPAN STYLE='color: black; background-color: yellow;'> {} Low </SPAN>".format(score)
elif float(score) < 7.0:
return "<SPAN STYLE='color: black; background-color: #FFBF00;'> {} Medium </SPAN>".format(score)
elif float(score) < 9.0:
return "<SPAN STYLE='color: black; background-color: red;'> {} High </SPAN>".format(score)
else:
return "<SPAN STYLE='color: white; background-color: black;'> {} Critical </SPAN>".format(score)
def generate_image_cve_sheet(html):
html.startDiv("images", "Image CVE / CVS")
html.addAnchor("images")
# link
html.addTitle("List of components on image:")
html.startTable(style="width: 80%; border: 1px solid black;")
html.startRow()
html.addContent("<TD width='20%'>")
count=0
col=0
with open(os.path.join(deploy_image_dir, "{}.json".format(ref_image_name))) as image_file:
json_component = json.load(image_file)
for i in json_component['package']:
issue=i['issue']
if len(issue) > 0:
html.addContent("<LI><a href='#image_{}'>{}</a></LI>\n".format(i['name'], i['name']))
count+=1
if count > 15:
count = 0
if col > 5:
col = 0
html.addContent("</td></tr><tr><td witdh='20%'>")
else:
html.addContent("</td><td witdh='10%'>")
col+=1
html.addContent("</TD>")
html.stopRow()
html.stopTable()
html.addNewLine()
html.addNewLine()
html.startTable(style="border: 1px solid black;")
with open(os.path.join(deploy_image_dir, ref_image_name + ".json")) as image_file:
json_component = json.load(image_file)
for i in json_component['package']:
issue=i['issue']
if len(issue) > 0:
html.startRow()
html.addColumnHeaderContent("Component Name <a href='#top'>[top]</a><a name='image_{}'/>".format(i['name']), style="font-weight: bold; background-color: #cccccc;")
html.addColumnHeaderContent("Version", style="font-weight: bold; background-color: #cccccc;")
html.addColumnHeaderContent("CVE Ref Name", style="font-weight: bold; background-color: #cccccc;")
html.stopRow()
html.startRow()
html.addColumnContent(i['name'])
html.addColumnContent(i['version'])
html.addColumnContent(i['products'][0]['product'])
html.stopRow()
html.startRow()
html.addColumnHeaderContent("Issues", style="font-weight: bold; background-color: #cccccc;")
html.addContent("<TD colspan='2'>")
for iss in issue:
classe = ''
if iss['status'].find("Unpatched") < 0:
classe += 'patched '
if float(iss['scorev3']) < 7.0 :
classe += 'scorev3 '
if float(iss['scorev2']) < 7.0 :
classe += 'scorev2 '
if len(classe) > 0:
html.startTable(style='border: 1px solid black; width=100%;', classes=classe)
else:
html.startTable(style='border: 1px solid black; width=100%;')
html.startRow()
html.addColumnContent(iss['id'], style="width: 10%;")
if iss['status'].find("Unpatched") > -1:
html.addColumnContent(iss['status'], style="background-color: red;")
else:
html.addColumnContent(iss['status'])
html.stopRow()
html.startRow()
html.addColumnContent("")
html.addColumnContent(iss['summary'])
html.stopRow()
html.startRow()
html.addColumnContent("")
html.addColumnContent("ScoreV2 = {} ScoreV3 = {}".format(score_v2_table(iss['scorev2']), score_v3_table(iss['scorev3'])))
html.stopRow()
html.startRow()
html.addColumnContent("")
html.addColumnContent("Link: <A HREF='{}'>NVD</A> or <A HREF='https://www.cve.org/CVERecord?id={}'>CVE.org</A>".format(iss['link'], iss['id']))
html.stopRow()
html.stopTable()
html.addContent("</TD>")
html.stopRow()
html.startRow()
html.stopRow()
html.startRow(style="bgcolor: gray;")
html.stopRow()
html.startRow()
html.stopRow()
html.stopTable()
html.stopDiv()
def generate_statistics_sheet(html, components):
general_MACHINE = d.getVar("MACHINE")
# Make sure to remove any DISTRO append to IMAGE_BASENAME for short display
general_IMAGE = re.sub(r'-%s$' % d.getVar('DISTRO'), '', d.getVar("IMAGE_BASENAME"))
general_DISTRO = d.getVar("DISTRO")
general_DISTRO_VERSION = d.getVar("DISTRO_VERSION")
general_DISTRO_CODENAME = d.getVar("DISTRO_CODENAME")
html.startDiv("statistic", "Main Statistics")
html.addAnchor("statistic")
html.addTitle("Number of CVE/CVS:")
html.startTable()
html.startRow()
html.addColumnHeaderContent("Component Name", style="font-weight: bold; background-color: #cccccc;")
html.addColumnHeaderContent("Issues", style="font-weight: bold; background-color: #cccccc;")
html.addColumnHeaderContent("Issues Patched", style="font-weight: bold; background-color: #cccccc;")
html.addColumnHeaderContent("Issues Unpatched", style="font-weight: bold; background-color: #cccccc;")
html.stopRow()
data = []
for c in components.split(','):
cvs = 0
patched = 0
unpatched = 0
file_name = os.path.join(cve_deploy_dir, "%s_cve.json" % c.lstrip().rstrip())
try:
with open(os.path.join(cve_deploy_dir, file_name)) as component_file:
json_component = json.load(component_file)
for i in json_component['package']:
issue=i['issue']
cvs = len(issue)
for err in issue:
if err['status'].find("Patched") > -1:
patched+= 1
elif err['status'].find("Unpatched") > -1:
unpatched+= 1
data.append([i['name'], cvs, patched, unpatched])
except FileNotFoundError:
bb.note("file (%s) are not present" % os.path.join(cve_deploy_dir, "%s_cve.json" % c.lstrip().rstrip()))
for i in data:
html.startRow()
html.addColumnContent(i[0], style="width: 10%;")
html.addColumnContent(i[1], style="width: 10%; text-align: center;")
html.addColumnContent(i[2], style="text-align: center;")
html.addColumnContent(i[3], style="text-align: center;")
html.stopRow()
html.stopTable()
html.addNewLine()
html.addNewLine()
# image count
with open( os.path.join(deploy_image_dir, "{}.json".format(ref_image_name))) as image_file:
json_component = json.load(image_file)
cvs = 0
package=0
patched = 0
unpatched = 0
for i in json_component['package']:
package += 1
issue=i['issue']
cvs += len(issue)
for err in issue:
if err['status'].find("Patched") > -1:
patched += 1
elif err['status'].find("Unpatched") > -1:
unpatched += 1
# package, cvs, patched, unpatched
html.addTitle("Number of CVE/CVS for image:")
html.startTable()
html.startRow()
html.addColumnHeaderContent("Image Name", style="font-weight: bold; background-color: #cccccc;")
html.addColumnHeaderContent("Packages", style="font-weight: bold; background-color: #cccccc;")
html.addColumnHeaderContent("Issues", style="font-weight: bold; background-color: #cccccc;")
html.addColumnHeaderContent("Issues Patched", style="font-weight: bold; background-color: #cccccc;")
html.addColumnHeaderContent("Issues Unpatched", style="font-weight: bold; background-color: #cccccc;")
html.stopRow()
html.startRow()
html.addColumnContent(ref_image_name, style="width: 25%; ")
html.addColumnContent(package, style="width: 10%; text-align: center;")
html.addColumnContent(cvs, style="text-align: center;")
html.addColumnContent(patched, style="text-align: center;")
html.addColumnContent(unpatched, style="text-align: center;")
html.stopRow()
html.stopTable()
html.stopDiv()
def generate_components_content_sheet(html, components):
html.startDiv("component", "Main Components CVE / CVS")
html.addAnchor("component")
html.addTitle("List of components:")
# link
for c in components.split(","):
html.addContent("<LI><a href='#component_{}'>{}</a></LI>\n".format(c, c))
html.addNewLine()
html.addNewLine()
for name in components.split(","):
html.addContent("<H1>Component: {} <a href='#top'>[top]</a></H1>\n".format(name))
html.addContent("<a name='component_{}'/>\n".format(name))
html.startTable(style="border: 1px solid black;")
html.startRow()
html.addColumnHeaderContent("Component Name", style="font-weight: bold; background-color: #cccccc;")
html.addColumnContent(name)
html.stopRow()
try:
with open(os.path.join(cve_deploy_dir, "%s_cve.json" % name.lstrip().rstrip())) as component_file:
json_component = json.load(component_file)
for i in json_component['package']:
issue=i['issue']
html.startRow()
html.addColumnHeaderContent("Version", style="font-weight: bold; background-color: #cccccc;")
html.addColumnContent(i['version'])
html.stopRow()
html.startRow()
html.addColumnHeaderContent("CVE Ref Name", style="font-weight: bold; background-color: #cccccc;")
html.addColumnContent(i['products'][0]['product'])
html.stopRow()
html.startRow()
html.addColumnHeaderContent("Issues", style="font-weight: bold; background-color: #cccccc;")
html.startColumn()
for iss in issue:
classe = ''
if iss['status'].find("Unpatched") < 0:
classe += 'patched '
if float(iss['scorev3']) < 7.0 :
classe += 'scorev3 '
if float(iss['scorev2']) < 7.0 :
classe += 'scorev2 '
if len(classe) > 0:
html.startTable(style='border: 1px solid black; width=100%;', classes=classe)
else:
html.startTable(style='border: 1px solid black; width=100%;')
html.startRow()
html.addColumnContent(iss['id'], style="width: 10%;")
if iss['status'].find("Unpatched") > -1:
html.addColumnContent(iss['status'], style="background-color: red;")
else:
html.addColumnContent(iss['status'])
html.stopRow()
html.startRow()
html.addColumnContent("")
html.addColumnContent(iss['summary'])
html.stopRow()
html.startRow()
html.addColumnContent("")
html.addColumnContent("ScoreV2 = {}; ScoreV3 = {}".format(score_v2_table(iss['scorev2']), score_v3_table(iss['scorev3'])))
html.stopRow()
html.startRow()
html.addColumnContent("")
html.addColumnContent("Link: <A HREF='{}'>NVD</A> or <A HREF='https://www.cve.org/CVERecord?id={}'>CVE.org</A>".format(iss['link'], iss['id']))
html.stopRow()
# empty line for separation
html.startRow(style="bgcolor: gray;")
html.stopRow()
html.stopTable()
html.stopColumn()
i = None
except FileNotFoundError:
bb.note("file (%s) are not present" % os.path.join(cve_deploy_dir, "%s_cve.json" % name.lstrip().rstrip()))
html.stopTable()
html.stopDiv()
# Create license summary file
cve_summary_name_path = os.path.join(cve_summary_deploydir, cve_summary_name)
print("generate ", cve_summary_name_path)
html = HTMLSummaryfile()
html.openfile(cve_summary_name_path)
html.beginHtml()
html.beginBody(with_tab)
html.addTitle("Image Name: {}<BR/>Generation Date: {}".format(ref_image_name, datetime))
html.addContent("<div class='one'>See Only 'Unpatched' CVE <input type='checkbox' valud='submit' class='btn' name='unpatched' onclick='toggleunpatched(this)'></div>")
html.addNewLine()
html.addContent("<div class='one'>See Only 'ScoreV3 > 7' (only)<input type='checkbox' valud='submit' class='btn' onclick='toggleunscorev3(this)'></div>")
html.addNewLine()
html.addContent("<div class='one'>See Only 'ScoreV2 > 7' (only)<input type='checkbox' valud='submit' class='btn' onclick='toggleunscorev2(this)'></div>")
html.addNewLine()
html.addApplicationTab()
''' generate first page: statistics cve / cvs information'''
generate_statistics_sheet(html, components_list)
''' generate image content '''
generate_components_content_sheet(html, components_list)
''' generate license spdx reference '''
generate_image_cve_sheet(html)
html.endBody(with_tab)
html.endHtml()
html.closefile()
# Create link
cve_summary_link_path = os.path.join(cve_summary_deploydir, cve_summary_link)
if os.path.exists(cve_summary_name_path):
bb.note("Creating symlink: %s -> %s" % (cve_summary_link_path, cve_summary_name))
if os.path.islink(cve_summary_link_path):
os.remove(cve_summary_link_path)
os.symlink(cve_summary_name, cve_summary_link_path)
else:
bb.note("Skipping symlink, source does not exist: %s -> %s" % (cve_summary_link_path, cve_summary_name))
python do_st_write_cve_create_summary() {
bb.note("---> ENABLE_IMAGE_CVE_SUMMARY %s" % (d.getVar('ENABLE_IMAGE_CVE_SUMMARY')))
if d.getVar('ENABLE_IMAGE_CVE_SUMMARY') == "1":
if not d.getVar('CVE_CHECK_MANIFEST') is None:
cve_create_summary(d)
else:
return
}
addtask st_write_cve_create_summary before do_build after do_image_complete
do_st_write_cve_create_summary[dirs] = "${ST_CVE_SUMMARY_DIR} ${IMGDEPLOYDIR}"
SSTATETASKS += "do_st_write_cve_create_summary"
do_st_write_cve_create_summary[cleandirs] = "${ST_CVE_SUMMARY_DIR}"
do_st_write_cve_create_summary[sstate-inputdirs] = "${ST_CVE_SUMMARY_DIR}"
do_st_write_cve_create_summary[sstate-outputdirs] = "${ST_CVE_SUMMARY_DEPLOYDIR}/"
python do_st_write_cve_create_summary_setscene () {
sstate_setscene(d)
}
addtask do_st_write_cve_create_summary_setscene
#excluded from basehash signature calculation
cve_create_summary[vardepsexclude] += "DATETIME"