Time-stamp: <2019-09-01 01:32:29 (bm3719)>
#+STARTUP: content

This setup procedure is a bit specific to hardware and use cases of my
machine(s).  I had to create this in order to get the exact setup I wanted,
so I've made it public in case others find it useful.  It does rely on
various external documents, shell scripts, and portable source installs
which don't appear here.  My current primary workstation is an Intel NUC
8i3BEK, the laptop is a ThinkPad x230, and VMs are in VMware Player.

I'll try to update it as needed for each release, but since I normally do
source upgrades and this document is more about a clean install/migration, some
parts of will only be updated when I do a new install from scratch.  Since I
know some people reference this document (particularly if stuck on something),
I try to keep it clean and free of errors.  If you're one of those people, I'd
stress how helpful it is to read the FreeBSD Handbook at least once, then keep
it handy as a reference.

* Setup procedure for FreeBSD 12.0-RELEASE
** Pre-install
*** back up current system
- Clean up any large files laying around user directories to speed up data
  migration.
- Run =make clean= or equivalent on any personal project directories.
- Run rsync scripts to backup all user and system data to smb share.  If this
  is my primary workstation, be sure to grab:
  - /home
  - /root
  - /boot
  - /etc
  - /usr/local/etc
  - System website directories like /usr/local/www/cgi-bin and
    /usr/local/www/nginx (though the latter should be under VCS).
- Backup databases.
** Install
*** memstick image
- Get the ISO or memstick image from:
  https://download.freebsd.org/ftp/releases/amd64/amd64/ISO-IMAGES/12.0/
- For memstick installs, put in USB drive and check dmesg to make sure it's
  deviced at da0.
- Image drive with something like:

  dd if=FreeBSD-12.0-RELEASE-amd64-memstick.img of=/dev/da0 bs=4096 conv=sync
*** prepare VM config (VMs only)
Some VMware guest configuration:
- Allocate at least 30GB of space.
- Use bridged networking.  VMware NAT used to work, but like with current
  OpenBSD, seems not to as of 12.0.
- Allocate >=2GB RAM.
*** install OS
On the workstation, use F2 to enter BIOS setup and F10 to select boot media.
On the laptop hit Enter when prompted for BIOS, F10 for hardware tests, and F12
for boot selection.

On the Intel NUC, the first time boot will require Secure Boot to be disabled
in the BIOS.  It's in one of the sub-menus under the Boot section.

Run through the standard setup:
- Choose default keyboard layout.
- Set hostname.
- Distributions: lib32, src, ports (doc, base and kernel are auto-included
  now).
- Partitioning: Do manual/expert setup, or ZFS (auto).
- Partition Editor (non-ZFS):
  - Delete any previous partitions.
  - Use entire disk, set slice to bootable, use GPT.  These will be prompted
    for automatically when creating first partitions.
  - For swap partitions, use freebsd-swap as the partition type.
  - For a 30GB drive: / 512M, SWAP 1xRAM, /var 512MB, /tmp 1G, /home 8G, /usr
    remaining space.  Skip SWAP if on an SSD.
  - For a 64GB SSD: / 1GB, /var 1GB, /tmp 1536MB, /home 28GB, /usr remaining
    space (includes a 4GB swap file).
  - Modify the above accordingly for VMs (add a swap partition) or drives of
    different sizes.  Consider making /var 3G or more if I have a lot of
    databases.
- Set root password.
- Setup network adapter with static IP.  Configure IPv4 without DHCP, skip
  IPv6.  For laptops, use DHCP and a non-static IP.  My Thinkpad requires
  setting regdomain to FCC4.  Otherwise, scans are non-functional.
- Set localdomain and DNS during resolver configuration.  The search field
  represents localdomain.  Grab the DNS entries from previous /etc/resolv.conf
  file.
- Set timezone and clock.
- System Configuration: sshd, moused.  On laptops, if I don't mind some extra
  RAM use, powerd can be useful.  On a VM, use ntpd.
- Security hardening options: Always disable opening a syslogd network socket.
  Disable sendmail on everything except my main workstation and VPS.
- Add bm3719 user.  Invite user to group wheel.
- As a final step, I may want to install the FreeBSD Handbook locally,
  especially on laptops, since I occasionally might get stuck without network
  access and have to look something up.
- Remove media and restart.  Don't pull the USB stick until after sync.

Some issues encountered in the past (though all seem resolved now):
- Prior to 10.2 on my workstation, installing from USB worked, but required
  entering =ufs:/dev/ad0= when dropped into the mountroot> prompt.
  Installation proceeded normally after that.
- In 10.0, when committing the filesystem changes, I would get a pre-check
  error.  This went away after awhile and seemingly had no ill effects.
*** enable TRIM support (SSD+UFS only)
If installing on an SSD, do this to increase write performance over the life
of the drive.  TRIM is enabled by default now, but can still be confirmed
this way.
- Boot into single user mode
- Run =mount=.  For other file systems besides /, use the =ro= option,
  e.g. =mount -r /dev/ada0p3 /var=.
- Run =tunefs -t enable /dev/ada0p2= (through ada0p6).
- Check that it's enabled with =tunefs -p /dev/ada0p2=.

Do the above for all slices.  Also ensure soft updates (softdep) are enabled.
They should be default on UFS now.  Soft updates' main tradeoff is a
semi-large .sujournal file in the root FS mount location.

Note that one of my SSDs, a Corsair I think, doesn't support TRIM.  If I see
AHCI timeouts, disable TRIM.
*** enable sshd
- Edit /etc/inetd.conf and uncomment IPV4 sshd.
- Edit /etc/rc.conf and ensure =sshd_enable="YES"= exists.
- Restart sshd daemon with =service sshd restart=.

From this point on, I can do all non-GUI tasks remotely.
*** set partitions noatime (non-ZFS)
If not using ZFS, edit /etc/fstab and set all non-swap slices to noatime.  This
saves some SSD wear and speeds up disk access.  I guess it's also good for
HDDs.
*** create swapfile in / (SSD and non-ZFS only)
Creating a swap file instead of using a partition will allow swap to make use
of TRIM.  Be sure not to do this if using ZFS.  This creates a 4GB swap file in
/usr/swap.  As root, do this:
- mkdir /usr/swap
- dd if=/dev/zero of=/usr/swap/swap bs=128k count=32768
- chmod 0600 /usr/swap/swap
- mdconfig -a -t vnode -f /usr/swap/swap -u 0
- swapon /dev/md0
- Confirm that the space shows up in =top=.
- Add the following to /etc/fstab.  Note that the "late" flag is required for
  this to work post 10.1:
  md none swap sw,file=/usr/swap/swap,late 0 0
- It may be prudent to reboot and test this again to be sure it comes up.

Note: Be sure to include =device    md= in the custom kernel config.
*** user account
A user add step has been in the installer for a few versions now, so my user
account should already exist at this point.
- Be sure user bm3719 is added to group wheel.  This should've been done during
  install, but is easy to forget.
- If I need to use the account right now, I can scp some stuff over, but it's
  more efficient to wait until later to rsync it all at once and preserve
  symlinks.
*** /root
Sometimes I have an old machine I'm migrating from, but usually I just swap
SSDs.  Modify the below accordingly if doing the former:
- Change /etc/ssh/sshd_config's PermitRootLogin to yes on old machine, and
  restart sshd there.
- scp various root files to root's home dir.
- Revert the sshd_config change on old box and restart service.

If not migrating machines, just scp /root from another FreeBSD machine (I
generally keep these synced).
*** pkgng
This is a replacement for pkg_tools.  It includes a built in security audit
(negating the need for portaudit).
- Bootstrap the pkg system by running =/usr/sbin/pkg= as root, if I hadn't
  installed the ports system from install.
- If an old pkg_tools database is still around (which it won't be on a fresh
  install), convert it to pkgng by running =pkg2ng=.
- Delete /var/db/pkg.bak, if it exists.
- Edit /etc/make.conf and add (with a tab before yes):
  WITH_PKGNG=    yes
*** portsnap
- portsnap fetch
- portsnap extract
- portsnap update
- pkg update
- pkg upgrade

Note: To update ports collection after this: `portsnap fetch update`
*** update world, src, kernel
- Ensure that the line =Components src world kernel= is present in
  /etc/freebsd-update.conf.
- =freebsd-update fetch=
- If there were any changes: =freebsd-update install=
- Comment out =kernel= from freebsd-update.conf.
- If the kernel was replaced, restart to begin using it.

Note that if source-upgrading, ensure world and kernel are commented out.
Update the source only and follow the steps to build a new world and kernel.
Only then update all ports.
*** copy over /etc/make.conf and /etc/ports.conf
These files are used to store common build flags preferences of mine for ports.

Merge the make.conf contents, since one was created earlier.
*** use clang as default compiler
Ensure /etc/make.conf includes this:
CC=clang
CXX=clang++
CPP=clang-cpp

# Some convenience flags.
OPTIMIZED_CFLAGS=YES
BUILD_OPTIMIZED=YES
WITH_CPUFLAGS=YES
WITH_OPTIMIZED_CFLAGS=YES
OPTIONS_UNSET=NLS IPV6 EXAMPLES
*** portmaster
- Install ports-mgmt/portmaster.  Flag for ZSH.
- Run =portmaster -L= to check if anything installed so far has new versions
  and update if necessary with =portmaster -a=.
** Post-install config
*** date/time
This should no longer be necessary with the new installer, but I'll leave this
step here in case it was skipped or done wrong.
- Set proper timezone with: cp /usr/share/zoneinfo/America/New_York /etc/localtime
- Check =date= command and if wrong set with ccyymmddhhmm.ss datemask.
*** loader config
- Ensure /boot/loader.rc has the following lines:
  include /boot/loader.4th
  start  # or beastie-start
- Either copy over stuff from old loader.conf or (preferably) check
  /boot/defaults/loader.conf for the current defaults and settings options.
- Set the default vt terminal console driver resolution by adding a line to
  /boot/loader.conf that corresponds to the native screen resolution:
  i915kms_load="YES"
  hw.vga.textmode=1
  kern.vty=vt
  kern.vt.fb.default_mode="2560x1440" # or "1366x768"
- Shorten the autoboot delay with an entry in /boot/loader.conf:
  autoboot_delay="3"
*** /etc/motd
- Copy over banner from old box.
- I include the traditional uname output in the first line, so be sure to
  update it later after kernel config (though I think this updates
  automatically now).
*** /etc/hosts
Add the following IPs to this file, excluding the box it is:
192.168.1.101           cellblock cellblock.bighouse.local
192.168.1.102           dreams    dreams.bighouse.local
192.168.1.100           hamtaahk  hamtaahk.bighouse.local

Also fix the domain name for localhost entries (fixes sendmail MTA errors) and
the sendmail timeouts at boot (if I see those, hit C-c to skip the wait).

Be sure 127.0.0.1 has two entries, one for localhost, the other for the actual
hostname.  Full names for both should have the proper domain name, which might
need to be fixed.

For my workstation, merge in my old /etc/hosts file if I want to include my
collection of blocked hostnames.
*** /etc/resolv.conf
If using DHCP since install time, add local DNS server here (should already be
added through install) and a backup OpenDNS one.  If setup to use a static IP
at install, this should already be properly configured, but I may still want to
add additional DNS servers.

For FreeBSD laptops and VMs, leave DHCP enabled.
*** virtual consoles
Edit /etc/ttys and disable ttyv3 through v7 by setting the status column to
=off= (probably from =onifexists=).  This leaves 3 consoles and saves a bunch
of getty processes.  It also keeps some clutter off the process list.
*** remap caps lock to control
This just changes caps lock, but still leaves the original control key as
control.
- cd /usr/share/syscons/keymaps/
- cp us.iso.kbd us.iso-swap.kbd
- Change the clock line to read:
  058   lctrl  lctrl  lctrl  lctrl  lctrl  lctrl  lctrl  lctrl   O
- chmod go+r us.iso-swap.kbd
- In /etc/rc.conf, add:
  keymap="us.iso-swap"

Will take effect on next restart.  Be sure to test this later.
*** install a few utility ports
- Since I usually do a test clean install on a VM, if this is the second run,
  copy over the contents of /usr/ports/distfiles to save some downloading time.
- www/lynx (with SSL; without color, IPV6, or NLS).
- sysutils/tmux (with BACKSPACE).
- shells/zsh (with DOCS).  Ensure .zshrc is copied over.
- net/rsync (with DOCS, SSH, ZLIB_BASE).   Also remove ENCODINGS from
  dependency converters/libiconv.

Confirm zsh appears in /etc/shells and chsh to that.  Also ensure .zshrc is
present.
*** sudo
- Install security/sudo (without AUDIT, NLS).
- Edit /usr/local/etc/sudoers and uncomment first line referencing group wheel.

I should now be able to stop su-ing to root and do everything via sudo.  The
only exception should be booting into single-user mode.
*** rsync $HOME directory
Don't use scp to restore $HOME due to symbolics links being followed, resulting
in copied data.  rsync preserves symlinks.  Run this:

rsync -av -e ssh old-server:~ ~/..

Check symlinks with =ls -alR | grep "\@"= and ensure they all still have
existing targets.

Delete ~/.cache, which contains a bunch of working files from various
applications.
*** ACPI extras (laptops only)
For Thinkpad laptops, enable the Fn keys by adding this to /boot/loader.conf:
acpi_ibm_load="YES"

If using this, be sure to add =device acpi_ibm= to the kernel config later.
*** Xorg
- Install devel/dbus.
- Install x11/xorg-minimal.  This takes a long time and prompts several times
  for build options.  It's probably a good idea to run =make config-recursive=
  first.  Be conservative with these flags.  For example, it's safe to disable
  all flags for docbook-related packages.  I did have build problems previously
  not including the WAYLAND flags, so leave those there.

  Note that if using hald, some additional config prompting will still occur.
  I might be able to get around that by first installing sysutils/hal.

  Note: For mesa-dri (a dependency of xorg-minimal), if using GPU acceleration
  with mesa, use the VAAPI option.  VDPAU is no longer actively developed.
- Install x11-drivers/xf86-video-intel (or xf86-video-vmware or whatever
  corresponds to my GPU) driver.  When installing X, one can run something like
  =make install VIDEO_DRIVER=intel= to skip installing vesa, though it's
  probably a good idea to include it if there's any uncertainty about a
  specific driver working, as it can isolate problems to the GPU config.

  For the intel driver, which appears to often be a mess, check the latest
  info here: https://wiki.freebsd.org/Intel_GPU
  For general Xorg info: https://wiki.freebsd.org/Xorg
  Additional info: https://wiki.archlinux.org/index.php/intel_graphics

  Note: graphics/libGLU and graphics/libGLw may be required by the intel
  driver's MESA dependency.

  Note: For intel drivers, AccelMethod can be defaulted to uxa or sna these
  days.  Choose sna when building, but if video has corruption issues, rebuild
  with uxa.  sna should work with most modern GPUs, however.  Ensure
  accelleration is enabled in xorg.conf with: =Option "AccelMethod" "sna"=
- For post-Haswell CPUs, install graphics/drm-kmod.  This provides a kernel module
  for integrated Intel/AMD GPUs.  Loading this requires an entry in rc.conf:

  kld_list="/boot/modules/i915kms.ko"

  This can replace the xf86-video-intel driver, but it's probably still a good idea
  (at least currently), to install it anyway to get VAAPI support.  It's probably a
  good idea to reboot now to ensure the kernel module auto-loads.

  Additional info: https://freebsddesktop.github.io/2018/12/08/drm-kmod-primer.html

  Note: Experimental support for VMWare in drm-devel-kmod exists, though it has
  bugs.
- Add the following to /etc/rc.conf to autodetect keyboards and mice:
  hald_enable="YES" # only if using HAL
  dbus_enable="YES"

  If using HAL, tart the hald service.  HALD may require a reboot.
- If this is a VM install, now is a good time to install
  emulators/open-vm-tools.  Unlike on Linux, this is the X-compatible version,
  with default flags.

  Also install x11-drivers/xf86-input-vmmouse.

  open-vm-tools installs a daemon called vmtools-guestd.  I probably want to
  add this to /etc/rc.conf.

  If going the VMware Tools route: Run =mkdir /mnt/cdrom= and mount the ISO
  with =mount_cd9660 /dev/cd0 /mnt/cdrom=.  This first requires that
  misc/compat6x is installed (last time I tried it).  This is probably not a
  good idea though, since these tools lag behind releases by quite a bit.
- As root run: =Xorg -configure=.  This will generate an xorg.conf.new file.
- Test this file with: =X -config xorg.conf.new -retro=.  If working, hit
  C-M-F1 and C-c.
- Check the Xorg stdout to check for errors.  Scan for warnings (WW) and errors
  (EE) in /var/log/Xorg.0.log.  If fbdev is needed, install
  x11-drivers/xf86-video-fbdev.
- Auto-configuration is almost never adequate though, so check older xorg.conf
  file and merge in anything important, like the monitor ModeLine.  Use =cvt=
  to find the appropriate settings.  On my current monitor, run =cvt --reduced
  2560 1440 60=.
- Check the detected video driver and change if necessary (like if vesa is used).
  Also check the mouse driver.
- Compare new config to old one to migrate over any other differences I want to
  keep.
- Once this is working: =cp xorg.conf.new /etc/X11/xorg.conf=
- Install ancillary Xorg apps that aren't in the minimal metaport, but that I
  still want to use:
  - x11/xmodmap
  - x11/xset
  - x11/xrdb
  - x11/xwd
  - x11/xkill
  - x11/libXrandr (For Haskell's X11.  Check if already installed first.)
  - x11-fonts/xfontsel
- Install deskutils/autocutsel and make sure its calls are uncommented in
  ~/.xinitrc.
- Make sure xmodmap key mappings in .xinitrc make sense with the keyboard being
  used.
- Ensure desktop user is in group wheel.  In the event I want to make a
  non-sudo-capable user able to use X, add them to the video group.

TODO: Switch using xorg.conf to files in /usr/local/etc/X11/xorg.conf.d that
correspond to the section being changed.  This lets Xorg auto-configure anything
not specifically defined.  Using =Xorg -configure= is also now considered not
recommended.  I've been putting this off since managing a bunch of small files
is less convenient.  It also seems like this method would make iterative testing
to get a working setup more of a pain.
*** urxvt
- Install x11/rxvt-unicode (without GDX_PIXBUF, ISO14755, NEXT_SCROLLBAR, PERL,
  or XTERM_SCROLLBAR).
- Once I get xmonad up, be sure to check if the urxvt font setting shows any
  weirdness at the chosen size.  Sometimes characters like underscores don't
  render.  Change the size in ~/.Xdefaults if there's any problems.

  Alternatively, see the suggested xmonad fixes for this here:
  https://wiki.haskell.org/Xmonad/Frequently_asked_questions#Showing_fractions_of_lines_in_gvim.2C_urxvt.2Cetc.
** Environments
*** Haskell
The only WM will be xmonad, but there are two options for installing it:
- From ports: This method is used on my main workstation, optimizing for
  stability by making it independent of stack's flakiness.  The downside is
  that I'll still want a user-specific version of GHC installed through
  stack, effectively doubling the Haskell environment disk usage and
  overhead.  A previous big downside was how far behind
- From stack: A user-specific install of xmonad, run entirely from stack.
  This means that GHC will not be installed via ports and everything
  Haskell-related has to go through stack.

We'll still want stack installed in either case, so this starts with that and
covers both situations.

Unfortunately, stack doesn't seem to be able to use clang.  Hopefully this will
be addressed at some point in the future, thought it's unlikely since it seems
be optimized for Linux with BSD support an afterthought.  As it is now, this
will pull in gcc.

Clean up any remaining cabal stuff:
- Ensure ~/.zshrc doesn't include ~/.cabal/bin in $PATH.
- Delete ~/.ghc and ~/.cabal.
- Delete contents of ~/.xmonad.  If xmonad versions haven't changed, I can
  probably keep the old xmonad.hs around.

stack setup:
- Delete ~/.local if it exists.
- Delete ~/.stack if it exists.
- stack requires: devel/gmake lang/perl5 lang/gcc misc/compat8x misc/compat9x
  converters/libiconv security/ca_root_nss.

  Probably lang/gcc, misc/compat8x, misc/compat9x, and maybe devel/gmake won't
  be installed yet by this point.  Installing misc/compat8x will pull in the
  higher level compat packages.
- Run: curl -sSL https://get.haskellstack.org/ | sh
- Run: stack update
- Run: stack setup
- Run =stack gchi= to test the GHC install.  If this doesn't work, see below
  note.
- Configure or copy a previous ~/.stack/config.yaml file.

Note: For recently released versions of FreeBSD, it seems the "bindists" are
not provided (meaning stack can't find a supported version of GHC to install
user-specific).  To resolve that, first confirm that a ports-available version
is supported by stack, install it, and set =system-ghc: true= in
~/.stack/config.yaml.  Rerun =stack ghci= after doing this.  I've also gotten
away with installing GHC with a minor version difference.

Perform only one of the following:

Ports xmonad setup:
- Install x11-wm/hs-xmonad-contrib.  This will pull in x11-wm/hs-xmonad,
  lang/ghc, and dependencies.
- Find a copy of xmonad.hs, probably somewhere in /usr/local/share.  Copy this
  to the ~/.xmonad directory and make any modifications desired.
- Manually compile the xmonad.hs file with (note the -- necessary to send the
  command flag to ghc, not stack): =stack ghc -- --make xmonad.hs= to be sure
  it works.

stack xmonad setup:
- Ensure $HOME/.local/bin is in $PATH.
- Either run both or just the second of the following commands.  Installing
  contrib might alleviate some dependency problems.
  stack install xmonad
  stack install xmonad-contrib
- If I get an error about missing libXss headers, install xll/libXScrnSaver.
- Somewhere deep in the ~/.stack directory will be an example xmonad.hs file.
  Copy that over to ~/.xmonad and edit it with my normal changes.  At least
  change the default terminal emulator, since I've skipped installing xterm,
  and the myModMask variable.  Ensure the key remappings correspond to any
  xmodmap changes in ~/.xinitrc.
- Manually compile the xmonad.hs file with (note the -- necessary to send the
  command flag to ghc, not stack): =stack ghc -- --make xmonad.hs=
  Be sure that ~/.xinitrc points to this new binary explicitly, and doesn't
  resolve to the one installed from stack.

Final tasks:
- Install x11/dmenu.
- Run startx as user.  Note that if fonts aren't installed yet, urxvt will
  have errors.  Skip ahead to the fonts task if I need to use X right now.
- Be sure dmenu, quitting, and recompiling xmonad.hs works.  Also check
  ~/.xmonad/xmonad.errors to see if there's any problems.
- Install any other Haskell apps from Stackage being used.  This depends on
  what I'm doing at the time, but might include Agda, pandoc, ShellCheck,
  happy, haskeline, alex, etc.

It might be a good idea to install fonts (see "fonts" section below) now in
order to test whether the full Xorg environment is functional.  With this
setup, rxvt-unicode won't have a font to default to, so I otherwise can't get a
terminal up.  If I'm okay with plowing ahead though, I can skip it until later.
An alternative is to modify ~/.xinitrc to launch an X app like xfontsel, just
to make sure xmonad works.
*** GNU Emacs
- Install editors/emacs.  Use GTK2 toolkit since Conkeror will use it anyway.
  Use config-recursive here.  Remove at least GCONF, GSETTINGS.
- Install from ports:
  - textproc/aspell
  - textproc/en-aspell
  - print/auctex (Long install.  Note that ghostscript9-agpl-base has had a
    broken docs build for a long time.  De-flag DOCS).
  - editors/apel
  - www/w3m (check if already installed first)
- devel/git (with CURL, ICONV, SUBTREE).  Presence of this binary is checked by
  one of the git-related addons.  Run my standard git user config after
  install.
- .emacs file and .emacs.d directory should already be present from
  scp/rsync-ing user directory over.
- Startup Emacs in Xorg to make sure there's no init errors.

Haskell went on first, but now that Emacs is setup, a final step needs
completing to integrate it with the new stack install:
- Ensure that intero-mode is installed via ELPA.
- Create a new project with stack (or use an existing one).
- Open one of the .hs files in it and run M-x intero-mode.  If everything's
  wired up properly, this should install intero, the Haskell project on Stack.
  Alternatively, I can also run =stack build --copy-compiler-tool intero=

Note: I used to install www/emacs-w3m (w/o SHIMBUN).  But, since www/w3m-m17n
was removed, use of normal w3m is required now.  Now I'm using emacs-w3m from
CVS.
*** Python
Migrated this to a very basic setup, which just installs pexpect for scripts.
Might deprecate this altogether next time.

- 2.7.x should be brought in by Xorg.
- Install devel/py-pip.
- Install pexpect via pip as root.
- Install pyflakes via pip as root.  If this doesn't work, go to
  http://pypi.python.org/pypi/pyflakes and download pyflakes.  Modify the
  hashbang in setup.py.  Run =setup.py install --user=.

I may want to defer these, if I don't plan on doing any Python development any
time soon.  That'll make installing them later easier.
- Install devel/pylint (no GUI).
- Install lang/python-doc-html.
- Use pip to install python-distribute.  As root, run =pip install distribute=.
- Install devel/py-nose or =pip install nose=.
- Install devel/py-virtualenv or =pip install virtualenv=.
- Install numpy via pip.
*** Java
The Java stack mainly just needs to host Clojure.  Ant is still needed to
compile l1j-en, however.
- Install java/openjdk12.  Look around first to see if a newer version is
  available first.
- Install devel/apache-ant (check if already installed first).
- Ensure /usr/local/openjdk12/bin binaries are symlinked and that $JAVA_HOME is
  properly set (which it won't be if the Java version changes).
- Install ftp/wget (needed for jde-help-symbol).
*** Clojure
This setup uses Leiningen to pull in the correct jar instead of the port in
lang/clojure, which there is no good reason to ever install.

My Clojure setup should be migrated from a previous system, but it's not a bad
idea to refresh everything by deleting ~/.m2 and everything in ~/.lein except
~/.lein/profiles.clj.
- The JDK and Ant should already be brought in by the openjdk install.
- Grab the latest Leiningen 2.x script with =wget --no-check-certificate
  https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein=
- Put this in ~/bin and chmod u+x it.
- Run =lein=, which does some setup on the first run.
- Systems without =shasum= may report a download error due to a failed checksum
  validation when grabbing the Clojure jar.  Just verify that
  ~/.m2/repository/org/clojure/clojure/1.x.x/clojure-1.x.x.jar and
  ~/.lein/self-installs/leiningen-2.x.x-preview-standalone.jar are there.
- Ensure ~/.lein/profiles.clj is present or update it from dotfiles project.
- Make a test project somewhere to make sure everything works by running =lein
  new test-prog= then pull up a REPL against it in Emacs.  Alternatively, use
  an existing, up-to-date project.

If for some reason I don't want to redo everything, at least run =lein
upgrade=.
*** JavaScript
- Install www/node
- Install www/npm.  Ensure the BACKEND matches the node version installed.
- Delete ~/node_modules and ~/.npm.
- Install these packages using =npm install= on user account.  I may want to
  defer this if I'm not going to use them right away, since the versions churn
  quickly:
  - webpack
  - eslint
- Install these only if I have an actual need for them, like building old
  projects.
  - bower
  - markdown-pdf

Note that there's been times when something here is broken, so if there's
any critical npm-managed infrastructure, backup ~/node_modules first.

markdown-pdf brings in an npm-installed phantomjs.  This install has been
troublesome occasionally.  I've gotten it working by symlinking the node
binary.
*** Lisp (optional)
Skipping now in my default install, since I don't write CL anymore and don't
use maxima much.  Keeping this here, just in case.

If I just want a backend for maxima:
- Install lang/sbcl.

For the rest of the CL dev environment:
- Install devel/clisp-hyperspec.
- Swank setup: Need to recreate symlink to swank.asd in .sbcl/asdf-registry.
  See .sbclrc for setup details.
- asdf-installed packages are portable as long as ~/.sbcl is propagated.  Code
  in .sbclrc handles stale fasls.  However, it might not be a bad idea to wipe
  these, since it'll rerun the package tests and alert for missing
  dependencies.
*** Math
I have some Maxima code, but since I haven't touched it in years, I'll
lazy-load it to simplify my setup, leaving only gnuplot.
- Install math/gnuplot (only DOCS, GD, X11).  Consider switching to
  gnuplot-lite next time.
- Install math/coq.  This will pull in OCaml dependencies, along with a lot of
  other stuff.  Be sure to de-flag ocaml-findlib's TOOLBOX.

If I want maxima:
- Install math/maxima (also brings in gnuplot).  For gnuplot, only enable DOCS,
  GD, X11.
- Make sure current version's elisp directory matches that referenced in
  ~/.emacs.  I've removed this from my base .emacs file, so grab the code out
  of the revision history.
*** Racket (optional)
Consider skipping this if I don't plan on doing any Racket programming.

- Delete existing ~/.racket.
- Ensure there's plenty of space on /var (raco writes to /var/tmp).
- Install lang/racket-minimal.
- As user, run =raco pkg install drracket=.
- Open up a .rkt file in Emacs and run M-x run-geiser.
*** C
- Install devel/global.

If I plan on doing any C programming, do this too:
- Install devel/valgrind (Check if it pulls in a gcc version).
- Add procfs entry in /etc/fstab, like:
      proc /proc procfs rw 0 0
  Then run =mount proc=.
*** OCaml (optional)
Skip this if not doing any OCaml programming.
- Install lang/ocaml (w/o X11).
- Install devel/ocaml-opam.
** Apps
*** fonts
- Install x11-fonts/code2000.
- Install x11-fonts/dejavu (check first if already installed).
- Install x11-fonts/xorg-fonts-100dpi.  This is needed by apps like xpdf and
  xfontsel.
- Run mkfontdir and mkfontscale in updated font directories under
  /usr/local/share/fonts/ (previously was /usr/local/lib/X11/fonts).  This will
  include OTF.  Can check if fonts.dir and fonts.scale are already there and
  skip if they are.
- Migrated .xinitrc should already xset fp+ these, but check to make sure they
  match available fonts.
- Update xorg.conf to include any missing font directories.
- In the Modules section of xorg.conf, add =Load "freetype"=.
- Check xfontsel to ensure all are registered.

Note that using x11-fonts/ttmkfdir and running =ttmkfdir -o fonts.dir= in any
TT font dirs (like dejavu) seems to no longer be necessary.  The package seems
to be gone altogether now, in fact.
*** GPG
- Install security/gnupg1 without NLS or CURL.
- Test that I can open an existing encrypted file using Emacs GPG integration.
*** general utilities
Check main apps list and install everything.  These (except tex-xdvik) are
good to install in parallel to the above:
- archivers/p7zip
- irc/irssi (with BOT, PERL, and TRUECOLOR)
- graphics/xpdf3 (looks like graphics/xpdf, which is v4, uses QT5)
- graphics/graphviz (w/o NLS, PANGOCAIRO, NVTHREADS. Check if already
  installed.)
- print/tex-xdvik *
- sysutils/tree
- textproc/code2html
- textproc/colordiff
- textproc/fzf (will pull in golang)
- textproc/markdown
- textproc/textogif (skip this on headless installs)
*** mutt
- Install mail/mutt.  Disable HTML, SMIME_OUTLOOK_COMPAT, XML.  A dependency,
  gpgme, should be set to GNUPG1 if enabled.  De-flag UISERVER.
- Install mail/msmtp.
- Ensure ~/.mutt, ~/.muttrc, ~/.msmtprc, and ~/.mutt/cert.pem are copied over
  and chmoded properly.
- Start up mutt to test.
- In another mail-related issue, if I see system messages similar to "Alias0:
  missing map file ...", run this command:
  makemap hash /etc/mail/aliases.db < /etc/mail/aliases
*** sound
- Do a kldload snd_driver (this scans for most common audio devices and loads
  proper driver), check =cat /dev/sndstat= to see which was loaded, then
  kldunload snd_driver and add the proper line to /boot/loader.conf, such as
  =snd_hda_load="YES"=.  Be sure to add this proper driver to kernel config
  later and remove it from loader.conf.  See driver manpage for details.  Note
  that PnP devices don't require this anymore.  If the chipset is just pcm,
  that's usually a sign this is the case.

  On ThinkPad laptops, ensure the volume buttons are maxed out.

  Note that if using HDMI sound, I'll need to ensure the correct device is set
  to default.  For example, on my workstation, I get pcm0 and pcm1.  If I
  wanted to default to pcm1, I'd need to add =hw.snd.default_unit=1= to
  /etc/sysctl.conf.  This can also be flipped with =sysctl hw.snd.default_unit="1"=.
- Install audio/flac.
*** mplayer
- Install multimedia/mplayer with build options: FONTCONFIG OPENGL RTCPU X11
  X11DGA X11VM XVIDEO.  Use OPENSSL on dependency ffmpeg.
- Play an mp3 or flac file in EMMS to test.

Note that mplayer has switched back and forth on whether it includes a THEORA
option.  If not, I'll have to install multimedia/libtheora for OGG support.
*** vim-lite
Install editors/vim-tiny.  This is vim without the GUI and a few other frills,
mainly for root and doing command line comments with Git.  Maybe skip this and
just use regular vi.
- Copy wombat.vim to /usr/local/share/vim/vim80/colors/ and ensure it has the
  same permissions as the other .vim files.
- Ensure .vimrc is copied over for user and root accounts.  Start up vim to
  ensure there are no config errors.  If it's working, the splash message won't
  be present.
*** Conkeror
XULRunner is no longer available as an independent library (it used to be
www/libxul).  This means the only way to get it is to install Firefox.
However, this is broken currently.  What's supposed to work:
- Install www/firefox or www/firefox-esr.  Exclude GCONF, JACK, and PULSEAUDIO.
- Create a script to launch Conkeror that contains something like:
  #!/bin/sh
  firefox -app /path/to/conkeror/application.ini "$@"
- This currently errors, both with www/xpi-conkeror from ports (which is
  ancient) and the current version from git.

Since this doesn't work, I'll stick with w3m for most web browsing, with
Iridium as a backup when needing a GUI.

Previously, this worked:
- Install www/libxul.  Flag for BUNDLED_CAIRO, DBUS, OPTIMIZED_CFLAGS, ALSA,
  GTK2.  This failed for me once because I forgot to install graphics/png with
  APNG support.  If that happens, just rebuild it with that.  Another issue can
  occur where /etc/machine-id is missing.  If this happens, run =dbus-uuidgen >
  /etc/machine-id= as root.
- Navigate to ~/src/javascript/conkeror and do a =git pull --rebase=.
- Install customized "blackened" theme (not necessary if propagating
  ~/.conkeror.mozdev.org directory).
- Modify conkeror/modules/webjump.js, removing useless webjumps.
- Remove unwanted stuff from conkeror/search-engines.
- Remove same stuff from end of conkeror/modules/search-engine.js
- In conkeror/modules/minibuffer-read-option.js, edit this function to the
  following:
  minibuffer.prototype.read_yes_or_no = function () {
      keywords(arguments);
      var result = yield this.read_explicit_option(forward_keywords(arguments),
                     $options = ["yes", "no", "y", "n"]);
      yield co_return(result == "yes" || result == "y");
  };
- Ensure script ~/bin/conkeror exists and test it.  Fix any rc file errors.
- To disable extensions security, run:
  session_pref("xpinstall.whitelist.required", false);
- Try to install Adblock Plus directly from adblockplus.org.  Sometimes this
  works, depending on the xulrunner/Conkeror version.  If so, run M-x
  extensions and configure the plugin.  If not, download the xpi file and
  manually install it from the extensions window.  Then add a filter list
  subscription.
- Grab NoScript .xpi (in ~/doc/conf) and run M-x extensions and manually
  install it.  Restart and go to the preferences.  Add macroexpand.com,
  127.0.0.1, localhost, and github.com to the whitelist.
*** Iridium
Install www/iridium, if Conkeror is non-functional.

Try starting it as is, and if I get drm errors, add user to group video and
add this to /etc/devfs.rules:

add path 'dri/*' mode 0666 group wheel

Maybe add this to /etc/devfs.conf:

perm    /dev/dri/card0      0666

These changes seem to need a reboot to stick.

Start this from the CLI to make sure there are no startup errors.  Then:
- Tweak all settings.
- Install uBlock Origin.
- Install some dark theme.
*** games
Always at least install:
- games/frotz (w/o OSS)

If this is a laptop install, maybe add a subset of these:
- games/nethack36-nox11
- games/stonesoup
- games/adom

  Add =linux_enable="YES"= to /etc/rc.conf.
- games/tome4
- games/avanor
*** printing
TODO: Skipping printing in latest build.  Will have to refresh this later.

Install/config CUPS and USB printer HL-5240:
- Install print/cups, print/cups-client, print/gutenprint (without gimp-print
  drivers, instead using IJS), and print/foomatic-filters.
- Create /etc/devfs.rules with the following, which sets the permissions and
  associates print devices with the cups group:
  [system=10]
  add path 'unlpt*' mode 0660 group cups
  add path 'ulpt*' mode 0660 group cups
  add path 'lpt*' mode 0660 group cups
- Add root and other users to cups group in /etc/group
- Enable CUPS and the above rules at startup by adding these lines to
  /etc/rc.conf:
  cupsd_enable="YES"
  devfs_system_ruleset="system"
- In order to enable CUPS printing under certain Windows clients, the line
  below should be uncommented in /usr/local/etc/cups/mime.types and
  /usr/local/etc/cups/mime.convs (this seems to be the default now, but check
  anyway):
  application/octet-stream
- Either reboot or issue the following commands:
  service devfs restart
  service cupsd restart
- Config printers via the CUPS web interface by going to: http://localhost:631
- Go to Administration|Add Printer, type in names, select USB printer 1,
  specify Brother-HL-5240-Postscript.ppd file from the local filesystem. Use
  root l/p when asked for a login.
- Set US Letter, no double siding, 600dpi, no banners.
- On Windows, just add a network printer (should find it automatically).
  Search for driver, install Brother HL-5420 BR-Script3.
- Print a test page from CUPS admin panel.
- Install print/xpp.
- Try printing a test file from Emacs with M-x print-buffer.
*** Samba
- Install net/samba44 (or whatever the latest is).  At least de-flag ADS,
  AD_DC, DEBUG, LDAP, QUOTAS, SYSLOG.
- /usr/local/etc/smb4.conf
[global]
        workgroup = BIGHOUSE
        server string = Samba Server Version %v
        netbios name = cellblock
        # Do not enable for more than one Samba server.
        wins support = Yes
        security = user
        passdb backend = tdbsam
# Share /usr/share/smb accessible only to bm3719 user.
[smb]
        path = /usr/share/smb
        valid users = bm3719
        writable  = yes
        browsable = yes
        read only = no
        guest ok = no
        public = no
        create mask = 0666
        directory mask = 0755
- Test setup with: /usr/local/bin/testparm -s
- Create local shared directory of /usr/share/smb, chmoded to 0755.
- Add bm3719 to samba users with: pdbedit -a bm3719
- Add =samba_server_enable="YES"= to /etc/rc.conf.
- Test local share from Windows by going to network/cellblock/smb and creating
  a file.
- TODO: Test printer from any local Windows machines and if not working
  reinstall it with driver (see CUPS entry for details.)
- For backups, create a directory like /mnt/smb and make sure rsync backup
  scripts point to it.

Note: Here was my old printer section for Samba 3.6.  I'll reintegrate this for
4.4 at some point.
[printers]
        comment = All Printers
        path = /var/spool/samba
        printable = Yes
        browseable = No
*** nginx
- Install www/nginx.  Skip most of the modules.  Recommended:
  - DSO
  - FILE_AIO
  - THREADS
  - WWW
  - HTTP
  - HTTP_AUTH_REQ
  - HTTP_REWRITE
  - HTTP_SSL
  - HTTP_STATUS
  - HTTP_SUB
  - HTTPV2
  - CLOJURE
- Add nginx_enable="YES" to /etc/rc.conf.
- Copy over old /usr/local/etc/nginx/nginx.conf, or start over.
  - Be sure to include this snippet for user public_html directories and
    directory browsing:
    # Home directories
    location ~ ^/~(.+?)(/.*)?$ {
        alias /home/$1/public_html$2;
        # Enable directory browsing.
        autoindex on;
    }
- Delete symlinked dir /usr/local/www/nginx.
- Clone server website to the above location.
- Test server and user sites.
*** ddclient
- Install dns/ddclient.
- Add =ddclient_enable="YES"= to /etc/rc.conf
- In ddclient.conf, ensure that for the interface, em0 is used locally, and xn0
  on the VPS.
- Copy over old ddclient.conf to /usr/local/etc/ddclient.conf
daemon=900                              # check every 15 minutes
timeout=10
syslog=yes                              # log update msgs to syslog
#mail=root                              # mail all msgs to root
#mail-failure=root                      # mail failed update msgs to root
pid=/var/run/ddclient.pid               # record PID in file.
use=if, if=em0                          # found after IP Address

protocol=freedns             ##
server=freedns.afraid.org    ## defaults to freedns.afraid.org
login=bm3719                 ## login name and password registered with the
## service
password=PASSWORD_GOES_HERE  ##
rcake.crabdance.com          ## the host registered with the service.
## single host update
protocol=freedns, \
login=bm3719, \
password=PASSWORD_GOES_HERE \
rcake.crabdance.com
- Ensure ddclient.conf is chmod-ed 0600.
- service ddclient start
*** MySQL
- See /root/mysql_setup.txt
- Install databases/mysql57-server (this pulls in mysql56-client as well).  I
  guess select INNOBASE as the engine and disable PERFSCHM unless I'm running a
  production DB.  For mysql57-client, deselect SASLCLIENT.

  This is an older version, but the current version (8.0) has a lot of active
  vulnerabilities.
- Edit /usr/local/etc/mysql/my.cnf.  At least change the bind-address to
  0.0.0.0 to allow remote access.
- /usr/local/libexec/mysqld --initialize
- Note the temporary password for the root user, which will be displayed to
  stdout.
- Run =mysqld_safe --user=mysql &=.  It's possible to copy
  support-files/mysql.server over to /etc/rc.d if i want to autostart at boot
  (which I don't).
- Check /var/db/mysql/cellblock.err to make sure everything starts okay.
- Login to mysql with: mysql -u root -p
- Change root password with:
  ALTER USER 'root'@'localhost' IDENTIFIED BY 'MYPASSWORD';
- Since I sometimes do db backups/restores from other machines, it'll need
  remote root access, so run the following after logging in as root locally:
  GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY "MYPASSWORD";
  FLUSH PRIVILEGES;
- Create database with: CREATE DATABASE l1jdb;
- Restore database from backup.
*** Docker
TODO
*** bhyve (ZFS only)
TODO
*** install optional ports
Here's some apps I've occasionally used on FreeBSD systems.  I'm excluding
these from the setup here by default do to keeping down unnecessary bloat.  If
I need these, a better option is to use them in a VM.
- Install sysutils/exa (maybe with Rust stack and cargo first).
- Install databases/mongodb32.
- Install databases/mongodb32-tools.
- Install math/R.
- Install x11/xrandr (useful for laptops I might hook to external devices)
- Install java/eclipse, java/eclipse-gef, java/eclipse-webtools, and all
  Eclipse plugins being used.
- Install textproc/weka.
- Source install RapidMiner.
- pip install scipy
- Install math/gmp and lang/go (go-ethereum dependencies).
- devel/subversion (if using an older version, config with SERF, not NEON)
- Install x11-fonts/terminus-font or x11-fonts/terminus-ttf.
** Test
*** Emacs
- Open a .c, .cpp, .tex, .xml, .html, .js, .java, and .py file
- M-x py-shell, w3m.
- Run magit-status on a git repo.
** Final tasks
*** build kernel and world
Normally, one might want to do this way earlier, but I'd rather get the system
working first.  Screwing something up on setting up the various environments is
far more likely than ruining the system with a kernel build (which is pretty
much impossible unless you're a total n00b).  On the other hand, if I'm
source-upgrading to a new version, switch the order here around and do this
first.

The most efficient method is to rebuild world and kernel and the same time,
with world going first.
- Go through all device listings in ports, read manpages of any newly added
  devices.
- Be sure to read /usr/src/UPDATING.
- Compare old kernel config to new one in ediff or something, but before
  merging anything in, be sure it still applies.
- Remove any temporarily added modules or kernel flags from /boot/loader.conf
  that will be redundant with the new kernel config.
- In particular, remove the sound driver load from /boot/loader.conf.
- Create a .hints file.
- Before something goes wrong, be sure to back up the last working kernel
  somewhere since /boot/kernel.old will be overwritten.
- After installing, run =ps aux= and =vmstat= to make sure they still work.  If
  not, the world and kernel are desynced.
- Test audio.
- Comment out =world= in /etc/freebsd-update.conf.
- Ensure uname output on the first line in /etc/motd is updated (should happen
  automatically).

For 12.0, GENERIC /boot/kernel/kernel is 35MB, a conservative build that mostly
just excludes unneeded drivers for non-existent hardware is 16.7MB.
*** custom info files
Copy these from ~/doc/conf and update the index in /usr/local/info/dir
accordingly.

- The entry for SICP should look like this:
  The Algorithmic Language Scheme
  * SICP: (sicp). Structure and Interpretation of Computer Programs
*** files
- Ensure that files being edited during install are checked in or scp-ed over.
- Do one last filesystem sweep for config files and such missed.
- Delete everything in /usr/ports/distfiles.
- Go to /usr/ports and run =make clean=.
- Check websites to ensure functionality.
- Backup old system before retiring it and don't wipe it for a couple weeks.
  If using the drive swap method, just set aside that drive for awhile (usually
  I just keep it until the next fresh install).
*** security
- Before putting box online, check the security advisories for this version on:
  http://www.freebsd.org/security/advisories.html
- Apply any patches necessary.  Most likely, this won't happen, since the
  latest source was retrieved.
- Run =pkg audit -F=.
*** other users
Migrate over other users and their data.
- Recursively scp user dirs from /home.
- Copy over entries for users in /etc/passwd, /etc/master.passwd, and
  /etc/group.
- Run =pwd_mkdb -p /etc/master.passwd=.
- Recursively chown all user directories to appropriate ownership.
*** storage devices
If not adding other users, I can probably safely allow untrusted user device
mounting, but I prefer to limit it to group wheel members.
- Edit /etc/devfs.rules and add:
  [my_usb=10]
  add path 'da*' mode 0660 group wheel
  add path 'msdosfs/*' mode 0660 group wheel
  add path 'usb/*' mode 0660 group wheel
  add path 'ugen*' mode 0660 group wheel
- Edit /etc/sysctl.conf and add:
  vfs.usermount=1
- Edit /etc/rc.conf and add:
  devfs_system_ruleset="my_usb"

Test by sticking in a USB drive and mounting /dev/da0.
*** setup SSH authentication
See projects.org "OpenSSH authentication" topic for details.
- Run =ssh-keygen -t rsa -C "bm3719@gmail.com"= locally and add to
  ~/.ssh/authorized_keys files on any remote hosts desired.
- Do the reverse for any hosts that need access to this machine.
- Add public key to GitHub and BitBucket accounts.
- Ensure ~/.gitconfig exists.
- Also create key pair for root and add its public key to GitHub and BitBucket
  accounts.
*** final update
If this has taken a few days, do a final update.
- portsnap fetch update
- =portmaster -ay= to upgrade all or =portmaster -v <portname>= to upgrade
  specific ports (maybe with -d and -w flags to cull distfiles and preserve
  dependent libs, respectively).
*** clean up leaf ports
Check leaf ports with =portmaster -l= and clean up ones that aren't needed but
were dragged in for a build.  Cycle on this until I don't see any that I don't
want to keep.

Only do this if I plan to incrementally update the ports rather rarely.
Regular updates will just keep pulling these back in and rebuilding them, but
if I only do it every 6 months or so, the version numbers will have mostly been
bumped by then anyway.  Alternatively, if I have plenty of space and don't care
too much about a bunch of build tools and libs laying around, I can just leave
them there.
*** clean up distfiles
Unless I want to keep these around (like for transferring to another system to
save downloading time), clean up the /usr/ports/distfiles directory either
manually or by running `portmaster --clean-distfiles`.
*** ZFS scrub (ZFS only)
If using ZFS, run: zfs scrub zpool

I think this command was removed.
*** done
- This gives a system with about 300-350 total packages installed and (if not
  using ZFS) idles at around 18MB of active RAM usage after boot with all
  services running + one user shell.  It's possible to squeeze this in under
  5GB of disk used, though I haven't tried that recently.  Leaving out the
  Haskell stack (though you'd have to replace xmonad with something else) or
  going headless would be a viable approach to optimize for disk usage.
- Commence writing code.