archlinux-downgrade / downgrade

Downgrade packages in Arch Linux
GNU General Public License v2.0
591 stars 24 forks source link

Downgrade with dependencies #208

Open Nowaker opened 2 years ago

Nowaker commented 2 years ago

:rocket: Feature Request

Checklist

Background

% sudo downgrade openssl
loading packages...
warning: downgrading package openssl (3.0.7-2 => 1.1.1.q-1)
resolving dependencies...
looking for conflicting packages...
error: failed to prepare transaction (could not satisfy dependencies)
:: installing openssl (1.1.1.q-1) breaks dependency 'libcrypto.so=3-64' required by libarchive
:: installing openssl (1.1.1.q-1) breaks dependency 'libcrypto.so=3-64' required by sudo
:: installing openssl (1.1.1.q-1) breaks dependency 'libssl.so=3-64' required by sudo
:: installing openssl (1.1.1.q-1) breaks dependency 'libcrypto.so=3-64' required by systemd
:: installing openssl (1.1.1.q-1) breaks dependency 'libssl.so=3-64' required by systemd

Proposed feature

I'm offered to also downgrade dependencies, I'm shown what gets downgraded to what, and I can continue or abort.

atreyasha commented 2 years ago

Hi @Nowaker, thanks for opening this feature request.

This issue is quite similar to #83, but it has been on hold for a while because we aren't sure how to proceed.

For some context, here is how downgrade works and why it fails in your use-case:

  1. When you enter sudo downgrade openssl, this opens up a search utility to find openssl and corresponding versions either locally or on the ALA

  2. Ater choosing your desired version, the package is collected and locally installed using pacman (as per the line below):

    https://github.com/archlinux-downgrade/downgrade/blob/1f73525b686f0e351b734ac17467e0b564a5b7f0/bin/downgrade#L457

  3. pacman observes these dependency conflicts and fails

What we discussed in #83 was whether it makes sense for downgrade to work around such dependency conflicts, for example by parsing these conflicts from the logs and then prompting the user to downgrade these conflicting dependencies.

There are two problems with this approach:

  1. AFAIK there is no easy way to parse these dependency conflicts, such as specifying a flag to pacman that just outputs the conflicting packages or files. That means we would need to try pacman -U as above and then somehow parse the conflicts from the logs, which is not the best solution.
  2. Even if we do manage to parse the logs and reliably retrieve the conflicting dependencies, one could then ask why downgrade should perform dependency/package management instead of pacman itself. In this case, it could be more appropriate for pacman to have a flag that manages such dependency conflicts given the -U operation (which would imply a feature request upstream).

So this is where we stand and as mentioned, I am not sure how to proceed. But I think it would be nice to discuss this further sometime and perhaps reach a conclusion on whether this should be a wont-fix or otherwise a longer-term goal for downgrade.

@pbrisbin WDYT?

pbrisbin commented 2 years ago

@pbrisbin WDYT?

So, as you might guess, I'm still in the camp of a separate tool that works out dependency packages and passes them to the main dowgrade script. In this case, I think it is actually important to do that, so that the user is naturally presented a selection UI per package.

So you have something like,

print-dependencies openssl | downgrade -

Which would just be a shortcut to building up the command downgrade openssl libarchive sudo systemd ....

This means the user will be presented selection UIs for each of these packages in turn, and they will be required to select compatible versions at each step. Provided they do, passing everything that's been selected and downloaded to a single pacman invocation should succeed.

To do otherwise (to have dowgrade actually figure out the set of compatible versions) is high complexity, I doubt we'd make it work in a maintainable way. But if someone wanted to embark on that, doing it as a totally separate script is a great way to isolate the work. If a tool output openssl=x libarchive=y ..., that'd Just Work.

But I think just finding the dependencies to send to a dowgrade command at once is really good value for low cost. That said, I actually think users can do this themselves today,

sudo downgrade $(pacman -Qi openssl | grep '^Required By' | cut -d: -f2) openssl

So do we even need to build anything?

Nowaker commented 2 years ago

@atreyasha My perspective as a user is pacman is deficient in not providing the tools to perform downgrades, and that's why I use downgrade in the first place. I don't agree with @pbrisbin because it's more of a library thinking, than a user utility thinking. downgrade is not a Node.js library for programmatic use. downgrade is an end-user's tool (it wouldn't be interactive if it was a library) for downgrading. And because of that, it should make everything in its power to downgrade a package, and if it requires downgrading its dependencies, they should be downgraded too.

Now, "should" is one thing, but "being able to" is another. I don't know the technicalities of dependency resolution for pacman packages. If it requires spinning up a separate library-like tool, then it requires it. Labor isn't free so it's understood when it cannot be done. But a clear statement that downgrade would love to provide dependency resolution when downgrading and we're open for submissions is a way better outcome than a wontfix.

pbrisbin commented 2 years ago

I should clarify a few things, since there is a long history in these conversations.

There is the UX level and the implementation level. I typically discuss the implementation level, you are speaking to the UX level -- which makes sense, you're a user and I'm an implementer!

So yes, downgrade foo resolving dependencies for foo and doing All The Things is not something I'm against at all. We're not anti-features here just for the sake of it. If someone wants to make that interface happen, I welcome it.

And when I speak of an external tool, I don't mean "some other project you should make". I mean "some separate script we have here and call internally". So I'm just suggesting that we approach implementing this under the hood as separate tools, each with a narrow scope of responsibility, and glued together via pipes. I jump to implementation details at this at this stage because a PR that implements this logic not built that way is likely to be a very messy diff of complicated code that is hard for us as maintainers to review and accept.

So that's a (hopefully) clarified take on the "should" side of things.

As for "being able to", a tool would need to take the initial target, at the chosen older version, download the .pkg, extract its .SRCINFO, parse its dependencies bounds, and then seek versions of those packages, then recurse. As someone who wrote such logic for aurget, I worry we're reaching the limits of what I'd want to write in bash, which is saying something. So this feels possible, but very high effort.

As for my suggestion of,

sudo downgrade $(pacman -Qi openssl | grep '^Required By' | cut -d: -f2) openssl

I realize now it came off as "wontfix, has workaround", but that's not my true feelings. It's more "here's an 80/20 that might be helpful to you if the better thing is not feasible."

Nowaker commented 2 years ago

I mean "some separate script we have here and call internally"

OK, cool. It's understood then. So speaking of the implementation, here's some thoughts:

As someone who wrote such logic for aurget, I worry we're reaching the limits of what I'd want to write in bash, which is saying something.

With Python present on almost any installation, it could be considered as an option. Maybe even an optional dependency if one wants to resolve dependencies for downgrade. In any case, downgrade (main) could use downgrade-resolver.py if bash is not feasible to generate a list of packages and maximum version numbers for each.

download the .pkg, extract its .SRCINFO

An alternative would be to look up git as downloads would be painful. All releases are automated and have a commit that starts with upgpkg. Example: https://github.com/archlinux/svntogit-packages/commits/packages/aalib/trunk/PKGBUILD and https://github.com/archlinux/svntogit-packages/commit/577b1861d0430f5dd08c7cec6c5241c54c5dbbd3.

pbrisbin commented 2 years ago

With Python present on almost any installation, it could be considered as an option

:ok_hand:

An alternative would be to look up git as downloads would be painful

So I was thinking you'd never have to download anything you don't have to download anyway...

downgrade openssl
-> selection screen finds a .pkg locally or to download and downloads it
-> pull .SRCINFO finds dep A, B, C
-> locates and possibly downloads A, B, C
-> repeat...
-> Install now needs all the .pkg you found and possibly downloaded anyway