Kickstart questions that remained unanswered by the docs

Hi all,

I’ve been trying to learn setting Fedora up with kickstart and was hoping to get a bit of help to ease the process.

The way I go about it is mainly reading the Kickstart Syntax Reference and developing a kickstart that I test in VMs with F40 Betas, with the purpose of having a reproducible system-state ready by the time F40 Final officially releases and I do a clean install.

I’ve also added the Kickstart Documentation to my studying material, since I figured it contains a bit more in-depth information that the syntax reference lacks, like, for example:

Note: If you want to enable one of the repos in /etc/anaconda.repos.d that is disabled by default (like “updates”), you should use –name= but none of the other options. anaconda will look for a repo by this name automatically. Providing a baseurl or mirrorlist URL will result in anaconda attempting to add another repo by the same name, which will cause a conflicting repo error.

I try to come up with answers for the questions that remain unanswered with experimentation - trial and error - however that means that the information feedback loop gets slowed down quite a bit. Also sometimes the experimentation lead to results that conflict with the documentation.

Here are some of my questions, starting with one relevant to my last statement:

  1. The syntax reference for repo states that to maintain a repo’s inclusion on the installed system, one needs to use --install. However, adding rpmfusion repos with eg:
    repo --name="rpmfusion-free" --metalink=https://mirrors.rpmfusion.org/metalink?repo=free-fedora-$releasever&arch=$basearch
    does still install the repo on the resulting system (same for nonfree) despite the lack of the installation argument. It also installs a bunch of repos for eg nvidia and Steam for some reason… When testing the same for other repos like “vscode”, the repository is not installed (which is the expected behavior). What’s happening here?

    • Only a “by-chance” relevant question:
      What are the [<repo>-debuginfo] and [<repo>-source] definitions in the repository configurations? Are they essential?
  2. I noticed that repo neither has an option to import keys, nor does it warn or fail without them. Does that mean this command results in simply skipping gpg checks? Would I be better of setting up those repos in a %pre script that adds .repo files in /etc/anaconda.repos.d/ (and a %post for /etc/yum.repos.d/)? Or maybe skip completely the pre and do the key importation and package installation of those via dnf in a post script?

  3. The sole purpose of the addition of rpmfusion for me personally, is to install the minimum amount of media packages needed to have an “actually usable” system. In an installed system, I would most probably just run sudo dnf swap ffmpeg-free ffmpeg --alowerasing (from free) and sudo dnf install intel-media-driver (from nonfree)

    • Is there a simple concise way to do that through %packages that correctly handles dependencies, or should I go about it again via dnf in a %post?

    • If I use --includepkgs ffmpeg of repo, would that automatically include its dependencies as well or would I have to be explicit for them as separate packages?

    • If I use --includepkgs of repo would that automatically exclude all other packages not specified, or would I need to also --excludepkgs *? (My intention of those last 2 points combined is to confine usage of rpmfusion to this limited selection of packages, making sure that no other package is ever fetched from them by mistake or otherwise)

  4. I am using a %pre script to configure dnf’s parallel downloads before starting fetching packages. Reading the docs (second link of the 2 provided above), I came across the existence of %pre-install. What is the “timeline” difference between the two? The docs only implicitly suggests the difference might be one is before filesystem creation and the other is after. Is that correct and if so should I be using %pre-install instead?

  5. I plan on keeping my kickstart in a public Github repo and using it during install by url.

    • I was considering to start breaking down my kickstart as it gets larger… Do %include and %ksappend statements resolve when using a https://raw.githubusercontent link, or do they assume that ksflatten will be used in advance and are only there to serve ease-of-maintainance needs?

    • Let me start by saying I’m not very knowledgeable about security. That said, publishing even a hashed version of a privileged user password sounds like a bad idea. (if I’m wrong, please do enlighten me).
      I planned on letting user creation to be configured manually through the installer instead, but I noticed if I’m not fast about it, anaconda just skips user configuration and starts the installation.
      Is there a way to simply “mark” it as “required” so that the installation doesn’t proceed before the configuration of a user? If not, would I be correct that, given rootpw --lock, using firstboot --enabled and having installed the initial-setup related packages, I would be offered to create a user on first boot?

    • Does that method effectively require an ethernet connection? I know you can configure the network in a kickstart, but is there any way to setup WiFi from an Everything iso in order to be able to fetch the remote kickstart itself?


I hope I didn’t tire people with my many questions, I figured I’d only post once I have collected my thoughts to avoid spamming with follow-ups. :slight_smile:

Added kickstart and removed f36, intel, nvidia

And your example repo command does not use —install?

Yes.
My entire repos section looks like this:

url --metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch&protocol=https&country=IE,DE,NL
repo --name="updates"
repo --name="fedora-cisco-openh264"

repo --name="rpmfusion-free" --metalink=https://mirrors.rpmfusion.org/metalink?repo=free-fedora-$releasever&arch=$basearch&protocol=https&country=IE,DE,NL
repo --name="rpmfusion-free-updates" --metalink=https://mirrors.rpmfusion.org/metalink?repo=free-fedora-updates-released-$releasever&arch=$basearch&protocol=https&country=IE,DE,NL

repo --name="rpmfusion-nonfree" --metalink=https://mirrors.rpmfusion.org/metalink?repo=nonfree-fedora-$releasever&arch=$basearch&protocol=https&country=IE,DE,NL
repo --name="rpmfusion-nonfree-updates" --metalink=https://mirrors.rpmfusion.org/metalink?repo=nonfree-fedora-updates-released-$releasever&arch=$basearch&protocol=https&country=IE,DE,NL

repo --name="vscode" --baseurl=https://packages.microsoft.com/yumrepos/vscode

rpmfusion repos get installed on the resulting system, while vscode does not.

In your example, rpmfusion is using --metalink=... whereas vscode is using --baseurl=.... Maybe that is significant?

I don’t know, maybe… (I probably will test that tomorrow)

My assumption was that for some reason, rpmfusion is handled differently in Fedora.
Maybe because of the high demand due to codec dependence?
I did check /etc/anaconda.repos.d/ to see if they might be predefined similar to Fedora’s native repos which causes them to be treated differently if declared in the kickstart, but they weren’t there.

My mention of the repositories for Steam and Nvidia and I believe a copr repo for Pycharm, was as much if not more confusing, as I didn’t declare them anywhere and they were still there.

Regardless, I didn’t see any such behavior documented in any docs I was able to discover, that’s why I’m here hoping to get answers :stuck_out_tongue:

This has been working for me.

# Use additional repos
repo --name="updates"  --metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-f$releasever&arch=$basearch&country=us
repo --name="fedora-cisco-openh264"  --metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-cisco-openh264-$releasever&arch=$basearch
repo --name="rpmfusion-free"  --metalink=https://mirrors.rpmfusion.org/metalink?repo=free-fedora-$releasever&arch=$basearch
repo --name="rpmfusion-free-updates"  --metalink=https://mirrors.rpmfusion.org/metalink?repo=free-fedora-updates-released-$releasever&arch=$basearch
repo --name="rpmfusion-nonfree"  --metalink=https://mirrors.rpmfusion.org/metalink?repo=nonfree-fedora-$releasever&arch=$basearch
repo --name="rpmfusion-nonfree-updates"  --metalink=https://mirrors.rpmfusion.org/metalink?repo=nonfree-fedora-updates-released-$releasever&arch=$basearch

# Use network installation
url --metalink="https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch&country=us"

I’m not sure what this statement addresses.

My repos section works too (I guess) - it fetches and installs the packages I later request in %packages. It just doesn’t work as documented, which is, it installs the repositories to /etc/yum.repos.d/ of the target system without me having set the --install argument. This shouldn’t normally happen.

Furthermore, just to be clear if it wasn’t already, I do actually intend to install those repositories. (Edit:) I just forgot to set --install and was very confused when I saw them installed regardless. I’m not complaining about the discussed behavior of repo but rather just trying to understand it in my effort to learn using kickstart.

1 Like

Ha, you got me there. I completely misunderstood but rereading I shouldn’t have.

The repo command in my mind has always meant it gets enabled in the target. The description does not say it will not be enabled unless the --install option is set. From the code it looks like the install option does not come into play. You are right the documentation is lacking.

Do you install the rpmfusion-free-release rpmfusion-nonfree-release packages in your %packages section? That would also enable the repos on the target. I do not and they are enabled.

Anaconda uses the repos without me telling it to import keys. On the target the first time you try to install a package from a repo gets you a prompt to import the keys. Here is what I do to import keys in a %post

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-38-x86_64
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-free-fedora-38
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-rpmfusion-nonfree-fedora-38

I also modify the dnf.conf used by anaconda during install

%pre
#!/bin/bash
set -x

cat<<'EOF'>>/etc/dnf/dnf.conf
group_package_types=mandatory
install_weak_deps=False
deltarpm=False
ip_resolve=4
excludepkgs=PackageKit,kf5-*,qt5-*
EOF
%end

Then make the same modifications on the target in a %post

debuginfo and source repos get you access to the debuginfo and source packages for debug symbols and source code. For instance you could then debug a running program following which line of code was being executed.

If I put ffmpeg in %packages, but not ffmpeg-free, the target only gets ffmpeg. If ffmpeg-free is in an environment or group I think ffmpeg serves as a package that supplies what ffmpeg-free supplies and so ffmpeg-free does not get installed. I’d have to test to make sure though.

As I understand it, --includepkgs and --excludepkgs are filters, not a selection method.

From the docs it looks like %pre-install is later than %pre. Time to experiment to see what exactly is going on. Have you been looking though all the logs in /var/log/anaconda once the target is booted? That is where I go to follow along and see what was going on after the target is up and running. It is also possible to look at the logs in anaconda before booting into the target (/tmp, not /mnt/sysimage or /mnt/sysroot).

Doing everything in kickstart has it’s drawbacks. Keep the kickstart simple. I go so far as to make a quite minimal system with no gui during kickstart.

I do put a ssh pubkey in the kickstart and configure an ansible user with sudo privledges. It is locked (as is root).

Use ansible to do the rest. Ansible is modular and works well with each playbook doing only one thing in an idempotent way. Ansible also has mechanisms to safely handle secrets.

Very fun to attempt to answer you questions. Thanks.

1 Like

First of all, thank you for taking the time to read and answer as much as possible, I really appreciate it! :slight_smile:

By enabled I suppose you mean just enabled=1 in /etc/yum.repos.d/<id>.repo ?
I’m pretty sure this is, indeed, the behavior for all of Fedora’s native packages (eg fedora-updates), for which simply declaring repo --name="<repo-id>" results in enabled=1 for /etc/anaconda.repos.d/ (note that those repos are enabled in the target system regardless!).

However, installation would mean if the repo files are present or not in that path of the target system at all. Take for example my repo for vscode. It is included for anaconda, the package is fetched and installed as instructed in my packages section, but the repo file is not installed in yum repos. This is exactly the behavior expected, as defined in the documentation. It’s just not consistent with rpmfusion.

As for the code, It seems like it does (or it should) take into account the --install argument, see: installation_enabled(self, value: Bool)

P.S:

Out of pure curiosity, could you share a cat of your fedora-updates.repo in a system installed by the kickstart you shared in your #1 post? The documentation suggests you are re-defining the native fedora repo (not just modifying the mirrorlist), which makes me curious about if the rest of the default configuration remains or not (eg if the -debug and -source details are included, if gpgcheck, rype, metadata_expire, etc are included or not in the resulting file).

Having read the docs, what I did to achieve the same as you, I do:

%pre
# Explicitly limit mirrors to https and a selection of countries
sed -ri 's/(^metalink=.*)/\1\&protocol=https\&country=IE,DE,NL/g' /etc/anaconda.repos.d/fedora*
%end

Yes, they are the last packages in my %packages section.

Did you mean to write you do not install packages and they are not enabled?
For the time being I run dnf config-manager --disable rpmfusion-\* in my %post (until I find a more fitting way to only enable those repos for specific packages), so I’m not sure of the default behavior.

This was my understanding as well. Which implies it uses dnf --nogpgcheck, no?
So my question on this matter is: If I want the gpg check to happen during the anaconda install, could I write the repos in %post to /etc/yum.repos.d, import the keys (as you do) and then, for example, dnf install vscode? Would that make the gpg check?

Pretty much exactly what I do too.

That’s interesting. I should probably do this at least once to learn how-to.
If you have some documentation pages that touch on this, please do share, because I have no idea how to go about it and wasn’t able to locate such docs with my searches.

What I want to achieve is something like what you are doing in your /etc/dnf/dnf.conf, applied to specifically the rpmfusion repos. Essentially, I want to be able to let the rpmfusion installed repositories enabled, with the guarantee that only x, y, z packages and their updates will ever be fetched from it. For example, for rpmfusion-nonfree I want dnf to only ever touch that repo for intel-media-driver and nothing else.

This was my understanding as well, just wasn’t 100% sure. I didn’t look at the logs and that’s a great idea that will probably answer my question.

My intention was to do as much as I can of the “installation” tasks in kickstart, so on first boot my system has all the software and repos I need, and is clean of packages that are usually installed but I don’t need/never use (so I have package removals as well in my %packages).

Next in my “things to learn”, was going to be using ansible for managing my ~/.config.
It might be a better idea to do what you suggest, but forcing myself to do “more” is a great way to learn.

I’m glad you had fun! It’s been a fun experience for me too :slight_smile:

Just some yum repo info in this reply.

When I run

rpm -qf /etc/yum.repos.d/*

I find all those files belong to installed packages. None of the packages that own the repo files are in my %packages section.

Maybe dnf pulls them in as a dependancy of something that is in %packages. But having those packages installed would explain why they are enabled on the target even though --install was not part of repo commands.

Looking at the root filesystem ananconda is running in

udisksctl loop-setup -f downloads/netinst.iso
udisksctl loop-setup -rf /run/media/.../Fedora-S-dvd-x86_64-39/images/install.img

dnf is configured to gpgcheck and the keys are in /etc/pki/rpm-gpg which is good evidence that anaconda installing packages does result in the possibility of signatures being checked.

An internet search did produce plenty of hits describing the desire to disable gpgcheck of repos added with the kickstart repo command so that is something.

I used a %post script to copy the dnf.conf and all repo files in the anaconda /etc to /root in the target. All shows that gpgcheck was enabled. Next I corrupted a package anaconda was instructed to install. Anaconda failed with an incorrect checksum error.

I conclude that anaconda indeed is performing gpgcheck on the repos it uses.

Thank you for the insight Stephen!
And sorry I took so long to follow up, was a bit busy.

After some iterations and tests, I decided to opt for explicitly declaring the extra repositories in a post-installation script. That option gives me way more options and flexibility while at the same time results in less unexpected behaviors.

This is true for your test-case, because the files you copy from /etc/anaconda.repos.d/ over to /etc/yum.repos.d/ are already declared in their respective yum repo files with the option gpgcheck=1 and the location to the key files.

Of course I would expect nothing less from fedora than GPG-checking the distribution’s own packages!

My question was more about what the default behavior would be for newly defined repositories, especially since kickstart’s repo command has limited options available, none of which provides a way to declare gpgcheck or a key file path.

To be more specific, my question would be:
Does

repo --name="vscode" --baseurl=https://packages.microsoft.com/yumrepos/vscode

skip gpgcheck?
My assumption would be yes (even though the key seems to be available in the target system under /usr/share/distribution-gpg-keys/microsoft/microsoft.gpg )

This among other reasons is why I’ve moved (for the time being at least) to:

%post

cat > /etc/yum.repos.d/vscode.repo << EOF
[vscode]
name=Microsoft VSCode
baseurl=https://packages.microsoft.com/yumrepos/vscode
enabled=1
gpgcheck=1
gpgkey=file:///usr/share/distribution-gpg-keys/microsoft/microsoft.gpg

EOF

# Other repos similarly written

rpmkeys --import /usr/share/distribution-gpg-keys/microsoft/microsoft.gpg

dnf clean all
dnf -y install code

%end

Note:
I believe dnf is supposed to automatically import the GPG key if defined through gpgkey=<path_or_url> in the .repo. However, testing showed it doesn’t (maybe it needs interactive confirmation?). This is why I opted for explicit key importation instead…

Overall, I’m starting to see the trend that being explicit rather than implicit does nothing but mitigate unexpected behaviors. So I’m leaning more and more towards doing exactly that, rather than trying to understand more of the defaults as that proves to be a painful journey with relevant docs lacking so much.

My understanding is dconf is used for configuration of Gnome based Desktop, right?
I’m using KDE Plasma, so I haven’t worked with dconf at all.

Regardless, I was planning on doing most configuration through ansible in the future because I was honestly just looking for an opportunity to learn ansible.

I haven’t come across that issue.
I currently only have 1 VM set up with kickstart (F40 stable release Everything iso), which only shows up 1 connection.

ls /etc/NetworkManager/system-connections/
>> enp1s0.nmconnection

Are you talking about manually configuring some wireless connection through the kickstart that gets duplicated?
If so, I haven’t tested that at all due to the way I’m fetching the kickstart (see Question 5.c of my original post)

1 Like

I would think gpgcheck state could be managed during kickstart for any repo that signs their packages.

On a test install copy the anaconda repo files to the target and see how they read. If vscode has gpgcheck turned off, turn it on in a pre or pre-install script. If importing the keys is needed add that to both pre and post scripts.