And one port to install them all!

And one port to install them all!

Today I was setting up a new box and wanted to get all my favorite ports installed with a minimum
of fuss. My first thoughts of were of a shell script. But then I thought of using a port to install
ports. After all, some ports have dependencies, and they install the ports they need. Why can’t I write
a port which just installs ports?

So I asked around. And I was told to use a meta-port. I was pointed at
misc/instant-workstation. That is what I used as the basis for this
example meta-port.

The Makefile

All the files for this port are available in the samples directory.
You can download the files for this port from
newbox-checklist.tgz.

The Makefile is pretty simple. Here is it:

# New ports collection makefile for: newbox-checklist
# Date created:	13 January 2002
# Whom:			Dan Langille
#
# $Id: meta-ports.php,v 1.6 2007/08/27 16:34:47 dan Exp $
#

PORTNAME=	newbox-checklist
PORTVERSION=	1.0
CATEGORIES=	misc

MASTER_SITES=   # none
DISTFILES=      # none

MAINTAINER=	ports@freebsddiary.org

RUN_DEPENDS=	bash:${PORTSDIR}/shells/bash2 \
		joe:${PORTSDIR}/editors/joe \
		screen:${PORTSDIR}/misc/screen \
		sudo:${PORTSDIR}/security/sudo \
		xtail:${PORTSDIR}/misc/xtail \
		${PREFIX}/distributed.net/dnetc:${PORTSDIR}/misc/dnetc \
		${PREFIX}/etc/logcheck.sh:${PORTSDIR}/security/logcheck

NO_WRKSUBDIR=	YES
NO_BUILD=	YES

do-install: # empty

.include <bsd.port.mk>

Here are a few comments on the various parts of this Makefile.

MASTER_SITES
The master site is where the distfile (distribution file) is downloaded from.
This file contains the source code, patches, etc, for the port. For our
meta-port, we don’t have any source ourselves. We are just using other ports.
This is why we have no master site.
DISTFILES
As mentioned in the previous item, we have no distfile. Therefore this is emtpy.

MAINTAINER
Put your email address here
RUN_DEPENDS
These are the ports which must be installed in order for our port to run. Well,
actually, *our* port never runs. But that is not relevant to our task. We will
exploit this feature for the ports tree for our our purpose. Namely, to install
the ports we want.

bash:${PORTSDIR}/shells/bash2
This entry consists of two fields. First, we have bash, the name of
the executable we are installing. We have not supplied a path name. Just
the file name of the executable. Next, we have the port which should be installed
if the executable is not found. We use the predefined value ${PORTSDIR}
in case our ports tree is not installed in /usr/ports. This format will work
well for most ports.
${PREFIX}/distributed.net/dnetc:${PORTSDIR}/misc/dnetc
In this case, we are not installing an executable which can be found in the normal
places (as determined by your $PATH variable). Therefore, we provide the full
pathname to the file in question. I determined this path by inspecting
/var/db/pkg/dnetc-2.8010.462_1,1/+CONTENTS. Because it starts
with a /, the ports system will know this is the name of a file, not an executable.
Therefore, it will not search your $PATH.
NO_WRKSUBDIR
This prevents the creation of any subdirectories.
NO_BUILD
We have nothing to build, so let’s not build anything.
do-install
We have nothing to install when it comes to installing, so let’s not install anything.

For more information on the RUN_DEPENDS, or any other entry in a Makefile, please read
/usr/ports/Mk/bsd.port.mk

Using the makefile

To use the port, download it from newbox-checklist.tgz.
Then unpack the tarball and install it.


fetch http://www.FreeBSDDiary.org/samples/ports/tarballs/newbox-checklist.tgz
tar xvfz newbox-checklist.tgz
cd newbox-checklist
make install
make clean
cd ..
rm -rf newbox-checklist newbox-checklist.tgz
pkg_delete newbox-checklist-1.0

Do not be concerned if you see the following error:


$ sudo pkg_delete newbox-checklist-1.0>
pkg_delete: couldn't open dependency file /var/db/pkg/sudo-1.6.3.7_2/+REQUIRED_BY'

That is to be expected. This is the ports tree attempting to do the right thing.
We told the ports tree with our RUN_DEPENDS entry that sudo
was required by our port. But because we already had sudo installed before I ran
this port, this dependency is not registered with sudo.

Other uses for metaports

In this example, all that we have done with this port is install other ports.
But you an also use the ports tree for system administration. You could
distribute configuration files for example. A good template to use might be
misc/instant-workstation. This port installs
several ports, modifies /etc/rc.conf, and adds
/etc/ntp.conf, amongst other things.

11 thoughts on “And one port to install them all!”

  1. Dennis Kovarsky

    Just use an /stand/sysinstall’s unattended install script. If you specify your CDROM as the installation media and don’t install XFree86 – you get a brand new box in just over 5 minutes. Play around with the script, it ain’t all that bad if you have a huge cluster to roll out. 🙂 And yes, you can use DHCP if you wanted to…

    ——————————————————–
    debug=yes

    hostname=your.host.here
    domainname=your.domain
    nameserver=primary_dns_ip_here
    nameserver=secondary_dns_ip_here
    defaultrouter=your_gateway_ip_here
    ipaddr=your_ip_here
    netmask=your_netmask_here

    _ftpPath=ftp://ftp3.freebsd.org/pub/FreeBSD
    netDev=ed0
    mediaSetFTPActive

    dists=bin crypto
    distSetCustom

    disk=ad0
    partition=all
    bootManager=standart
    diskPartitionEditor
    ad0s1-1=ufs 204800 /
    ad0s1-2=swap 786432 none
    ad0s1-3=ufs 104857 /var 1
    ad0s1-4=ufs 0 /usr 1
    diskLabelEditor
    diskPartitionWrite
    diskLabelCommit

    installCommit

    command=mount -t msdos /dev/fd0 /mnt
    system
    command=cp /mnt/etc/rc.conf /etc
    system
    command=cp /mnt/etc/resolv.conf /etc
    system
    command=cp /mnt/etc/XF86Config /etc/X11
    system

    package=bash-2.05
    packageAdd
    package=XFree86-4.1.0_6
    packageAdd
    package=linux_base-6.1
    packageAdd
    package=linux-navigator-4.78
    packageAdd

    command=/usr/sbin/tzsetup
    system
    command=/usr/bin/passwd
    system
    command=pw user add -n new_username_here -d /usr/home/new_username_here -g wheel -L wheel -m -s /usr/local/bin/bash -w random
    | mail -s "new_username_here password" email_address_here
    system
    shutdown

    1. James A. Peltier

      I think the meta-port is a better option since chances are your ports directory will be more up-to-date than any of the files on the original CD. On a side note though this would be much quicker than compiling from ports

      1. James A. Peltier wrote:
        >
        > On a side note though this
        > would be much quicker than compiling from ports

        But the meta-port <I>does</I> compile from ports. The meta-port is just a short hand way of doing:

        is port x/y installed?
        no, cd /usr/ports/x/y && make install

        is port a/by installed?
        no, cd /usr/ports/a/b && make install

        etc.

    2. James A. Peltier

      can you have the script automatically run another script ie. if I install BIND 9.2.0 from the ports directory can I have it automatically run /usr/local/sbin/bind9-enable ??? same with qmail or anything else???

    3. Dennis Kovarsky

      Yes, you can have the script run another script/program. If you look at the bottom of it, that’s how a new user is created. You call command="you script here without the quotes" and then do a ‘system’ call. From man sysinstall:

      system Execute an arbitrary command with system(3)

      Variables:

      command
      The name of the command to execute.

  2. You wrote "I determined this path by inspecting /var/db/pkg/dnetc-2.8010.462_1,1/+CONTENTS. Because it starts with a /, the ports system will know this is the name of a file, not an executable. Therefore, it will not search your $PATH. " All files, even executable ones, have names that start with a / , for the ports system to "know" that files with such names are not executable may be some restriction placed on users of the ports system, but it is not an inherent condition of a UNIX-like system. Once a / is involved in the name of the first file on a command line, the PATH is not searched.

    1. Gerald Stoller wrote:
      >
      > You wrote "I determined this path by inspecting
      > /var/db/pkg/dnetc-2.8010.462_1,1/+CONTENTS. Because it starts
      > with a /, the ports system will know this is the name of a
      > file, not an executable. Therefore, it will not search your
      > $PATH. "

      Yes, I did write that.

      > All files, even executable ones, have names that
      > start with a / , for the ports system to "know" that files
      > with such names are not executable may be some restriction
      > placed on users of the ports system, but it is not an
      > inherent condition of a UNIX-like system.

      Note: I did not say system. I said "the ports system". I maintain my statement is correct. However, I did not state where I obtained this information. Sorry about that. The following extract is from /usr/ports/Mk/bsd.port.mk

      # FETCH_DEPENDS – A list of "path:dir[:target]" tuples of other ports this
      # package depends in the "fetch" stage. "path" is the
      # name of a file if it starts with a slash (/), an
      # executable otherwise. make will test for the
      # existence (if it is a full pathname) or search for
      # it in your $PATH (if it is an executable) and go
      # into "dir" to do a "make all install" if it’s not
      # found. If the third field ("target") exists, it will

      > Once a / is
      > involved in the name of the first file on a command line,
      > the PATH is not searched.

      I think we are talking about two different things here.

Leave a Comment

Scroll to Top