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

fix: Use update-alternatives instead of symlinks for #7500 #7501

Merged
merged 10 commits into from
Apr 7, 2023

Conversation

markizano
Copy link
Contributor

Where possible, use update-alternatives instead to avoid hardcoding links in Linux. This will allow for downstream users to specify paths to their own executables with higher priority if they wish.

Backwards compatibility is preserved by still using the symlinking route if the command update-alternatives is not available.

…inks to executable if available.

Where possible, use `update-alternatives` instead to avoid hardcoding links in Linux.
This will allow for downstream users to specify paths to their own executables
with higher priority if they wish.

Backwards compatibility is preserved by still using the symlinking route if
the command `update-alternatives` is not available.
@changeset-bot
Copy link

changeset-bot bot commented Mar 25, 2023

🦋 Changeset detected

Latest commit: ea5c970

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
app-builder-lib Patch
dmg-builder Patch
electron-builder-squirrel-windows Patch
electron-builder Patch
electron-forge-maker-appimage Patch
electron-forge-maker-nsis-web Patch
electron-forge-maker-nsis Patch
electron-forge-maker-snap Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify
Copy link

netlify bot commented Mar 25, 2023

Deploy Preview for car-park-attendant-cleat-11576 ready!

Name Link
🔨 Latest commit ea5c970
🔍 Latest deploy log https://app.netlify.com/sites/car-park-attendant-cleat-11576/deploys/6430452c5c8fe40008781dbe
😎 Deploy Preview https://deploy-preview-7501--car-park-attendant-cleat-11576.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@markizano markizano changed the title Issue #7500: Use update-alternatives instead of symlinks to executable if available. Fix Issue #7500: Use update-alternatives instead of symlinks to executable if available. Mar 25, 2023
@markizano markizano changed the title Fix Issue #7500: Use update-alternatives instead of symlinks to executable if available. Fix: Use update-alternatives instead of symlinks for #7500 Mar 25, 2023
@markizano markizano changed the title Fix: Use update-alternatives instead of symlinks for #7500 fix: Use update-alternatives instead of symlinks for #7500 Mar 25, 2023
@markizano
Copy link
Contributor Author

okay, I think I have included all the requirements for this to be accepted.

Ready for review!

@mmaietta
Copy link
Collaborator

Thank you!
Test is failing

  ● executable path in postinst script

    expect(received).toMatchSnapshot()

    Snapshot name: `executable path in postinst script 5`

    - Snapshot  - 1
    + Received  + 5

    @@ -1,9 +1,13 @@
      #!/bin/bash

      # Link to the binary
    - ln -sf '/opt/foo/Boo' '/usr/bin/Boo'
    + if type update-alternatives 2>/dev/null >&1; then
    +    update-alternatives --install '/usr/bin/Boo' 'Boo' '/opt/foo/Boo' 100
    + else
    + ln -sf '/opt/foo/Boo' '/usr/bin/Boo'
    + fi

You'll need to run the specific test file and update the snapshot

TESt_FILES= debTest UPDATE_SNAPSHOT=true pnpm test

(Might need to run within docker image, not sure off the top of my head

@markizano
Copy link
Contributor Author

markizano commented Apr 4, 2023

Seems like I am missing post-compiled resources?

When running this command, I get errors around a missing compiled test file:

redacted@redacted:~/git/signalapp/electron-builder $ docker run --rm -e DEBUG=${DEBUG:-} -e UPDATE_SNAPSHOT=true -e TEST_FILES="${TEST_FILES:-HoistedNodeModuleTest}" -v $(pwd):/project -v $(pwd)-node-modules:/project/node_modules -v $HOME/Library/Caches/electron:/root/.cache/electron -v $HOME/Library/Caches/electron-builder:/root/.cache/electron-builder electronuserland/builder:wine-mono /bin/bash -c "pnpm install && node ./test/out/helpers/runTests.js"
Scope: all 14 workspace projects
 WARN  There are cyclic workspace dependencies: /project/packages/app-builder-lib, /project/packages/dmg-builder; /project/packages/app-builder-lib, /project/packages/dmg-builder, /project/packages/app-builder-lib, /project/packages/electron-builder-squirrel-windows
Lockfile is up to date, resolution step is skipped
Progress: resolved 1, reused 0, downloaded 0, added 0
Packages: +10 -1
++++++++++-

   ╭─────────────────────────────────────────────────────────────────╮
   │                                                                 │
   │                Update available! 7.13.2 → 8.1.1.                │
   │   Changelog: https://github.com/pnpm/pnpm/releases/tag/v8.1.1   │
   │                Run "pnpm add -g pnpm" to update.                │
   │                                                                 │
   │     Follow @pnpmjs for updates: https://twitter.com/pnpmjs      │
   │                                                                 │
   ╰─────────────────────────────────────────────────────────────────╯


dependencies:
+ dmg-license 1.0.11
- pnpm 7.30.3

. prepare$ husky install
. prepare: fatal: detected dubious ownership in repository at '/project'
. prepare: To add an exception for this directory, call:
. prepare: 	git config --global --add safe.directory /project
. prepare: Done
Progress: resolved 10, reused 8, downloaded 2, added 10, done
internal/modules/cjs/loader.js:905
  throw err;
  ^

Error: Cannot find module '/project/test/out/helpers/runTests.js'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)
    at Function.Module._load (internal/modules/cjs/loader.js:746:27)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:75:12)
    at internal/main/run_main_module.js:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}

I cannot seem to find any documentation around how to compile the TypeScript stuff into test/out/helpers/*.js

@mmaietta
Copy link
Collaborator

mmaietta commented Apr 4, 2023

Good to note that the docs need to be updated.
You'll need to compile before running the tests

pnpm compile
TEST_FILES=debTest UPDATE_SNAPSHOT=true pnpm test-linux

…ithout errors about dmg-license cannot be installed.

I get this error without this change:

```
npm WARN deprecated puppeteer@2.1.1: < 19.4.0 is no longer supported
npm WARN deprecated @braintree/sanitize-url@3.1.0: Potential XSS vulnerability patched in v6.0.0.
npm WARN deprecated w3c-hr-time@1.0.2: Use your platform's native performance.now() and performance.timeOrigin.
npm ERR! code EBADPLATFORM
npm ERR! notsup Unsupported platform for dmg-license@1.0.11: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm ERR! notsup Valid OS:    darwin
npm ERR! notsup Valid Arch:  any
npm ERR! notsup Actual OS:   linux
npm ERR! notsup Actual Arch: x64

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/user/.npm/_logs/2023-04-04T23_28_28_809Z-debug.log
```

Changing to an optionalDependency allowed me to proceed without errors.
pnpm-lock.yaml Outdated Show resolved Hide resolved
@markizano
Copy link
Contributor Author

Apologies for the sporadic work here and there on this and thanks so much for the incredible responsiveness on this, @mmaietta !!!

.husky/pre-push Outdated Show resolved Hide resolved
.husky/pre-commit Outdated Show resolved Hide resolved
pnpm-lock.yaml Outdated Show resolved Hide resolved
@@ -1,7 +1,11 @@
#!/bin/bash

# Link to the binary
ln -sf '/opt/${sanitizedProductName}/${executable}' '/usr/bin/${executable}'
if type update-alternatives 2>/dev/null >&1; then
update-alternatives --install '/usr/bin/${executable}' '${executable}' '/opt/${sanitizedProductName}/${executable}' 100
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just read this in your changeset. (My apologies for pinging back n forth on this)

If you are having issues on install or get errors about /usr/bin/${executable} already
exists, then simply remove the link and update-alternatives will take over from there.

Do we need to update this code as follows? We can't expect all linux users to know they need to remove the link on their own during the install process

previousLink = "/usr/bin/${executable}"
# remove previously existing symlink if applicable
[ -L "${previousLink}" ] && [ -e "${previousLink}" ] && rm -f "${previousLink}"

update-alternatives --install "${previousLink}" "${executable}" "/opt/${sanitizedProductName}/${executable}" 100

Note: I didn't test this logic, just pulled resources from online and changed ' to ". So you'd need to test this change

What are your thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries, it was an upstream change I wanted to propose into this project and grateful for the thoughtful discussion!

Do we need to update this code as follows? We can't expect all linux users to know they need to remove the link on their own during the install process

I think I see what you mean in the updates here, so I updated the changeset accordingly. This is very valid and for a project as core as this to so many others, it would cause a lot of heartburn.

In this corrected way, the end-user nor middleware have to take any action in consuming this update.

With the above proposed change, it might produce output durring the install about having to correct a broken link as such:

update-alternatives: warning: forcing reinstallation of alternative /opt/${sanitizedProductName}/${executable} because link group ${executable} is broken

on each update.

Single quotes are considered string literals. Double-quotes are considered interpolatable strings. Since the templates are passing through a template processor and not the bash interpreter itself, single quotes in this case would be fine since it's not in-script variables that are being used. Since those variables are "userland" variables outside of the script (interpolated by the template filter), single quotes would also be more secure in this case, so I think it might have been correct. In-script variable use might require double-quotes.
(sorry if this sounds wordy -- I am an instructor on my TikTok & YouTube channels :D )

rm -f "/usr/bin/${executable}"
fi

update-alternatives --install '/usr/bin/${executable}' '${executable}' '/opt/${sanitizedProductName}/${executable}' 100
Copy link
Collaborator

@mmaietta mmaietta Apr 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need this check, right?

if type update-alternatives 2>/dev/null >&1; then
   update-alternatives --install '/usr/bin/${executable}' '${executable}' '/opt/${sanitizedProductName}/${executable}' 100

else
    ln -sf '/opt/${sanitizedProductName}/${executable}' '/usr/bin/${executable}'
fi

Or is that covered by != "/etc/alternatives/${executable}"?

ln -sf '/opt/${sanitizedProductName}/${executable}' '/usr/bin/${executable}'
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what this line means, but I trust 😅

Copy link
Contributor Author

@markizano markizano Apr 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries :)

https://ss64.com/bash/test.html

-L - file is symlink.
EXPR -a EXPR - AND operation between expressions.
-e - check if file exists.

Should result in something like (pseudo code ahead):

if ( isSymLink(file) && isExist(file) && readlink(file) != "/etc/alternatives/$exec" )

Copy link
Collaborator

@mmaietta mmaietta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kicking off CI

@mmaietta mmaietta merged commit e83dc81 into electron-userland:master Apr 7, 2023
@github-actions github-actions bot mentioned this pull request Apr 7, 2023
@markizano
Copy link
Contributor Author

@mmaietta -- Thanks so much for working with me to get this into the project!!

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

Successfully merging this pull request may close these issues.

None yet

2 participants