Verwalten von PPAs mit Puppet
Mit dem von Puppet Labs zur Verfügung gestellten Apt Modul werden PPAs (personal package archive) nur experimentell unterstützt. Daher habe ich mir für das Einbinden und Entfernen von PPAs in meine Ubuntu Konfiguration selbst zwei Defines / benutzerdefinierte Ressourcen erstellt. Das erste Define kümmert sich um die Integration des eigentlichen PPA in die Paketverwaltung. Das zweites Define dient zur Verwaltung des zugehörigen Zertifikats zur Überprüfung der Pakete.
Das Define zur Verwaltung des eigentlichen PPA (pparepo
) handhabt die .list
Datei im Verzeichnis /etc/apt/sources.list.d/
für das Repository.
Ich lege mir für jedes verwaltete PPA eine eigene Datei mit dem Namen des PPA als Name der .list
Datei an.
Das Define kümmert sich nach dem Hinzufügen bzw. Entfernen der .list
Datei auch darum, dass mittels apt-get update
auch die Paketverwaltung von der Änderung erfährt.
define pparepo(
$ensure = present,
$apt_key = '',
$comment = '',
$dist = $lsbdistcodename,
$supported = ['maverick', 'lucid', 'oneiric', 'precise'],
$keyserver = 'keyserver.ubuntu.com'
) {
$ppa_file_name = regsubst($name, '/', '-', 'G')
$file = "/etc/apt/sources.list.d/pparepo-${ppa_file_name}.list"
file { "${file}":
}
case $ensure {
present: {
if ($dist) and ($dist in $supported) {
File["${file}"] {
ensure => file,
content => "deb http://ppa.launchpad.net/$name/ubuntu ${dist} main #${comment}\n"
}
if ( $apt_key ) {
apt-defines::key { "${apt_key}":
keyserver => $keyserver
}
}
}
else {
File["${file}"] {
ensure => false
}
}
}
absent: {
File["${file}"] {
ensure => false
}
}
default: {
fail "Invalid 'ensure' value '${ensure}' for pparepo"
}
}
exec { "update apt repositories for $name":
path => '/bin:/usr/bin',
environment => 'HOME=/root',
command => 'apt-get update',
user => 'root',
group => 'root',
logoutput => on_failure,
subscribe => File["${file}"],
refreshonly => true,
}
if ( $apt_key ) {
Exec["update apt repositories for $name"] {
require => Apt-defines::Key["${apt_key}"],
}
}
}
Steht für das PPA ein Zertifikat zur Verfügung, wird vom pparepo
Define das ppakey
Define als Abhängigkeit gesetzt.
Das Define für die Handhabung des Zertifikats ruft das Kommando apt-key
zum Hinzufügen bzw. Entfernen des Zertifikats auf.
Das Zertifikat wird hierzu mittels gpg vom Key-Server abgerufen.
define ppakey(
$ensure = present,
$keyserver = 'keyserver.ubuntu.com'
) {
case $ensure {
present: {
exec { "Import ${name} to apt keystore":
path => '/bin:/usr/bin',
environment => 'HOME=/root',
command => "gpg --keyserver ${keyserver} --recv-keys $name && gpg --export --armor ${name} | apt-key add -",
user => 'root',
group => 'root',
unless => "apt-key list | grep ${name}",
logoutput => on_failure,
}
}
absent: {
exec { "Remove ${name} from apt keystore":
path => '/bin:/usr/bin',
environment => 'HOME=/root',
command => "apt-key del ${name}",
user => 'root',
group => 'root',
onlyif => "apt-key list | grep ${name}",
}
}
default: {
fail "Invalid 'ensure' value '${ensure}' for ppakey"
}
}
}
Möchte man ein Paket aus einem PPA installieren, fügt man in dem Modul die Resource pparepo
hinzu.
Die eigentlichen Pakete haben dann eine Abhängigkeit zu diesem pparepo
, um sicher zu stellen, dass auf jeden Fall erst die PPA Definition eingebunden wird.
class example {
pparepo { 'blueyed/ppa':
apt_key => '7CC17CD2',
}
package { 'example':
ensure => present,
require => Pparepo["blueyed/ppa"],
}
}
Ich habe mit diesen beiden Defines bereits einige PPAs zu meiner Standard Ubuntu Konfiguration hinzugefügt. Nach der Grundinstallation kann ich nun mit einem Puppet-Lauf meine eigene Konfiguration anwenden lassen.