Unattended Package Installation with Debian and Ubuntu 1
Apt is a wonderful tool, but it does have its quirks. One of those is that it likes to ask you interactive questions during package installation. This makes total sense when a human is doing apt-get install foobar
, but it causes all sorts of consternation when you want to automatically install packages. (You do this all the time with Puppet, which I’ll talk more about at the end of this post.)
The answer to this problem is to pre-seed debconf with the correct answers to it’s questions. To do this, first you need to install the package by hand:
$ apt-get install libnss-ldap
You’ll need to provide answers to the questions it asks, which we’re going to re-use later as the basis for our seed file. Next, make sure you have debconf-utils
installed, and grab the answers to your questions:
$ apt-get install debconf-utils # Only if you need it
$ debconf-get-selections | grep libnss-ldap
libnss-ldap libnss-ldap/rootbindpw password
libnss-ldap libnss-ldap/bindpw password
libnss-ldap libnss-ldap/dblogin boolean false
# Automatically update libnss-ldap's configuration file?
libnss-ldap libnss-ldap/override boolean false
libnss-ldap shared/ldapns/base-dn string dc=example,dc=com
libnss-ldap libnss-ldap/rootbinddn string cn=admin,dc=example,dc=com
libnss-ldap shared/ldapns/ldap_version select 3
libnss-ldap libnss-ldap/binddn string cn=proxyuser,dc=example,dc=net
libnss-ldap shared/ldapns/ldap-server string ldapi:///
libnss-ldap libnss-ldap/nsswitch note
libnss-ldap libnss-ldap/confperm boolean false
libnss-ldap libnss-ldap/dbrootlogin boolean true
Take the output of that and stick it in a file, say libnss-ldap.seed
. You can now use that file to pre-seed a new system with those answers using debconf-set-selections:
$ debconf-get-selections | grep libnss-ldap > /tmp/libnss-ldap.seed
$ debconf-set-selections /tmp/libnss-ldap.seed
Or use ssh to pre-seed a new box:
$ cat /tmp/libnss-ldap.seed | ssh somehost debconf-set-selections
If you are using Puppet (and if you’re not, you should be) to manage your systems, you can use a recipe like this to automatically install packages that require interaction:
define seed_package($ensure = latest) {
$seedpath = "/var/cache/local/preseeding"
file { "$seedpath/$name.seed":
source => "puppet://$puppet_server/seeds/$lsbdistcodename/$name.seed",
mode => 0600,
owner => root,
group => root
}
package { $name:
ensure => $ensure,
responsefile => "$seedpath/$name.seed",
require => File["$seedpath/$name.seed"],
}
}
class foobar {
seed_package { "libnss-ldap":
ensure => latest
}
}
Some other resources on ways to use pre-seeding to great effect:
- Automating new Debian installations with preseeding at Debian Administration
- Preseed entry at the Debian Wiki
Happy unattended package installation! :)
Using runit with Upstart
When using runit with Upstart in Ubuntu 7.04, you’re going to run in to a couple of problems. The first is that the package doesn’t install cleanly without the presence of /etc/inittab
, which Upstart doesn’t need. You can fix that with a simple:
$ sudo touch /etc/inittab
Now, you need to actually add runit to Upstart. You do this by putting the following in /etc/event.d/runsvdir
:
start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on shutdown
respawn
exec /usr/sbin/runsvdir-start
This will cause runsvdir-start
to run during runlevel 2, 3, 4, and 5, stop when the system is going to be shutdown, and respawn if it goes away.
If you are on Ubuntu 6.10, the syntax is a bit different:
start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on shutdown
respawn /usr/sbin/runsvdir-start