Thanks. Do you think the tests for the script should as well be
adjusted so that they fail without the change, and pass with it?
(test_bitbakelayers_setup in meta/lib/oeqa/selftest/cases/bblayers.py)

This is clearly fixing a problem you saw in local testing, and it
would be good to ensure the problem does not silently reoccur in the
future.

Alex

On Sun, 15 Jan 2023 at 01:54, Chuck Wolber <chuck.wol...@boeing.com> wrote:
>
> The effect of subsequent setup-layers executions is now either a NOOP
> or the minimal set of changes required to ensure layers precisely match
> the JSON configuration.
>
> This change allows setup-layers to be incorporated into a team's
> configuration management strategy. In particular, the configuration
> JSON manages a "pinning policy" that documents the oversight of sources
> of change (a requirement for embedded development in highly regulated
> industries).
>
> One model for this strategy would work as follows. Team level policy is
> developed to regularly review upstream commits that occur between the
> current upstream HEAD and the previously pinned revision. The JSON
> configuration is periodically updated after a review, test, and approval
> process. In the rare instance that an upstream change is considered
> problematic, the bbappend mechanism can be used to make relevant
> changes in the team's project repository. This approach also requires
> that team developers regularly run the project repository copy of
> setup-layers. This is most easily accomplished by including setup-layers
> in a wrapper script that all team developers use to interact with the
> bitbake tool suite (e.g. "bb bitbake foo-image"). Project level policy
> and oversight is effectively "contained" within this wrapper script,
> thereby reducing a significant source of human error.
>
> It is also worth noting that, where project level policy cannot be
> asserted on layers with the bbappend mechanism (e.g. bbclass files), a
> patch set can be checked in to the project repository and automatically
> managed by the wrapper script. Patch management against local layer
> clones would be superficial in nature (not pushed upstream). This
> enables projects to "pull in" functionality and manage bug fixes on an
> as-needed basis.
>
> Left unstated, but acknowledged here, are a number of nuances required
> to successfully implement this strategy e.g. setup-layers does not work
> so well if your layer clone is dirty from locally applied patches, etc.
> The details are out of scope for this explanation. What should be
> clear is that a larger configuration management strategy can now benefit
> from the utility provided by setup-layers.
>
> Note: Neither the above configuration management strategy example nor
> the change itself is intended to alter the original intent to use
> "bitbake-layers create-layers-setup destdir" to keep pace with upstream
> activity for those who wish to use it that way.
>
> Signed-off-by: Chuck Wolber <chuck.wol...@boeing.com>
> ---
>  scripts/oe-setup-layers | 55 
> +++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 46 insertions(+), 9 deletions(-)
>
> diff --git a/scripts/oe-setup-layers b/scripts/oe-setup-layers
> index 7fe250c..a042a6c 100755
> --- a/scripts/oe-setup-layers
> +++ b/scripts/oe-setup-layers
> @@ -10,12 +10,42 @@
>  # bitbake-layers create-layers-setup destdir
>  #
>  # It is recommended that you do not modify this file directly, but rather 
> re-run the above command to get the freshest upstream copy.
> +#
> +# This script is idempotent. Subsequent runs only change what is necessary to
> +# ensure your layers match your configuration.
>
>  import argparse
>  import json
>  import os
>  import subprocess
>
> +def _is_layer_git_repo(layerdir):
> +    git_dir = os.path.join(layerdir, ".git")
> +    if not os.access(git_dir, os.R_OK):
> +        return False
> +    try:
> +        return subprocess.check_output("git -C %s rev-parse 
> --is-inside-git-dir" % git_dir, shell=True, stderr=subprocess.DEVNULL)
> +    except subprocess.CalledProcessError:
> +        return False
> +
> +def _is_layer_at_rev(layerdir, rev):
> +    try:
> +        curr_rev = subprocess.check_output("git -C %s rev-parse HEAD" % 
> layerdir, shell=True, stderr=subprocess.DEVNULL)
> +        if curr_rev.strip().decode("utf-8") == rev:
> +            return True
> +    except subprocess.CalledProcessError:
> +        pass
> +    return False
> +
> +def _is_layer_at_remote_uri(layerdir, remote, uri):
> +    try:
> +        curr_uri = subprocess.check_output("git -C %s remote get-url %s" % 
> (layerdir, remote), shell=True, stderr=subprocess.DEVNULL)
> +        if curr_uri.strip().decode("utf-8") == uri:
> +            return True
> +    except subprocess.CalledProcessError:
> +        pass
> +    return False
> +
>  def _do_checkout(args, json):
>      oesetupbuild = None
>      layers = json['sources']
> @@ -37,23 +67,30 @@ def _do_checkout(args, json):
>          remotes = l_remote['remotes']
>
>          print('\nSetting up source {}, revision {}, branch 
> {}'.format(l_name, desc, branch))
> -        cmd = 'git init -q {}'.format(layerdir)
> -        print("Running '{}'".format(cmd))
> -        subprocess.check_output(cmd, shell=True)
> +        if not _is_layer_git_repo(layerdir):
> +            cmd = 'git init -q {}'.format(layerdir)
> +            print("Running '{}'".format(cmd))
> +            subprocess.check_output(cmd, shell=True)
>
>          for remote in remotes:
> -            cmd = "git remote remove {} > /dev/null 2>&1; git remote add {} 
> {}".format(remote, remote, remotes[remote]['uri'])
> +            if not _is_layer_at_remote_uri(layerdir, remote, 
> remotes[remote]['uri']):
> +                cmd = "git remote remove {} > /dev/null 2>&1; git remote add 
> {} {}".format(remote, remote, remotes[remote]['uri'])
> +                print("Running '{}' in {}".format(cmd, layerdir))
> +                subprocess.check_output(cmd, shell=True, cwd=layerdir)
> +
> +                cmd = "git fetch -q {} || true".format(remote)
> +                print("Running '{}' in {}".format(cmd, layerdir))
> +                subprocess.check_output(cmd, shell=True, cwd=layerdir)
> +
> +        if not _is_layer_at_rev(layerdir, rev):
> +            cmd = "git fetch -q --all || true"
>              print("Running '{}' in {}".format(cmd, layerdir))
>              subprocess.check_output(cmd, shell=True, cwd=layerdir)
>
> -            cmd = "git fetch -q {} || true".format(remote)
> +            cmd = 'git checkout -q {}'.format(rev)
>              print("Running '{}' in {}".format(cmd, layerdir))
>              subprocess.check_output(cmd, shell=True, cwd=layerdir)
>
> -        cmd = 'git checkout -q {}'.format(rev)
> -        print("Running '{}' in {}".format(cmd, layerdir))
> -        subprocess.check_output(cmd, shell=True, cwd=layerdir)
> -
>          if os.path.exists(os.path.join(layerdir, 'scripts/oe-setup-build')):
>              oesetupbuild = os.path.join(layerdir, 'scripts/oe-setup-build')
>
> --
> 1.8.3.1
>
>
> 
>
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#175956): 
https://lists.openembedded.org/g/openembedded-core/message/175956
Mute This Topic: https://lists.openembedded.org/mt/96278464/21656
Group Owner: openembedded-core+ow...@lists.openembedded.org
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to