Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

[r10133]: branches / 8.0.4 / nanobsd / freenas-common Maximize Restore History

Download this file

freenas-common    788 lines (711 with data), 22.5 kB

#!/bin/sh
#-
# Copyright (c) 2010-2011 iXsystems, Inc., All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL iXsystems, Inc. OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# This file is heavily derived from both Sam Leffler's Avilia config,
# as well as the BSDRP project's config file.  Neither of these have
# an explicit copyright/license statement, but are implicitly BSDL.
#

#
# FreeNAS specific bits of the common stuff.
#

export NANO_CFG_BASE="$FREENAS_ROOT/nanobsd"
export NANO_MODULES="cxgb ext2fs geom ipmi smbfs libiconv libmchain syscons udf zfs opensolaris usb/xhci"
export NANO_SRC="$FREENAS_ROOT/FreeBSD/src"
export NANO_TOOLS="$FREENAS_ROOT/build/nanobsd"

if [ -n "${FREENAS_ARCH}" ]; then
    NANO_ARCH=${FREENAS_ARCH}
fi
case "$FREENAS_ARCH" in
amd64)
    NANO_ARCH_HUMANIZED="x64"
    ;;
i386)
    NANO_ARCH_HUMANIZED="x86"
    ;;
*)
    NANO_ARCH_HUMANIZED=$NANO_ARCH
    ;;
esac
# REVISION gets overloaded when doing tagged versions, SVNREVISION allows
# us to kleep the SVN revision number even when the version string is
# overloaded with a name.
: ${SVNREVISION=`svnversion ${NANO_CFG_BASE}`}
REVISION="8.0.4-BETA2"
NANO_NAME="FreeNAS-${REVISION}-${NANO_ARCH_HUMANIZED}"
NANO_IMGNAME="${NANO_NAME}"
NANO_KERNEL=${NANO_CFG_BASE}/FREENAS.${NANO_ARCH}
: ${NANO_OBJ=/tmp/${LOGNAME}/obj.freenas.${NANO_ARCH}}
NANO_LABEL=FreeNAS
NANO_BOOT0CFG="-o packet -s 1 -m 3 -t 18"

DEBUG="0"
MULTIMEDIA="0"
REPORTING="1"

# /var -> ~150MB (look through rc.initdiskless for the formula of how this
# number is calculated out).
# This is needed for samba as it drops a lot of files in /var/db/samba for
# locking purposes when transferring large collections of data (~100MB for
# ~4 TB in-flight data). I added overhead just in case, because when space
# can't be obtained for /var/db/samba, smbd and nmbd have a nasty habit of
# SIGABRTing and crashing, and this causes other applications to get unhappy
# (vi and friends ;(..).
#
# Set to a lower default for lower footprints with home usecases in FreeNAS.
NANO_RAM_TMPVARSIZE=327680

NANO_IMAGES=2
FlashDevice generic 2g

. ${NANO_CFG_BASE}/common

add_port converters/libiconv
add_port converters/iconv
add_port devel/gettext
add_port devel/pkg-config
add_port devel/libpthread-stubs WITHOUT_X11=y
add_port devel/cdialog
add_port dns/inadyn			# -mt?
#+editors/nano
add_port lang/perl5.12
#-editors/nano
add_port editors/nano
add_port ftp/proftpd
add_port net-mgmt/bsnmp-ucd
add_port net-mgmt/bsnmptools
add_port net-mgmt/clog
add_port net-mgmt/sipcalc
add_port net/istgt
add_port security/libgcrypt
add_port security/libgpg-error
add_port databases/db46
#+net/nss_ldap
add_port security/cyrus-sasl2
add_port net/openldap24-sasl-client
#-net/nss_ldap
add_port net/nss_ldap
add_port net/rsync WITHOUT_POPT_PORT=true WITH_SSH=true WITHOUT_ATIMES=true \
	WITH_ACL=true WITHOUT_ICONV=true WITHOUT_TIMELIMIT=true
add_port lang/python27 -DWITH_HUGE_STACK_SIZE
add_port dns/py-dnspython
#+net/samba
add_port devel/talloc
add_port devel/libexecinfo
add_port devel/popt
add_port databases/tdb
add_port sysutils/libsunacl
#-net/samba
add_port net/samba36	WITHOUT_CUPS=y WITH_LDAP=y WITH_ADS=y WITH_WINBIND=y \
			WITH_ACL_SUPPORT=y WITH_PAM_SMBPASS=y \
			WITH_AIO_SUPPORT=y WITH_EXP_MODULES=y
add_port security/pam_ldap
add_port security/pam_mkhomedir
add_port shells/bash WITHOUT_NLS=y
add_port shells/scponly
add_port sysutils/e2fsprogs
#+sysutils/fusefs-ntfs
add_port sysutils/fusefs-kmod
add_port sysutils/fusefs-libs
add_port devel/libublio
#-sysutils/fusefs-ntfs
add_port sysutils/fusefs-ntfs
add_port sysutils/ntfsprogs
add_port sysutils/smartmontools
#+emulators/open-vm-tools-nox11
add_port devel/pcre
add_port devel/glib20
add_port net/libdnet
#-emulators/open-vm-tools-nox11
add_port emulators/open-vm-tools-nox11 WITHOUT_ICU=y
add_port databases/sqlite3
add_port databases/py-sqlite3
add_port databases/py-bsddb3
add_port www/py-django WITHOUT_MYSQL=y
add_port www/py-dojango
#+databases/py-south
add_port devel/py-setuptools
#-databases/py-south
add_port databases/py-south
add_port devel/py-asn1
add_port devel/py-asn1-modules
#+add_port www/lighttpd
add_port www/spawn-fcgi
#-add_port www/lighttpd
add_port www/lighttpd
#+add_port www/py-flup
#-add_port www/py-flup
add_port www/py-flup
#+add_port sysutils/nut
#-add_port sysutils/nut
add_port net-mgmt/net-snmp
add_port sysutils/nut -DWITHOUT_NEON

add_port textproc/libxml2 WITHOUT_X11=y
add_port textproc/py-libxml2 WITHOUT_X11=y

add_port textproc/expat2 WITHOUT_X11=y
add_port devel/gamin WITHOUT_X11=y
add_port devel/gio-fam-backend WITHOUT_X11=y
add_port devel/m4 WITHOUT_X11=y
add_port devel/bison WITHOUT_X11=y
add_port devel/libffi WITHOUT_X11=y
add_port devel/gobject-introspection

if [ "${REPORTING}" = 1 -o "${MULTIMEDIA}" = 1 ]; then
add_port graphics/png WITHOUT_X11=y
fi

if [ "${REPORTING}" = 1 ]; then
#+add_port net-mgmt/collectd
add_port devel/libstatgrab WITHOUT_X11=y
add_port devel/libltdl WITHOUT_X11=y
add_port print/freetype2 WITHOUT_X11=y
add_port x11/kbproto
add_port x11/xproto WITHOUT_X11=y
add_port x11/libXdmcp WITHOUT_X11=y
add_port x11/libXau WITHOUT_X11=y
add_port x11/libxcb WITHOUT_X11=y
add_port x11/libX11
add_port x11-fonts/fontconfig WITHOUT_X11=y
add_port x11-fonts/libfontenc WITHOUT_X11=y
add_port x11-fonts/mkfontscale WITHOUT_X11=y
add_port x11-fonts/mkfontdir WITHOUT_X11=y
add_port x11-fonts/font-bh-ttf WITHOUT_X11=y
add_port x11-fonts/font-misc-meltho WITHOUT_X11=y
add_port x11-fonts/font-misc-ethiopic WITHOUT_X11=y
add_port x11-fonts/bitstream-vera WITHOUT_X11=y
add_port x11-fonts/font-util WITHOUT_X11=y
add_port x11-fonts/encodings WITHOUT_X11=y
add_port x11-fonts/xorg-fonts-truetype WITHOUT_X11=y
add_port x11/xcb-util WITHOUT_X11=y
add_port x11/libXrender
add_port x11/renderproto
add_port x11/xcb-proto WITHOUT_X11=y
add_port x11/pixman WITHOUT_X11=y
add_port graphics/png WITHOUT_X11=y
add_port graphics/cairo WITHOUT_X11=y
add_port x11-toolkits/pango WITHOUT_X11=y
add_port databases/rrdtool	WITHOUT_X11=y WITHOUT_PERL_MODULE=y \
				WITH_PYTHON_MODULE=y
add_port net/liboping WITHOUT_X11=y
#-add_port net-mgmt/collectd
add_port net-mgmt/collectd WITHOUT_BIND=y WITHOUT_SNMP=y WITHOUT_X11=y
fi
add_port devel/py-ipaddr
add_port converters/base64
add_port emulators/mtools WITHOUT_X11=y
add_port sysutils/arcconf
add_port sysutils/tw_cli
add_port sysutils/megacli
add_port net/py-ldap2 WITH_SASL=y
add_port sysutils/ataidle
add_port sysutils/gnome_subr
add_port devel/dbus WITHOUT_X11=y
add_port devel/dbus-glib WITHOUT_X11=y
add_port devel/libdaemon
add_port databases/gdbm
add_port net/avahi-app
add_port net/avahi-libdns
add_port textproc/py-xml
add_port sysutils/throttle
add_port sysutils/dmidecode
add_port devel/libevent
add_port sysutils/tmux
add_port net/netatalk WITH_PAM=y WITHOUT_APPLETALK=y
#+add_port ftp/wget
add_port dns/libidn
#-add_port ftp/wget
add_port ftp/wget
add_port benchmarks/iozone
add_port benchmarks/iperf
add_port benchmarks/netperf
#add_port security/nmap
add_port sysutils/ipmitool

if [ "${DEBUG}" = 1 -o "${MULTIMEDIA}" = 1 ]; then
	#+add_port devel/git || net-p2p/transmission-daemon
	add_port security/ca_root_nss WITH_ETCSYMLINK=y
	add_port ftp/curl
	#-add_port devel/git || net-p2p/transmission-daemon
fi

if [ "${MULTIMEDIA}" = 1 ]; then
	#+add_port audio/firefly || net/minidlna
	#add_port graphics/png WITHOUT_APNG=y
	#add_port devel/pkg-config
	add_port audio/libid3tag
	add_port audio/libogg
	add_port audio/libvorbis
	add_port audio/speex
	#-add_port audio/firefly || net/minidlna
	add_port audio/libao
	add_port audio/vorbis-tools
	add_port multimedia/libkate
	#add_port databases/sqlite3
	#-add_port audio/firefly || net/minidlna
	#+add_port net/minidlna
	#add_port converters/libiconv
	add_port multimedia/mp4v2
	add_port audio/faac
	add_port audio/flac
	add_port audio/lame
	#add_port databases/sqlite3
	add_port graphics/jpeg
	#add_port devel/gettext
	add_port graphics/libexif
	add_port audio/opencore-amr
	add_port graphics/opencv-core
	add_port multimedia/libtheora
	#add_port devel/yasm ?
	#add_port lang/perl5.12
	#add_port shells/bash
	add_port devel/orc
	add_port multimedia/schroedinger
	add_port multimedia/gpac-libgpac WITHOUT_OPENGL=y
	add_port multimedia/x264 WITHOUT_ASM=y
	add_port multimedia/xvid WITHOUT_OPTIMIZED_CFLAGS=y
	#add_port multimedia/libvpx
	add_port multimedia/ffmpeg	WITH_FAAC=y WITH_LAME=y WITH_SPEEX=y \
					WITHOUT_FFSERVER=y WITHOUT_FREETYPE=y \
					WITHOUT_VP8=y
	#-add_port net/minidlna
	add_port audio/firefly
	add_port net/minidlna
	#+add_port net-p2p/transmission-daemon
	#add_port devel/pkg-config
	add_port devel/libevent2
	add_port www/transmission-web
	#-add_port net-p2p/transmission-daemon
	add_port net-p2p/transmission-daemon
fi

if [ "${DEBUG}" -eq "1" ]; then 
	add_port databases/db42
	add_port devel/apr1
	add_port devel/py-logilab-common
	add_port devel/py-astng
	add_port devel/pylint
	add_port www/neon29
	add_port devel/subversion
	add_port editors/vim-lite
	add_port misc/py-pexpect
	add_port devel/ipython
	add_port devel/p5-Term-ReadKey
	add_port devel/p5-subversion
	add_port mail/p5-Net-SMTP-SSL
	add_port lang/p5-Error
	add_port devel/git -DWITH_SVN -DWITHOUT_P4 -DWITHOUT_CVS
	add_port devel/ctags 
fi

if [ "${NANO_PACKAGE_ONLY}" -eq 1 ]; then
 	CONF_INSTALL="${CONF_INSTALL}
${PKG_ONLY_MAKE_CONF}
"
	echo "Automatically building a thin image with packages"
else
	echo "Automatically building a * * F A T * * image so we can build ports"
fi

hack_nsswitch_conf ( )
{
	# Neuter out all references to NIS in the nsswitch.conf file
	sed -i.bak -es/nis/files/g ${NANO_WORLDDIR}/etc/nsswitch.conf
	rm -f ${NANO_WORLDDIR}/etc/nsswitch.conf.bak
}
customize_cmd hack_nsswitch_conf

add_gui()
{
    local gui dst dstCR;
    gui=${NANO_CFG_BASE}/../gui
    dstCR=/usr/local/www/freenasUI
    dst=${NANO_WORLDDIR}${dstCR}
    if [ -d ${gui} ]; then
	pprint 2 "Adding freenas web gui"
	mkdir ${dst}
	( cd ${gui}
	  find . -print | grep -Ev '/(CVS|\.svn)' | cpio -R root:wheel -dumpv ${dst} )
	pprint 2 "Making freenas initial database"
	mkdir ${NANO_WORLDDIR}/data
	CR "(cd ${dstCR}; python manage.py syncdb --noinput --migrate)"
	CR "(cd ${dstCR}; python manage.py createadmin --email root@freenas.local)"
	CR "(cd ${dstCR}; python manage.py compilemessages)"
	CR "(cd /data; cp freenas-v1.db factory-v1.db)"
	CR "ln -sf /etc/local_settings.py ${dstCR}/local_settings.py"
	CR "chown -R www:www ${dstCR} data"
    else
        pprint 2 "GUI OMITTED from image"
    fi
}
customize_cmd add_gui

# Move the $world/data to the /data partion
move_data()
{
	set -x
	db=${NANO_WORLDDIR}/data
	rm -rf ${NANO_DATADIR}
	mkdir -p ${NANO_DATADIR}
	( cd ${db} ; find . | cpio -R root:wheel -dumpv ${NANO_DATADIR} )
	rm -rf ${db}
}
customize_cmd move_data

add_data_to_fstab ( )
{
	(
	cd ${NANO_WORLDDIR}
	echo "/dev/${NANO_DRIVE}s4 /data ufs rw,noatime 2 2" >> etc/fstab
	mkdir -p data
	)
	
}
customize_cmd add_data_to_fstab

afpd_conf_symlink ( )
{
	ln -sfh /etc/afpd.conf ${NANO_WORLDDIR}/usr/local/etc/afpd.conf
}
customize_cmd afpd_conf_symlink

select_httpd ( )
{
	echo "lighttpd_enable=YES" >> ${NANO_WORLDDIR}/etc/rc.conf
}
customize_cmd select_httpd

remove_patch_divots ( )
{
	find ${NANO_WORLDDIR} -name \*.orig -delete
}
customize_cmd remove_patch_divots

configure_mnt_md ( )
{
	mkdir -p ${NANO_WORLDDIR}/conf/base/mnt
	echo 2048 > ${NANO_WORLDDIR}/conf/base/mnt/md_size
}
customize_cmd configure_mnt_md

shrink_md_fbsize()
{
	# We have a lot of little files on our memory disks. Let's decrease
	# the block and frag size to fit more little files on them (this
	# halves our space requirement by ~50% on /etc and /var on 8.x --
	# and gives us more back on 9.x as the default block and frag size
	# are 4 times larger).
	sed -i '' -e 's,-S -i 4096,-S -i 4096 -b 4096 -f 512,' \
	    ${NANO_WORLDDIR}/etc/rc.initdiskless
}
customize_cmd shrink_md_fbsize

performance_sanity_caps()
{
	local arc_max_in_mb kmem_size nmbclusters

	# For FreeNAS, there are a wide variety of heterogenous configs.
	# Bottom line is that these are meant to be safe defaults s.t.
	# FreeBSD doesn't overcommit memory without excessive prodding
	# from the end-user.
	#
	# DISCLAIMER: These settings are not a free pass for running on
	# platforms that do not meet the conditions listed on the FreeNAS
	# system requirements page!!!
	(

	echo
	echo "# System defaults for $NANO_LABEL ($FREENAS_ARCH)"
	echo

	# MBUF cluster defaults.
	case "$FREENAS_ARCH" in
	amd64)
		nmbclusters=50000
		;;
	i386)
		nmbclusters=25000
		;;
	esac
	echo "kern.ipc.nmbclusters=\"$nmbclusters\""

	# ZFS defaults.
	case "$FREENAS_ARCH" in
	amd64)
		arc_max_in_mb=1024
		;;
	i386)
		arc_max_in_mb=256
		;;
	esac
	echo "vfs.zfs.arc_max=\"$(( $arc_max_in_mb * 1024 * 1024 ))\""

	case "$FREENAS_ARCH" in
	amd64)
		kmem_size=1024
		;;
	i386)
		kmem_size=348
		;;
	esac
	echo "vm.kmem_size=\"${kmem_size}M\""
	echo "vm.kmem_size_max=\"${kmem_size}M\""

	) >> ${NANO_WORLDDIR}/boot/loader.conf
}
customize_cmd performance_sanity_caps

save_build ( )
{
	if [ "${SVNREVISION}" = "${REVISION}" ]; then
		echo "${NANO_NAME}" > ${NANO_WORLDDIR}/etc/version.freenas
	else
		echo "${NANO_NAME} (${SVNREVISION})" > ${NANO_WORLDDIR}/etc/version.freenas
	fi
}
customize_cmd save_build

if [ "${DEBUG}" = 1 ]; then

unmute_console_logging()
{
	# /var is small. Don't fill it up with messages from console.log
	# because it's a chatty log.
	sed -i '' -e 's/#console.info/console.info/' \
		     "${NANO_WORLDDIR}/etc/syslog.conf"
}
customize_cmd unmute_console_logging

else

remove_perl()
{
	# Perl seems to be needed for build, but nothing after the
	# build.  cope with bad dependencies (or misunderstood) and
	# blow it away (saves 45MB)
	CR "/usr/sbin/pkg_delete -f /var/db/pkg/perl* || :"
}
customize_cmd remove_perl

fi

remove_var_db_pkg()
{
	# Eats up ~7 MB on the install image.
	rm -Rf ${NANO_WORLDDIR}/var/db/pkg
}
customize_cmd remove_var_db_pkg

fix_fuse_module_location()
{
	local bad_modules_dir

	# fuse.ko, et all gets installed into the wrong spot.
	bad_modules_dir=${NANO_WORLDDIR}/usr/local/modules

	tar -cf - -C "$bad_modules_dir" . | \
	    tar -xpvf - -C ${NANO_WORLDDIR}/boot/kernel/.
	rm -Rf "$bad_modules_dir"
}
customize_cmd fix_fuse_module_location

if [ "$MULTIMEDIA" = 1 ]; then
minidlna_hacks()
{
	# Port installs the user; package doesn't appear to.
	CR "id dlna || pw useradd dlna -d /var/empty -s /sbin/nologin"
	cat >> ${NANO_WORLDDIR}/etc/rc.conf <<EOF

minidlna_enable="NO"
minidlna_flags="-f /mnt/tank/home/myuser/minidlna.conf"
EOF
	# XXX: minidlna requires a UID, not a username for the -u option
	#      (script rc.d bug). That being said, it still doesn't start with
	#      the dlna user *grump*. Run as root for the super insecure win!
	# XXX: Make sure the database is rebuilt every time it's restarted.
	# TODO: implement directory watch via kqueues in minidlna.
	# XXX: remove check for /var/db directory to avoid having to rewrite
	#      minidlna's rc.d script.
	sed -i '' \
	    -e 's/-"dlna"}/-$(id -u "root")}/' \
	    -e 's/\(command_args="-P $pidfile.*\)"/\1 -R"/g' \
	    -e '/^required_dirs/d' \
	    ${NANO_WORLDDIR}/usr/local/etc/rc.d/minidlna
	cat > "${NANO_WORLDDIR}/usr/local/etc/minidlna.conf" <<EOF
port=8200
# GC: Look for everything (audio, pictures, video) in this directory.
#media_dir=/mnt/tank/home/myuser
# GC: Just audio
#media_dir=A,/mnt/tank/home/myuser
# GC: Just pictures
#media_dir=P,/mnt/tank/home/myuser
# GC: Just video
#media_dir=V,/mnt/tank/home/myuser
# GC: might want to change this.
friendly_name=freenas
# GC: change this
db_dir=/mnt/tank/home/myuser/var/db/minidlna
album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg/AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg/Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg
inotify=no
enable_tivo=no
strict_dlna=no
notify_interval=300
# You might want to change the following if you have more than one NAS box.
serial=12345678
model_number=1
EOF

}
customize_cmd minidlna_hacks

firefly_hacks()
{
	# Port installs the user; package doesn't appear to.
	CR "id daapd || pw useradd daapd -d /var/empty -s /sbin/nologin"
	cat >> ${NANO_WORLDDIR}/etc/rc.conf <<EOF

firefly_enable="NO"
firefly_flags="-c /mnt/tank/home/myuser/mt-daapd.conf"
EOF
	# XXX: --prefix bug in port; just omit the db directory check to avoid
	# having to re-edit the script after a reboot.
	sed -i '' -e '/^required_dirs/d' \
	    ${NANO_WORLDDIR}/usr/local/etc/rc.d/mt-daapd
	cat > ${NANO_WORLDDIR}/usr/local/etc/mt-daapd.conf <<EOF
[general]
web_root = /usr/local/share/mt-daapd/admin-root
port = 3689
admin_pw = mt-daapd
db_type = sqlite3
# GC: change this
db_parms = /mnt/tank/myuser/var/db/firefly
# GC: change this
#mp3_dir = /mnt/tank/myuser
# GC: might want to change this.
servername = FreeNAS %v on %h
runas = daapd
# Set this if you want to have password access to your share.
#password = password
extensions = .mp3,.m4a,.m4p,.ogg,.flac
ssc_codectypes = ogg,flac,alac
ssc_prog = /usr/local/bin/mt-daapd-ssc.sh
logfile = /var/log/mt-daapd.log
debuglevel = 5  
rescan_interval = 300
always_scan = 0
scan_type = 0
compress = 1

[plugins]
plugin_dir = /usr/local/lib/mt-daapd/plugins

[scanning]
process_playlists = 1
process_itunes = 1
process_m3u = 1
EOF
}
customize_cmd firefly_hacks

transmission_hacks()
{
	# Port installs the user; package doesn't appear to.
	CR "id transmission || pw useradd transmission -d /var/empty -s /sbin/nologin"
	cat >> ${NANO_WORLDDIR}/etc/rc.conf <<EOF

transmission_enable="NO"
transmission_watch_dir=""
transmission_download_dir=""
transmission_user="myuser"
EOF
	# No comments for JSON ;(..
	cat >> ${NANO_WORLDDIR}/usr/local/etc/transmission/home/settings.json <<EOF
{
    "alt-speed-down": 50,
    "alt-speed-enabled": false,
    "alt-speed-time-begin": 540,
    "alt-speed-time-day": 127,
    "alt-speed-time-enabled": false,
    "alt-speed-time-end": 1020,
    "alt-speed-up": 50,
    "bind-address-ipv4": "0.0.0.0",
    "bind-address-ipv6": "::",
    "blocklist-enabled": false,
    "blocklist-url": "http://www.example.com/blocklist",
    "cache-size-mb": 4,
    "dht-enabled": true,
    "download-dir": "/mnt/tank/home/myuser/transmission/complete",
    "encryption": 1,
    "idle-seeding-limit": 30,
    "idle-seeding-limit-enabled": false,
    "incomplete-dir": "/mnt/tank/home/myuser/transmission/incomplete",
    "incomplete-dir-enabled": true,
    "lpd-enabled": false,
    "message-level": 2,
    "peer-congestion-algorithm": "",
    "peer-limit-global": 240,
    "peer-limit-per-torrent": 60,
    "peer-port": 51413,
    "peer-port-random-high": 65535,
    "peer-port-random-low": 49152,
    "peer-port-random-on-start": false,
    "peer-socket-tos": "default",
    "pex-enabled": true,
    "port-forwarding-enabled": true,
    "preallocation": 1,
    "prefetch-enabled": 1,
    "ratio-limit": 2,
    "ratio-limit-enabled": false,
    "rename-partial-files": true,
    "rpc-authentication-required": false,
    "rpc-bind-address": "0.0.0.0",
    "rpc-enabled": false,
    "rpc-password": "{83ea26654a4e4ffa421cc53e5cc9fd3394d8412cX46GA39K",
    "rpc-port": 9091,
    "rpc-url": "/transmission/",
    "rpc-username": "",
    "rpc-whitelist": "127.0.0.1,192.168.*.*",
    "rpc-whitelist-enabled": true,
    "script-torrent-done-enabled": false,
    "script-torrent-done-filename": "",
    "speed-limit-down": 100,
    "speed-limit-down-enabled": false,
    "speed-limit-up": 100,
    "speed-limit-up-enabled": false,
    "start-added-torrents": true,
    "trash-original-torrent-files": false,
    "umask": 18,
    "upload-slots-per-torrent": 14,
    "utp-enabled": true
}
EOF
}
customize_cmd transmission_hacks
fi

fix_easy_install_pth()
{
	local site_packages

	site_packages="$NANO_WORLDDIR/usr/local/lib/$PYTHON_DEFAULT_VERSION/site-packages"

	env PYTHONPATH=$site_packages \
	    python ${FREENAS_ROOT}/tools/sanitize_pth.py -f \
	    $site_packages
}
customize_cmd fix_easy_install_pth

create_var_home_symlink()
{
	# Create a link to a non-persistent location that ix-activedirectory
	# and ix-ldap can use as a pointer to a home directory on persistent
	# storage (/mnt/tank/homes, etc).
	rm -f $NANO_WORLDDIR/home || :
	rm -Rf $NANO_WORLDDIR/home
	ln -sfh /var/home $NANO_WORLDDIR/home
}
customize_cmd create_var_home_symlink

if $do_image; then
last_orders() {
	local cd_image_log
	local full_image full_image_log
	local gui_upgrade gui_upgrade_image_log

	cd_image_log="${MAKEOBJDIRPREFIX}/_.cd_iso"
	full_image_log="${MAKEOBJDIRPREFIX}/_.full_image"
	gui_image_log="${MAKEOBJDIRPREFIX}/_.gui_image"

	full_image="$NANO_DISKIMGDIR/$NANO_IMGNAME.Full_Install.img"
	gui_upgrade="$NANO_DISKIMGDIR/$NANO_IMGNAME.GUI_Upgrade"

	if $do_image && $do_copyout_partition; then

		pprint 2 "Compressing GUI upgrade image"
		pprint 3 "log: ${gui_image_log}"

		(

		# NOTE: keep in synch with create_*_diskimage.
		mv "$NANO_DISKIMGDIR/_.disk.image" "$gui_upgrade"
		xz --verbose -9 -f "$gui_upgrade"

		) > "${gui_image_log}" 2>&1

	fi

	if $do_image; then

		pprint 2 "Compressing full disk image"
		pprint 3 "log: ${full_image_log}"

		(

		# NOTE: keep in synch with create_iso.sh.
		mv "$NANO_DISKIMGDIR/$NANO_IMGNAME" "$full_image"
		xz --verbose -9 -f "$full_image"

		) > "${full_image_log}" 2>&1

		pprint 2 "Creating ISO image"
		pprint 3 "log: ${cd_image_log}"

		(

		sh "$FREENAS_ROOT/build/create_iso.sh"

		) > "${cd_image_log}" 2>&1

	fi

}
fi # $do_image