Simple puppet update-alternatives
Posted by Admin • Thursday, June 11. 2015 • Category: DevOps, Linux
This is a quick and dirty interface to update-alternatives on Centos/Redhat/Ubuntu for puppet. Seems to work well and doesn't require any modules.
Usage example: alternatives_update { 'java': versiongrep => '1.8' }
Usage example: alternatives_update { 'java': versiongrep => '1.8' }
class my_alternatives {
# Manipulates alternatives using update-alternatives.
# Supports RHEL, Centos and Suse.
# Ubuntu not tested (yet).
#
# If multiple matches are available, picks the first one.
#
# There is rudimentary alternatives support in the java class,
# but it's rather limited and doesn't support most platforms and java versions.
define update (
$item = $title, # the item to manage, ie "java"
$versiongrep, # string to pass to grep to select an alternative, ie '1.8' (1.8.*openjdk would also work)
$optional = true, # if false, execution will fail if the version is not found
$altcmd = 'update-alternatives' # command to use
) {
case $::osfamily {
'RedHat','SuSE': {
if ! $optional {
# verify that we have exactly 1 matching alternatives, unless it's optional
exec { "check alternatives for ${item}":
path => ['/sbin','/bin','/usr/bin','/usr/sbin'],
command => "echo Alternative for ${item} version containing ${versiongrep} was not found, or multiple found ; false",
unless => "test $(${altcmd} --display ${item} | grep '^/' | grep -- '$versiongrep' | wc -l) -eq 1",
before => Exec["update alternatives for ${item} to ${versiongrep}"],
}
}
# Runs the update alternatives command
# - unless it reports that it's already set to that version
# - unless that version is not found via grep
exec { "update alternatives for ${item} to ${versiongrep}":
path => ['/sbin','/bin','/usr/bin','/usr/sbin'],
command => "${altcmd} --set ${item} $( ${altcmd} --display ${item} | grep '^/' | grep -- '$versiongrep' | head -n 1 | sed 's/ .*$//' ) ",
unless => "test -x \"$(${altcmd} --display ${item} | grep 'currently points' | grep -- '$versiongrep' | awk '{print \$NF}')\"",
onlyif => "${altcmd} --display ${item} | grep '^/' | grep -- '$versiongrep' ", # check that there is one (if optional and not found, this won't run)
}
}
# Leave Ubuntu alone, this probably won't work there anyway
}
}
}
Hi,
thanks for the very nice snippet. However, there are certain circumstances where this will not work, e.g. if your regexp matches the priority level... Consider this example:
myhost ~ $ update-alternatives --display java | grep '^/' | grep -- 1.6 /usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java - priority 16000 /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java - priority 1865
In this case the "grep -- 1.6" will find both alternatives, 1.6 and 1.8, b/c the "1865" priority reading also matches the "1.6" regexp. So your code will fail b/c it does not know what version to create the link for.
I found two solutions to this problem (only relevant code):
replace the "--" with "-w" to have grep look for the word-regexp "1.6":
myhost ~ $ update-alternatives --display java | grep '^/' | grep -w 1.6 /usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java - priority 16000
remove everything but the package name prior to grep:
myhost ~ $ update-alternatives --display java | grep '^/' | awk -F "priority" '{print $1}' | grep -- 1.6 /usr/lib/jvm/jre-1.6.0-openjdk.x86_64/bin/java -
This needs to be corrected in BOTH exec commands for this Puppet "module" to work under any circumstances.
Cheers!