The life of an admin in Higher Ed inevitably means, now that classes have started, your software is expiring. This is an annual problem. So I wanted to see how Puppet can help me.
In order for this to work, you need an application that can be licensed with a static file on the machine. Something that can be updated on a master machine and then copied to the clients. My examples involve Mathematica … insert your software in it’s place.
Puppet is perfect at enforcing configuration, so the idea of enforcing a license file is an ideal task. Take this file and put it there .. no questions asked.
class mathematica_license {
file { "/Library/Mathematica/Licensing/mathpass":
ensure => 'present',
mode => "0644",
owner => 'root',
group => 'wheel',
source => "puppet:///modules/mathematica_license/mathpass",
}
}
This works and if that’s all you need, great. You take your new license file, and put it in the files folder in your module, and use a file resource to say .. if this file doesn’t exist on the client … then copy it.
But a simple check would be great. What if I run this on all Lab machines, some of which don’t run Mathematica. An If statement makes a lot of sense. If Mathematica exist in the Applications folder, then copy new license file over. Sounds simple, but this isn’t always Puppets strongest skill. You can try to use an “unless” statement or “onlyif” … but I usually find myself fighting with the syntax.
class mathematica_license {
exec {"mathematica_check":
command => "true",
path => ["/usr/bin","/usr/sbin", "/bin"],
unless => "ls /Applications/ | grep Mathematica.app",
}
file { "/Library/Mathematica/Licensing/mathpass":
ensure => 'present',
mode => '0644',
owner => 'root',
group => 'wheel',
require => Exec["mathematica_check"],
source => "puppet:///modules/mathematica_license/mathpass",
}
}
It works, but maybe not in the way you want. The “unless” statement says, if results come back from the “ls” command, and grep finds “Mathematica ,then execute the “command” statement, which just evaluates to true. Then puppet runs the file resource below it. But it only runs the “file” resource if the “require” statement is true .. which is the “mathematica_check” above it.
If you’re just running puppet on the client side, you get the results you want. If the Application is installed, the file gets copied over. But if the Application isn’t installed, nothing happens.
If you’re reporting back to a dashboard like the Foreman … a side effort of a client not having your Application installed, is lots of errors. All those errors get reported back to your dashboard, causing a lot of false positives you need to over look. Your client reports back in an error state, even though it did exactly what you wanted it to do .. not copy the file if Mathematica isn’t installed.
A better solution seems to be, to create a custom fact. A fact that checks for the existence of the application. Then use an “If” to qulalify your resource in the manifest. Now the code only runs, if “Mathematica” is installed. If it can’t find the Application … the code exits and moves on. No errors in your log.
class mathematica_license {
if $mathematica == true {
file { "/Library/Mathematica/Licensing/mathpass":
mode => "0644",
owner => 'root',
group => 'wheel',
source => "puppet:///modules/mathematica_license/mathpass",
}
}
}
This does involve you creating a module with custom facts and deploying it to your clients. But to be honest, that can be easier then trying to manage puppets onlyif or unless statement in exec resources. Just my opinion