Symlinks break when pushing with local mode on MacOS

Using the balena cli, and following all of these instructions (I’m running balenaOS 2.31.0+rev1) when I do a local push my symlinks break in the destination container.

I’m pushing from a Mac running macOS Mojave 10.14.4 to a Tx2 running an Ubuntu 16 container.

Don’t have time right now to figure out steps to reproduce, but I figured I’d share, since it will probably affect others. Happy to provide additional information if it would be helpful.

@cnr, thanks for reporting this. Even without steps to reproduce it, could you confirm if what you observed was that, perhaps, the targets of symlinks were copied instead of the symlink itself? Or maybe, that the symlink itself was copied, but pointing to the wrong target?

I will attempt to reproduce it and let you know.

Ok, this is what it should look like:

me: ~/my-code/bin/cli > ls -l
total 8
lrwxr-xr-x  1 me  staff    32B Jan 21 16:22 a.sh -> ../code/a/a.sh
lrwxr-xr-x  1 me  staff    44B Jan 21 16:22 b.py -> ../code/b/b.py
lrwxr-xr-x  1 me  staff    30B Jan 21 16:22 c.py -> ../code/c/c.py
lrwxr-xr-x  1 me  staff    32B Jan 21 16:22 d.py -> ../code/d/d.py
lrwxr-xr-x  1 me  staff    28B Jan 21 16:22 e.py -> ../code/e/e.py
-rw-r--r--  1 me  staff   183B Jan 21 16:22 readme.txt
lrwxr-xr-x  1 me  staff    26B Jan 21 16:22 f.py -> ../code/g/g.py
-rwxr-xr-x  1 me  staff   1.2K Mar 11 10:43 g.sh

Instead, after running balena push 10.0.0.65, it looks like:

[root@my-code cli]$ ls -l
total 72
-rwxr-xr-x 1 root root 18847 Apr 12 17:29 a.sh
-rwxr-xr-x 1 root root  3270 Apr 12 17:29 b.py
-rwxr-xr-x 1 root root  8820 Apr 12 17:29 c.py
-rwxr-xr-x 1 root root  5670 Apr 12 17:29 d.py
-rwxr-xr-x 1 root root  5986 Apr 12 17:29 e.py
-rw-r--r-- 1 root root   183 Apr 12 17:29 readme.txt
-rwxr-xr-x 1 root root 11040 Apr 12 17:29 f.py
-rwxr-xr-x 1 root root  1240 Apr 12 17:29 g.sh

Does that help?

Thanks @cnr, it does help! It has also helped that you shared the command line, because when I read “when I do a local push” in your first message I had assumed that it was the balena local push command instead of the balena push command. :smile: That’s good, because balena local push is deprecated and will be removed soon.

I believe it is a bug in the CLI and I have created this GitHub issue:

As a workaround in case this is getting in your way, you could create a tgz file with the symlinks, then use a RUN instruction in the Dockerfile to extract them on the device. Something along these lines:

# create a tgz with the symlinks
find . -maxdepth 1 -type l | xargs tar cvzf code-links.tgz
balena push 10.0.0.65

The Dockerfile should extract the symlinks:

# Dockerfile
...
COPY code-links.tgz ./
RUN tar xvzf code-links.tgz
...

Let us know if you need help with the workaround or have any other questions. Thanks again for reporting this issue!

1 Like

I commented on the GH issue, but wanted to mirror it here for context, too:

@pdcastro The behavior of not preserving symlinks can actually be incredibly helpful and solves a common challenge with Docker of not being able to easily include external files in a build context.

I’m leveraging the existing behavior (of not preserving symlinks) to override some of my app’s dependencies during local development. These dependencies are elsewhere on the filesystem and symlinked in the current app folder. Note that these dependencies are normally pulled from git repos during most builds, but the ability to override during development is so helpful.

Balena then treats these symlinks like normal folders at build time, which is what I was hoping for.

Here are some links that expand on some more use cases:

1 Like