[elbe-devel] [PATCH 4/4] RFC: elbepack: add check-image-list/check-script XML element
Thomas Weißschuh
thomas.weissschuh at linutronix.de
Thu May 23 09:30:44 CEST 2024
The contents of the XML element define a test script which can be used
to validate the result of an ELBE build.
The script will be executed by "elbe check-build img".
To make authorship easier the path to a script can be specified in the
"location" XML attribute and it will be inlined during preprocessing.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh at linutronix.de>
---
elbepack/commands/check-build.py | 15 +++++++++++++++
elbepack/schema/dbsfed.xsd | 30 ++++++++++++++++++++++++++----
elbepack/xmlpreprocess.py | 16 ++++++++++++++++
tests/simple-validation-image.xml | 3 +++
4 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/elbepack/commands/check-build.py b/elbepack/commands/check-build.py
index d04e15a6ac5c..106386ec4f10 100644
--- a/elbepack/commands/check-build.py
+++ b/elbepack/commands/check-build.py
@@ -408,6 +408,10 @@ class CheckImage(CheckBase):
fail_cnt += self.do_img(tag)
total_cnt += 1
+ for tag in self.xml.all('.//check-image-list/check-script'):
+ fail_cnt += self.do_check_script(tag)
+ total_cnt += 1
+
logging.info('Succesfully validate %d images out of %d',
total_cnt - fail_cnt, total_cnt)
@@ -560,6 +564,17 @@ class CheckImage(CheckBase):
return ret or child.exitstatus
+ def do_check_script(self, tag):
+ with tempfile.NamedTemporaryFile(prefix='elbe-test-script-') as script:
+ script.write(tag.et.text.encode('utf-8'))
+ # To execute the file it needs to be closed.
+ script.file.close()
+
+ os.chmod(script.name, 0o500)
+ ps = subprocess.run([script.name, self.directory])
+
+ return not not ps.returncode
+
@CheckBase.register('sdk')
class CheckSDK(CheckBase):
diff --git a/elbepack/schema/dbsfed.xsd b/elbepack/schema/dbsfed.xsd
index 380e16cc8c80..5fbe2e726c18 100644
--- a/elbepack/schema/dbsfed.xsd
+++ b/elbepack/schema/dbsfed.xsd
@@ -553,10 +553,10 @@ SPDX-FileCopyrightText: Linutronix GmbH
Describes a sequence of check to be done on images.
</documentation>
</annotation>
- <sequence>
- <element name="check" type="rfs:check-img" minOccurs="0" maxOccurs="10">
- </element>
- </sequence>
+ <choice minOccurs="0" maxOccurs="10">
+ <element name="check" type="rfs:check-img" />
+ <element name="check-script" type="rfs:check-script" />
+ </choice>
<attributeGroup ref="xml:specialAttrs"/>
</complexType>
@@ -697,6 +697,28 @@ SPDX-FileCopyrightText: Linutronix GmbH
</choice>
</group>
+ <complexType name="check-script">
+ <annotation>
+ <documentation>
+ Validate the build results by running a script.
+
+ The script will be passed the build directory as argument.
+ Exit code 0 means success.
+ </documentation>
+ </annotation>
+ <simpleContent>
+ <extension base="rfs:string">
+ <attribute name="location" type="string" use="optional">
+ <annotation>
+ <documentation>
+ Read the script from a location on disk.
+ </documentation>
+ </annotation>
+ </attribute>
+ </extension>
+ </simpleContent>
+ </complexType>
+
<simpleType name="suite-initvm">
<restriction base="string">
<enumeration value="sid" />
diff --git a/elbepack/xmlpreprocess.py b/elbepack/xmlpreprocess.py
index 835d218076d0..407927f83073 100644
--- a/elbepack/xmlpreprocess.py
+++ b/elbepack/xmlpreprocess.py
@@ -4,6 +4,7 @@
import logging
import os
+import pathlib
import re
import subprocess
import sys
@@ -178,6 +179,17 @@ def preprocess_pkg_pinning(xml):
raise XMLPreprocessError('Invalid package pinning attributes')
+def preprocess_check_script(xml, basedir):
+ """Inline check scripts"""
+
+ for script in xml.iterfind('//check-image-list/check-script'):
+ location = script.attrib.pop('location')
+ if location is None:
+ continue
+
+ script.text = basedir.joinpath(location).read_text()
+
+
def preprocess_proxy_add(xml, opt_proxy=None):
"""Add proxy to mirrors from CLI arguments or environment variable"""
@@ -360,6 +372,8 @@ def xmlpreprocess(xml_input_file, xml_output_file, variants=None, proxy=None, gz
xml = etree.parse(xml_input_file, parser=parser)
xml.xinclude()
+ basedir = pathlib.Path(xml_input_file).parent
+
# Variant management
# check all nodes for variant field, and act accordingly.
# The result will not contain any variant attributes anymore.
@@ -430,6 +444,8 @@ def xmlpreprocess(xml_input_file, xml_output_file, variants=None, proxy=None, gz
preprocess_pkg_pinning(xml)
+ preprocess_check_script(xml, basedir)
+
if schema.validate(xml):
# if validation succedes write xml file
xml.write(
diff --git a/tests/simple-validation-image.xml b/tests/simple-validation-image.xml
index 1c87c3c46896..e2fe03c4b9a8 100644
--- a/tests/simple-validation-image.xml
+++ b/tests/simple-validation-image.xml
@@ -54,4 +54,7 @@ SPDX-FileCopyrightText: Linutronix GmbH
<set_packer packer="none">sda.img</set_packer>
</project-finetuning>
</target>
+ <check-image-list>
+ <check-script location="simple-validation-image-test.py" />
+ </check-image-list>
</ns0:RootFileSystem>
--
2.45.1
More information about the elbe-devel
mailing list