Building a custom CentOS 7 kickstart disc, part 2

Note: this series of articles applies to CentOS 7; for CentOS 6, see this

Once you’ve decided which packages you’re going to include in your kickstart disc,
it’s time to pull them all together.

Which RPMs do you need? Assuming that you are including at least the @core and @base
package groups (and you should), you’ll need the RPMs for all the packages in those

One way to obtain the list of RPMs you need is to look in the file comps.xml
for the core and base groups. You will see XML
like this:

At a bare minimum, you will want all the required packages from within the
core group.
I also like to install the
base group.
Look for <packagereq type="mandatory"> and <packagereq type="default">
entries within the
<group> tags. This tells you which
packages to get. These package names correspond to the names of the RPM files.

To make this easier, I have built a script to parse the comps.xml
file and gather all the non-optional packages
for the base and core package groups. Download
and save it in your ~/kickstart_build/utils

Before you can run, you’ll
need to install some perl libraries. All I wanted to use was XML::Simple, but that
set off a chain of dependencies. Use the rpm command below to install all the dependencies.

Note that I started with the minimal install; your system may start with a
different set of packages installed, so you
may get messages indicating that one or more of these packages is already installed (or
you might get errors about additional dependencies that you don’t have installed that I
did happen to have installed). These should be fairly easily resolved.

Once you have the prerequisites installed, run the script this way:

By default, will
gather all the packages for the
base and
core package groups. You can specify more
on the command line. For example, for my system, I do this:

Add your own RPMs

If you want to add any RPMs not included in the base
and core
groups (for example, httpd, php, or mysql), copy those into the
~/kickstart_build/isolinux/Packages directory at this

Resolve dependencies

Now we have all the base and core RPMs in our
~/kickstart_build/isolinux/Packages directory, along with
any other RPMs you’ve added, but many are missing their dependencies. So the next step
is to track down all the dependencies of these packages and throw those into the
directory, too. You can use another script,,
to perform this step.

Testing dependencies

Once you’ve got a set of RPMs ready, you’ll need to test the dependencies of the
RPMs. Each RPM may require that other RPMs be installed in order for it to be
installed. If each RPM’s dependencies are included in the set of RPMs, then all the
dependencies are resolved. The objective is to have a set of RPMs that have no
unresolved dependencies.

To test the dependencies in your set of RPMs, run these commands:

If you find you have unresolved dependencies (and you will almost certainly have
some), you can do one of two things:

  • remove the RPM with the unresolved dependencies (a good idea if the RPM is going
    to set off a chain of dependencies that you don’t want, for example X Windows on a
    server class installation)
  • track down the RPMs to fulfill the dependency

Here, again, you need a little bit of savvy to determine which packages should be
removed. In general, if the package is one that you explicitly added to the base and
core groups, then you’ll probably want to find the dependencies and include them. If
it’s an RPM that you don’t really want (one that got matched by the wildcard, for
example), you might decide to eliminate that RPM.

Resolving dependencies

The script
will get most dependencies automatically. But not always.

Some RPMs report their dependencies in strange ways. For example, usbutils
reports a dependency on /usr/bin/pkg-config.
But not a single package in the distribution reports that it provides

/usr/bin/pkg-config is contained within
the pkgconfig RPM. But the RPM reports that
it provides the following:

Note that rpm does not report that the package provides
My script isn’t smart enough to know that
means that the binary
gets installed. So the dependency goes unmatched.

There are a few packages in the base and core groups that do this, but not too many,
thankfully. After running,
I got these failed dependencies when I tested the repo:

So through some sleuthing, I determined that I needed these files:

Depending on which package groups you specified to,
you may have
additional situations like this that require more investigation. If you’ve brought
in RPMs from other repos, or you’ve included your own compiled RPMs, the situation
could be even more complicated, but if you are doing this, hopefully you know how
to deal with it.

When runs, it creates a file
/tmp/providers.txt that lists every RPM
and the capabilities provided by each. It might help you match up some of these
non-obvious dependencies.

If you have installed CentOS 7 to another system with a lot of RPMs installed,
you can use the
rpm -q --whatprovides query on that
system to try to track it down.

When all else fails, try googling for “rpm /path/to/file/in/question”; sometimes
you can figure it out that way.

This is an iterative process. Every time you add a new RPM to the directory, you
need to test the dependencies. Be prepared to spend a while chasing down these
dependencies to build a fine-tuned collection of RPMs with no unresolved

“Hidden” dependencies

One would hope that the resulting collection of RPMs would be complete, providing
all dependencies. However, it seems that anaconda can’t complete the installation
without some additional packages:

  • authconfig (@base)
  • chrony (@base)
  • firewalld (@base)
  • grub2 (@anaconda-tools)

(the containing package group for each package is listed in parens)

If you’re using, these should not be a problem; always includes the @base package group.
It also includes grub2 specifically because of this problem.

Next steps

The next step is to build your disk image. I will cover that in the next

Part 1
Part 2 •
Part 3
Part 4

Join the Conversation


  1. Hi
    I used that as a base to build a CentOS 6 kickstart ISO, (well the CentOS 6 version). Unfortunately, for CentOS7, I am left with an un-bootable system. I discovered the vmlinuz is not installed and the initrd images are missing from the resulting system.
    There seems to be a few file that are quietly now installed….
    I am experimenting – happy to work through with it get to a bootable result.
    First, I will read the pages again…. 😉
    Thank you for you help


    1. hi Buggycode,
      Did you notice that there were 2 way to gather all the packages for the base and core package groups. Choosing the 2nd way to gather all the packages, you will resolve such a problem you encountered : )

  2. buggycode

    I am having a similar issue with my kickstart script. got everything working, installing looking good.

    But when I reboot after install the boot loader won’t load and if I hit alt tab over to see the log during the install I get the following:

    WARN anaconda: no kernel was installed — boot loader config unchanged.

    doing this with Centos 7

    Can anyone give me a hint as to what the issue is?

    Barry McCormick

    1. hi Barry McCormick,
      The first time i build the custom iso and then finished installation, i found the same question like you mentioned! But…
      Did you notice that there were 2 way to gather all the packages for the base and core package groups. Choosing the 2nd way to gather all the packages, you will resolve such a problem you encountered : )
      If that still does not work, copy all the packages from DVD or minimal-version from iso which definitely can resolve your packages dependencies problem. And it definitely works!

  3. Thanks for this really helpful blog! I was really battling without it.

    I found it best to get rid of the inst.stage2=hd:LABEL in isolinux.cfg:

    sed -i ‘s/inst.stage2=hd:LABEL=CentOS\\x207\\x20x86_64/inst.ks=cdrom:\/dev\/cdrom:\/ks\/ks.cfg/’ ~/kickstart_build/isolinux/isolinux.cfg

    1. Thank you for your comment as it helped me. With my setup I am appending the following kernel parameters: inst.ks=http://… and inst.repo=http://… and it just kept getting stuck with “no suitable images” after trying to remount /dev/sr0 (I didn’t want to access any packages or whatnot on /dev/sr0 but over the network).

      Removing the inst.stage2 parameter solved that error for me.

  4. hi
    when i run this command ~/kickstart_build/utils/ ~/kickstart_build/comps.xml \ ~/kickstart_build/all_rpms ~/kickstart_build/isolinux/Packages x86_64
    show this lines for me

    RPM source path ‘ ‘ does not exist comps_file rpm_src_path arch [xtra_grps_and_pkgs]

    comps_file the full path to the comps.xml file (as provided
    in the original distro

    rpm_src_path the full path to the directory of all RPMs from
    the distro

    rpm_dst_path the full path to the directory where you want
    to save the RPMs for your kickstart

    arch the target system architecture (e.g. x86_64)

    xtra_grps_and_pkgs a list of extra groups and packages, separated by spaces

    1. Something isn’t right here. Either you didn’t really type the command the way you presented it here, or your is corrupt somehow.

      You’re going to have to look at the code for and probably add some print statements to it so you can see what is inside the @ARGV array, specifically the value for $rpm_src_path.

      If the script is intact, and you really typed the command the way you pasted it here, it should not have output an empty string for $rpm_src_path.

  5. Hi,

    I’m having an issue as well, which may be related to what people describe here.
    When I issue the command /tar/no-lang.comps.xml /mnt/Packages /tar/kickstart_build/isolinux/Packages x86_64
    where /mnt/Packages is the mounted CentOS7 DVD, and /tar/kickstart_build/isolinux/Packages is the _empty_ directory where the rpms need to go, I get two errors.

    First, I get an error that rm goes wrong because the dir is empty. More of a warning, I guess.

    Second, and more importantly, the script aborts, saying :
    Not an ARRAY reference at ./ line 47.

    which is: foreach $group (@{$comps->{group}})

    Please advise.


    1. Hi,

      Replace line 38
      $comps = $xml->XMLin($comps_file);
      $comps = $xml->XMLin($comps_file, ForceArray=>1);

  6. I replaced line 38 with the above and now it runs but none of the rpms from core or base get copied, only the additional packages added at the end of the list.

  7. OK after changing line 38 I had to change the following lines as well

    line 49
    $id = $group->{id};
    $id = $group->{id}[0];

    line 56
    $packagelist = $group->{packagelist};
    $packagelist = $group->{packagelist}[0];

  8. Hi,My enviroment is centos 7.5,but I encoutered this error,and it made me puzzled:
    [[email protected] Packages]# rpm –test –dbpath /tmp/testdb -Uvh *.rpm
    warning: acl-2.2.51-14.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
    error: Failed dependencies:
    /usr/bin/nm is needed by kmod-20-21.el7.x86_64
    I really have no idea,thanks…

  9. Replace line 38
    $comps = $xml->XMLin($comps_file);
    $comps = $xml->XMLin($comps_file, ForceArray=>[‘name’]);

    Because, I dont know why XMLin command on perl not able to find nodes, with this update it will locate the name.

Leave a comment

Your email address will not be published. Required fields are marked *