electron-builder
electron-builder copied to clipboard
DEB build created hardlinks which breaks when /opt is on a different drive
- Version: 22.9.1
- Electron Version: 9.x
- Target: DEB
If /opt
is on it's own device the DEB installer throws errors when creating hardlinks:
Preparing to unpack .../beekeeper-studio_1.10.0_amd64.deb ...
Unpacking beekeeper-studio (1.10.0) over (1.9.4) ...
13dpkg: error processing archive /var/cache/apt/archives/beekeeper-studio_1.10.0
_amd64.deb (--unpack):
error creating hard link './usr/share/icons/hicolor/24x24/apps/beekeeper-studio
.png': Invalid cross-device link
Errors were encountered while processing:
/var/cache/apt/archives/beekeeper-studio_1.10.0_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
This is present in the app I maintain (Beekeeper Studio) and found for other electron apps hosted on GitHub:
- https://github.com/beekeeper-studio/beekeeper-studio/issues/593
- https://github.com/LN-Zap/zap-desktop/issues/2089
I believe that means it's failing at this line: https://github.com/electron-userland/electron-builder/blob/da85087143d2c6a63faab4c44c28dc625326e9ee/packages/app-builder-lib/templates/linux/after-install.tpl#L4
I had a similar issue with our project in that we couldn't use symlinks either. Instead I mirrored the after-install.tpl
of electron-builder and swapped out the ln
line with a script.
#!/bin/bash
# Link to the binary
cat <<< '
#!/bin/bash
cd "/opt/${productFilename}/"
exec "./${executable}" "$@"
' > "/usr/bin/${executable}"
chmod 4755 "/usr/bin/${executable}"
# SUID chrome-sandbox for Electron 5+
chmod 4755 '/opt/${productFilename}/chrome-sandbox' || true
update-mime-database /usr/share/mime || true
update-desktop-database /usr/share/applications || true
Used in electron-builder as:
deb: {
afterInstall:"path/to/your/after-install.tpl"
}
Try giving that a shot? 🙂
The line mentioned by you looks OK, it's a symbolic link (-s
option), not a hardlink so this part won't fail. It's something about how electron-builder links icons.
I found this issue: https://github.com/AppImage/appimaged/issues/34 and it mentions this:
update-desktop-database ~/.local/share/applications/
update-mime-database ~/.local/share/mime/
Where are your desktop/mime databases located? I'm wondering if the assumption of /usr/share
is causing this hardlink error then
@mmaietta If set "productName": "破笼"
, chmod 4755 '/opt/${productFilename}/chrome-sandbox' || true
error:
$ sudo dpkg -i po-long_1.0.1_amd64_linux.deb
[sudo] m 的密码:
正在选中未选择的软件包 po-long。
(正在读取数据库 ... 系统当前共安装有 249729 个文件和目录。)
准备解压 po-long_1.0.1_amd64_linux.deb ...
正在解压 po-long (1.0.1) ...
正在设置 po-long (1.0.1) ...
chmod: 无法访问 '/opt/po-long/chrome-sandbox': 没有那个文件或目录
electron 12.0.5, electron-builder 22.10.5.
Real install path is /opt/破笼
, but the script find /opt/po-long
. If change electron-builder to 22.9.1
, no error.
package.json:
{
"name": "po-long",
...
"build": {
"appId": "red.lilu.app.pl",
"productName": "破笼",
...
"artifactName": "${name}_${version}_${arch}_${os}.${ext}",
"linux": {
"category": "Network.P2P",
"target": [
"deb",
"rpm"
],
"icon": "build/assets",
"executableName": "po-long"
},
additional:
I want to change the name of shortcut from po-long
to 破笼
. So i set "productName": "破笼"
. But it doesn't look good. The installation path and executable file name have also been modified... "executableName": "po-long"
change the executable file name back to po-long
, but not the installation path.
Is there any way to just change the shortcut name?
Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
I think I may be misunderstanding what you're looking for. When you mean shortcut, are you referring to what the Desktop entry shows? https://github.com/electron-userland/electron-builder/blob/28cb86bdcb6dd0b10e75a69ccd34ece6cca1d204/packages/app-builder-lib/src/targets/LinuxTargetHelper.ts#L111-L116
Can you try using this file for your afterInstall
hook for Linux? This tpl
file uses productFilename
instead of the default sanitizedProductName
which is what I think is creating your issue. Ref: Docs
https://github.com/electron-userland/electron-builder/blob/28cb86bdcb6dd0b10e75a69ccd34ece6cca1d204/packages/app-builder-lib/templates/linux/after-install.tpl
Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
@mmaietta so sorry I missed your response. It seems like that template always gets executed?
I have an after-install
FPM hook specified for my DEB builds: --after-install=build/deb-postinstall
, but I still have this issue. Do you know if there's a way to disable that script?
For some reason, afterInstall
was made explicitly available instead of through the FPM hook.
deb: {
afterInstall: 'build/deb-postinstall'
}
@mmaietta Thanks for your fix https://github.com/electron-userland/electron-builder/pull/5941/files/326873dafe3ac38b0fa2819c7f7176791c572070
package.json:
{
"name": "polong",
...
"build": {
"appId": "red.lilu.app.pl",
"productName": "破笼",
...
"linux": {
"category": "Network;P2P",
"target": [
"deb"
],
"executableName": "po-long"
}
works fine from v22.11.7.
It is better to remove update-desktop-database /usr/share/applications || true
from after-install.tpl. Debian 11 KDE not install desktop-file-utils, update-desktop-database
can not execute:
/var/lib/dpkg/info/polong.postinst:行10: update-desktop-database:未找到命令
It doesn't affect the use, but it doesn't look good.
or change to:
if hash update-mime-database 2>/dev/null; then
update-mime-database /usr/share/mime
fi
if hash update-desktop-database 2>/dev/null; then
update-desktop-database /usr/share/applications
fi
reference vscode
/var/lib/dpkg/info/code.postinst
@alx696 would you be willing to open a PR for that? I always am encouraging community contributions 🙂 Setting up a local dev environment is fairly straightforward too https://github.com/electron-userland/electron-builder/blob/master/CONTRIBUTING.md#to-setup-a-local-dev-environment
@mmaietta does your commit fix this issue? Should this be closed?
Ah no, I don't think this fixes is for us as it's the assets being hard linked causing this issue:
"E:/var/cache/apt/archives/beekeeper-studio_2.1.5_amd64.deb: error creating hard link './usr/share/icons/hicolor/256x256/apps/beekeeper- studio.png':Invalid cross-device link"
Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
Ping.
Would it be adequate to just ignore the result of this line and echo that it failed? https://github.com/kris7t/electron-builder/blob/dc359de5019807a014c62468385dfb14bbb5bd83/packages/app-builder-lib/templates/linux/after-install.tpl#L4
Not sure if there is another way ln -sf
could fail.
I just ran into this whilst trying to install upscayl https://github.com/upscayl/upscayl/issues/652.
Please fix it, it should be extremely simple to fix, just create a symlink instead of a hardlink.
Not sure if there is another way ln -sf could fail.
This is unrelated to the bug. ln -sf
cannot fail by creating instead a hardlink. Something is calling ln
without the -s
flag.
A workaround for end users that have no control over the .deb
creation process, is to install the package with dpkg --path-exclude
then create the symlinks manually. For example for Upscayl:
$ sudo dpkg -i \
--path-exclude=/usr/share/icons/hicolor/512x512/apps/upscayl.png \
--path-exclude=/usr/share/icons/hicolor/128x128/apps/upscayl.png \
upscayl-2.9.9-linux.deb
$ sudo ln -s /opt/Upscayl/resources/128x128.png /usr/share/icons/hicolor/128x128/apps/upscayl.png
$ sudo ln -s /opt/Upscayl/resources/512x512.png /usr/share/icons/hicolor/512x512/apps/upscayl.png
@infinity0 I'm tackling some high-priority items already in addition to swamped with work. Please open a PR with your suggested changes and I'm happy to give it a review
In the real world you can't expect unrelated strangers to fix boring bugs on your own project for free. I've reported exactly how to fix it, this is already more time than most strangers are willing to spend.
"In the real world" Get off your high horse. I'm the only maintainer on this project and have a life outside of this, what I do here is for free and out of care for helping others succeed at their own projects. Have a constructive mindset and conversation or don't comment at all.
I'll attend to this issue when I get around to it. Anyone is still free to open a PR with changes and I'm happy to review
Update: I've created a PR targeting this issue but am struggling to set up a Parallels VM that can test this directly. I'll be continuing to investigate how to do so
If anyone is willing to try this patch via patch-package
in the interim, it'd be greatly appreciated to help verify the fix.
app-builder-lib+24.13.1.patch
diff --git a/node_modules/app-builder-lib/templates/linux/after-install.tpl b/node_modules/app-builder-lib/templates/linux/after-install.tpl
index 0f541f9..65e7326 100644
--- a/node_modules/app-builder-lib/templates/linux/after-install.tpl
+++ b/node_modules/app-builder-lib/templates/linux/after-install.tpl
@@ -3,9 +3,9 @@
if type update-alternatives 2>/dev/null >&1; then
# Remove previous link if it doesn't use update-alternatives
if [ -L '/usr/bin/${executable}' -a -e '/usr/bin/${executable}' -a "`readlink '/usr/bin/${executable}'`" != '/etc/alternatives/${executable}' ]; then
- rm -f '/usr/bin/${executable}'
+ rm -f '/usr/bin/${executable}'
fi
- update-alternatives --install '/usr/bin/${executable}' '${executable}' '/opt/${sanitizedProductName}/${executable}' 100
+ update-alternatives --install '/usr/bin/${executable}' '${executable}' '/opt/${sanitizedProductName}/${executable}' 100 || ln -sf '/opt/${sanitizedProductName}/${executable}' '/usr/bin/${executable}'
else
ln -sf '/opt/${sanitizedProductName}/${executable}' '/usr/bin/${executable}'
fi
@@ -13,5 +13,10 @@ fi
# SUID chrome-sandbox for Electron 5+
chmod 4755 '/opt/${sanitizedProductName}/chrome-sandbox' || true
-update-mime-database /usr/share/mime || true
-update-desktop-database /usr/share/applications || true
+if hash update-mime-database 2>/dev/null; then
+ update-mime-database /usr/share/mime || true
+fi
+
+if hash update-desktop-database 2>/dev/null; then
+ update-desktop-database /usr/share/applications || true
+fi
From what I understand, update-alternatives
is supposed to create symlinks, not hardlinks, but it's the only mention I see that is referencing /opt
and that doesn't have a fallback
I've also added the change to ensure update-mime/desktop-database
exists on the system before attempting to execute it.
From what I understand, update-alternatives is supposed to create symlinks, not hardlinks
Furthermore, the files being hardlinked that users have reported are icons, not the binaries that are managed by update-alternatives.
Furthermore your general approach can't work because these commands are executed at build time. If builder computer has /opt on the same partition, the hardlink will succeed. But it's end-user computers that matter. There should be no attempt made to create hardlinks in the first place. forget this, seems I misinterpreted the script
You should re-open the bug. I predict other people are going to experience the same problem even with this "fix".
Have a think about what's dealing with the icons. I'm not familiar with the nodejs/electron ecosystem, and purposefully refuse to become familiar with it, it's bad for my mental health.
Have a think about what's dealing with the icons.
Also, the icons are created as hardlinks directly in the data portion of the deb file. In other words, this can't possibly be anything to do with post-install scripts or any other scripts being run on the end-user computer. Something is creating hardlinks on the builder computer and packaging them as hardlinks in the data portion of the deb file.