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

feat: dnf module #377

Open
wants to merge 73 commits into
base: main
Choose a base branch
from
Open

feat: dnf module #377

wants to merge 73 commits into from

Conversation

fiftydinar
Copy link
Collaborator

@fiftydinar fiftydinar commented Dec 22, 2024

Changes

Recipe format

  • Recipe format changed a bit, to satisfy the new feature of dnf flags.

Existing features code changes

  • Adding repos is now using dnf -y config-manager addrepo --from-repofile=$repo for repo URLs & repo files, while COPR repos are using native dnf -y copr enable user/project.
    COPR repos are written in separate copr: array & in simpler user/project format in recipe, instead of long URL in repos: array.
  • rpm-ostree override remove --install=$pkg is replaced with 2 operations of dnf removal & then install.
    Single operation of removal + installation of dnf doesn't currently exist, but it's not a breaking behavior to not have it.
  • rpm-ostree override replace is replaced with dnf -y distro-sync --refresh --repo $repo $packages, which is compatible with all repos.
    Adding the repository along with replacement is disabled, so it must be done before replacement in repos: array if repo doesn't exist.

New features

  • dnf group removal & installation. Those are declared as group-remove & group-install array in recipe.
    They run before the packages installation.
  • Option for additional flags when doing installation or replacement of packages.
    • install-weak-dependencies: option for declaring if weak dependencies (such as Recommended) should be installed.
      It modifies the install & replace commands itself using --setopt=install_weak_deps=True/False flag, it doesn't modify the dnf config file. It defaults to true (reflecting dnf defaults).
    • skip-unavailable-packages: option for skipping unavailable packages when not available in repositories, or when not available on the system in case of replacing. Passes --skip-unavailable flag. Defaults to false.
    • skip-broken-packages: option for skipping the installation/replacement of broken packages. Passes --skip-broken flag. Defaults to false.
    • allow-erasing-packages: option for erasing/removing the problematic packages during dependency problems. Passes --allowerasing flag. Defaults to false.
  • Option for additional flags when doing removal of packages.
    • remove-unused-dependencies is true by default. If false is specified, it passes the --no-autoremove flag, which won't remove any unused dependencies during removal operation.

Issues to be closed

Fixes: #361
Fixes: #370
Fixes: #325
Fixes: #282

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit

shellcheck

⚠️ [shellcheck] reported by reviewdog 🐶
Did you forget to close this double quoted string? SC1078

CLASSIC_PKGS+=("${PKG}")


📝 [shellcheck] reported by reviewdog 🐶
This is actually an end quote, but due to next char it looks suspect. SC1079

echo "Installing: ${CLASSIC_PKGS[*]}"


🚫 [shellcheck] reported by reviewdog 🐶
'(' is invalid here. Did you forget to escape it? SC1036

echo "Installing package(s) directly from URL: ${HTTPS_PKGS[*]}"


🚫 [shellcheck] reported by reviewdog 🐶
Expected 'fi' matching previously mentioned 'if'. SC1047

echo "Installing package(s) directly from URL: ${HTTPS_PKGS[*]}"


🚫 [shellcheck] reported by reviewdog 🐶
Expected 'fi'. Fix any mentioned problems and try again. SC1072

echo "Installing package(s) directly from URL: ${HTTPS_PKGS[*]}"

Copy link
Contributor

Choose a reason for hiding this comment

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

📝 [shellcheck] reported by reviewdog 🐶
Possible misspelling: REPOS may not be assigned. Did you mean REPO? SC2153

if [[ ${#REPOS[@]} -gt 0 ]]; then

@certifiedfoolio
Copy link

Hopefully we can add it around that timeframe, yeah. Thanks for the progress update.

@certifiedfoolio
Copy link

certifiedfoolio commented Mar 13, 2025

hey @fiftydinar , is it possible to have a separate module for dnf4? it would prove useful for working with certain images, in my case, centos-bootc:stream10. I did start on this myself, and the modified module is at https://github.com/cherry-os/cherryOS/tree/live/modules/dnf. It mostly contains minor syntax changes and a few links to external bash scripts that modify the output of some dnf4 commands into json that can be parsed properly, due to dnf4 not having the --json flag. Thanks!

@certifiedfoolio
Copy link

hey @fiftydinar , is it possible to have a separate module for dnf4? it would prove useful for working with certain images, in my case, centos-bootc:stream10. I did start on this myself, and the modified module is at https://github.com/cherry-os/cherryOS/tree/live/modules/dnf. It mostly contains minor syntax changes and a few links to external bash scripts that modify the output of some dnf4 commands into json that can be parsed properly, due to dnf4 not having --json. Thanks!

@certifiedfoolio
Copy link

So far my dnf4 module works, you just can't add repositories with it. There may be other issues I'm unaware of though.

@fiftydinar
Copy link
Collaborator Author

fiftydinar commented Mar 13, 2025

hey @fiftydinar , is it possible to have a separate module for dnf4?

Hi,

What's the status of dnf5 for centos & similar images which still utilize dnf4? Will it come soon?
I would prefer to officially only have dnf5 module, to make things simpler & avoid potential confusion of some users.

Another option would be to detect if dnf4 is used, then if it is, just change the necessary syntax in the module for the commands.

Adding your unofficial dnf4 module as a note in the README can also suffice I think.

However, I would like @gmpinder & @xynydev opinions on this.

@certifiedfoolio
Copy link

certifiedfoolio commented Mar 13, 2025

hey @fiftydinar , is it possible to have a separate module for dnf4?

Hi,

What's the status of dnf5 for centos & similar images which still utilize dnf4? Will it come soon? I would prefer to officially only have dnf5 module, to make things simpler & avoid potential confusion of some users.

Another option would be to detect if dnf4 is used, then if it is, just change the necessary syntax in the module for the commands.

Adding your unofficial dnf4 module as a note in the README can also suffice I think.

However, I would like @gmpinder & @xynydev opinions on this.

Hey,
'dnf5' isn't available at all on CentOS Stream or EPEL yet. It's why i'm proposing a seperate dnf4 module.
Due to CentOS Stream/EPEL's release cycle, it may be quite a while, as in years, before dnf5 arrives on Stream/EPEL repositories.

@gmpinder
Copy link
Member

So far my dnf4 module works, you just can't add repositories with it. There may be other issues I'm unaware of though.

We'd be more than happy for you to contribute what you have. I don't think mixing the two in a single module would be the best option as you claim it doesn't operate the same.

@certifiedfoolio
Copy link

certifiedfoolio commented Mar 14, 2025

We'd be more than happy for you to contribute what you have. I don't think mixing the two in a single module would be the best option as you claim it doesn't operate the same.

It operates the same; the only code that's been changed is the addition of two bash scripts and syntax changes for dnf commands. The thing is it outputs a weird error when I try to add a repository using the modified module.

@certifiedfoolio
Copy link

certifiedfoolio commented Mar 14, 2025

@gmpinder This is the error I seem to be getting when using the below structure to add a repository file:
Structure:

type: dnf
source: local
repos:
   files:
      - filename.repo

Error:

[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04   × Cannot find column 'id'
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04      ╭─[/tmp/modules/dnf/dnf.nu:258:6]
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  257 │   let repo_info = try {
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  258 │     ^bash /tmp/modules/dnf/dnf-repolist.sh
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04      ·      ──┬─
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04      ·        ╰── value originates here
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  259 │   } catch {
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  260 │     exit 1
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  261 │   }
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  262 │     | from json
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  263 │     | get id
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  264 │     | par-each {|repo|
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  265 │       try {
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  266 │         ^bash /tmp/modules/dnf/dnf-repoinfo.sh $repo
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  267 │       } catch {
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  268 │         exit 1
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  269 │       }
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  270 │         | from json
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  271 │     }
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  272 │     | flatten
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  273 │ 
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  274 │   # Return the IDs of all repos that were added
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  275 │   let repo_ids = $repo_info
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  276 │     | filter {|repo|
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  277 │       $repo.repo_file_path in $repo_files
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  278 │     }
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  279 │     | get id
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04      ·           ─┬
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04      ·            ╰── cannot find column 'id'
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04  280 │ 
[23:35:20 g.i/c/stem-bourbon:latest] => #48 27.04      ╰────

@gmpinder
Copy link
Member

gmpinder commented Mar 14, 2025

@gmpinder This is the error I seem to be getting when using the below structure to add a repository file:
Structure:

type: dnf
source: local
repos:
   files:
      filename.repo

The files needs to be an array

@certifiedfoolio
Copy link

certifiedfoolio commented Mar 15, 2025

@gmpinder
Apologies for the formatting mistake, but that isn't the problem.
If i'm understanding the logs correctly, nu cant find the column "id" in the value originating from one of my scripts, and i've already verified that the output of the script is as accurate to that of dnf5's as possible. Of course, I may be wrong.

@gmpinder
Copy link
Member

@gmpinder
Apologies for the formatting mistake, but that isn't the problem.
If i'm understanding the logs correctly, nu cant find the column "id" in the value originating from one of my scripts, and i've already verified that the output of the script is as accurate to that of dnf5's as possible. Of course, I may be wrong.

Your error looks nothing like the code we have in this PR. You're using your own local changes. Please use our discord server for the discussion instead as it isn't pertinent to these changes.

@certifiedfoolio
Copy link

Gotcha.

@evanc577
Copy link

Can support be added for adding repos with baseurl and (optional) gpg key for repos that don't provide .repo links (e.g. terra)?

Something like this:

dnf5 -y install --repofrompath "$reponame,$repobaseurl" --repo "$reponame" "--setopt=${reponame}.gpgkey=${gpgkey}" "${packages[@]}"

Or with --nogpgcheck if no gpg key is provided.

gmpinder
gmpinder previously approved these changes Mar 19, 2025
Copy link
Member

@gmpinder gmpinder left a comment

Choose a reason for hiding this comment

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

I'm ready to have this merged if y'all are

@gmpinder
Copy link
Member

gmpinder commented Mar 19, 2025

Can support be added for adding repos with baseurl and (optional) gpg key for repos that don't provide .repo links (e.g. terra)?

Something like this:

dnf5 -y install --repofrompath "$reponame,$repobaseurl" --repo "$reponame" "--setopt=${reponame}.gpgkey=${gpgkey}" "${packages[@]}"

Or with --nogpgcheck if no gpg key is provided.

In this case, you would want to create your own .repo file under files/dnf/ of your repo and specify the name of the file under repos.files in your recipe.

Comment on lines 180 to 191
### Fix Optfix

* Specify a list of packages to fix optfix issues in the `optfix` field

Example:
```yaml
type: dnf
optfix:
packages:
- package1
- package2
```
Copy link
Member

Choose a reason for hiding this comment

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

There is no such thing as an "optfix fix". Optfix is the fix.

Suggested change
### Fix Optfix
* Specify a list of packages to fix optfix issues in the `optfix` field
Example:
```yaml
type: dnf
optfix:
packages:
- package1
- package2
```
* Optfix is a script used to work around problems with certain packages that install into `/opt/`
* These issues are caused by Fedora Atomic storing `/opt/` at the location `/var/opt/` by default, while `/var/` is only writeable on a live system
* The script works around these issues by moving the folder to `/usr/lib/opt/` and creating the proper symlinks at runtime
* Specify a list of folders inside `/opt/`
Example:
```yaml
type: dnf
optfix:
packages:
- foldername # ADD AN ACTUAL EXAMPLE FOLDER HERE

Excuse me for the potentially problematic formatting.

Comment on lines +195 to +196
Replacing the kernel with `dnf` module is not done cleanly & some remaints of old kernel will be present.
Please use `rpm-ostree` module for this purpose until this `dnf` behavior is fixed.
Copy link
Member

Choose a reason for hiding this comment

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

Was this fixed already in some images? I think I remember hearing about this.

Comment on lines +143 to +145
## Package Group Removal

### Remove Packages Groups
Copy link
Member

Choose a reason for hiding this comment

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

Remove all of these sorts of double-titles from the whole document. This is not a sensible structure.

## Doing a Specific Thing

### Do The Thing

Copy link
Member

Choose a reason for hiding this comment

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

When there are multiple ###-level titles below the top-level title, that is fine. Might only need minor rewording.

* Specify packages to install in the `install.packages` field
* Use the `repo` parameter to specify a specific repository for installation
* Use the `%OS_VERSION%` variable to automatically determine the operating system version
* Use flags such as `skip-unavailable`, `install-weak-deps`, `skip-broken` and `allow-erasing` to customize package installation
Copy link
Member

Choose a reason for hiding this comment

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

I think there should be a section in the README dedicated to explaining what all the available flags are and what they mean. Language such as such as should be avoided here to avoid ambiguity. I would rather format this as

* You can specify the following flags with this operation
 * ...

type: dnf
# Add repos, COPR repos, and repo keys
repos:
cleanup: false # (optional) Set to true to automatically remove added repos at the end of the module execution
Copy link
Member

Choose a reason for hiding this comment

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

# (optional) Set to true to automatically remove added repos at the end of the module execution
# Add a repo file from a URL

IMO these types of comments are not something that need to be in the example. All of this information should be in the documentation in the schema file, and that will be included on the documentation page on the website as well.

The example should be a fairly clean and readable configuration that one could mostly copy into their own recipe if they wished to. Flags should not be set to their default state manually, they should only be set if there is a specific reason to use the non-default state, with a comment explaining the reasoning.

@certifiedfoolio
Copy link

Starting to get strange errors with this module.
dnf5 isn't recognizing config-manager as an argument, judging by the errors im getting.

@gmpinder
Copy link
Member

@xynydev guess that's what happens when I use AI to create the README.

@gmpinder
Copy link
Member

Starting to get strange errors with this module.
dnf5 isn't recognizing config-manager as an argument, judging by the errors im getting.

The dnf plugin will need to be installed first for that to work. Maybe we should have a check for that and install it if you're trying to use it

@certifiedfoolio
Copy link

The dnf plugin will need to be installed first for that to work. Maybe we should have a check for that and install it if you're trying to use it
It wasn't installed by default? Huh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants