Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEB build created hardlinks which breaks when /opt is on a different drive #5721

Open
rathboma opened this issue Mar 19, 2021 · 25 comments · Fixed by #8067
Open

DEB build created hardlinks which breaks when /opt is on a different drive #5721

rathboma opened this issue Mar 19, 2021 · 25 comments · Fixed by #8067

Comments

@rathboma
Copy link

rathboma commented Mar 19, 2021

  • 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:

@mmaietta
Copy link
Collaborator

I believe that means it's failing at this line:

ln -sf '/opt/${productFilename}/${executable}' '/usr/bin/${executable}'

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? 🙂

@furai
Copy link

furai commented Mar 25, 2021

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.

@mmaietta
Copy link
Collaborator

I found this issue: AppImageCommunity/appimaged#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

@alx696
Copy link
Contributor

alx696 commented Apr 25, 2021

@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?

@stale
Copy link

stale bot commented Jun 26, 2021

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.

@stale stale bot added backlog and removed backlog labels Jun 26, 2021
@mmaietta
Copy link
Collaborator

I think I may be misunderstanding what you're looking for. When you mean shortcut, are you referring to what the Desktop entry shows?

const desktopMeta: any = {
Name: appInfo.productName,
Exec: exec,
Terminal: "false",
Type: "Application",
Icon: packager.executableName,

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

@stale
Copy link

stale bot commented Aug 28, 2021

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.

@stale stale bot added the backlog label Aug 28, 2021
@rathboma
Copy link
Author

@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?

@stale stale bot removed the backlog label Aug 30, 2021
@mmaietta
Copy link
Collaborator

For some reason, afterInstall was made explicitly available instead of through the FPM hook.

deb: {
   afterInstall: 'build/deb-postinstall'
}

@alx696
Copy link
Contributor

alx696 commented Sep 2, 2021

@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

@mmaietta
Copy link
Collaborator

mmaietta commented Sep 2, 2021

@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

@rathboma
Copy link
Author

rathboma commented Dec 2, 2021

@mmaietta does your commit fix this issue? Should this be closed?

@rathboma
Copy link
Author

rathboma commented Dec 2, 2021

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"

@stale
Copy link

stale bot commented Apr 16, 2022

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.

@stale stale bot added the backlog label Apr 16, 2022
@dhs-rec
Copy link

dhs-rec commented Apr 19, 2022

Ping.

@stale stale bot removed the backlog label Apr 19, 2022
@mmaietta
Copy link
Collaborator

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.

@infinity0
Copy link

I just ran into this whilst trying to install upscayl upscayl/upscayl#652.

Please fix it, it should be extremely simple to fix, just create a symlink instead of a hardlink.

@infinity0
Copy link

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.

@infinity0
Copy link

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

@mmaietta
Copy link
Collaborator

@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

@infinity0
Copy link

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.

@mmaietta
Copy link
Collaborator

mmaietta commented Feb 15, 2024

"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

@mmaietta
Copy link
Collaborator

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.

@infinity0
Copy link

infinity0 commented Mar 11, 2024

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.

@mmaietta mmaietta reopened this Mar 11, 2024
@infinity0
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants