[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