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

dnfjson: skip TestDepsolver() if no osbuild-depsolve-dnf is installed #321

Merged
merged 3 commits into from
Jan 12, 2024

Conversation

mvo5
Copy link
Contributor

@mvo5 mvo5 commented Dec 14, 2023

Do not fail if osbuild-depsolve-dnf is missing.

It also fixes dnfjson.go so that the comment (and I think intention) matches the code :)

@mvo5 mvo5 marked this pull request as draft December 14, 2023 14:24
@mvo5 mvo5 force-pushed the skip-dnfjson-no-dnfjson branch from fecdf93 to 7ffefb9 Compare December 14, 2023 14:28
@mvo5 mvo5 marked this pull request as ready for review December 14, 2023 16:34
bcl
bcl previously approved these changes Dec 14, 2023
Copy link
Contributor

@bcl bcl left a comment

Choose a reason for hiding this comment

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

Looks good to me. The tests run with -force-dnf so we won't accidentally pass if it's missing :)

@achilleas-k
Copy link
Member

achilleas-k commented Dec 14, 2023

Maybe we should remove the python3 -c "import dnf" check now. The osbuild-depsolve-dnf package should depend on libdnf so all we need to do is check if that exists. The shelling out to python thing is a bit silly.

It also fixes dnfjson.go so that the comment (and I think intention) matches the code :)

aaah yeah the comment matches my initial idea and then I thought it might be better to set the the default so that, when (if) it fails, you get an error that shows the primary default location. I'm not sure which is better.

@mvo5
Copy link
Contributor Author

mvo5 commented Dec 19, 2023

Maybe we should remove the python3 -c "import dnf" check now. The osbuild-depsolve-dnf package should depend on libdnf so all we need to do is check if that exists. The shelling out to python thing is a bit silly.

Thanks, I think that makes sense, I updated the PR.

It also fixes dnfjson.go so that the comment (and I think intention) matches the code :)

aaah yeah the comment matches my initial idea and then I thought it might be better to set the the default so that, when (if) it fails, you get an error that shows the primary default location. I'm not sure which is better.

I have no strong opinion either way, I pushed a small commit that makes New{,Base}Solver() return an error when no osbuild-depsolve-dnf is found with a descriptive error message. But it has drawbacks in the test (as more are skipped now) so I can just drop this commit again if desired (it feels like the cleanest option though).

mvo5 added 2 commits January 5, 2024 10:16
Do not fail if `osbuild-depsolve-dnf` is missing.
As suggested by Achilleas this commit removes the dnfInstalled()
helper as it's now redundant with the new findDepsolveDnf() check
(the osbuild-depsolve-dnf package should depend on libdnf).
@mvo5 mvo5 force-pushed the skip-dnfjson-no-dnfjson branch from 0c664d0 to b94540e Compare January 5, 2024 09:17
@mvo5 mvo5 requested a review from achilleas-k January 5, 2024 09:17
@achilleas-k
Copy link
Member

achilleas-k commented Jan 5, 2024

I pushed a small commit that makes New{,Base}Solver() return an error when no osbuild-depsolve-dnf is found with a descriptive error message.

We don't want this. It makes it impossible (or harder) to set up the solver externally with a depsolver in a non-standard location. For example, this should be possible:

solver := NewBaseSolver(cacheDir)
solver.SetDNFJSONPath("/some/odd/path/to/solver")

without having osbuild-depsolve-dnf installed, either for testing or for non-standard setups.

So there's a question now about what findDepsolveDnf() should do if the depsolver isn't found:

  1. Return the default and let callers change it or fail when run() is called (which will show the primary default location in the error message). This is what happens now in main but admittedly it's not the best since it relies on non-local behaviour for error messaging.
  2. Return an empty string and either:
    2.1 Let run() fail (if the path isn't changed) with an empty path in the error message.
    2.2 Make run() check if it's empty and print an appropriate message that it's unset.
  3. Return an error but catch it in the caller and set the path to an empty slice (and then do 2.2).

EDIT: Oh...

if len(dnfJsonCmd) == 0 {
return nil, fmt.Errorf("osbuild-depsolve-dnf command undefined")
}

Just set it to an empty slice then.

Copy link
Member

@achilleas-k achilleas-k left a comment

Choose a reason for hiding this comment

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

@mvo5 mvo5 force-pushed the skip-dnfjson-no-dnfjson branch from b94540e to 02ef207 Compare January 10, 2024 13:54
@mvo5
Copy link
Contributor Author

mvo5 commented Jan 10, 2024

I pushed a small commit that makes New{,Base}Solver() return an error when no osbuild-depsolve-dnf is found with a descriptive error message.

We don't want this. It makes it impossible (or harder) to set up the solver externally with a depsolver in a non-standard location. For example, this should be possible:

solver := NewBaseSolver(cacheDir)
solver.SetDNFJSONPath("/some/odd/path/to/solver")

[..]

Thank you, that is an interesting use-case and I have no considered it. I tweaked the PR slightly to run the findDepsolverDnf later. This seems to be the most minimal change and I pushed it. But below another idea if you prefer to detect the missing dnfjson early :)

If we don't want this and make any detection of missing dnfjson part of the constructor I wonder if it would make sense to change the signature of NewBaseSolver() to make sure that the solver path is passed in when constructing? Something like:

diff --git a/pkg/dnfjson/dnfjson.go b/pkg/dnfjson/dnfjson.go
index 9505e09b3..d11ce164a 100644
--- a/pkg/dnfjson/dnfjson.go
+++ b/pkg/dnfjson/dnfjson.go
@@ -61,13 +61,24 @@ func findDepsolveDnf() (string, error) {
        return "", fmt.Errorf("cannot find required osbuild-depsolve-dnf in any of %q", depSolveDnfPaths)
 }
 
+type SolverOptions struct {
+       DNFJsonPath string
+}
+
 // Create a new unconfigured BaseSolver (without platform information). It can
 // be used to create configured Solver instances with the NewWithConfig()
 // method.
-func NewBaseSolver(cacheDir string) (*BaseSolver, error) {
-       depsolveDnf, err := findDepsolveDnf()
-       if err != nil {
-               return nil, err
+func NewBaseSolver(cacheDir string, opts *SolverOptions) (*BaseSolver, error) {
+       if opts == nil {
+               opts = &SolverOptions{}
+       }
+       depsolveDnf := opts.DNFJsonPath
+       if depsolveDnf == "" {
+               foundSolver, err := findDepsolveDnf()
+               if err != nil {
+                       return nil, err
+               }
+               depsolveDnf = foundSolver
        }
        return &BaseSolver{
                cache:       newRPMCache(cacheDir, 1024*1024*1024), // 1 GiB
@@ -135,7 +146,7 @@ type Solver struct {
 
 // Create a new Solver with the given configuration. Initialising a Solver also loads system subscription information.
 func NewSolver(modulePlatformID, releaseVer, arch, distro, cacheDir string) (*Solver, error) {
-       s, err := NewBaseSolver(cacheDir)
+       s, err := NewBaseSolver(cacheDir, nil)
        if err != nil {
                return nil, err
        }

or is an API break like this too annoying?

@mvo5 mvo5 requested a review from achilleas-k January 10, 2024 13:57
@achilleas-k
Copy link
Member

or is an API break like this too annoying?

Not that annoying. We'll have to change all the calls in composer and bib when we pull in the change but it's not that much work. There's an interesting use case that gets a bit dirty when you want to init the Solver without a solver though (either because you don't intend to use it but need an instance for a test or because you might want to "discover" the solver path later), where the caller would have to do something like:

NewBaseSolver(cacheDir, &SolverOptions{DNFJsonPath: "NOTEMPTY"})

and then change it.

Would we also add the options to the NewSolver() function?

Copy link
Member

@achilleas-k achilleas-k left a comment

Choose a reason for hiding this comment

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

Current state LGTM

@achilleas-k achilleas-k added this pull request to the merge queue Jan 12, 2024
Merged via the queue into osbuild:main with commit 6645f6f Jan 12, 2024
10 checks passed
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.

3 participants