📄 0298-0300.html
字号:
<HTML>
<HEAD>
<TITLE>Maximum RPM (RPM):Real-World Package Building:EarthWeb Inc.-</TITLE>
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
<SCRIPT>
<!--
function displayWindow(url, width, height) {
var Win = window.open(url,"displayWindow",'width=' + width +
',height=' + height + ',resizable=1,scrollbars=yes');
}
//-->
</SCRIPT>
</HEAD>
-->
<!-- ISBN=0672311054 //-->
<!-- TITLE=Maximum RPM (RPM)//-->
<!-- AUTHOR=Edward Bailey//-->
<!-- PUBLISHER=Macmillan Computer Publishing//-->
<!-- IMPRINT=Sams//-->
<!-- CHAPTER=20 //-->
<!-- PAGES=0275-0304 //-->
<!-- UNASSIGNED1 //-->
<!-- UNASSIGNED2 //-->
<P><CENTER>
<a href="0294-0297.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0301-0303.html">Next</A>
</CENTER></P>
<!-- END CODE //--><A NAME="PAGENUM-298"><P>Page 298</P></A>
<P>First, we start the script with a %post statement and indicate that this script is for the
client subpackage. As the comments indicate, we only want to perform the following tasks if this
is the first time the client subpackage has been installed. To do this, we use the first and
only argument passed to the script. It is a number indicating how many instances of this
package will be installed after the current installation is complete.
</P>
<P>If the argument is equal to 1, no other instances of the client subpackage are presently
installed and this one is the first. Let's continue:
</P>
<!-- CODE //-->
<PRE>
# Set disk devices so that bin can read them
# (This is actually done on Red Hat Linux; only need to add bin to
# group disk)
if grep "^disk::.*bin" /etc/group > /dev/null
then
true
else
# If there are any members in group disk, add bin after a comma...
sed -e `s/\(^disk::[0-9]\{1,\}:.\{1,\}\)/\1,bin/' /etc/group > /etc/group.tmp
# If there are no members in group disk, add bin...
sed -e `s/\(^disk::[0-9]\{1,\}:$\)/\1bin/' /etc/group.tmp > /etc/group
# clean up!
rm -f /etc/group.tmp
fi
</PRE>
<!-- END CODE //-->
<P>One of amanda's requirements is that the user ID running the dumps on the client
needs to be able to read from every disk's device file. The folks at Red Hat have done half the work for
us by creating a group disk and giving that group read/write access to every disk device. Since
our dumpuser is bin, we only need to add bin to the
disk group. Two lines of sed, and we're done!
</P>
<P>The next section is related to the last. It also focuses on making sure
bin can access everything it needs while doing backups:
</P>
<!-- CODE SNIP //-->
<PRE>
# Also set /etc/dumpdates to be writable by group disk
chgrp disk /etc/dumpdates
chmod g+w /etc/dumpdates
</PRE>
<!-- END CODE SNIP //-->
<P>Since amanda uses dump to obtain the backups, and since
dump keeps track of the backups in
/etc/dumpdates, it's only natural that bin will need read/write access to
the file. In a perfect world, /etc/dumpdates would have already been set to allow group
disk to read and write, but we had to do it ourselves. It's not a big problem, though.
</P>
<P>Next, we need to create the appropriate network-related entries so that amanda
clients can communicate with amanda servers and vice versa:
</P>
<!-- CODE SNIP //-->
<PRE>
# Add amanda line to /etc/services
if grep "^amanda" /etc/services >/dev/null
then
</PRE>
<!-- END CODE SNIP //--><A NAME="PAGENUM-299"><P>Page 299</P></A><!-- CODE //-->
<PRE>
true
else
echo "amanda 10080/udp # Added by package amanda-client" >>/etc/services
fi
</PRE>
<!-- END CODE //-->
<P>By using grep to look for lines that begin with the letters
amanda, we can easily see whether
</P>
<P>/etc/services is already configured properly. If it isn't, we simply append a line to the end.
</P>
<P>We also added a comment so that sysadmins will know where the entry came from and
either take our word for it or issue an rpm -q --scripts
amanda-client command and see for themselves. We did it all on one line because it makes the script simpler.
</P>
<P>Let's look at the rest of the network-related part of this script:
</P>
<!-- CODE //-->
<PRE>
# Add amanda line to /etc/inetd.conf
if grep "^amanda" /etc/inetd.conf >/dev/null
then
true
else
echo "amanda dgram udp wait bin /usr/lib/amanda/amandad amandad
# added by package amanda-client" >>/etc/inetd.conf
# Kick inetd
if [ -f /var/run/inetd.pid ];
then
kill -HUP `cat /var/run/inetd.pid`
fi
fi
fi
</PRE>
<!-- END CODE //-->
<P>Here, we've used the same approach to add an entry to
/etc/inetd.conf. We then send a hangup signal to
inetd so the change will take effect, and we're done!
</P>
<P>Oh, and that last fi at the end? That's to close the
if [ "$1" = 1 ] at the start of the
script. Now let's look at the server's postinstall script:
</P>
<!-- CODE //-->
<PRE>
%post server
# See if they've installed amanda before...
if [ "$1" = 1 ];
then
# Add amanda line to /etc/services
if grep "^amanda" /etc/services >/dev/null
then
true
else
echo "amanda 10080/udp # Added by package amanda-server">>/etc/services
fi
fi
</PRE>
<!-- END CODE //--><A NAME="PAGENUM-300"><P>Page 300</P></A>
<P>That was short! And this huge difference brings up a good point about writing install
scripts: It's important to understand what you as the package builder should do for the users, and
what they should do for themselves.
</P>
<P>In the case of the client package, every one of the steps performed by the postinstall script
was something that a fairly knowledgeable user could have done. But all these steps have one
thing in common. No matter how the user configures amanda, these steps will never change.
And given the nature of client/server applications,
there's a good chance that many more amanda client packages will be installed than amanda servers. Would you like to be tasked with
installing this package on 20 systems and performing each of the steps we've automated 20
times? We thought not.
</p>
<P>
There is one step we did not automate for the client package: the creation of an
.rhosts file. Since this file must contain the name of the amanda server, we have no way of knowing
what the file should look like. Therefore, that's one step we can't automate.
</P>
<P>The server's postinstall script is so short because there's little else that can be automated.
The other steps required to set up an amanda server include the following:
</P>
<OL>
<LI> Choosing a configuration name, which requires user input.
<LI> Creating a directory to hold the server configuration files, named according to
the configuration name, which depends on the first step.
<LI> Modifying sample configuration files to suit the site, which requires user input.
<LI> Adding crontab entries to run amanda nightly, which requires user input.
</OL>
<P>Since every step depends on the user making decisions, the best way to handle them is to
not handle them at all. Let the user do it!
</P>
<H4>
20.4.3.2. Creating Uninstall Scripts
</H4>
<P>Where there are install scripts, there are uninstall scripts. While there is no ironclad rule to
that effect, it is a good practice. Following this practice, we have an uninstall script for the
client package, and one for the server. Let's take the client first:
</P>
<!-- CODE //-->
<PRE>
%postun client
# First, see if we're the last amanda-client package on the system...
# If not, then we don't need to do this stuff...
if [ "$1" = 0 ];
then
</PRE>
<!-- END CODE //-->
<P>As before, we start out with a declaration of the type of script this is and which subpackage
it is for. Following that, we have an if statement similar to the one we used in the install
scripts, save one difference. Here, we're comparing the argument against zero. The reason is that
we
</P>
<P><CENTER>
<a href="0294-0297.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0301-0303.html">Next</A>
</CENTER></P>
</td>
</tr>
</table>
<!-- begin footer information -->
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -