diff mbox series

[2/2] classes/yocto-check-layer: add check for tasks that allow network access

Message ID 20250501140234.4113519-2-ross.burton@arm.com
State New
Headers show
Series [1/2] classes/yocto-check-layer: refactor to be extended easily | expand

Commit Message

Ross Burton May 1, 2025, 2:02 p.m. UTC
Add a new test that checks that no tasks between do_fetch (exclusive)
and do_build (inclusive) are allowed to use the network, with rare
exceptions.

The only exception currently is build-appliance-image's do_image task,
as that currently usese pip to install the required Toaster dependencies.

Note that this will mean layers that have Go-based recipes will fail
unless they're using the gomod fetcher and have a complete list of
modules in the SRC_URI.

Signed-off-by: Ross Burton <ross.burton@arm.com>
---
 meta/classes-global/yocto-check-layer.bbclass | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)
diff mbox series

Patch

diff --git a/meta/classes-global/yocto-check-layer.bbclass b/meta/classes-global/yocto-check-layer.bbclass
index 92a392af9c3..ba93085325f 100644
--- a/meta/classes-global/yocto-check-layer.bbclass
+++ b/meta/classes-global/yocto-check-layer.bbclass
@@ -27,6 +27,36 @@  def check_insane_skip(d):
             d.setVar("QA_ERRORS_FOUND", "True")
 
 
+# Check that no tasks (with rare exceptions) between do_fetch and do_build
+# use the network.
+def check_network_flag(d):
+    # BPN:task names that are allowed to reach the network, using fnmatch to compare.
+    allowed = []
+    # build-appliance-image uses pip at image time
+    allowed += ["build-appliance-image:do_image"]
+
+    def is_allowed(bpn, task):
+        from fnmatch import fnmatch
+        name = f"{bpn}:{task}"
+        return any(fnmatch(name, pattern) for pattern in allowed)
+
+    bpn = d.getVar("BPN")
+    seen = set()
+    stack = {"do_build"}
+    while stack:
+        task = stack.pop()
+        if task == "do_fetch":
+            continue
+
+        seen.add(task)
+        deps = d.getVarFlag(task, "deps") or []
+        stack |= {d for d in deps if d not in seen}
+
+        network = bb.utils.to_boolean(d.getVarFlag(task, "network"))
+        if network and not is_allowed(bpn, task):
+            bb.error(f"QA Issue: task {task} has network enabled")
+
 python () {
     check_insane_skip(d)
+    check_network_flag(d)
 }