这是indexloc提供的服务,不要输入任何密码
Skip to content

[RFC] pkg: never implicitly update package cache without upgrading all packages #172

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

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

robertkirkman
Copy link

@robertkirkman robertkirkman commented May 29, 2025

Important

These changes are not intended to be considered absolutely necessary or mandatory to merge.
They are changes that would alter behavior users might have come to expect from Termux pkg, that has been different from how other distros behave for a long time.
These changes are instead meant to serve an example of how Termux's pkg command could have been designed in retrospect, in order to prevent accidental partial upgrades, in a way that is familiar to users of other rolling-release distributions that existed for a long time before Termux existed.

  • Fixes pkg i uses pacman -Sy, which is fundamentally unsafe #137

  • Never skip updating the package cache based on a timeout or the presence of metadata files.

  • Instead, always try directly installing packages first, then interpret the output message from the package manager to determine the appropriate action.

  • If the package installation was successful despite the package cache not having been updated, then everything is actually OK, and no further action is required

  • If the package installation failed with an error indicating failure to download the package or an error indicating the package was not found (which could happen in three cases: the package cache has never been generated, or the package is new and the package cache has not been updated since the package became available, or the package name has a typo and does not actually exist), then automatically update package cache and upgrade all packages, and then attempt to install the package again.

    • This change of behavior prevents the accidental partial upgrades that currently happen mainly because of the current pkg install command updating package cache without upgrading all packages simultaneously.
  • If the package installation failed, but one of the errors handled here was not not detected in the output of the package manager, then exit and do nothing since in that case, there is no reason that updating the package cache or upgrading all packages would help.

  • Do not implicitly update package cache during pkg search before running the package manager search command, because it could result in accidentally updating the package cache without upgrading all packages, which could result in accidental partial upgrades.

What would change

  • pkg install would no longer automatically rotate mirrors every time it has run if it has been more than 6 hours since the last mirror rotation. Instead, it would only rotate mirrors when both of the following conditions are met:

    • A package failed to download, and the reason is detected to be due to missing or outdated package cache
    • It has been more than 6 hours since the last mirror rotation
  • pkg install would no longer automatically update the package cache every single time it is run. Instead, it would only update the package cache when the following condition is met:

    • A package failed to download, and the reason is detected to be due to missing or outdated package cache
  • pkg install would no longer install package(s) immediately after updating the package cache, because that would perform a partial upgrade, which can sometimes cause CANNOT LINK EXECUTABLE errors, and other kinds of errors, to appear afterward.

    • Instead, it would either install package(s) successfully without updating the package cache (which is an acceptable situation if it succeeds),
    • or, if that fails, and the reason is detected to be due to a missing or outdated package cache, it would then:
      • update the package cache,
      • then interactively prompt for a full upgrade,
      • then interactively prompt to reattempt the installation of the package(s) that previously failed to download
    • If the package(s) failed to install due to any other reason, it is assumed that a problem has occurred that would not have any chance of being resolved by updating the package cache or performing a full upgrade (for example a package file conflict), and pkg install exits in a failure state, after showing the original error message.
  • pkg search would no longer automatically update the package cache before searching for packages.

    • Instead, it would either search the existing package cache and display packages that could be found in the current package cache, which would be at the state it was the last time a package cache update was performed,
    • or, if no package cache has yet been downloaded (a clean installation of Termux), it would only show results from packages that are currently installed, and no results from available packages that are not installed.

What wouldn't change

  • pkg install would still always provide a pathway to installing packages successfully even if the package cache was missing or outdated at the moment that pkg install was initiated
  • pkg update would still always perform only a package cache update, because that command is taken to mean an explicit, not an implicit, request to update the package cache.
  • pkg upgrade would still keep the exact same behavior:
    • If the mirror has not been rotated for more than 6 hours, it would perform a mirror rotation,
    • then, it would update the package cache,
    • then, it would interactively prompt for a full upgrade
  • All the behaviors described would remain consistent between pacman-based and apt-based Termux installations, meaning:
    • that all changes would take place for installations of both package manager types simultaneously,
    • and, since pacman-based Termux installations do not currently perform "mirror rotation", changes related to "mirror rotation" would not apply to pacman-based Termux installations.
    • All other changes would apply to pacman-based Termux installations, and all other changes are equally relevant to pacman-based and apt-based Termux installations.
    • This would preserve the current state of consistency between pacman-based and apt-based Termux installations, without increasing or reducing the degree of consistency between them.
  • The behaviors of all other pkg subcommands not yet mentioned (f*, sh*, autoc*, cl*, list-a*, list-i*, rei*, un*) would remain exactly the same, and would not be affected by any of these changes.
  • The behaviors of apt and pacman when invoked directly would remain exactly the same
    • The behaviors of apt and pacman when directly invoked are essentially consistent, insofar as they relate to package cache synchronizing and package downloading, with their equivalent behaviors found in the GNU/Linux distros Debian sid and Arch Linux both prior to and after the creation of Termux.
    • These changes would only affect the behavior of the pkg wrapper of apt and pacman, with the goal of removing pkg's current tendency to perform implicit package cache updates without upgrading all packages immediately afterward (implicit partial upgrades)

@TomJo2000 TomJo2000 changed the title termux-tools: pkg: never implicitly update package cache without upgrading all packages [RFC] pkg: never implicitly update package cache without upgrading all packages May 29, 2025
Copy link
Member

@TomJo2000 TomJo2000 left a comment

Choose a reason for hiding this comment

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

Thanks for putting in the work Robert.
I mostly agree with the changes proposed here but I would like to discourage the non-interactive upgrade part of the handle_install_${TERMUX_APP_PACKAGE_MANAGER} functions.

If you'll indulge me and my soapbox for a bit.
<soapbox>
Users should be able to cancel out of a suggested update at any point, and no changes requesting user confirmation should be made without user consent.

I understand the dpkg "What would you like to do about it" prompt,
e.g:

What would you like to do about it ?  Your options are:
 Y or I  : install the package maintainer's version
 N or O  : keep your currently-installed version
   D     : show the differences between the versions
   Z     : start a shell to examine the situation
The default action is to keep your current version.
*** %s (Y/I/N/O/D/Z) [default=N] ?

can be intimidating for new users.
But I think the better remedy to that would be building dpkg to default to [default=Y] on that prompt, but still offer it to the user.
Instead of skipping it with the -y flag.
</soapbox>

@robertkirkman robertkirkman force-pushed the pkg-do-not-partial-upgrade branch 6 times, most recently from 0bf138e to 8d2da30 Compare May 30, 2025 01:59
@twaik
Copy link
Member

twaik commented May 30, 2025

I am fine with the idea but I think it is not really compatible with mirror rotation in pkg. We must download up to date data from mirror, otherwise apt will use stale data (because there is separate *_Release file for each mirror).

If other maintainers agree with this using this concept we can workaround it though.
We can define our own transport which will replace URL of server to the one defined in current selected mirror's file with simple sed command and fallback to regular https transport and it will work fine for all mirrors without explicitly doing pkg up for all of them since all of them will have a single *_Release file. In this case we will have immutable deb termux://server termux termux-main record in termux.list file and mirror selection will fully rely on the selected mirror symlink/record/other mechanism fully defined by pkg.

@twaik
Copy link
Member

twaik commented May 30, 2025

Also since we have full control on apt we can simply patch it to invoke DoUpdate + DoInstall after receiving 404 error. In this case we will be sure the user gave consent to installing packages and re-apply the consent to subsequent DoInstall invocation.

@twaik
Copy link
Member

twaik commented May 30, 2025

Or we could simply do a simple GET request to current mirror for reading first 200 bytes in Release file, compare it with the 200 first bytes of the current release file and ask user if they want to perform an update (in apt). Probably it is naive but it also a viable option, it breaks current UX though.

@TomJo2000
Copy link
Member

Also since we have full control on apt we can simply patch it to invoke DoUpdate + DoInstall after receiving 404 error. In this case we will be sure the user gave consent to installing packages and re-apply the consent to subsequent DoInstall invocation.

I think we should not patch apt (or pacman)'s behavior if it can be avoided.
Any deviation for the upstream default behaviors is a potential stumbling block for users.

image
Obligatory XKCD.

@robertkirkman
Copy link
Author

robertkirkman commented May 30, 2025

I am fine with the idea but I think it is not really compatible with mirror rotation in pkg. We must download up to date data from mirror, otherwise apt will use stale data

I will add some additional clarification. This is intended behavior in my idea here.

In my personal opinion, it is completely OK for apt to use stale data and continue to use the last selected mirror for as long as the packages can be successfully downloaded, until it is time for package cache to be updated and a full upgrade also performed.

You can see here that, when the failure to download the package during package installation is detected for any reason, which could also include the mirror being down, too slow, or a network outage (which can take many forms and can be partial), select_mirror is immediately run to select a new, accessible mirror (if the criteria within the select_mirror function, including its timeout, are met), and also the package cache is updated and a full upgrade is performed too.

I chose this because it is my personal belief that a mirror should implicitly be allowed to default to being used (just in pkg install specifically, I have left the original behavior of pkg upgrade unchanged here because I agree with the original behavior of pkg upgrade) for as long as it continues to remain online and accessible, if it was sufficiently up to date at the last time the device ran select_mirror.

If your opinion is different that the detection of the mirror outdatedness compared to the main mirror packages-cf.termux.dev needs to be run very regularly, for example after this PR:

And that you believe pkg install should be included in always checking the mirror outdatedness, then what I can do here is, I can make the select_mirror timeout check happen in all pkg install situations (not only in the case of when the package failed to download on the first try), and if the current mirror's rotation has timed out, then proceed with select_mirror to select a mirror that is not outdated, and updating package cache, and updating all packages.

Also since we have full control on apt we can simply patch it to invoke DoUpdate + DoInstall after receiving 404 error. In this case we will be sure the user gave consent to installing packages and re-apply the consent to subsequent DoInstall invocation.

I would agree with this idea and it is fine in my opinion (note: my approval of the behavior of changes to apt internal code is conditional on my review when testing the changes to apt, to make sure what it would do is the same thing I am imagining now). However, I do not currently know how to implement that inside apt code, but I could try. I might have a little easier time doing the part of implementing it inside pacman code since I am a little more experienced with pacman internal code than apt.

Also, If you read the discussions above, originally I had a little bit more assumptions that the user gave consent, but I removed them in favor of complete interactive prompts at every possible step, because Tomjo2000 requested that all interactive prompts be kept.

We can define our own transport which will replace URL of server to the one defined in current selected mirror's file with simple sed command and fallback to regular https transport and it will work fine for all mirrors without explicitly doing pkg up for all of them since all of them will have a single *_Release file. In this case we will have immutable deb termux://server termux termux-main record in termux.list file and mirror selection will fully rely on the selected mirror symlink/record/other mechanism fully defined by pkg.

I am not very sure whether that would work because, if any mirror is not absolutely 100% up to date always, then it will not contain identical package versions to the versions in other mirrors, so it is not be possible to swap between mirrors like that without performing either a full upgrade (desired situation in this proposal) or a partial upgrade (undesired situation in this proposal). Maybe I do not exactly understand what you mean by this part though.

@robertkirkman
Copy link
Author

robertkirkman commented May 30, 2025

Or we could simply do a simple GET request to current mirror for reading first 200 bytes in Release file, compare it with the 200 first bytes of the current release file and ask user if they want to perform an update (in apt). Probably it is naive but it also a viable option, it breaks current UX though.

I do not fully understand this idea. By "current release file" do you mean a similar, second GET request to the main mirror packages-cf.termux.dev to compare with its release file? Or do you mean the local release file copy stored on the device?

@twaik
Copy link
Member

twaik commented May 31, 2025

In my personal opinion, it is completely OK for apt to use stale data and continue to use the last selected mirror for as long as the packages can be successfully downloaded, until it is time for package cache to be updated and a full upgrade also performed.

Apt stores separate local copies of Release files for every single mirror. So after rotating mirrors most likely Release file will be outdated by more that 6/12/24/48 hours because most likely a mirror was not used for a long time.

I do not fully understand this idea. By "current release file" do you mean a similar, second GET request to the main mirror packages-cf.termux.dev to compare with its release file? Or do you mean the local release file copy stored on the device?

Second GET request to obtain actual timestamp of current mirror because of the reason above.

@robertkirkman
Copy link
Author

robertkirkman commented May 31, 2025

Apt stores separate local copies of Release files for every single mirror. So after rotating mirrors most likely Release file will be outdated by more that 6/12/24/48 hours because most likely a mirror was not used for a long time.

What I mean is that in the proposal shown here, just as before (except without checking the metadata files or timeout anymore that I mentioned at the start of the PR description), the package cache is always updated immediately after the select_mirror function is run, which downloads new release files anyway. So, by "last selected mirror", I mean that in this proposal, the same mirror is used for potentially a long time without rotating it, and then the way that it is determined that select_mirror should be run is in three cases:

  1. the first apt install during pkg install produced an error, and it is determined from the error message that select_mirror and updating package cache and updating all packages has a reasonable chance to help fix the error.
  2. the user used pkg update which is an explicit command to update package cache (not an implicit one)
  3. the user used pkg upgrade which is an explicit full upgrade

select_mirror
# since package installation failed because of failure to download a package,
# updating the package cache is always necessary
apt update
Copy link
Author

Choose a reason for hiding this comment

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

here is where I mean that apt update is still always run after select_mirror in this proposal.

…ading all packages

> [!IMPORTANT]
> These changes are not intended to be considered absolutely necessary or mandatory to merge.
> They are changes that would alter behavior users might have come to expect from Termux `pkg`, that has been different from how other distros behave for a long time.
> These changes are instead meant to serve an example of how Termux's `pkg` command **could** have been designed in retrospect, in order to prevent accidental partial upgrades, in a way that is familiar to users of other rolling-release distributions that existed for a long time before Termux existed.

- Fixes termux#137

- Never skip updating the package cache based on a timeout or the presence of metadata files.
- Instead, always try directly installing packages first, then interpret the output message from the package manager to determine the appropriate action.
- If the package installation was successful despite the package cache not having been updated, then everything is actually OK, and no further action is required
- If the package installation failed with an error indicating failure to download the package **or** an error indicating the package was not found (which could happen in three cases: the package cache has never been generated, or the package is new and the package cache has not been updated since the package became available, or the package name has a typo and does not actually exist), then automatically update package cache **and** upgrade all packages, and **then** attempt to install the package again.
  - This change of behavior prevents the accidental partial upgrades that currently happen mainly because of the current `pkg install` command updating package cache without upgrading all packages simultaneously.
- If the package installation failed, but one of the errors handled here was not not detected in the output of the package manager, then exit and do nothing since in that case, there is no reason that updating the package cache or upgrading all packages would help.
- Do not implicitly update package cache during `pkg search` before running the package manager search command, because it could result in accidentally updating the package cache without upgrading all packages, which could result in accidental partial upgrades.
@robertkirkman robertkirkman force-pushed the pkg-do-not-partial-upgrade branch from 8d2da30 to f3fcdba Compare May 31, 2025 04:00
@robertkirkman
Copy link
Author

I realized I forgot to close fd 3 in the codepath where execution is returned to the case statement which called handle_install_*, so the change I made just now fixes that.

@tstein
Copy link
Contributor

tstein commented Jun 4, 2025

The logic around individual install ops in the top comment makes some sense to me, and I'm (obviously) motivated by the goal of not doing things in common paths that are known to be dangerous. :)

Just thinking out loud for now, not voting either way. Other goals that are important to us and maybe don't interact well with this proposal:

  1. We're talking elsewhere about mirror availability and performance, and the best card in our hand at the moment is the assumption that after 6h, most pkg ops will result in a fresh choice of mirror, which doesn't seem separable from a metadata update. The logic in this proposal would say that we also need to do an upgrade/-Su everytime there's a metadata update. Seems like the difference between this proposal and the clumsier "just translate every install into an update+upgrade/Syu would only exist in 6h periods after the first op, and it won't actually be different from the clumsy answer in practice for casual/infrequent usage, which is probably the common case?

  2. One of my least favorite categories of user issue is when someone runs a long package install, switches to another app because it's boring, and ends up with broken packages/package management because Android killed termux and left things in an inconsistent state. It's difficult for us to diagnose (users often don't realize this is a risk), difficult to fix (it can break almost anything), and I think it's much more common than real breakage caused by partial updates. So I'm wary of increasing the risk of bored users by increasing the wall time required to do common package ops.

  3. Both in conversational support and in READMEs, we're used to being able to say pkg i $whatever and assume that if pkg succeeds, the user has a pretty recent version of $whatever installed. This isn't really different if we implement your proposal as currently written - the resulting installed packages would tend to be staler, but I think they're still capped at 6h of staleness for metadata reasons. But if you took a more aggressive approach to addressing 1), you might introduce more of a risk here. It would not be great if we lost the assumption of recency from "okay now pkg i it" -> "okay it worked".

@robertkirkman
Copy link
Author

robertkirkman commented Jun 4, 2025

The logic in this proposal would say that we also need to do an upgrade/-Su everytime there's a metadata update. Seems like the difference between this proposal and the clumsier "just translate every install into an update+upgrade/Syu would only exist in 6h periods after the first op, and it won't actually be different from the clumsy answer in practice for casual/infrequent usage, which is probably the common case?

Correct except for the "6h period" part, I don't think there is any enforced "6h period" involved here in this version of this proposal except for the time between rotating mirrors, which is not modified here, with the exception that this proposes to not rotate mirrors during pkg install operations unless the package cache is missing, or outdated relative to the current mirror.

This proposal is designed to provide users of pkg an imitation of my own behavior while using the package managers of rolling-release distros before and after Termux came to exist:

  1. Try to install package without updating package cache
  2. If the package installs successfully, it means that the package cache with relation to this package and all its dependencies is sufficiently up-to-date to the degree that the mirror still contains the cached versions of all needed packages, so no further action is necessary
  3. If the package failed to install because of a missing or outdated package cache, that means that it is time to perform a package cache update and a full upgrade, because partial upgrades are not reliable on rolling-release distros.

One of my least favorite categories of user issue is when someone runs a long package install, switches to another app because it's boring, and ends up with broken packages/package management because Android killed termux and left things in an inconsistent state... I think it's much more common than real breakage caused by partial updates.

I personally disagree. In my opinion, errors caused by partial updates are more common than errors caused by interrupted updates, but it could just be that I've personally seen more errors caused by partial updates, and you've personally seen more errors caused by interrupted updates. It's hard to gather evidence to identify which type of error is objectively more common. There is, however, the factor in support of my position that, if all intended package operations complete successfully, then if implicit partial updates are invoked repeatedly, an error will always eventually happen to at least one package, but if implicit partial updates are disallowed, then all user-side dependency-related errors are prevented.

the resulting installed packages would tend to be staler, but I think they're still capped at 6h of staleness for metadata reasons.

Not quite correct - this proposal would introduce the behavior that, if someone types pkg install and the package is already installed (but a potentially old version if they have not used pkg upgrade in a long time), then nothing will happen. If the package is not already installed, then in that case, the package age would not be capped at "6h of staleness", it would be capped at "the age of the package in the current mirror or, should the package cache be outdated, the next mirror according to the mirror rotation logic", because if the package fails to download from the mirror (due to the package cache being outdated), the mirror rotation logic would be run, then the package cache updated, then a full upgrade performed, then the package installed from the next mirror.

It would not be great if we lost the assumption of recency from "okay now pkg i it" -> "okay it worked".

Correct, this proposal introduces a behavior where if someone types pkg install and the package is already installed, then nothing will happen (because the package will remain at the current, possibly-outdated version). If this proposal were accepted, then after it deployed, people offering support would have to realize that pkg install does not guarantee an updated package cache anymore, and that the only command to guarantee a fully up-to-date Termux installation is pkg upgrade (true anyway regardless of this proposal, because updating the package cache and then installing packages without performing a full upgrade is a partial upgrade, which does not guarantee a fully up-to-date Termux installation).

@robertkirkman
Copy link
Author

robertkirkman commented Jun 4, 2025

General message for readers here:

I have tried to explain every detail of the proposed changes in a precise way through the commit message and my responses here,

but despite that, I believe that the full extent of the subtle changes in the behavior of the pkg install command that this would cause is not easy to realize just from reading my messages, particularly because of how different the behavior is from the behavior that Termux currently has, and has had for a long time.

If anyone is confused about what these changes would mean for them, I encourage them to consider installing and testing this PR on a temporary Termux installation, such as an installation on a test device, an Android virtual device, or a termux-docker container, so that they can experience the changes firsthand and compare with their expectations and preferences of how they believe Termux pkg install should behave.

@tstein
Copy link
Contributor

tstein commented Jun 4, 2025

I don't think there is any enforced "6h period" involved here in this version of this proposal except for the time between rotating mirrors, which is not modified here

Sorry, wasn't saying there was. I meant that in the other discussions, in today's pkg, we are significantly depending on the assumption that if select_mirror makes a bad choice, it only holds onto it for 6h. (I am taking others at their word that it works that way - haven't had a chance to familiarize myself with that code yet.)

it could just be that I've personally seen more errors caused by partial updates, and you've personally seen more errors caused by interrupted updates. It's hard to gather evidence to identify which type of error is objectively more common.

To be clear, I'm reporting my experience of other people's problems in the discord/matrix, not my own. :) apt-getting-killed feels like it comes up every month or three, is independent of changes or lack of changes to repo state, and is largely independent of user behavior. (It doesn't matter a ton if you have lots of packages or any specific packages or an old install or run upgrades frequently/rarely/through any specific path - you just have background Termux mid-update, which is a natural thing to do.) The partial update problem, and particularly the version of the partial update problem that isn't trivially fixed by a pkg up, has happened to anyone in a way that made it into my field of view, I wanna say, twice?

I agree that it's a problem worth fixing! But I'm worried about worsening something that's in the first few pages of my playbook for "someone says their shit is broken".

Not quite correct - this proposal would introduce the behavior...

I think we're saying the same thing here, but I didn't do a great job explaining it. One of the sources of package staleness is metadata staleness; I think your proposal will increase the average, but not the tail, contribution of metadata staleness to overall staleness, as long as we don't mess with the behavior of only holding mirror choices for 6h. That's not a problem.

Mentioning this because thinking through this proposal seems to create an incentive to mess with that behavior, and doing so has negatives for the way we do support communications and write instructions.

General message for readers here:

I think I'm following, but if you'd like to develop this further and build some consensus, I recommend adding a "what would change / what wouldn't change" to the top comment. I mean that in the broad sense: software behavior, UX, assumptions we can/can't have about the world. This is a thorny space and it'll help to get that front and center.

@robertkirkman
Copy link
Author

robertkirkman commented Jun 4, 2025

To be clear, I'm reporting my experience of other people's problems in the discord/matrix, not my own.
The partial update problem, and particularly the version of the partial update problem that isn't trivially fixed by a pkg up, has happened to anyone in a way that made it into my field of view, I wanna say, twice?

My guess is that the discrepancy we're seeing is because partial upgrade errors may be more commonly reported in GitHub Issues, while interrupted upgrade errors may be more commonly reported in Discord/Matrix.

In messages above this, I didn't want to basically "spam ping" in GitHub by saying something like "fixes all of these", because what I'm about to do will GitHub-ping all subscribers to these issues, but the topic has more or less been forced, so doing so now:

Issue list collected from searches like this: https://github.com/termux/termux-packages/issues?q=label%3Anot-bug%20is%3Aclosed%20CANNOT%20LINK%20EXECUTABLE

It's a bit hard to separate out issues that this proposal would actually fix from ones that have other causes (limited information provided, real dependency bug, mirror partially synced, revision-bumps still building in CI, interrupted upgrade), but ones where termux-info is provided, and does not show "All packages are up to date", can confidently be assumed to have been preventable by the changes in this proposal.

I recommend adding a "what would change / what wouldn't change" to the top comment. I mean that in the broad sense: software behavior, UX, assumptions we can/can't have about the world. This is a thorny space and it'll help to get that front and center.

Noted, like you suggest, I could probably think of a clearer way to summarize the changes with phrasing that fits under headings "what would change" and "what wouldn't change" for easier understanding. I'll work on writing that.

@robertkirkman
Copy link
Author

"What would change" and "What wouldn't change" summaries are now added to the description of the PR.

@robertkirkman
Copy link
Author

robertkirkman commented Jun 8, 2025

I think we're saying the same thing here, but I didn't do a great job explaining it. One of the sources of package staleness is metadata staleness; I think your proposal will increase the average, but not the tail, contribution of metadata staleness to overall staleness, as long as we don't mess with the behavior of only holding mirror choices for 6h. That's not a problem.

If I am understanding the concern you are talking about here correctly, I believe I can provide a worst-case scenario example of what would become possible after the changes proposed here.

In a worst-case scenario of what you describe, what would become possible is this:

  1. Someone installs a package, and their package cache is outdated relative to their current mirror, and it has been more than 6 hours, or they perform a package upgrade,
  2. so mirror rotation is run and a mirror from termux-tools' builtin mirrorlist that for the purposes of this example, is assumed to be valid and up-to-date at the time it is first selected, is selected, and used to install packages
  3. The person continues to use Termux and install packages, and they don't use pkg upgrade, instead they continue to install packages successfully using their current mirror and package cache, which remain matched to each other for as long as the mirror does not sync with a Termux main mirror on the mirror's side.
  4. The mirror, which for the purposes of this example is assumed to have been up-to-date and valid at the moment that it was selected by the mirror rotation, gradually becomes outdated because it either has not been synchronized in a long time, or it has become stale and its operator is no longer performing synchronizations of it with a Termux main mirror.
  5. The person continues to install packages and use Termux, but since they never use pkg upgrade explicitly, and the mirror continues to not receive any bumps of any packages, their mirror is never automatically rotated, they are receiving outdated Termux packages, and they are not necessarily aware of this.

This is essentially one of the intended behaviors of the current design of this proposal, because I personally have a belief that if a mirror was not stale when it was initially rotated to, and the user does not ever experience any errors nor perform an explicit pkg upgrade command, then the mirror becoming stale and serving outdated packages is possibly a situation desired by that user (this seems like a confusing assumption to make, but the key part of this for me is that the user's avoidance of the pkg upgrade command could imply that they might actually be trying to avoid upgrading their packages and avoid rotating away from their current mirror, and I propose that these changes should not impose mirror rotations or package upgrades on a user who appears to be doing that unless a package download error actually occurs because of their actions, at which point the handler of mirror rotation and package cache update and full upgrading takes over)

However, if this part of the proposal is disliked, this could be resolved and avoided by changing this proposal in a way that I mentioned in one of my earlier comments. Quoting what I said above:

If you believe pkg install should be included in always checking the mirror outdatedness, then what I can do here is, I can make the select_mirror timeout check happen in all pkg install situations (not only in the case of when the package failed to download on the first try), and if the current mirror's rotation has timed out, then proceed with select_mirror to select a mirror that is not outdated, and updating package cache, and updating all packages.

@robertkirkman robertkirkman force-pushed the pkg-do-not-partial-upgrade branch from 098b6db to efb1463 Compare July 3, 2025 22:21
…e not for (if the package cache has not been updated since) 6 hours
@robertkirkman robertkirkman force-pushed the pkg-do-not-partial-upgrade branch from efb1463 to 351a46c Compare July 3, 2025 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pkg i uses pacman -Sy, which is fundamentally unsafe
4 participants