balena-cli
balena-cli copied to clipboard
balena-cli tries to resolve unnecessary directories during livepush
- balena CLI version: 11.8.0
When starting a livepush session, any dangling symlink in the working directory (or in a child directory) will cause the push to fail, despite not being needed for resolution.
~/balena/balena-on-balena master*
❯ DEBUG=1 balena push --registry-secrets registry.json 192.168.43.114
[debug] original argv0="node" argv=[/usr/bin/node,/bin/balena,push,--registry-secrets,registry.json,192.168.43.114] length=6
[debug] Using . as build source
[Debug] Checking we can access device
[Debug] Sending request to http://192.168.43.114:48484/ping
[Debug] Checking device version: 10.1.5
[Info] Starting build on device 192.168.43.114
[Debug] Loading project...
[Debug] Resolving project...
[Info] Compose file detected
[Debug] Creating project...
Error: ENOENT: no such file or directory, stat '/home/matthew/balena/balena-on-balena/src/balena-mdns-publisher'
...
❯ file src/balena-mdns-publisher
src/balena-mdns-publisher: broken symbolic link to ../../balena-mdns-publisher
...
❯ grep -ir src/balena-mdns * | echo $?
1
Any updates on this? Same error
If the offending symlinks / directories are known in advance, a workaround may be to list them in a .dockerignore
file, which is supported with livepush since CLI v12.28.0. See balena help push
for more details on how to use .dockerignore
files.
Good day, we encountered the same issue today, and we actually have the file listed in the .dockerignore, once via listing a parent directory (our preferred method) but we also tried once via including the full path to the file (relative to .dockerignore). Both methods caused this issue. Therefore as it stands any broken link somewhere in the source directory can cause the push to fail, even if the file is .dockerignored. Additionally the link might not be broken on the target device, which makes it also a valid use-case to push broken links as-is.
My presumption is that the CLI somehow still needs to check the links when creating an index of files that the .dockerignore is then applied to, which causes it to crash because it can't follow the link to get the subdirectories & files at the link.
I think in the case of creating this index links should be added to the index as files without resolving them. That would either correctly apply the .dockerignore on the index afterwards and ignore the file altogether or just push it as a file. It would be impossible to dockerignore files within links though, which currently seems(?) possible, but I don't see an immediate use-case as I think the links are/ should be pushed as files to the device anyway and this is just an issue for the creation of an index for dockerignoring.
Resolving the links for the creation of the index also crashes the pushing if I create a loop of links. I tested this by having two directories with a link to one another inside. Both folders were in the dockerignore. This caused the pushing to fail as well:
Error: ELOOP: too many symbolic links encountered, stat '{{WORKING_DIR}}/bar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo/toBar/toFoo'
In our concrete use case we circumvented the issue by creating the target of the link as an empty directory/ file on our developer system to be able to push, as the file seems to be correctly ignored afterwards, but this might not be a viable solution for everyone, as there could be links to system folders as well. Pushing them as anything but links would also effectively copy the system folder if I am not mistaken? But I don't know if the actual tarring copies the files into the archive as links or as resolved files. As stated above I think this issue is limited to listing filepaths to check against the dockerignore.
Edit: Following the code a bit I pinpointed the place where I think the issue lies: https://github.com/balena-io/balena-cli/blob/ff3abe1fba2f6912228f9024fa84275ae320477c/lib/utils/ignore.ts#L56-L58 The walk function checks whether a symlink is a directory so it can follow it. This check itself fails (stat is mentioned in the error message as throwing the error and the error also happens if the dead link is a file). As mentioned above I think it should not follow symlinks and instead just handle symlinks as files, removing the capability to dockerignore files and directories inside a symlink, which I don't see an immediate use-case for. Open for discussion of course. Other more minimal invasive solution would be to check whether the link is dead and only then handle it like a file.
[rahul-thakoor] This issue has attached support thread https://jel.ly.fish/91388935-fa34-42ca-9561-90faf7d87a4f
Any feedback would be appreciated :)