diff mbox series

bitbake-setup: _symlink_local fix case when update

Message ID 20251222181527.2424323-1-anibal@limonsoftware.com
State New
Headers show
Series bitbake-setup: _symlink_local fix case when update | expand

Commit Message

Anibal Limon Dec. 22, 2025, 6:15 p.m. UTC
When run an update with setup_dir containing a local symlinked source it
fails because symlink already exists, so test for previous symlink
existance and update it if not point to the same local source directory.

Fixes,

```
$ bitbake-setup update --setup_dir /home/workspaces/ls/meta-ls/bitbake-setup/ls-master/stm32-toolchain

...
Traceback (most recent call last):
  File "/home/workspaces/ls/meta-ls/bitbake/bin/bitbake-setup", line 1042, in <module>
    main()
    ~~~~^^
  File "/home/workspaces/ls/meta-ls/bitbake/bin/bitbake-setup", line 1035, in main
    args.func(top_dir, all_settings, args, d)
    ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/workspaces/ls/meta-ls/bitbake/bin/bitbake-setup", line 667, in build_update
    build_status(top_dir, settings, args, d, update=True)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/workspaces/ls/meta-ls/bitbake/bin/bitbake-setup", line 652, in build_status
    update_build(new_upstream_config, confdir, setupdir, layerdir, d,
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                 update_bb_conf=args.update_bb_conf)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/workspaces/ls/meta-ls/bitbake/bin/bitbake-setup", line 340, in update_build
    sources_fixed_revisions = checkout_layers(layer_config, layerdir, d)
  File "/home/workspaces/ls/meta-ls/bitbake/bin/bitbake-setup", line 132, in checkout_layers
    _symlink_local(os.path.expanduser(r_local["path"]), os.path.join(layerdir,repodir))
    ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/workspaces/ls/meta-ls/bitbake/bin/bitbake-setup", line 114, in _symlink_local
    os.symlink(src, dst)
    ~~~~~~~~~~^^^^^^^^^^
FileExistsError: [Errno 17] File exists: '/home/workspaces/ls/meta-ls/layers' -> '/home/workspaces/ls/meta-ls/bitbake-setup/ls-master/stm32-toolc
hain/layers/ls-layers'
```

Signed-off-by: Anibal Limon <anibal@limonsoftware.com>
---
 bin/bitbake-setup | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

Comments

Alexander Kanavin Dec. 22, 2025, 7:18 p.m. UTC | #1
On Mon, 22 Dec 2025 at 19:15, Anibal Limon <anibal@limonsoftware.com> wrote:

> +        if os.path.islink(dst):
> +            if not os.path.samefile(src, dst):
> +                logger.plain("Updating symbolic link {} pointing to {}".format(dst, src))
> +                os.remove(src)
> +                do_symlink = True

dst is the symlink, but os.remove is taking src parameter. Is that correct?

> +        else:
> +            logger.plain("Making a symbolic link {} pointing to {}".format(dst, src))
> +            do_symlink = True
> +
> +        if do_symlink:
> +            os.symlink(src, dst)

Is this logic complete? It seems to cover the use case when one local
path is replaced with another local path in a json config, or when
local path is unchanged, but maybe we should cover the situation where
a git checkout is replaced by a local source as well?

This and the previous patch expose a gap in testing, perhaps
status/update tests should be extended to cover local sources?

Alex
Anibal Limon Dec. 22, 2025, 7:53 p.m. UTC | #2
On Mon, Dec 22, 2025 at 1:18 PM Alexander Kanavin <alex.kanavin@gmail.com>
wrote:

> On Mon, 22 Dec 2025 at 19:15, Anibal Limon <anibal@limonsoftware.com>
> wrote:
>
> > +        if os.path.islink(dst):
> > +            if not os.path.samefile(src, dst):
> > +                logger.plain("Updating symbolic link {} pointing to
> {}".format(dst, src))
> > +                os.remove(src)
> > +                do_symlink = True
>
> dst is the symlink, but os.remove is taking src parameter. Is that correct?
>

It is wrong, updating.


>
> > +        else:
> > +            logger.plain("Making a symbolic link {} pointing to
> {}".format(dst, src))
> > +            do_symlink = True
> > +
> > +        if do_symlink:
> > +            os.symlink(src, dst)
>
> Is this logic complete? It seems to cover the use case when one local
> path is replaced with another local path in a json config, or when
> local path is unchanged, but maybe we should cover the situation where
> a git checkout is replaced by a local source as well?
>

Right,
I think it should cover switching from local to remote or vice-versa too.

I'm using local sources, on the manifest:

```
....
        "ls-layers": {
            "local": {
                "path": "/home/workspaces/ls/meta-ls/layers'"
            }
        }
...
```

Then we run an update for a change on the manifest; it tries to make the
symlink again and fails.


>
> This and the previous patch expose a gap in testing, perhaps
> status/update tests should be extended to cover local sources?
>

Ack. I will look at the tests and send v2.


>
> Alex
>
diff mbox series

Patch

diff --git a/bin/bitbake-setup b/bin/bitbake-setup
index 1ea6796b5..378fbdc91 100755
--- a/bin/bitbake-setup
+++ b/bin/bitbake-setup
@@ -110,8 +110,19 @@  def checkout_layers(layers, layerdir, d):
             layers_fixed_revisions[r_name]['git-remote']['rev'] = revision
 
     def _symlink_local(src, dst):
-        logger.plain("Making a symbolic link {} pointing to {}".format(dst, src))
-        os.symlink(src, dst)
+        do_symlink = False
+
+        if os.path.islink(dst):
+            if not os.path.samefile(src, dst):
+                logger.plain("Updating symbolic link {} pointing to {}".format(dst, src))
+                os.remove(src)
+                do_symlink = True
+        else:
+            logger.plain("Making a symbolic link {} pointing to {}".format(dst, src))
+            do_symlink = True
+
+        if do_symlink:
+            os.symlink(src, dst)
 
     layers_fixed_revisions = copy.deepcopy(layers)
     repodirs = []