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

postinst error in securedrop-app-code package install #6230

Closed
eloquence opened this issue Jan 19, 2022 · 7 comments · Fixed by #6231
Closed

postinst error in securedrop-app-code package install #6230

eloquence opened this issue Jan 19, 2022 · 7 comments · Fixed by #6231
Assignees
Labels

Comments

@eloquence
Copy link
Member

Seen on my test instance and one other:

Processing triggers for securedrop-app-code (2.1.0+focal) ...
+ set -o pipefail
+ SDVE=/opt/venvs/securedrop-app-code
+ SDBIN=/opt/venvs/securedrop-app-code/bin
+ case "$1" in
+ echo 'postinst called with unknown argument `triggered'\'''
postinst called with unknown argument `triggered'
+ exit 1
dpkg: error processing package securedrop-app-code (--configure):
 installed securedrop-app-code package post-installation script subprocess returned error exit status 1

I see this for upgrades going back to SecureDrop 2.0.0, so it does not appear to interfere with successful upgrades.

@conorsch
Copy link
Contributor

Took a quick look at this today. My understanding is that we're registering a trigger for changes to the python3.8 interpreter in the securedrop-app-code package, as the dh-virtualenv docs recommend, but our postinst for securedrop-app-code wrongly assumes that triggered is not a valid argument for postinst. It definitely is. So our support of the trigger is incomplete, which explains the error. Open questions in my mind are why we want to declare interest in interpreter changes, and whether this failure can break updates (it appears not, given reports of seeing it all the back in 2.0.0, ~2021-05).

@legoktm
Copy link
Member

legoktm commented Jan 19, 2022

I posted the fully generated postinst at https://gist.github.com/legoktm/0542388d8639e2a4bacb072ec5649c41

The problem is that we inject the autogenerated dh-virtualenv snippet, which correctly handles "triggered", after we bail out for not recognizing "triggered".

I think we either teach our postinst about "triggered", OR not erroring out on an invalid postinst command. I'll codesearch the Debian archive to see which pattern is more popular.

I considered for a minute putting the #DEBHELPER# placeholder above our postinst but I think that's a bad idea, we don't want to start systemd services before our migrations run.

@legoktm
Copy link
Member

legoktm commented Jan 19, 2022

The codesearch wasn't that helpful, mostly because I can't easily search for the absence of "triggered".

So if we do go ahead and add it to the known list, it does mean there will be a behavior change in that we will now run the dh_venv_safe_interpreter_update step when Python is updated. I don't actually understand what the point of it is, it seems like it's supposed to hardlink in a new interpreter if the patch changes, but AFAIK Ubuntu/Debian always has it at /usr/bin/python3 unless we start using other Python packages, so it'll never change? Plus we'd put out new packages that freshly create a new venv for OS upgrades.

It seems safe and future proof to add "triggered" in either way, so I'll put up PRs for that shortly.

Per https://manpages.debian.org/bullseye/dpkg-dev/deb-postinst.5.en.html triggered is the only one we're missing.

legoktm added a commit that referenced this issue Jan 19, 2022
Per deb-postinst(5), the postinst is called with "triggered" after the
package was triggered. We currently register a trigger with the Python
interpreter so dh_virtualenv can fix up the interpreter's symlinks
in case something changes as recommended in their docs[1].

However, our custom postinst snippet was running before that and erroring
out on any invocation for "triggered", so it never ran. Now "triggered" will
fall through and the dh-virtualenv inserted code will run whenever Python
is upgraded.

I am a bit skeptical of the need for the trigger and what dh-virtualenv wants
to do (especially given it hasn't run up until now), but having "triggered"
here seems like good future-proofing in general.

[1] https://dh-virtualenv.readthedocs.io/en/latest/tutorial.html?highlight=trigger#step-2-set-up-packaging-for-your-project

Fixes #6230.
@legoktm
Copy link
Member

legoktm commented Jan 20, 2022

I re-reviewed the code for dh_venv_safe_interpreter_update and am pretty sure it's a no-op and we really don't need it at all.

dh_venv_safe_interpreter_update() {
    # get Python version used
    local pythonX_Y=$(cd "$dh_venv_install_dir/lib" && ls -1d python[2-9].*[0-9] | tail -n1)

    local i
    for i in python ${pythonX_Y%.*} ${pythonX_Y}; do
        local interpreter_path="$dh_venv_install_dir/bin/$i"

        # skip any symlinks, and make sure we have an existing target
        test ! -L "$interpreter_path" || continue
        test -x "$interpreter_path" || continue

        # skip if already identical
        if cmp "/usr/bin/$pythonX_Y" "$interpreter_path" >/dev/null 2>&1; then
            continue
        fi
        ...

Stepping through that code, the pythonX_Y variable will be set to python3.8. Then it iterates over python, python3.8%.*, python3.8.

Looking in /opt/venvs/securedrop-app-code/bin/ the only binaries exist are:

user@debian-test:~/app-code/opt/venvs/securedrop-app-code$ ls -l bin/python*
lrwxrwxrwx 1 user user  7 Oct 19 15:20 bin/python -> python3
lrwxrwxrwx 1 user user 16 Oct 19 15:20 bin/python3 -> /usr/bin/python3

Except both of those are symlinks, so they get skipped by the "skip any symlinks" step. So it really does nothing. After git-blaming a bit, I found spotify/dh-virtualenv#48 which describes the issue it's trying to solve: "virtualenvs tend to break horribly after certain host Python updates – those that change internal, statically linked modules, or make symlinked .so modules incompatible to the old "python" binary contained in the virtualenv."

Which isn't an issue for us because there is no "python" binary in the virtualenv, it's all symlinks back to the system /usr/bin/python3. So I'd suggest we remove the trigger on the basis that it adds no value for us and just adds extra points where this could potentially break.

This is the first time I'm looking at the packaging, so let me know if I'm missing something.

@kushaldas
Copy link
Contributor

Debian/Ubuntu will not update to a new major Python version within a release, means the ABI will be the same and the virtualenv should be just functioning. Our virtualenv is already having compiled code in it, means if we update the OS and get a new Python ABI, then we should have a new virtualenv via a new package.

@conorsch
Copy link
Contributor

@kushaldas Thanks for chiming in! My takeaway is that we should remove the trigger altogether, no longer registering an "interest" in the python interpreter. That's a slightly different approach from what's in #6231, but would be a similarly minimal diff, with the added advantage that the functionality wouldn't change: triggers would continue not to run! Do you agree? cc @legoktm

legoktm added a commit that referenced this issue Jan 20, 2022
We currently register a trigger with the Python
interpreter so dh_virtualenv can fix up the interpreter's symlinks
in case something changes as recommended in their docs[1].

However, our packages are designed for a single Ubuntu release, which
keeps the same version of Python for its entire lifetime, so the
interpreter in the venv will always be a symlink to `/usr/bin/python3`
and the dh_virtualenv postinst code will always be a no-op because it
skips all symlinks.

This was noticed because our custom postinst was not handling the
"triggered" state, which is valid per deb-postinst(5). Add that in for
future proofing even though we don't expect it to be called.

[1]
https://dh-virtualenv.readthedocs.io/en/latest/tutorial.html?highlight=trigger#step-2-set-up-packaging-for-your-project

Fixes #6230.
@legoktm
Copy link
Member

legoktm commented Jan 20, 2022

Sounds good to me, I reworked #6231 in that direction.

conorsch pushed a commit that referenced this issue Jan 24, 2022
We currently register a trigger with the Python
interpreter so dh_virtualenv can fix up the interpreter's symlinks
in case something changes as recommended in their docs[1].

However, our packages are designed for a single Ubuntu release, which
keeps the same version of Python for its entire lifetime, so the
interpreter in the venv will always be a symlink to `/usr/bin/python3`
and the dh_virtualenv postinst code will always be a no-op because it
skips all symlinks.

This was noticed because our custom postinst was not handling the
"triggered" state, which is valid per deb-postinst(5). Add that in for
future proofing even though we don't expect it to be called.

[1]
https://dh-virtualenv.readthedocs.io/en/latest/tutorial.html?highlight=trigger#step-2-set-up-packaging-for-your-project

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

Successfully merging a pull request may close this issue.

4 participants