\documentclass{ictlab}

\RCS $Revision: 1.19 $

\usepackage{alltt,key,xr,cols}
\externaldocument[lt-]%
{../../linux_training-plus-config-files-ossi/build/masterfile}

\usepackage[bf,flushleft]{caption2}
\ifx\pdftexversion\undefined \else
  \usepackage[pdfpagemode=None,pdfauthor={Nick Urbanik}]{hyperref}
\fi

\newcommand*{\labTitle}{Applying OS Updates}
\renewcommand*{\subject}{Operating Systems and Systems Integration}

\providecommand*{\RPM}{\acro{RPM}\xspace}
\providecommand*{\CD}{\acro{CD}\xspace}

\begin{document}

% \tableofcontents

\section{Aim}
\label{sec:aim}

After successfully working through this exercise, You will:
\begin{itemize}
\item understand the importance of applying updates to the operating
  system of servers

\item understand how to apply the updates to Red Hat Linux.

\item understand how to use \RPM and \texttt{yum} to resolve
  software package dependencies

\item understand how to automate the update process
\end{itemize}

\section{Background}
\label{sec:background}

All operating systems contain bugs.  Even Microsoft's OS, despite what
Bill may say (See \url{http://www.cantrip.org/nobugs.html}), contains
bugs.  See for example,
\sloppypar\url{http://www.gcn.com/archives/gcn/1998/july13/cov2.htm}.
And Linux contains bugs.  Now crackers are just waiting for a new bug
to be uncovered.  The company that provides the OS also will provide
updates to their OS, thanks to \acro{CERT}:
\url{http://www.cert.org/}, who eventually publish information about
the bug even if the company does not. As a system administrator, it is
a vitally important part of your duty to apply updates to important or
sensitive computers in your company.

Here in the \acro{ICT} Department, I have implemented a system that
automatically downloads the current updates for Red Hat Linux from the
Internet every day.  You will use these updates and apply them to your
computer.  The updates are software packages.

You will use the Network File System (\NFS) to \emph{mount} the network
drive containing these updates, and then use the \RPM Package
Manager (\RPM) to apply these updates to your machine.

The \RPM package manager does far more than allow you to install
updates.  It can also check that the installed software packages are
correctly installed, and verify that none of the programs have been
changed by a cracker (as long as \RPM itself is unchanged!)  See
chapter 25, \emph{Package Management with RPM}, of the \emph{The
  Official Red Hat Linux Customization Guide}, available from the Red
Hat web site at
\sloppypar\url{http://www.redhat.com/docs/manuals/linux/}, and also on
the documentation \CDROM (burn a copy on our \CD burner).

\subsection{The RPM Package Manager}
\label{sec:rpm}

The \RPM package manager has a number of basic capabilities: It can
\emph{install} software, \emph{update} software packages,
\emph{remove} packages, \emph{build} software packages, \emph{query}
and \emph{verify} software packages.

Please see section~\vref{lt-sec:rpm} in the \emph{Linux Training
  Materials Project} (the workshop notes we have used in the lab) for
more information about using \RPM to query and verify software
packages.  


\paragraph{Building RPM Packages}

If anyone is interested in building your own \RPM packages, you are
very welcome to see Nick, he may even give you a book about it!  The
online book is called \emph{Maximum RPM}, and is good reading for those
who are interested.

If you find an \RPM package for another version of Linux, it is a good
idea to rebuild it, since that will solve library dependencies.  For
this, you use the \emph{source} \RPM package.  To do this is simple.
For example, suppose you download the latest Emacs package from
\url{ftp://rawhide.redhat.com/pub/redhat/linux/rawhide/SRPMS/SRPMS/emacs-21.1-3.src.rpm}
and want to use it in Red Hat 9 instead of the older version there.
All you need do is:
\begin{alltt}
$ \textbf{sudo rpmbuild --rebuild emacs-21.3-6.src.rpm}
\end{alltt}%$
The code compiles, and eventually creates the binary \RPM{}s, which
you can then install:
\begin{alltt}
$ \textbf{sudo rpm -Uhv /usr/src/redhat/RPMS/i386/emacs-*21.3-6.i386.rpm}
\end{alltt}%$

Table~\vref{tab:rpm} shows the basic \RPM operations that we will use
today.  Table~\vref{tab:rpm-queries} shows more information about how
to make queries using \RPM.

\begin{table}[htb]
  \caption{The \RPM options that we use to install and upgrade software.}
  \label{tab:rpm}
  \begin{tabularx}{\linewidth}[t]{@{}>{\ttfamily}llY@{}}
    \toprule%
    \textnormal{\emph{Command}} & \emph{Action} & \emph{Description}\\
    \midrule%
    rpm -i & install & install the software package; do not uninstall
    any previous version of the software.  Use this when installing
    kernels; normally, use the \texttt{upgrade} action. \\
    rpm -U & upgrade & if an older copy of the package has been
    installed, uninstall it and replace it with this newer package.
    Do not delete the configuration files from the old package.
    Otherwise, it is the same as the \texttt{install} action, and is
    what I use most often. \\
    rpm -F & freshen & install this package only if an older version
    of this software package has already been installed.  Otherwise,
    do nothing.  Useful when upgrading software packages.\\
    rpm -e & remove & will completely erase the software package.\\
    \midrule%
    \multicolumn{3}{c}{Useful ``helper'' options}\\
    \midrule%
    -h & hashes & Print fifty hashes (`\textsl{\#}') to show progress
    of
    installation \\
    -v & verbose & print the name of each package as it is installed.
    Useful when installing more than one package at a time.  In
    practice, I always use this option, as well as the \texttt{-h}
    option. \\
    --force & force \texttt{:-)} & For updates, go ahead and force the
    update, even if the same package or a newer one is already
    installed.  Be very careful in using this; understand what you are
    doing.  It can also override dependencies, and you can end up with
    a system that does not work if you use this option carelessly. \\
    \bottomrule
  \end{tabularx}
\end{table}

\begin{table}[htb]
  \caption{This is a brief list of \RPM query commands.  I have used the
  \texttt{openssh} package as an example.}
  \label{tab:rpm-queries}
  \begin{minipage}{{\linewidth}}
  \renewcommand{\thefootnote}{\thempfootnote}
  \renewcommand{\footnoterule}{\vspace*{-2ex}}
  \begin{tabularx}{\linewidth}{@{}>{\ttfamily}lY@{}}
    \toprule%
    \emph{command} & \emph{effect}\\
    \midrule%
    rpm -qa \textbar{} less & list all installed software packages\\
    rpm -q openssh & show the version of the \texttt{openssh}
    package,\footnote{OpenSSH is the most popular version of software
      that supports the \emph{Secure Shell protocol}.  We study \SSH
      in detail later.} if it is installed.  Also use this to
    determine if a package is installed
    or not. \\
    rpm -qa \textbar{} grep openssh & show all installed packages that
    have \emph{openssh} in their name\\
    rpm -ql openssh & list all files in the openssh package \\
    rpm -qd openssh & list all documentation files in the openssh package \\
    rpm -qc openssh & list all configuration files in the openssh
    package \\
    rpm -qi openssh & display information about the package \\
    rpm -V openssh & verify that the openssh package is correctly
    installed\\
    rpm -qf /etc/passwd & determine which package the
    \texttt{/etc/passwd} file belongs to\\
    \bottomrule
  \end{tabularx}%
\end{minipage}
\end{table}

\section{Procedure}
\label{sec:procedure}

Note that updating the kernel requires that you keep the current
kernel, otherwise the loadable modules will no longer be available for
the currently running kernel.

We will use two methods; a manual method in which you manually resolve
software package dependencies, and an automatic method using
\texttt{yum}.  The \texttt{yum} program is available from
\url{http://linux.duke.edu/projects/yum/}.

There are three steps in the manual method:
\begin{itemize}
\item Access the network drive

\item If there are kernel updates that need to be applied, apply them
  first, installing any dependent packages first.
  
\item Apply the remaining updates, first those specialised to the
  Pentium II and above, and secondly, the remaining updates.
\end{itemize}

Here is how we do it.


\subsection{Accessing the network drive}
\label{sec:mountictlab}

\begin{enumerate}
\item Type:
\begin{alltt}
$ \textbf{cd /home/nfs/redhat-9/updates}
\end{alltt}%$
  \begin{explanation}
    Now you have \emph{automounted} the directory \texttt{/var/ftp/pub} from the machine
    \texttt{ictlab} over the network to the local directory
    \texttt{/home/nfs}, using the \acro{NFS} protocol.  When you change to
    your local directory \texttt{/home/nfs}, you will be accessing the
    directory \texttt{/var/ftp/pub} on \texttt{ictlab} over the
    network.

    We say that \texttt{ictlab} \emph{exports} the directory
    \texttt{/var/ftp/pub} by \acro{NFS}, and that your machine has
    \emph{mounted} this on the local directory \texttt{/home/nfs}.
  \end{explanation}
\end{enumerate}


\subsection{The Organisation of the Updates}

The updates, as organised on Red Hat's ftp sites and mirrors, is in a
group of directories.
\begin{enumerate}
\item Type
\begin{alltt}
$ \textbf{ls}
athlon  i386  i586  i686  noarch  SRPMS
\end{alltt}%$
Most binary packages we need are in the \texttt{i386} directory.  Some
platforms benefit from packages that are compiled specifically for
their architecture, so if you have a P-III or P-4, install the
packages from the \texttt{i686} directory rather than the same
packages from the \texttt{i386} directory.  Table~\vref{tab:arch}
summarises what is in each of the directories.
\end{enumerate}
\begin{table}[htb]
  \caption{The directories in the updates directory.}
  \label{tab:arch}
  \begin{tabularx}{\linewidth}[t]{@{}>{\ttfamily}lY@{}}
    \toprule%
    \textnormal{\emph{directory}} & \emph{What it's for} \\
    \midrule%
    athlon & Contains packages for \acro{AMD}'s Athlon and Duron processors \\
    i386 & Most of the packages you install come from here \\
    i586 & Packages optimised for the Pentium \\
    i686 & Packages optimised for the Pentium-II \\
%%     ia64 & Packages compiled for the new 64-bit processors from Intel \\
%%     images & These are updated installation disk images to put
%%     on a floppy disk using the \texttt{dd} command \\
    noarch & These software packages contain no architecture specific
    code, and are used on all platforms \\
    SRPMS & The source \RPM packages \\
    \bottomrule
  \end{tabularx}
\end{table}


\section{Installing yum}
\label{sec:installing-yum}


\begin{enumerate}
\item Change to the directory on our server, and list all the yum
  software packages:
\begin{alltt}
$ \textbf{cd /home/nfs/redhat/contrib}
$ \textbf{ls yum*}
\end{alltt}

\item Then install the latest:
\begin{alltt}
$ \textbf{sudo rpm -Uhv yum-2.0.3-1.noarch.rpm}
\end{alltt}%$
\end{enumerate}


\section{Setting up yum}
\label{sec:setting-up-yum}

\begin{enumerate}
\item edit the main configuration file:
\begin{alltt}
$ \textbf{xhost +localhost}
$ \textbf{sudo -v}
$ \textbf{sudo emacs /etc/yum.conf &}
\end{alltt}%$
\begin{explanation}
  \begin{itemize}
  \item The first command allows the \texttt{root} user to display
    graphical output on your X display
  \item The second command allows you to type your password, and start
    a new five-minute period during which you can execute programs
    using \texttt{sudo} without typing a password
  \item The last command starts a \emph{text editor} called
    \texttt{emacs}.  The \texttt{\&} at the end of the line executes
    the program in the \emph{background}, so that you can type more
    commands while \texttt{emacs} is running
  \end{itemize}
\end{explanation}

\item Copy the two sections near the bottom and duplicate them like
  this.  To copy and paste, select the text with the mouse, then move
  the mouse to the end of the file, then press the middle mouse button
  (or the wheel if a wheel mouse, or both mouse buttons at the same
  time if it is a two button mouse.)
{\footnotesize
\begin{verbatim}
[base]
name=Red Hat Linux $releasever - $basearch - Base
baseurl=http://mirror.dulug.duke.edu/pub/yum-repository/redhat/$releasever/$basearch/
 
[updates]
name=Red Hat Linux $releasever - Updates
baseurl=http://mirror.dulug.duke.edu/pub/yum-repository/redhat/updates/$releasever/
 
[base]
name=Red Hat Linux $releasever - $basearch - Base
baseurl=http://mirror.dulug.duke.edu/pub/yum-repository/redhat/$releasever/$basearch/
 
[updates]
name=Red Hat Linux $releasever - Updates
baseurl=http://mirror.dulug.duke.edu/pub/yum-repository/redhat/updates/$releasever/
\end{verbatim}
}

\item Put \emph{comment characters} (the `\texttt{\#}' character) at
  the start of the original two lines, then change the copies, so that
  the end of the file looks like this:
{\footnotesize
\begin{verbatim}
# [base]
# name=Red Hat Linux $releasever - $basearch - Base
# baseurl=http://mirror.dulug.duke.edu/pub/yum-repository/redhat/$releasever/$basearch/
 
# [updates]
# name=Red Hat Linux $releasever - Updates
# baseurl=http://mirror.dulug.duke.edu/pub/yum-repository/redhat/updates/$releasever/
 
[base]
name=Red Hat Linux $releasever - $basearch - Base
baseurl=file:///home/nfs/redhat-$releasever/RedHat/
 
[updates]
name=Red Hat Linux $releasever - Updates ictlab
baseurl=file:///home/nfs/redhat-$releasever/updates/
\end{verbatim}
}
\item Now enable the yum service:
\begin{alltt}
$ \textbf{sudo /sbin/chkconfig yum on}
$ \textbf{/sbin/chkconfig yum --list}
yum             0:off   1:off   2:on    3:on    4:on    5:on    6:off
\end{alltt}
\begin{explanation}
  See the lectures notes about \emph{runlevels}.  The lecture note
  slides discuss what you are doing here in detail.  Try the exercises
  described in the lecture notes.
\end{explanation}

\item Now run it once, manually:
\begin{alltt}
$ \textbf{sudo yum update}
\end{alltt}%$
\end{enumerate}

\subsection{Using \texttt{yum} Elsewhere}
\label{sec:using-yum-elsewhere}

Here we changed the \texttt{/etc/yum.conf} configuration file so that
your machine would download the updates from our local server
\texttt{ictlab}.  It is more efficient for all of us to download them
once, then have all machines update from our local server.  The
alternative, to have each machine update directly from the machine at
Duke University in the United States would be less efficient, and less
friendly with network resources.

However, at home, or for a few machines at work, you should simply
install \texttt{yum} and let it download the updates from Duke
University\@.  You would not need to edit the \texttt{/etc/yum.conf}
file at all.

Note that there are many other \texttt{yum} repositories listed at the
\texttt{yum} website.  The most important are the fedora web sites,
since the fedora stable packages are sponsored by Red Hat, and
freshrpms, which provides software packages for many things, including
reading and writing \acro{DVD}s and for playing \acro{MP3}s with
Xmms\@.


%% \subsection{Remote upgrade with \texttt{yum}}
%% \label{sec:remote-upgrade}

%% One problem system administrators face is upgrading a production
%% system.  Normally, upgrading the \OS (say from Red Hat 7.0 to 7.2)
%% would involve taking the machine out of production for a couple of
%% hours, rebooting it from a kickstart boot disk or \CDROM.

%% I have use \texttt{rpmfind} to upgrade our laboratory server from Red
%% hat 9 to Red hat 7.2 while it was online, and with no physical
%% access to the computer.  I upgraded it from my home on the weekend.
%% This is not recommended by Red Hat, and you need to know what to do if
%% you have any problems, but it was smooth for our machine, and is
%% viable.  The Debian Linux distribution has a much better system for
%% doing updates and upgrades called \texttt{apt-get}.  \texttt{rpmfind}
%% is not as good, but it does the job.
\end{document}
