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

How to implement 'strict channel priority'? #458

Closed
wolfv opened this issue Jun 30, 2021 · 7 comments · Fixed by #459
Closed

How to implement 'strict channel priority'? #458

wolfv opened this issue Jun 30, 2021 · 7 comments · Fixed by #459

Comments

@wolfv
Copy link
Contributor

wolfv commented Jun 30, 2021

Conda has a "strict channel priority" where it will only take into account a package from a lower-priority channel if the package doesn't appear in any higher prio channel.

We're currently assigning a repo priority and sub-priority in mamba. However, it's not enough because the repo priority is only checked on the (already) filtered Queue if I understand correctly.

So for example, suppose we have

channel a:

  • numpy 1.0

channel b:

  • numpy 0.1

And b has a lower priority than a, I could still install numpy 0.1 by asking for it specifically mamba install numpy==0.1 for example. Conda would throw a solver error here.

I could go through all solvables, find those from the highest-prio repo and add them to a SOLVER_SOLVABLE_ONE_OF job but that doesn't strike me as the cleanest solution.

Any ideas how to filter the lower-priority ones out easily?

@mlschroe
Copy link
Member

There's multiple levels of strictness here. The not so strict variant is pruning the packages from repos with lower prios when selecting a package. The really strict variant is to force the solver to backtrack if the providers are from repos with lower prios.

Backtrack means doing things at the SAT level, i.e. you would need to add negative assertions for all low prio packages.

@wolfv
Copy link
Contributor Author

wolfv commented Jun 30, 2021

Thanks for the reply!

So I guess I could either add blacklist jobs for each package, or do something like solver_addrule(solv, -p, 0, 0); directly?

@wolfv
Copy link
Contributor Author

wolfv commented Jun 30, 2021

I've got some code like this:

            Repo *installed = pool->installed;

            FOR_POOL_SOLVABLES(p)
            {
                Solvable *s = pool->solvables + p;
                if (s->repo != installed && s->repo->priority < max_prio_map[s->name])
                {
                    // std::cout << "Removing " << pool_solvable2str(pool, s) << "( " << s->repo->name << " )\n";
                    queue_push(&selected_pkgs, p);
                }
            }
            Id d = pool_queuetowhatprovides(pool, &selected_pkgs);
            queue_push2(&m_jobs, SOLVER_BLACKLIST | SOLVER_SOLVABLE_ONE_OF, d);
            queue_free(&selected_pkgs);

And it seems to do the job.

@mlschroe
Copy link
Member

mlschroe commented Jul 1, 2021

That would work, but doing it in the solver code is probably way more efficient.

@wolfv
Copy link
Contributor Author

wolfv commented Jul 2, 2021

I'd be happy to try to implement this if you can give me some hints where to start :)

@mlschroe
Copy link
Member

mlschroe commented Jul 2, 2021

Pretty much like with my track feature commit. I.e. a new rule type, a solver_addrepopriorules() function. And you also need to tweak problems.c so that the error reporting works.

Hmm. I guess we also need to disable some rules if we directly access a package from a low-prio repo. We can add that later, though.

@wolfv
Copy link
Contributor Author

wolfv commented Jul 3, 2021

We'd probably need some map to store the max prio per name, right? Otherwise finding that each time again could be a bit costly

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 a pull request may close this issue.

2 participants