\documentclass{beamer}

%\usepackage{beamerthemesplit}
\usepackage{upquote}

\mode<presentation>
{ \usetheme{boxes} }

\title{Debian Configuration Packages}
\author{
Tim Abbott (\texttt{tabbott@mit.edu})\\
Evan Broder (\texttt{broder@mit.edu})\\
Greg Price (\texttt{price@mit.edu})
}
\date{January 8, 2009}

% This fails miserably (keeps only the last \author.)  Silly beamer.
% \author{Tim Abbott \\ tabbott@mit.edu}
% \author{Evan Broder \\ broder@mit.edu}
% \author{Greg Price \\ price@mit.edu}

\begin{document}

\frame{\titlepage}

\section{Debian Configuration Packages}

\frame{\frametitle{Outline}\tableofcontents}

\subsection{Debian configuration files}

\begin{frame}[fragile]
  \frametitle{Debian configuration files}
  There are two classes of configuration files in Debian:
  \begin{itemize}
    \item Debian ``conffiles'', shipped in \texttt{.deb}, handled by \texttt{dpkg}
    \item Generated configuration files: with \texttt{debconf}, \texttt{ucf}, or ad hoc
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Debian configuration files: conffiles}
\small{
\begin{verbatim}

Setting up debathena-kerberos-config (1.0debathena5~debian4.0) ...

Configuration file `/etc/krb5.conf.debathena'
 ==> Modified (by you or by a script) since installation.
 ==> Package distributor has shipped an updated version.
   What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : background this process to examine the situation
 The default action is to keep your current version.
*** krb5.conf.debathena (Y/I/N/O/D/Z) [default=N] ? Y
Installing new version of config file /etc/krb5.conf.debathena ...

\end{verbatim}}
\end{frame}


\begin{frame}[fragile]
  \frametitle{Debian configuration files: debconf}
  \includegraphics[width=300pt]{155DCLynx.png}
\end{frame}

\subsection{Ways to do site configuration}
\frame{
  \frametitle{Ways to do site configuration}
  \begin{itemize}
    \item Preseed files (debconf-get-selections)
      % All packages aren't configured by debconf, and debconf doesn't
      % always give you all the frobs you need
    \item Private apt repository with modified upstream packages
      % Pain to keep up to date
    \item cfengine, systemimager, bcfg2, puppet, etc.
    \item Configuration packages (this talk)
  \end{itemize}
}


\subsection{Replacing a config file}

\begin{frame}[fragile]
  \frametitle{Replacing a config file: \texttt{dpkg-divert}}
  \begin{itemize}
    \item First try: just ship the new file.
    \item That gets clobbered when the original package is upgraded.
    \item Solution: ``divert'' the file, renaming it for other packages.
    \item So if we diverted dpkg to dpkg.divert, whenever we get a new
      version of dpkg, it gets installed at dpkg.divert.
    \item Designed for use in the /etc/alternatives system
    \item Only changes for unpacking, not for maintainer scripts
    \item \verb|DEB_DIVERT_FILES|, \verb|DEB_TRANSFORM_FILES|
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Replacing a config file: diverting /etc/ldap/ldap.conf}
\begin{verbatim}
$ dpkg-divert --list | grep ldap
diversion of /etc/ldap/ldap.conf to
 /etc/ldap/ldap.conf.debathena-orig
 by debathena-ldap-config

$ ls -l /etc/ldap/* | sed 's,.*/,/,'
/ldap.conf -> ldap.conf.debathena
/ldap.conf.debathena
/ldap.conf.debathena-orig
\end{verbatim}
On install,
\begin{itemize}
  \item \texttt{ldap.conf} was moved to \texttt{...debathena-orig}
  \item \texttt{ldap.conf.debathena} was unpacked
  \item the symlink was added
\end{itemize}
\end{frame}

\subsection{Problems with dpkg-divert for generated config files}

\begin{frame}[fragile]
  \frametitle{dpkg-divert problems with generated config files}

  \begin{itemize}
  \item dpkg-divert works great for conffiles
  \item For debconf/etc packages, less clear.
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{dpkg-divert problems with generated config files}

  Debian Policy, Section 10.7.3
  \hrule
  \vspace{\lineheight}

  Configuration file handling must conform to the following behavior:
  \begin{itemize}
    \item \alert{local changes must be preserved during a package upgrade}
    \item configuration files must be preserved when the package is
      removed, and only deleted when the package is purged.
  \end{itemize}
  ...
\end{frame}

\begin{frame}[fragile]
  \frametitle{dpkg-divert problems with generated config files}
\begin{verbatim}
$ cat /var/lib/dpkg/info/libhesiod0.postinst
if [ ! -f $hesconf ]; then
  ...
else
  sed -e "s/^lhs=.*/lhs=$lhs/" \
      -e "s/^rhs=.*/rhs=$rhs/" \
      -e "s/^classes=.*/classes=$classes/" \
      < $hesconf > $hesconf.new
  mv -f $hesconf.new $hesconf
fi
\end{verbatim}
  % The issue here is that libhesiod0 always uses the information in
  % the debconf database to replace whatever's in the actual file.
\end{frame}

\subsection{Transforming files}
\begin{frame}[fragile]
  \frametitle{Transforming files}

  Often, one wants to just change a single line of a configuration
  file.  This should be simple.  With \verb|DEB_TRANSFORM_FILES| it is.
  \begin{itemize}
    \pause \item Want to verify we're changing the original upstream version,
      rather than a version tabbott messed with \pause (Check md5sums)
    \pause \item Putting shell or perl scripts in makefiles sucks: \$ symbols must be
      doubled and you need a backslash at the end of each line. \pause
      (Place script in a separate file whose name can be easily computed).
    \pause \item Two packages configuring the same file should
      conflict \pause (We Provides: and Conflicts: an encoding of the
      filename).
    \pause \item Have to install modified configuration file
  \end{itemize}
\end{frame}

\subsection{Examples}
\begin{frame}[fragile]
  \frametitle{Example: debathena-ldap-config}
\par \$ cat debian/rules

\small{\begin{verbatim}
#!/usr/bin/make -f

DEB_AUTO_UPDATE_DEBIAN_CONTROL = 1
DEB_DIVERT_EXTENSION = .debathena
DEB_TRANSFORM_FILES_debathena-ldap-config += \
        /etc/ldap/ldap.conf.debathena
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/rules/config-package.mk
\end{verbatim}
  \hrule
\par \$ cat debian/transform\_ldap.conf.debathena
\begin{verbatim}
#!/usr/bin/perl -0p
s/^#BASE.*$/BASE\tdc=mit, dc=edu/m or die;
s/^#URI.*$/URI\tldap:\/\/ldap.mit.edu\nTLS_CACERT\t\/usr\/share\/debathena-ssl-certificates\/mitCA.pem/m or die;
\end{verbatim}}
\end{frame}


\end{document}
