Creating custom pkgng repository for FreeBSD

pkg is a utility for installing binary packages in FreeBSD. But to install non-default options not selected by the packager/maintainer across multiple servers, use the ports to roll out custom packages. Creating custom package is very easy. There are only small changes compared to creating packages for the old pkg_* toolset.

mkdir -p /usr/ports/packages/All
make package-recursive install

Note that install keyword has been used, because new pkgng does not install the main port while creating the package. It will install all dependent ports though. Once packages are created, copy all of them to a staging directory:

cp /usr/ports/packages/All/* .

Alternatively, if the ports are already installed, create packages using:

pkg create -a

This will create packages for all installed ports in the current directory.

Once all the packages are in current directory, run pkg repo command to create repo files:

pkg repo .

Current directory now contains all the files to host custom repository :). Move it to some publicly accessible place which is reachable by target computers. Use of directory under a web server makes it easier. For more control over repository creation and how packages are created, see poudriere and tinderbox

On the target computers to use this repository, make a few changes. Disable the base FreeBSD repository:

mkdir -p /usr/local/etc/pkg/repos
echo "FreeBSD: { enabled: no }" > /usr/local/etc/pkg/repos/FreeBSD.conf

Now make the new repository active

echo 'REPONAME: { url: "http://REPO_URL"}' > /usr/local/etc/pkg/repos/REPONAME.conf
pkg upgrade

There are tons of options for the conf files, and also how to use multiple repositories with priorities, but those are beyond the scope this article. Consult man pages for pkg-repository and pkg.conf for more details.

Custom repository is now ready for use.

Please note that anything related to PACKAGESITE is no longer valid for the new versions of pkgng .

Advertisements

Installing Subversion server on FreeBSD using svnserve

There are lots of guides on net that help you out on installing subversion server on FreeBSD, but most of them describe installing subversion server with Apache and mod_dav. Apache is used to access your subversion repository using http or https. But this becomes a problem if you are using one of the alternate servers (nginx ot lighttpd), or would not like to install any web server. In that case, it is much easier to use “svnserve” daemon to access the repository. This is how I went about doing it after updating my ports tree:

cd /usr/ports/devel/subversion; make -DBATCH all install clean
or alternatively use the new pkgng ( to install binaries.Search for the right package using
pkg search subversion
and then install the latest version(1.8.5 as on date) available using
pkg install subversion-1.8.5
Using binary packages is far easier and faster, but you loose the flexibility of ports. You can also install subversion through the older pkg_add tools if it’s still supported in your release.

Once you have installed the subversion through either of the methods, create a user for svn:
pw groupadd svn; pw adduser svn -g svn -s /usr/sbin/nologin
Create a home directory for all repository:
mkdir -p /usr/home/svn/repos; chown -R svn:svn /usr/home/svn
Add entries in /etc/rc.conf to run svnserve daemon on startup
echo 'svnserve_enable="YES"' >> /etc/rc.conf ; echo 'svnserve_data="/usr/home/svn/repos"' >> /etc/rc.conf
Now start the svnserve daemon either by
service svnserve start
or by
/usr/local/etc/rc.d/svnserve start
Check if svnserve is running by
sockstat |grep svnserve
If it is running on port 3690, you have successfully installed subversion and is accessible through the svnserve daemon.

Now create the repositories in svn. Remember, each repository has its own configuration and access control. Once you create a repository using
svnadmin create /usr/home/svn/repos/myfirstrepo
the newly created repository is now located at /usr/home/svn/repos/myfirstrepo. You will need to modify three files for the repository to be accessible for you. Under /usr/home/svn/repos/myfirstrepo/conf, you will find authz, passwd & svnserve.conf files. In passwd file, create username and password in the following syntax:
username = password. Place each user in a new line. In the authz file, the simplest way is to set the access control for the repository itself, although there are a lot of combinations available for access control. I simply use this:
[/]
username = rw

You can use r for read access, w for write access and blank for no access. For the svnserve.conf file, under the [general] section, set the following three lines:
anon-access = none
auth-access = read
auth-access = write

This should replace any existing similar values.

You should now be ready to access the repository from a svn client. Just remember that you need to access the repository using svn:///myfirstrepo scheme. Hope it works out for you as well.

Cheers

Installing Freeswitch on FreeBSD 9

[This is a work in progress article. There can be changes or additions to this article in the near future.]

Freeswitch port on Freebsd is at 1.0.6 while the current version of Freeswitch is on 1.3.x . The devel port for Freeswitch does not compile on FreeBSD 9.1 at the moment. Instructions at Freeswitch site does not work cleanly for the current version of FreeBSD (9.1). It requires tweaking in the script/code to get it working correctly. Also, make sure that you have “source” selected while installing FreeBSD, otherwise DAHDI kernel module with fail to build.

First step is to install all the required dependencies using ports. FreeBSD 9.1 does not have pre-built packages because of the security breach found during the end quarter of 2012.

# portsnap fetch extract
# mkdir -p /usr/ports/packages/All

The reason I have created a packages/All directory is because I like to keep all the packages pre-built with me to save time on subsequent installations. Most of the ports can be left to their default configurations. One port that needs extra settings is Perl. In the config dialog box for perl, make sure to select multithreading and mulitplicity if you need mod_perl module enabled in Freeswitch.

# cd /usr/ports/lang/perl5.14
# make config
# make config-recursive
# make package-recursive clean

Install all the other ports in batch mode. If you are not interested in making packages, you can instead use

make all install clean

instead in the above command as well as all the commands that follow. I also needed access to Postgresql database from Freeswitch/mod_perl, for which certain modules are required to be installed. These are optional if you do not need mod_perl and/or Postgresql connectivity.

# cd /usr/ports/databases/postgresql92-client; make -DBATCH package-recursive clean
cd /usr/ports/databases/unixODBC; make -DBATCH package-recursive clean
# cd /usr/ports/databases/p5-DBI; make -DBATCH package-recursive clean
# cd /usr/ports/databases/p5-DBD-Pg; make -DBATCH package-recursive clean
# cd /usr/ports/net/p5-URI; make -DBATCH package-recursive clean

The dependency list is mentioned on the Freeswitch website:

# cd /usr/ports/devel/autoconf; make -DBATCH package-recursive clean
# cd /usr/ports/lang/gcc34; make -DBATCH package-recursive clean
# cd /usr/ports/devel/automake; make -DBATCH package-recursive clean
# cd /usr/ports/devel/git; make -DBATCH package-recursive clean
# cd /usr/ports/devel/libtool; make -DBATCH package-recursive clean
# cd /usr/ports/devel/ncurses; make -DBATCH package-recursive clean
# cd /usr/ports/ftp/wget; make -DBATCH package-recursive clean
# cd /usr/ports/devel/pkgconf; make -DBATCH package-recursive clean
# cd /usr/ports/graphics/tiff; make -DBATCH package-recursive clean

Install libpri and dahdi-kmod (installs dahdi as dependency). If you are making packages, you need to modify the Makefile for dahdi-kmod26 located in /usr/ports/misc/dahdi-kmod26. Comment out line number 47 which says “NO_PACKAGE= Should be in sync with the kernel to work correctly

# cd /usr/ports/misc/libpri; make -DBATCH package-recursive clean
# cd /usr/ports/misc/dahdi-dmod26; make -DBATCH package-recursive clean
# echo 'dahdi_enable="YES"' >> /etc/rc.conf
# echo 'dahdi_module="{MODULE_NAME}"' >> /etc/rc.conf

Replace the module name with the appropriate module for your card. For a list of modules, see this page. At the moment, support is only available for Digium cards on FreeBSD. If anybody knows how to configure Sangoma or other cards, I would love to hear about it.

Download Freeswitch from git repository:

# cd /usr/src
# /usr/local/bin/git clone git://git.freeswitch.org/freeswitch.git freeswitch-upstream
# cd freeswitch-upstream
# ./bootstrap.sh

Once the bootstrap process completes, move into spandsp directory.

# cd libs/spandsp

Edit the spandsp configure file and comment out the following code

for ac_header in tgmath.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "tgmath.h" "ac_cv_header_tgmath_h" "$ac_includes_default"
if test "x$ac_cv_header_tgmath_h" = xyes; then :
cat >>confdefs.h < <_ACEOF
#define HAVE_TGMATH_H 1
_ACEOF
INSERT_TGMATH_HEADER="#include "
fi

done

Once you are done with the changes, configure and install spandsp module. Also, freetdm needs to be configured with libpri enabled. Make sure that you use gmake as bsd make would not work for compiling spandsp and freeswtich

# setenv LDFLAGS -L/usr/local/lib
# setenv CPPFLAGS -I/usr/local/include
# ./configure; gmake install; cd ..
# cd freetdm; ./configure --with-libpri --prefix=/usr/local/freeswitch; gmake
# ./configure; gmake install samples sounds-install moh-install hd-sounds-install hd-moh-install

spandsp libs will be installed in /usr/local/libs while freeswitch and freetdm would be installed in /usr/local/freeswitch and /usr/local/freetdm respectively.

References:
(1) Freeswitch installation Guide
(2) FreeBSD Forums

Adding additional ip addresses in FreeBSD – Alternate methods

Traditional way of adding additional ip address in FreeBSD has been to add entries in /etc/rc.conf:

ifconfig_em0_alias0="inet 10.1.30.15 netmask 255.255.255.255"
ifconfig_em0_alias1="inet 10.5.30.16 netmask 255.255.255.255"
ifconfig_em0_alias2="inet 192.168.1.10 netmask 255.255.255.255"
ifconfig_em0_alias3="inet 10.1.30.245 netmask 255.255.255.255"

This works nicely, but the problem lies in the fact that if you miss the numbering in alias, subsequent aliases will not be read by the system. So a listing like

ifconfig_em0_alias0="inet 10.1.30.15 netmask 255.255.255.255"
ifconfig_em0_alias1="inet 10.5.30.16 netmask 255.255.255.255"
ifconfig_em0_alias3="inet 10.1.30.245 netmask 255.255.255.255"

will lead to the last alias ‘10.1.30.245’ to be not read/set by the OS. There exists an alternate way to set up additional ip address which does not include numbering of aliases. All you need to do is create a file /etc/start_if.<interface>, where <interface> is the name of the network interface you want to bind the aliases to. So for example you have an interface em0, the file that needs to be created is /etc/start_if.em0. This file is a shell script (bourne shell) file where you can call the ifconfig command to add the aliases to your nic. An example file could be:

#!/bin/sh
/sbin/ifconfig em0 alias 10.1.50.15 netmask 255.255.255.255
/sbin/ifconfig em0 alias 10.5.30.16 netmask 255.255.255.255
/sbin/ifconfig em0 alias 192.168.1.10 netmask 255.255.255.255
/sbin/ifconfig em0 alias 10.1.30.245 netmask 255.255.255.255

Since this is a standard shell script, you will be able to all sorts of scripting inside (Not tested though, apart from placing comments using # sign). This allows for better administration and scripting for aliases.

There exists another way to set aliases, though I haven’t tested them myself. This goes into /etc/rc.conf file and lets you easily add groups of ip address at a time:

ipv4_addrs_em0="192.168.1.10/32 10.1.30.0/27 10.1.30.245/32"

Partition automation in bsdinstall auto script in FreeBSD

[This post is part of the bsdinstall automation series. It should be read with the main article posted @ http://www.amitabhkant.com/custom_iso_with_bsdinstall_in_freebsd/]

These lines should go out in the bsdinstall auto file, after commenting out bsdinstall autopart and bsdinstall mount section. Remember, this would wipe out the entire disk contents without any warning, so use it at your own risk. I am also assuming that if you have multiple disks connected, the first disk is what you want to install your OS on. Otherwise, you might have to modify the script accordingly.

Get the disk layout, and the first disk connected to the system
# disk_layout=`sysctl -n kern.disks`
# first_disk=${disk_layout%% *}

Destroy any existing partition, and then create a gpt partition
# gpart destroy -F $first_disk
# gpart create -s gpt $first_disk

Create a boot partition to hold the loader, size of 512K. Give it a GPT label of gpboot, which will show up in /dev/gpt when the device is discovered:
# gpart add -t freebsd-boot -l gpboot -b 40 -s 512K $first_disk

Install the GPT bootcode into the boot partition:
# gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 $first_disk

Create a swap parition
# gpart add -t freebsd-swap -l gpswap -s 4G $first_disk

Create a partition for /. It should start at the 1M boundary for proper sector alignment on 4K sector drives or SSDs. This is compatible with GPT drive layout for many other systems. Give it a GPT label of gprootfs.
# gpart add -t freebsd-ufs -l gprootfs -a 1M $first_disk

Format the root partition
# newfs -U /dev/gpt/gprootfs

Mount the partition at /mnt
# mount /dev/gpt/gprootfs /mnt

Add entry to fstab ($PATH_FSTAB)
# echo '# Device Mountpoint FStype Options Dump Pass#' > $PATH_FSTAB
# echo '/dev/gpt/gpswap none swap sw 0 0' >> $PATH_FSTAB
# echo '/dev/gpt/gprootfs / ufs rw 1 1' >> $PATH_FSTAB

(1) Although the post is meant as part of automating bsdinstall, the concept could be used to create partitions over a new disk with appropriate safeguards

Adding new disk in FreeBSD

Check if the disks are being detected. There are multiple ways to do it, but the most simplest is to check a sysctl variable.
# sysctl kern.disks

Disk types are displayed in the following format: SAS & SCSI are designated “da” while IDE & SATA (including SSD) drives are “ada“. Disk types are followed by numbers, i.e. da0, ada0, ada1 etc. To check which disks are being used currently, use “df -h” command. It should list out all the currently used disks.

Once you have determined which disk you need to attach, use the following commands. The examples below assume the disk to be configured is at ada1. Change it as per your configuration.
Re-initialize the disk with all zero’s
# dd if=/dev/zero of=/dev/ada1 bs=1k count=2
Label the disk. If you use auto parameter, the disk would be labeled from a, i.e. ada1a
# bsdlabel -Bw ada1 auto
Format the new parition
# newfs /dev/ada1a
Create the directory where you would like to mount the new disk / partition
# mkdir -p /usr/local/disk2
To mount the disk temporarily
# mount /dev/ada1a /usr/local/disk2

For auto mounting the disk across reboot, make the following entries in your “/etc/fstab” file
/dev/ada1a /usr/local/disk2 ufs rw 2 2

Keep in mind that these disks will not be readable by any other os’s (Windows). To make the disks compatible with other os, you need to create a slice before labeling it. Also, the above code has been tested in FreeBSD 9.0, earlier versions might differ in commands or outputs.

Scripting bsdinstall in FreeBSD 9.0 for custom installation CD

Starting with FreeBSD 9.0, the default installer for FreeBSD has changed from sysinstall to bsdinstall. While there has been mixed reactions from old time users, the process of creating a custom install CD for FreeBSD has become a lot easier (although longer). bsdinstall uses a set of shell scripts which can be modified as per requirements.

First step is to install a fresh 9.0 RELEASE, and select the src to be installed along with the base system. Once the system with source is installed (by default /usr/src) execute the following commands

# cd /usr/src
# make buildworld buildkernel

Installation scripts are located at /usr/src/usr.sbin/bsdinstall/scripts/ . First file to run is ‘auto’, which then calls other files. Almost all of them are shell scripts. Remember, you do not need to repeat ‘make buildworld buildkernel’ if you are just making changes to the install script file.

# cd /usr/src/release
# make release

Once the release has been built we now copy the iso / usb image / ftp files to the desired directory

# make install DESTDIR=/usr/freebsd-snapshot clean

This creates the iso file, memory stick image and ftp folder for ftp install. In case you are wondering how to use the memory stick image, see this blog post:
http://koitsu.wordpress.com/2009/11/03/writing-freebsd-memstick-img-to-a-usb-drive-in-windows/

Cheers
Amitabh

Port conflict between p5-Mail-SPF-Query and p5-Mail-SPF while installing Maia port in FreeBSD

If you are trying to install Maia or any other port which depends upon p5-Mail-SPF-Query, and your server already has p5-Mail-SPF installed, you will not be allowed to do so as both install files at the same location. You would be receiving errors like:

usr/ports/mail/p5-Mail-SPF-Query

===>  p5-Mail-SPF-Query-1.999.1 conflicts with installed package(s): 
      p5-Mail-SPF-2.007

According to this post at FreeBSD forums, p5-Mail-SPF should be preferred. An easy way to do is to edit the Makefile of the port (in my case it’s Maia) to replace the dependency line. Edit /usr/ports/security/maia/Makefile (replace path based on your port) in your favorite editor and search for

.if defined(WITH_SPFQUERY)
RUN_DEPENDS+=   ${SITE_PERL}/Mail/SPF/Query.pm:${PORTSDIR}/mail/p5-Mail-SPF-Query
.endif

and replace it with

.if defined(WITH_SPFQUERY)
RUN_DEPENDS+=   ${SITE_PERL}/Mail/SPF/Query.pm:${PORTSDIR}/mail/p5-Mail-SPF
.endif

That should be it unless you have some other conflicts in your package.

Amitabh Kant

Updating Apache22 from ports in FreeBSD 8.0

If you are trying to update apache22 from ports in FreeBSD 8.0, keep in mind that is now links to apr from devel/apr1 and not devel/apr . The simplest way out is to delete the apache22 port, then install/upgrade the devel/apr1 port and then re-install the apache22 port. For more info, look at /usr/ports/UPDATING file.

Amitabh