diff mbox series

[v2] bitbake-setup: preserve build config when init script is missing

Message ID 20260819120644.23750-1-giancarlo.cicellyn@gmail.com
State New
Headers show
Series [v2] bitbake-setup: preserve build config when init script is missing | expand

Commit Message

Giancarlo Cicellyn Comneno Aug. 19, 2026, 12:06 p.m. UTC
Source revisions can change during bitbake-setup updates. If an updated
source still provides scripts/oe-setup-build but no longer provides
oe-init-build-env, checkout_layers() continues to select that source as
the build environment provider.

setup_bitbake_build() currently discovers the missing init script only
after moving the active build/conf aside and creating replacement
configuration files. It then logs an error and returns, allowing
update_build() to continue writing fixed revisions and committing
configuration state despite the failed environment initialization.

Check for oe-init-build-env before modifying build/conf and raise an
exception when it is unavailable.

The regression test changes the configured source from master to another
branch that retains scripts/oe-setup-build but removes oe-init-build-env,
matching the supported source revision update mechanism. It verifies that
the failed update is reported and leaves the active local.conf unchanged.

Tests:
  LC_ALL=C LANG=C ./bin/bitbake-selftest bb.tests.setup

AI-Generated: Uses OpenAI ChatGPT
Signed-off-by: Giancarlo Cicellyn Comneno <giancarlo.cicellyn@gmail.com>
---
Changes in v2:
- model the failure through a supported source revision update instead of
  removing oe-init-build-env from the already configured revision
- make the regression test retain scripts/oe-setup-build while the updated
  revision removes oe-init-build-env
- clarify that the failed initialization replaces the active build/conf
  before returning success to update_build()
- verify the regression on unmodified origin/master and validate the revised
  patch with the full bb.tests.setup suite
---
 bin/bitbake-setup     |  8 +++---
 lib/bb/tests/setup.py | 67 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+), 4 deletions(-)

Comments

Alexander Kanavin Aug. 19, 2026, 12:10 p.m. UTC | #1
No. Please talk to me first (or wait for my reply) before sending any
revised patches.

Alex

On Wed, 19 Aug 2026 at 14:07, Giancarlo Cicellyn Comneno
<giancarlo.cicellyn@gmail.com> wrote:
>
> Source revisions can change during bitbake-setup updates. If an updated
> source still provides scripts/oe-setup-build but no longer provides
> oe-init-build-env, checkout_layers() continues to select that source as
> the build environment provider.
>
> setup_bitbake_build() currently discovers the missing init script only
> after moving the active build/conf aside and creating replacement
> configuration files. It then logs an error and returns, allowing
> update_build() to continue writing fixed revisions and committing
> configuration state despite the failed environment initialization.
>
> Check for oe-init-build-env before modifying build/conf and raise an
> exception when it is unavailable.
>
> The regression test changes the configured source from master to another
> branch that retains scripts/oe-setup-build but removes oe-init-build-env,
> matching the supported source revision update mechanism. It verifies that
> the failed update is reported and leaves the active local.conf unchanged.
>
> Tests:
>   LC_ALL=C LANG=C ./bin/bitbake-selftest bb.tests.setup
>
> AI-Generated: Uses OpenAI ChatGPT
> Signed-off-by: Giancarlo Cicellyn Comneno <giancarlo.cicellyn@gmail.com>
> ---
> Changes in v2:
> - model the failure through a supported source revision update instead of
>   removing oe-init-build-env from the already configured revision
> - make the regression test retain scripts/oe-setup-build while the updated
>   revision removes oe-init-build-env
> - clarify that the failed initialization replaces the active build/conf
>   before returning success to update_build()
> - verify the regression on unmodified origin/master and validate the revised
>   patch with the full bb.tests.setup suite
> ---
>  bin/bitbake-setup     |  8 +++---
>  lib/bb/tests/setup.py | 67 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 71 insertions(+), 4 deletions(-)
>
> diff --git a/bin/bitbake-setup b/bin/bitbake-setup
> index 34260139c..d214ad568 100755
> --- a/bin/bitbake-setup
> +++ b/bin/bitbake-setup
> @@ -354,6 +354,10 @@ def setup_bitbake_build(bitbake_config, layerdir, setupdir, thisdir, update_bb_c
>      if template and not os.path.exists(oesetupbuild):
>          raise Exception("Cannot complete setting up a bitbake build directory from OpenEmbedded template '{}' as oe-setup-build was not found in any layers; please use oe-init-build-env manually.".format(template))
>
> +    oeinitbuildenvdir = os.path.join(layerdir, 'oe-init-build-env-dir')
> +    if not template and not os.path.exists(os.path.join(oeinitbuildenvdir, "oe-init-build-env")):
> +        raise Exception("Could not find oe-init-build-env in any of the layers; please use another mechanism to initialize the bitbake environment")
> +
>      bitbake_confdir = os.path.join(bitbake_builddir, 'conf')
>      backup_bitbake_confdir = add_unique_timestamp_to_path(os.path.join(bitbake_builddir, 'conf-backup'))
>      upstream_bitbake_confdir = add_unique_timestamp_to_path(os.path.join(bitbake_builddir, 'conf-upstream'))
> @@ -368,10 +372,6 @@ def setup_bitbake_build(bitbake_config, layerdir, setupdir, thisdir, update_bb_c
>      if template:
>          bb.process.run([oesetupbuild, "setup", "-c", template, "-b", bitbake_builddir, "--no-shell"])
>      else:
> -        oeinitbuildenvdir = os.path.join(layerdir, 'oe-init-build-env-dir')
> -        if not os.path.exists(os.path.join(oeinitbuildenvdir, "oe-init-build-env")):
> -            logger.error("Could not find oe-init-build-env in any of the layers; please use another mechanism to initialize the bitbake environment")
> -            return
>          _make_init_build_env(bitbake_builddir, os.path.realpath(oeinitbuildenvdir))
>
>      _prepend_passthrough_to_init_build_env(bitbake_builddir)
> diff --git a/lib/bb/tests/setup.py b/lib/bb/tests/setup.py
> index 53a07ee3a..33ceaf3ce 100644
> --- a/lib/bb/tests/setup.py
> +++ b/lib/bb/tests/setup.py
> @@ -578,6 +578,73 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"]))
>          out = self.runbbsetup(["init", "--non-interactive", "-L", "test-repo", self.testrepopath, "--setup-dir-name", custom_setup_dir, "test-config-1", "gadget"])
>          _check_local_sources(custom_setup_dir)
>
> +    def test_update_preserves_build_conf_when_init_build_env_missing(self):
> +        if 'BBPATH' in os.environ:
> +            del os.environ['BBPATH']
> +        os.chdir(self.tempdir)
> +
> +        self.runbbsetup([
> +            "settings", "set", "default", "registry",
> +            "'git://{};protocol=file;branch=master;rev=master'".format(
> +                self.registrypath
> +            ),
> +        ])
> +        self.add_file_to_testrepo('test-file', 'initial\n')
> +        self.add_json_config_to_registry(
> +            'test-config-1.conf.json', 'master', 'master'
> +        )
> +
> +        self.runbbsetup([
> +            "init",
> +            "--non-interactive",
> +            "test-config-1",
> +            "gadget-notemplate",
> +        ])
> +
> +        setuppath = self.get_setup_path(
> +            'test-config-1', 'gadget-notemplate'
> +        )
> +        local_conf = os.path.join(
> +            setuppath, 'build', 'conf', 'local.conf'
> +        )
> +
> +        user_content = 'USER_SETTING = "preserve-me"\n'
> +        with open(local_conf, 'w') as f:
> +            f.write(user_content)
> +
> +        branch = 'missing-init-build-env'
> +        self.git(['checkout', '-b', branch], cwd=self.testrepopath)
> +
> +        self.assertTrue(os.path.exists(os.path.join(
> +            self.testrepopath, 'scripts', 'oe-setup-build'
> +        )))
> +        os.remove(os.path.join(self.testrepopath, 'oe-init-build-env'))
> +        self.git(['add', '-u'], cwd=self.testrepopath)
> +        self.git(
> +            ['commit', '-m', 'Remove oe-init-build-env'],
> +            cwd=self.testrepopath,
> +        )
> +
> +        self.add_json_config_to_registry(
> +            'test-config-1.conf.json', branch, branch
> +        )
> +
> +        os.environ['BBPATH'] = os.path.join(setuppath, 'build')
> +        try:
> +            with self.assertRaisesRegex(
> +                bb.process.ExecutionError,
> +                "Could not find oe-init-build-env",
> +            ):
> +                self.runbbsetup([
> +                    "update",
> +                    "--update-bb-conf=yes",
> +                ])
> +        finally:
> +            del os.environ['BBPATH']
> +
> +        with open(local_conf) as f:
> +            self.assertEqual(f.read(), user_content)
> +
>      def test_vscode(self):
>          if 'BBPATH' in os.environ:
>              del os.environ['BBPATH']
> --
> 2.43.0
>
diff mbox series

Patch

diff --git a/bin/bitbake-setup b/bin/bitbake-setup
index 34260139c..d214ad568 100755
--- a/bin/bitbake-setup
+++ b/bin/bitbake-setup
@@ -354,6 +354,10 @@  def setup_bitbake_build(bitbake_config, layerdir, setupdir, thisdir, update_bb_c
     if template and not os.path.exists(oesetupbuild):
         raise Exception("Cannot complete setting up a bitbake build directory from OpenEmbedded template '{}' as oe-setup-build was not found in any layers; please use oe-init-build-env manually.".format(template))
 
+    oeinitbuildenvdir = os.path.join(layerdir, 'oe-init-build-env-dir')
+    if not template and not os.path.exists(os.path.join(oeinitbuildenvdir, "oe-init-build-env")):
+        raise Exception("Could not find oe-init-build-env in any of the layers; please use another mechanism to initialize the bitbake environment")
+
     bitbake_confdir = os.path.join(bitbake_builddir, 'conf')
     backup_bitbake_confdir = add_unique_timestamp_to_path(os.path.join(bitbake_builddir, 'conf-backup'))
     upstream_bitbake_confdir = add_unique_timestamp_to_path(os.path.join(bitbake_builddir, 'conf-upstream'))
@@ -368,10 +372,6 @@  def setup_bitbake_build(bitbake_config, layerdir, setupdir, thisdir, update_bb_c
     if template:
         bb.process.run([oesetupbuild, "setup", "-c", template, "-b", bitbake_builddir, "--no-shell"])
     else:
-        oeinitbuildenvdir = os.path.join(layerdir, 'oe-init-build-env-dir')
-        if not os.path.exists(os.path.join(oeinitbuildenvdir, "oe-init-build-env")):
-            logger.error("Could not find oe-init-build-env in any of the layers; please use another mechanism to initialize the bitbake environment")
-            return
         _make_init_build_env(bitbake_builddir, os.path.realpath(oeinitbuildenvdir))
 
     _prepend_passthrough_to_init_build_env(bitbake_builddir)
diff --git a/lib/bb/tests/setup.py b/lib/bb/tests/setup.py
index 53a07ee3a..33ceaf3ce 100644
--- a/lib/bb/tests/setup.py
+++ b/lib/bb/tests/setup.py
@@ -578,6 +578,73 @@  print("BBPATH is {{}}".format(os.environ["BBPATH"]))
         out = self.runbbsetup(["init", "--non-interactive", "-L", "test-repo", self.testrepopath, "--setup-dir-name", custom_setup_dir, "test-config-1", "gadget"])
         _check_local_sources(custom_setup_dir)
 
+    def test_update_preserves_build_conf_when_init_build_env_missing(self):
+        if 'BBPATH' in os.environ:
+            del os.environ['BBPATH']
+        os.chdir(self.tempdir)
+
+        self.runbbsetup([
+            "settings", "set", "default", "registry",
+            "'git://{};protocol=file;branch=master;rev=master'".format(
+                self.registrypath
+            ),
+        ])
+        self.add_file_to_testrepo('test-file', 'initial\n')
+        self.add_json_config_to_registry(
+            'test-config-1.conf.json', 'master', 'master'
+        )
+
+        self.runbbsetup([
+            "init",
+            "--non-interactive",
+            "test-config-1",
+            "gadget-notemplate",
+        ])
+
+        setuppath = self.get_setup_path(
+            'test-config-1', 'gadget-notemplate'
+        )
+        local_conf = os.path.join(
+            setuppath, 'build', 'conf', 'local.conf'
+        )
+
+        user_content = 'USER_SETTING = "preserve-me"\n'
+        with open(local_conf, 'w') as f:
+            f.write(user_content)
+
+        branch = 'missing-init-build-env'
+        self.git(['checkout', '-b', branch], cwd=self.testrepopath)
+
+        self.assertTrue(os.path.exists(os.path.join(
+            self.testrepopath, 'scripts', 'oe-setup-build'
+        )))
+        os.remove(os.path.join(self.testrepopath, 'oe-init-build-env'))
+        self.git(['add', '-u'], cwd=self.testrepopath)
+        self.git(
+            ['commit', '-m', 'Remove oe-init-build-env'],
+            cwd=self.testrepopath,
+        )
+
+        self.add_json_config_to_registry(
+            'test-config-1.conf.json', branch, branch
+        )
+
+        os.environ['BBPATH'] = os.path.join(setuppath, 'build')
+        try:
+            with self.assertRaisesRegex(
+                bb.process.ExecutionError,
+                "Could not find oe-init-build-env",
+            ):
+                self.runbbsetup([
+                    "update",
+                    "--update-bb-conf=yes",
+                ])
+        finally:
+            del os.environ['BBPATH']
+
+        with open(local_conf) as f:
+            self.assertEqual(f.read(), user_content)
+
     def test_vscode(self):
         if 'BBPATH' in os.environ:
             del os.environ['BBPATH']