111

I am setting up a yum repository, and need to debug some of the URLs in the yum.conf file. I need to know why is Scientific Linux trying to grab this URL, when I was expecting it to grab another URL:

# yum install package 
http://192.168.1.100/pub/scientific/6.1/x86_64/repodata/repomd.xml: [Errno 14] PYCURL ERROR 22 - "The requested URL returned error: 404"
Trying other mirror.
Error: Cannot retrieve repository metadata (repomd.xml) for repository: sl. Please verify its path and try again

The yum.conf(5) manpage gives some information about these variables:

Variables

There are a number of variables you can use to ease maintenance of yum's configuration files. They are available in the values of several options including name, baseurl and commands.

$releasever This will be replaced with the value of the version of the package listed in distroverpkg. This defaults to the version of 'redhat-release' package.

$arch This will be replaced with your architecture as listed by os.uname()[4] in Python.

$basearch This will be replaced with your base architecture in yum. For example, if your $arch is i686 your $basearch will be i386.

$YUM0-$YUM9 These will be replaced with the value of the shell environment variable of the same name. If the shell environment variable does not exist then the configuration file variable will not be replaced.

Is there a way to view these variables by using the yum commandline utility? I would prefer to not hunt down the version of the 'redhat-release' package, or manually get the value of os.uname()[4] in Python.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Stefan Lasiewski
  • 19,754
  • 24
  • 70
  • 85
  • 1
    'hunt down the version of redhat-release' is trivial. cat /etc/redhat-release Actually, use cat /etc/system-release instead, since this will be a symlink to /etc/redhat-release, /etc/centos-release, /etc/oel-release, /etc/, as appropriate. – Jeter-work Oct 19 '16 at 16:01
  • 8
    /etc/redhat-release is not the same thing as the $releasever variable. The question here is to figure out what is Yum substituting in place of these variables? What's happening programmatically? – Stefan Lasiewski Oct 20 '16 at 18:46
  • 2
    'hunt down the version of redhat-release' is also NOT the same as 'cat /etc/redhat-release'. The former asks for a version, whereas the latter views a completely unreliable and infinitely mutable file which should NEVER be trusted.

    rpm -qf /etc/issue is the canonical method, and would have been the method in LSB except SuSE didn't budge in the FSStnd meetings. YARLY.

    – user2066657 Dec 05 '17 at 19:09

8 Answers8

144

When this answer was written in 2011, json wasn't installed for python by default for all the versions of RHEL/CentOS at that time so I used pprint to print the stuff nicely.

It is now 2020 and all current versions of RHEL/CentOS have json by default for python. The answer has been updated to use json and updated to include RHEL/CentOS 8 by modifying @sysadmiral's answer for Fedora.

RHEL/CentOS 8:

/usr/libexec/platform-python -c 'import dnf, json; db = dnf.dnf.Base(); print(json.dumps(db.conf.substitutions, indent=2))'

RHEL/CentOS 6 and 7

python -c 'import yum, json; yb = yum.YumBase(); print json.dumps(yb.conf.yumvar, indent=2)'

RHEL/CentOS 4 and 5

# if you install python-simplejson
python -c 'import yum, simplejson as json; yb = yum.YumBase(); print json.dumps(yb.conf.yumvar, indent=2)'

# otherwise
python -c 'import yum, pprint; yb = yum.YumBase(); pprint.pprint(yb.conf.yumvar, width=1)'

Example output:

# CentOS 8:
# ---
[root@0928d3917e32 /]# /usr/libexec/platform-python -c 'import dnf, json; db = dnf.dnf.Base(); print(json.dumps(db.conf.substitutions, indent=2))'
Failed to set locale, defaulting to C
{
  "arch": "x86_64",
  "basearch": "x86_64",
  "releasever": "8"
}
[root@0928d3917e32 /]# 


# CentOS 7:
# ---
[root@c41adb7f40c2 /]# python -c 'import yum, json; yb = yum.YumBase(); print json.dumps(yb.conf.yumvar, indent=2)'
Loaded plugins: fastestmirror, ovl
{
  "uuid": "cb5f5f60-d45c-4270-8c36-a4e64d2dece4", 
  "contentdir": "centos", 
  "basearch": "x86_64", 
  "infra": "container", 
  "releasever": "7", 
  "arch": "ia32e"
}
[root@c41adb7f40c2 /]# 

# CentOS 6:
# ---
[root@bfd11c9a0880 /]# python -c 'import yum, json; yb = yum.YumBase(); print json.dumps(yb.conf.yumvar, indent=2)'
Loaded plugins: fastestmirror, ovl
{
  "releasever": "6", 
  "basearch": "x86_64", 
  "arch": "ia32e", 
  "uuid": "3e0273f1-f5b6-481b-987c-b5f21dde4310", 
  "infra": "container"
}
[root@bfd11c9a0880 /]# 

Original answer below:

If you install yum-utils, that will give you yum-debug-dump which will write those variables and more debugging info to a file. There is no option to write to stdout, it will always write to some file which really isn't that helpful.

This is obviously not a great solution so here's a python one-liner you can copy and paste which will print those variables to stdout.

python -c 'import yum, pprint; yb = yum.YumBase(); pprint.pprint(yb.conf.yumvar, width=1)'

This works on CentOS 5 and 6, but not 4. yum is written in python, so the yum python module is already on your server, no need to install anything exra.

Here's what it looks like on CentOS 5:

[root@somebox]# python -c 'import yum, pprint; yb = yum.YumBase(); pprint.pprint(yb.conf.yumvar, width=1)'
{'arch': 'ia32e',
 'basearch': 'x86_64',
 'releasever': '5',
 'yum0': '200',
 'yum5': 'foo'}
[root@somebox]# 
  • 2
    yum-debug-dump seems to do what I need. Looks like the information is all there under the %%%%YUM INFO section. I can't seem to make things like $YUM0-$YUM9 appear, but I never use those variables anyways. – Stefan Lasiewski Sep 07 '11 at 01:12
  • 2
    To get a clean display of $releasever in the bash shell, use this: /usr/bin/python -c 'import yum;yb=yum.YumBase();yb.doConfigSetup(init_plugins=False);print yb.conf.yumvar["releasever"]' – Rockallite Feb 09 '17 at 07:36
  • This only works for the system version of Python - how do you get this working for an additional "alt-install" version of Python? – RCross Sep 01 '17 at 15:57
  • 1
    what do you do if releasever is actually $releasever the string.... – The Lazy Coder Nov 29 '17 at 07:35
  • This is a great answer, and @StefanLasiewski answer is helpful too. But I need to know if my $os evaluates to RedHat or RedHatEnterprise, and none of the above seems to answer it for me. Does anyone know how to find the value of $os? – Edward Ned Harvey Feb 22 '21 at 20:44
  • Except python is not universal. You need to import "yum" on some systems and "dnf" on others. On the other hand yum-debug-dump does seem universal, but also slow, as it dumps a lot of uneeded info. – anthony Dec 14 '23 at 02:20
18

Just in case anybody ends up here, like me, looking for the equivalent answer for dnf on Fedora I fathomed out the following python one-liner:

python3 -c 'import dnf, pprint; db = dnf.dnf.Base(); pprint.pprint(db.conf.substitutions,width=1)'

On Fedora 24 it looks like this:

{'arch': 'x86_64',
 'basearch': 'x86_64',
 'releasever': '24'}
sysadmiral
  • 1,604
  • 1
    Found this from searching yum variables repo names. This answers the question for now, with the replacement of yum with dnf. Great work! – bgStack15 Feb 21 '17 at 22:08
  • 1
    Note that there are also direct variables: use import dnf; b = dnf.Base(); print("basearch=%s, releasever=%s" % (b.conf.basearch, b.conf.releasever)) – Craig Ringer Dec 12 '19 at 04:24
  • Using python 'dnf' does not work of RHEL 7, Better for something that works on both "yum" and "dnf" based systems. This is a "rpm" problem, and the solution should be a "rpm" solution – anthony Dec 14 '23 at 01:12
13

To get all of them you'll need to use code like mmckinst posted, but if you just want to check $releasever you can run yum version nogroups on RHEL-6.

The other thing to do, in RHEL-6, is to just create your own in /etc/yum/vars.

James Antill
  • 1,973
  • can you elaborate? What does creating /etc/yum/vars accomplish? Also, do you happen to know if this changed from RHEL5 to RHEL6? – Stefan Lasiewski Sep 29 '11 at 16:12
  • 1
    You should be able to write code which works on RHEL-5 and RHEL-6, without a problem. The version command is not in RHEL-5 atm. What I meant about /etc/yum/vars (RHEL-6 only) is that you can just create a /etc/yum/vars/foorelease ... which has your own release data in it, or even just override the system releasever by writing to /etc/yum/vars/releasever. – James Antill Oct 03 '11 at 20:07
  • More info about /etc/yum/vars can be found at https://access.redhat.com/knowledge/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sec-Using_Yum_Variables.html – Stefan Lasiewski Dec 03 '12 at 19:47
  • However yum version nogroups does not work on newer system using dnf. Arrrgghhh... and /etc/yum/vars does not have all the vars! – anthony Dec 14 '23 at 02:22
8

For a full dump you can use:

yum config-manager --dump
dnf config-manager --dump

To dump variables you can use:

yum config-manager --dump-variables
dnf config-manager --dump-variables

yum-config-manager is also available but typically redirects to the dnf config-manager Plugin.

From https://linux.die.net/man/5/yum.conf:

$releasever This will be replaced with the value of the version of the package listed in distroverpkg. This defaults to the version of 'redhat-release' package. $arch This will be replaced with your architecture as listed by os.uname()[4] in Python.

$basearch This will be replaced with your base architecture in yum. For example, if your $arch is i686 your $basearch will be i386.
$uuid This will be replaced with a unique but persistent uuid for this machine. The value that is first generated will be stored in /var/lib/yum/uuid and reused until this file is deleted.

$YUM0-$YUM9 These will be replaced with the value of the shell environment variable of the same name. If the shell environment variable does not exist then the configuration file variable will not be replaced.

muru
  • 72,889
6

And drilling down how $releasever is assigned:

The function _getsysver query the rpm database like:

rpm -q --provides $(rpm -q --whatprovides "system-release(releasever)") | grep "system-release(releasever)" | cut -d ' ' -f 3

"system-release(releasever)" value is defined here, and it could be override by distroverpkg in yum.conf

If the query did not return any value, releasever is set to '$releasever' (for example if you set distroverpkg=centos-release but have installed the rpm redhat-release-server)

adrianlzt
  • 161
2

For CentOS 8 Stream, which uses more variables like $stream - you can also do this:-

# cd /etc/dnf/vars;grep . *

which reveals them thusly:-

contentdir:centos
infra:stock
stream:8-stream
cnd
  • 209
1

Getting the value for $arch should really be as simple as arch="$(arch)" or arch="$(uname --machine)" but if you really want to know what yum's value for $arch is, try:

bash-4.2# arch="$(python -c 'from rpmUtils import arch; print(arch.getCanonArch());')";
bash-4.2# declare -p arch
declare -- arch="ia32e"

Getting the values for the other vars without needing to use Python is a little easier.

Option 1:

bash-4.2# distroverpkg="$(awk --field-separator \= '/distroverpkg/{print$2}' /etc/yum.conf)";
bash-4.2# releasever="$(rpm --query --queryformat '%{VERSION}\n' "${distroverpkg:-redhat-release}")";
bash-4.2# basearch="${HOSTTYPE:-$(uname --machine)}";
bash-4.2# declare -p distroverpkg releasever basearch
declare -- distroverpkg="centos-release"
declare -- releasever="7"
declare -- basearch="x86_64"

Option 2:

bash-4.2# releasever="$(rpm --query --file --queryformat '%{VERSION}\n' /etc/system-release)";
bash-4.2# basearch="$(rpm --query --queryformat '%{ARCH}\n' "kernel-$(uname --kernel-release)")";
bash-4.2# declare -p releasever basearch
declare -- releasever="7"
declare -- basearch="x86_64"

Note: Commands shown using long-opts (when available) for clarity.

bfs
  • 11
  • 1
0

Another way to see the results of variable substitution is to do something like this:

yum-config-manager -c /etc/reposyncb.conf  | grep -i spacewalk

I was tinkering with yum variables to control which spacewalk client is selected for building a local repo and found this useful to see how the variables are being interpreted.

Anthon
  • 79,293