aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCullum Smith <cullum@sacredheartsc.com>2024-07-17 06:45:00 -0400
committerCullum Smith <cullum@sacredheartsc.com>2024-07-17 06:46:22 -0400
commitf036b9c0da685d11e341d61e5aaeb75cac576111 (patch)
tree22b08ae6bb7e83d529fe49fe99ea8da87a8d25a4
parent89cdd1c872694797a8f6f0185be2b2cd3467bfcc (diff)
downloadinfrastructure-f036b9c0da685d11e341d61e5aaeb75cac576111.tar.gz
add pkg_repository hostclass
-rwxr-xr-xboxconf6
-rw-r--r--docs/10-bootstrapping.md76
-rw-r--r--files/etc/ssh/ssh_config.freebsd9
-rw-r--r--files/etc/ssh/sshd_config.freebsd16
-rw-r--r--files/usr/local/etc/jailctl.conf.freebsd_hypervisor2
-rw-r--r--files/usr/local/etc/nginx/nginx.conf.common44
-rw-r--r--files/usr/local/etc/nginx/vhosts.conf.pkg_repository47
-rw-r--r--files/usr/local/etc/pkg/repos/FreeBSD.conf.common1
-rw-r--r--files/usr/local/etc/pkg/repos/onprem.conf.pkg_repository5
-rw-r--r--files/usr/local/etc/poudriere.conf.pkg_repository16
-rw-r--r--files/usr/local/etc/poudriere.d/make.conf.pkg_repository83
-rw-r--r--files/usr/local/etc/poudriere.d/pkglist.pkg_repository33
-rw-r--r--files/usr/local/etc/ssl/repo.crt.readme3
-rw-r--r--files/usr/local/etc/ssl/repo.key.readme4
-rw-r--r--files/usr/local/libexec/poudriere-cron.pkg_repository16
-rw-r--r--files/usr/local/poudriere/ccache/ccache.conf.pkg_repository1
-rw-r--r--files/usr/local/sbin/jailctl.freebsd_hypervisor4
-rw-r--r--lib/10-core2
-rw-r--r--scripts/hostclass/pkg_repository92
-rw-r--r--vars/common18
-rw-r--r--vars/hostclass/pkg_repository3
21 files changed, 472 insertions, 9 deletions
diff --git a/boxconf b/boxconf
index c9dc6c5..c9955e7 100755
--- a/boxconf
+++ b/boxconf
@@ -26,10 +26,8 @@ while getopts :hde:s:X _bc_opt; do
esac
done
-shift $((OPTIND - 1))
-[ $# -eq 1 ] || usage
-
-BOXCONF_HOSTNAME=$1
+[ $(( OPTIND - $# )) -eq 1 ] && usage 'HOST not specified'
+eval "BOXCONF_HOSTNAME=\$$#"
for _bc_lib in "${BOXCONF_ROOT}/lib"/*; do
. "$_bc_lib"
diff --git a/docs/10-bootstrapping.md b/docs/10-bootstrapping.md
new file mode 100644
index 0000000..05f8867
--- /dev/null
+++ b/docs/10-bootstrapping.md
@@ -0,0 +1,76 @@
+Bootstrapping the Environment
+=============================
+
+Most hosts that are built with `boxconf` depend on at least two other hosts
+being available:
+
+ 1. The IDM (identity management) server. This server provides DNS, Kerberos
+ authentication, and LDAP user and group lookups.
+
+ 2. The package repository. Almost all hosts are FreeBSD, and they depend on
+ the local `poudriere` server which hosts in-house packages built with
+ custom options.
+
+The IDM servers and the package repo are themselves built with boxconf, but you
+must build them in a specific order to solve the chicken-and-egg problem.
+
+
+## Step 1: The Hypervisor
+
+It is assumed that most hosts will be FreeBSD jails. Therefore, you will need
+a FreeBSD "hypervisor" along with our custom `jailctl` script.
+
+Boxconf can be used to configure a FreeBSD hypervisor for running jails and
+bhyve VMs. The only requirement for this server is a NIC that supports VLAN
+tagging. By default, this interface is assumed to be `lagg0`.
+
+Boxconf assumes any host named `alcatraz[0-9]` has the `freebsd_hypervisor`
+hostclass. Therefore, you can run the following to setup the jail host:
+
+ ./boxconf -s $FREEBSD_HYPERVISOR_IP alcatraz1
+
+Then, on `alcatraz1`, download a FreeBSD rootfs image used for templating jails:
+
+ alcatraz1# jailctl download-release 14.1-RELEASE
+
+
+## Step 2: The Pkg Repository
+
+First, we'll need a jail to serve as our Poudriere server. This jail will build
+all the necessary packages and serve them over HTTP.
+
+On the FreeBSD hypervisor, use `jailctl` to create a jail for the `pkg` repo.
+The following command will create a jail named `pkg1` with VLAN tag `199`,
+IP address `10.11.199.4`, 32G memory limit, 256G disk quota, and 32 CPU cores.
+Note that running `poudriere` in a jail requires many custom jail options, which
+are also set with this command.
+
+ alcatraz1# jailctl create \
+ -v 199 \
+ -a 10.11.199.4 \
+ -k ~/id_ed25519.pub \
+ -c 64-95 \
+ -m 32g \
+ -q 256g \
+ -e mount.procfs=true \
+ -e allow.mount.tmpfs=true \
+ -e allow.mount.devfs=true \
+ -e allow.mount.procfs=true \
+ -e allow.mount.nullfs=true \
+ -e allow.mount.linprocfs=true \
+ -e allow.raw_sockets=true \
+ -e allow.socket_af=true \
+ -e allow.mlock=true \
+ -e sysvmsg=new \
+ -e sysvsem=new \
+ -e sysvshm=new \
+ -e children.max=1000 \
+ pkg1 freebsd14.1
+
+Now you are ready to build all the packages and create the repository. `boxconf`
+assumes that any host named `pkg[0-1]` has the `pkg_repository` hostclass.
+
+ ./boxconf -e idm_bootstrap=true 10.11.199.4
+
+Substitute whatever IP you chose for the `pkg1` jail as necessary. Note that it
+will take a while to build all the packages for the first time.
diff --git a/files/etc/ssh/ssh_config.freebsd b/files/etc/ssh/ssh_config.freebsd
new file mode 100644
index 0000000..9be624a
--- /dev/null
+++ b/files/etc/ssh/ssh_config.freebsd
@@ -0,0 +1,9 @@
+CanonicalizeHostname always
+CanonicalizeMaxDots 0
+CanonicalDomains ${domain}
+CanonicalizePermittedCNAMEs *.${domain}:*.${domain}
+KnownHostsCommand /usr/local/libexec/idm-ssh-known-hosts %H
+
+Host *.${domain}
+ GSSAPIAuthentication yes
+ GSSAPIDelegateCredentials yes
diff --git a/files/etc/ssh/sshd_config.freebsd b/files/etc/ssh/sshd_config.freebsd
new file mode 100644
index 0000000..c933741
--- /dev/null
+++ b/files/etc/ssh/sshd_config.freebsd
@@ -0,0 +1,16 @@
+Include /etc/ssh/sshd_config.d/*.conf
+
+PermitRootLogin prohibit-password
+AuthorizedKeysFile .ssh/authorized_keys
+AuthorizedKeysCommand /usr/local/libexec/idm-ssh-authorized-keys %u
+AuthorizedKeysCommandUser ${ssh_authzkeys_user}
+
+KbdInteractiveAuthentication no
+PasswordAuthentication yes
+
+GSSAPIAuthentication yes
+GSSAPICleanupCredentials yes
+UsePAM yes
+UseDNS no
+
+Subsystem sftp /usr/libexec/sftp-server
diff --git a/files/usr/local/etc/jailctl.conf.freebsd_hypervisor b/files/usr/local/etc/jailctl.conf.freebsd_hypervisor
index a3a37dc..0b51308 100644
--- a/files/usr/local/etc/jailctl.conf.freebsd_hypervisor
+++ b/files/usr/local/etc/jailctl.conf.freebsd_hypervisor
@@ -5,7 +5,7 @@ JAIL_DATASET='${hypervisor_jail_dataset}'
TRUNK_INTERFACE='${hypervisor_trunk_interface}'
DEFAULT_DOMAIN='${domain}'
-DEFAULT_NAMESERVERS='${resolvers:-1.1.1.1}'
+DEFAULT_NAMESERVERS='1.1.1.1'
DEFAULT_VLAN='${hypervisor_default_vlan}'
DEFAULT_NETMASK='$(prefix2netmask "$hypervisor_default_prefix")'
DEFAULT_OS_QUOTA='${hypervisor_default_os_quota}'
diff --git a/files/usr/local/etc/nginx/nginx.conf.common b/files/usr/local/etc/nginx/nginx.conf.common
new file mode 100644
index 0000000..b0a9a06
--- /dev/null
+++ b/files/usr/local/etc/nginx/nginx.conf.common
@@ -0,0 +1,44 @@
+worker_processes ${nginx_worker_processes};
+worker_rlimit_nofile ${nginx_nofile};
+
+events {
+ worker_connections ${nginx_worker_connections};
+}
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+ index index.html;
+
+ aio threads;
+ aio_write on;
+ sendfile on;
+ directio 4m;
+ tcp_nopush on;
+ tcp_nodelay on;
+ keepalive_timeout 65;
+ types_hash_max_size 2048;
+ server_tokens off;
+ client_max_body_size 5m;
+ charset utf-8;
+ gzip on;
+ gzip_http_version 1.0;
+ gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json image/svg+xml;
+
+ proxy_buffers 64 32k;
+ proxy_busy_buffers_size 64k;
+ fastcgi_buffers 64 32k;
+
+ ssl_session_timeout 1d;
+ ssl_session_cache shared:SSL:10m;
+ ssl_session_tickets off;
+ ssl_protocols TLSv1.3;
+ ssl_prefer_server_ciphers off;
+
+ map \$http_upgrade \$connection_upgrade {
+ default upgrade;
+ '' keep-alive;
+ }
+
+ include vhosts.conf;
+}
diff --git a/files/usr/local/etc/nginx/vhosts.conf.pkg_repository b/files/usr/local/etc/nginx/vhosts.conf.pkg_repository
new file mode 100644
index 0000000..8177626
--- /dev/null
+++ b/files/usr/local/etc/nginx/vhosts.conf.pkg_repository
@@ -0,0 +1,47 @@
+server {
+ listen 0.0.0.0:80 default_server;
+ listen [::]:80 default_server;
+ server_name ${fqdn};
+ root ${poudriere_data_dir}/data/packages;
+
+ include mime.types;
+ types {
+ text/plain log;
+ }
+
+ location /poudriere/ {
+ alias /usr/local/share/poudriere/html/;
+
+ # Allow caching static resources
+ location ~* ^.+\.(jpg|jpeg|gif|png|ico|svg|woff|css|js|html)$ {
+ add_header Cache-Control "public";
+ expires 2d;
+ }
+
+ location /poudriere/data {
+ alias ${poudriere_data_dir}/data/logs/bulk;
+
+ # Allow caching dynamic files but ensure they get rechecked
+ location ~* ^.+\.(log|txz|tbz|bz2|gz)$ {
+ add_header Cache-Control "public, must-revalidate, proxy-revalidate";
+ }
+
+ # Don't log json requests as they come in frequently and ensure
+ # caching works as expected
+ location ~* ^.+\.(json)$ {
+ add_header Cache-Control "public, must-revalidate, proxy-revalidate";
+ access_log off;
+ log_not_found off;
+ }
+
+ # Allow indexing only in log dirs
+ location ~ /poudriere/data/?.*/(logs|latest-per-pkg)/ {
+ autoindex on;
+ }
+ }
+ }
+
+ location / {
+ autoindex on;
+ }
+}
diff --git a/files/usr/local/etc/pkg/repos/FreeBSD.conf.common b/files/usr/local/etc/pkg/repos/FreeBSD.conf.common
new file mode 100644
index 0000000..22521b5
--- /dev/null
+++ b/files/usr/local/etc/pkg/repos/FreeBSD.conf.common
@@ -0,0 +1 @@
+FreeBSD: { enabled: no }
diff --git a/files/usr/local/etc/pkg/repos/onprem.conf.pkg_repository b/files/usr/local/etc/pkg/repos/onprem.conf.pkg_repository
new file mode 100644
index 0000000..ec75151
--- /dev/null
+++ b/files/usr/local/etc/pkg/repos/onprem.conf.pkg_repository
@@ -0,0 +1,5 @@
+${site}: {
+ enabled: yes,
+ url: "file://${poudriere_data_dir}/data/packages/\${ABI}/latest",
+ signature_type: "none",
+}
diff --git a/files/usr/local/etc/poudriere.conf.pkg_repository b/files/usr/local/etc/poudriere.conf.pkg_repository
new file mode 100644
index 0000000..bc9ca75
--- /dev/null
+++ b/files/usr/local/etc/poudriere.conf.pkg_repository
@@ -0,0 +1,16 @@
+ZPOOL=${poudriere_dataset%%/*}
+ZROOTFS=/${poudriere_dataset#*/}/poudriere
+FREEBSD_HOST=https://download.freebsd.org
+RESOLV_CONF=/etc/resolv.conf
+BASEFS=${poudriere_data_dir}
+POUDRIERE_DATA=\${BASEFS}/data
+PARALLEL_JOBS=${poudriere_jobs}
+USE_PORTLINT=no
+USE_TMPFS=yes
+DISTFILES_CACHE=/usr/ports/distfiles
+PKG_REPO_SIGNING_KEY=/usr/local/etc/ssl/repo.key
+URL_BASE=http://${fqdn}/poudriere/
+ALLOW_MAKE_JOBS_PACKAGES='${poudriere_allow_make_jobs_packages:-}'
+PRIORITY_BOOST='${poudriere_priority_boost:-}'
+CCACHE_DIR=\${BASEFS}/ccache
+CCACHE_DIR_NON_ROOT_SAFE=yes
diff --git a/files/usr/local/etc/poudriere.d/make.conf.pkg_repository b/files/usr/local/etc/poudriere.d/make.conf.pkg_repository
new file mode 100644
index 0000000..8348621
--- /dev/null
+++ b/files/usr/local/etc/poudriere.d/make.conf.pkg_repository
@@ -0,0 +1,83 @@
+CFLAGS=-O2 -pipe
+DISABLE_LICENSES=yes
+DEFAULT_VERSIONS+=${poudriere_default_versions:-}
+MAKE_JOBS_NUMBER=${poudriere_make_jobs_number}
+
+# Global port options
+OPTIONS_UNSET=TEST DEBUG GSSAPI_HEIMDAL GSSAPI_BASE GSSAPI_NONE HEIMDAL NLS DOCS AVAHI LIBWRAP MYSQL MSQLND ODBC READLINE PULSEAUDIO UPNP BASH ZSH INFO ALSA SAMBA WAYLAND PLATFORM_WAYLAND PIPEWIRE
+OPTIONS_SET=GSSAPI GSSAPI_MIT NONFREE LIBEDIT
+
+# Per-port options
+databases_akonadi_SET=MYSQL
+databases_luadbi_SET=PGSQL
+databases_postgresql15-client_SET=PAM
+databases_postgresql15-server_SET=PAM
+devel_gitolite_SET=GITUSER
+devel_kio-extras_UNSET=AFC
+devel_librelp_UNSET=GNUTLS
+devel_libudev_devd_SET=GPL
+devel_py-hypothesis_UNSET=CLI CODEMODS DATEUTIL DJANGO DPCONTRACTS GHOSTWRITER LARK NUMPY PANDAS PYTEST PYTZ REDIS
+devel_qca_SET=SASL
+dns_powerdns_SET=OPENLDAP
+dns_powerdns_UNSET=PGSQL SQLITE3
+dns_unbound_SET=TFOCL TFOSE
+dns_unbound_UNSET=DOH
+editors_libreoffice_SET=KF5 PDFIUM
+editors_vim_SET=CTAGS_EXUBERANT XTERM_SAVE
+editors_vim_UNSET=CTAGS_BASE
+finance_gnucash_UNSET=AQBANKING
+graphics_vips_UNSET=MATIO
+irc_znc_SET=CYRUS
+lang_lua53_SET=LIBEDIT_DL
+lang_lua53_UNSET=LIBEDIT
+lang_lua54_SET=LIBEDIT_DL
+lang_lua54_UNSET=LIBEDIT
+mail_dovecot-pigeonhole_SET=LDAP
+mail_dovecot_SET=SOLR LDAP
+mail_mutt_UNSET=HTML
+mail_postfix_SET=LDAP SASL SASLKRB5
+mail_rspamd_SET=HYPERSCAN
+misc_kdeutils_UNSET=KFLOPPY KTEATIME
+multimedia_ffmpeg_SET=OPENSSL
+multimedia_ffmpeg_UNSET=GNUTLS
+multimedia_kdemultimedia_UNSET=KDENLIVE
+multimedia_qt6-multimedia_SET=ALSA
+multimedia_vlc_SET=FLAC MPEG2 X264 X265 VPX DCA FAAD AOM
+net-im_dino_UNSET=RTP
+net-im_py-matrix-synapse_SET=PGSQL URLPREVIEW LDAP
+net_asterisk18_SET=NEWG711 G729 NCURSES
+net_asterisk18_UNSET=DAHDI FREETDS RADIUS NEWT
+net_freeradius3_SET=LDAP MITKRB_PORT
+net_freerdp_SET=OPENH264
+net_kdenetwork_UNSET=FILESHARING KOPETE KRFB
+net_openldap26-server_SET=DEBUG
+net_openldap26-server_UNSET=SMBPWD
+print_cups-filters_UNSET=COLORD
+print_freetype2_SET=LCD_FILTERING
+print_freetype2_UNSET=LCD_RENDERING
+security_cyrus-sasl2-saslauthd_UNSET=BDB1
+security_heimdal-devel_SET=LDAP
+security_heimdal-devel_UNSET=BDB
+security_heimdal_SET=LDAP
+security_heimdal_UNSET=BDB
+security_kf5-kdesu_SET=SUDO
+security_kf5-kdesu_UNSET=SU
+security_krb5_SET=DNS_FOR_REALM
+security_krb5_UNSET=KRB5_HTML KRB5_PDF
+security_pinentry-qt5_SET=LIBSECRET
+security_sudo_SET=LDAP
+security_sudo_UNSET=GSSAPI_MIT
+security_vaultwarden_SET=PGSQL
+shells_bash_UNSET=PORTS_READLINE
+sysutils_htop_SET=LSOF
+sysutils_k3b_UNSET=EMOVIX VCDIMAGER
+sysutils_rsyslog8_SET=GSSAPI RELP OPENSSL
+sysutils_rsyslog8_UNSET=GCRYPT
+www_chromium_SET=WIDEVINE
+www_firefox_UNSET=PROFILE JACK
+www_nginx_SET=HTTPV3 HTTPV3_QTLS HTTP_AUTH_KRB5 HTTP_AUTH_LDAP
+www_nginx_UNSET=MAIL
+www_qt5-webengine_SET=ALSA
+x11-toolkits_gtk30_UNSET=COLORD BROADWAY
+x11_kde5_UNSET=KDEADMIN KDEEDU KDEGAMES
+x11_libinput_UNSET=LIBWACOM
diff --git a/files/usr/local/etc/poudriere.d/pkglist.pkg_repository b/files/usr/local/etc/poudriere.d/pkglist.pkg_repository
new file mode 100644
index 0000000..80fc5e5
--- /dev/null
+++ b/files/usr/local/etc/poudriere.d/pkglist.pkg_repository
@@ -0,0 +1,33 @@
+devel/ccache
+devel/git@lite
+dns/bind-tools
+dns/nsd
+dns/powerdns
+dns/unbound
+editors/vim@console
+editors/vim@tiny
+lang/python
+net/nss-pam-ldapd-sasl
+net/openldap26-client
+net/openldap26-server
+net/p5-perl-ldap
+net/py-python-ldap
+net/rsync
+ports-mgmt/poudriere
+security/acme.sh
+security/cyrus-sasl2-saslauthd
+security/kstart
+security/krb5@default
+security/krb5@ldap
+security/pam_krb5@mit
+security/pam_mkhomedir
+security/sshpass
+security/sudo
+sysutils/htop
+sysutils/lsof
+sysutils/p5-Sys-Syslog
+sysutils/pwgen
+sysutils/stow
+sysutils/tmux
+sysutils/tree
+www/nginx
diff --git a/files/usr/local/etc/ssl/repo.crt.readme b/files/usr/local/etc/ssl/repo.crt.readme
new file mode 100644
index 0000000..1c1ad53
--- /dev/null
+++ b/files/usr/local/etc/ssl/repo.crt.readme
@@ -0,0 +1,3 @@
+Generate this file using:
+
+ openssl rsa -in site/files/usr/local/etc/ssl/repo.key.pkg_repository -pubout -out site/files/usr/local/etc/ssl/repo.crt.freebsd
diff --git a/files/usr/local/etc/ssl/repo.key.readme b/files/usr/local/etc/ssl/repo.key.readme
new file mode 100644
index 0000000..3b14bc6
--- /dev/null
+++ b/files/usr/local/etc/ssl/repo.key.readme
@@ -0,0 +1,4 @@
+Generate this file using:
+
+ openssl genrsa -out site/files/usr/local/etc/ssl/repo.key.pkg_repository 4096
+ ./vault encrypt site/files/usr/local/etc/ssl/repo.key.pkg_repository
diff --git a/files/usr/local/libexec/poudriere-cron.pkg_repository b/files/usr/local/libexec/poudriere-cron.pkg_repository
new file mode 100644
index 0000000..f0291ec
--- /dev/null
+++ b/files/usr/local/libexec/poudriere-cron.pkg_repository
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+set -eu -o pipefail
+
+ports_tree=latest
+
+# update ports tree
+poudriere ports -u -p "$ports_tree" > /dev/null
+
+for jail in "$@"; do
+ poudriere jail -u -j "$jail" > /dev/null
+ poudriere bulk -j "$jail" -f /usr/local/etc/poudriere.d/pkglist -p "$ports_tree" > /dev/null
+done
+
+poudriere distclean -p "$ports_tree" -a -y > /dev/null
+poudriere logclean -N 5 -p "$ports_tree" -y > /dev/null
diff --git a/files/usr/local/poudriere/ccache/ccache.conf.pkg_repository b/files/usr/local/poudriere/ccache/ccache.conf.pkg_repository
new file mode 100644
index 0000000..6c725c8
--- /dev/null
+++ b/files/usr/local/poudriere/ccache/ccache.conf.pkg_repository
@@ -0,0 +1 @@
+max_size = ${poudriere_ccache_size}
diff --git a/files/usr/local/sbin/jailctl.freebsd_hypervisor b/files/usr/local/sbin/jailctl.freebsd_hypervisor
index 03ed563..df48f57 100644
--- a/files/usr/local/sbin/jailctl.freebsd_hypervisor
+++ b/files/usr/local/sbin/jailctl.freebsd_hypervisor
@@ -1072,8 +1072,8 @@ template::download_release(){
template::release2name(){
# Convert a FreeBSD release version to a template name.
- # e.g. for "13.2-RELEASE", return "freebsd13".
- setvar "$1" "freebsd${2%.*}"
+ # e.g. for "13.2-RELEASE", return "freebsd13.2".
+ setvar "$1" "freebsd${2%-*}"
}
template::update_release(){
diff --git a/lib/10-core b/lib/10-core
index 5fa2a16..a97340d 100644
--- a/lib/10-core
+++ b/lib/10-core
@@ -226,7 +226,7 @@ _boxconf_deploy(){
_bc_deploy_target=$1; shift
_bc_deploy_hostname=$1; shift
- _bc_stagedir=$(mktemp -d -t "boxconf-${_bc_deploy_hostname}")
+ _bc_stagedir=$(mktemp -d -t "boxconf-${_bc_deploy_hostname}.XXXXXX")
trap 'rm -rf -- "$_bc_stagedir"' HUP INT QUIT TERM ABRT EXIT
_boxconf_stage "$_bc_deploy_hostname" "$_bc_stagedir"
diff --git a/scripts/hostclass/pkg_repository b/scripts/hostclass/pkg_repository
new file mode 100644
index 0000000..b86704a
--- /dev/null
+++ b/scripts/hostclass/pkg_repository
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+: ${poudriere_versions:='14.1-RELEASE'}
+: ${poudriere_jobs:="$nproc"}
+: ${poudriere_dataset:="${state_dataset:-zroot}"}
+: ${poudriere_make_jobs_number:='8'}
+: ${poudriere_priority_boost:='gcc* llvm* rust'}
+: ${poudriere_allow_make_jobs_packages:='ImageMagick* bitwarden-cli cargo-c *chromium* cmake cmake-core eclipse electron* ffmpeg firefox gcc* gnutls gtk3* icu libreoffice* llvm* mongodb* mysql*-client mysql*-server node* openjdk* openssl pkg qt*-webengine rust webkit* vaultwarden'}
+: ${poudriere_ccache_size:='50.0G'}
+: ${poudriere_default_versions:='imagemagick=7-nox11'}
+
+poudriere_data_dir=/usr/local/poudriere
+poudriere_conf_dir=/usr/local/etc/poudriere.d
+
+# Create poudriere datasets.
+create_dataset -o "mountpoint=${poudriere_data_dir}" "${state_dataset}/poudriere"
+create_dataset -o "mountpoint=${poudriere_conf_dir}" "${state_dataset}/poudriere-config"
+
+# These packages are needed to bootstrap poudriere. On the first run, they'll
+# be installed from the public FreeBSD repos.
+pkg install -y \
+ poudriere \
+ git-lite \
+ nginx \
+ ccache
+
+# Generate poudriere configuration.
+install_template -m 0644 \
+ /usr/local/etc/poudriere.conf \
+ "${poudriere_conf_dir}/make.conf" \
+ "${poudriere_conf_dir}/pkglist"
+install_file -m 0400 /usr/local/etc/ssl/repo.key
+install_directory -m 0755 /usr/ports/distfiles
+install_directory -m 0755 -o nobody -g nobody "${poudriere_data_dir}/ccache"
+install_template -m 0644 -o nobody -g nobody "${poudriere_data_dir}/ccache/ccache.conf"
+
+# Configure and enable nginx to serve the packages.
+install_template -m 0644 \
+ /usr/local/etc/nginx/nginx.conf \
+ /usr/local/etc/nginx/vhosts.conf
+sysrc -v nginx_enable=YES
+service nginx restart
+
+# Create and update the `latest` ports tree.
+[ -d "${poudriere_data_dir}/ports/latest" ] || poudriere ports -c -v -p latest
+poudriere ports -v -u -p latest
+
+# Since we're doing a ton of compilation, disable sync on the poudriere dataset.
+# Possibly snakeoil, but my hope is that most file I/O will end up in the ARC cache
+# and not thrash the disks.
+zfs set sync=disabled "${poudriere_dataset}/poudriere"
+
+# For each specified FreeBSD version, build all packages.
+for version in $poudriere_versions; do
+ jail=$(echo "$version" | tr . _)
+ abi="FreeBSD:${version%%.*}:$(uname -p)"
+
+ [ -d "${poudriere_data_dir}/jails/${jail}" ] || poudriere jail -c -j "$jail" -v "$version"
+ poudriere jail -u -j "$jail"
+ poudriere bulk -v -j "$jail" -f "${poudriere_conf_dir}/pkglist" -p latest
+
+ install_directory -m 0755 "${poudriere_data_dir}/data/packages/${abi}"
+ ln -snfv "../${jail}-latest" "${poudriere_data_dir}/data/packages/${abi}/latest"
+done
+
+# Clean stale distfiles and logs.
+poudriere distclean -v -a -p latest -y
+poudriere logclean -N 5 -p latest -y
+
+# Add an empty directory named "poudriere" in the webroot, just so we can easily
+# click on something in the autoindex page that takes us to the Poudriere interface.
+install_directory -m 0555 "${poudriere_data_dir}/data/packages/poudriere"
+
+# Create cron job to update packages automatically.
+install_file -m 0555 /usr/local/libexec/poudriere-cron
+echo "@weekly root lockf -t 0 /tmp/poudriere-cron.lock /usr/local/libexec/poudriere-cron $(echo "$poudriere_versions" | tr . _)" \
+ | tee /etc/cron.d/poudriere
+
+# Now that we have a valid repo, switch the pkg repo to the local filesystem.
+install_directory -m 0755 \
+ /usr/local/etc/pkg \
+ /usr/local/etc/pkg/repos
+
+install_file -m 0644 /usr/local/etc/pkg/repos/FreeBSD.conf
+install_template -m 0644 /usr/local/etc/pkg/repos/onprem.conf
+
+# Install default packages (now that they've been built).
+pkg update -f
+
+if [ -n "${install_packages:-}" ]; then
+ pkg install $install_packages
+fi
diff --git a/vars/common b/vars/common
index bb7c4db..6ecfc24 100644
--- a/vars/common
+++ b/vars/common
@@ -1,5 +1,6 @@
#!/bin/sh
+site=myhomelab
domain=idm.example.com
email_domain=example.com
locale=en_US.UTF-8
@@ -11,8 +12,23 @@ root_mail_alias="you@${email_domain}"
smtp_host_ip=1.2.3.4
timezone=America/New_York
+nproc=$(nproc)
allowed_tcp_ports=ssh
-bootstrap_resolvers='8.8.8.8 8.8.4.4'
+bootstrap_resolvers='1.1.1.1'
+fqdn="${BOXCONF_HOSTNAME}.${domain}"
smtp_host="smtp.${domain}"
+ssh_authzkeys_user=_authzkeys
tcp_buffer_size=2097152 # suitable for 1 GigE
+
+nginx_nofile=2048
+nginx_worker_connections=768
+if $(( nproc > 4 )); then
+ nginx_worker_processes=4
+else
+ nginx_worker_processes=$nproc
+fi
+
+if [ "${idm_bootstrap:-}" = true ]; then
+ resolvers=$bootstrap_resolvers
+fi
diff --git a/vars/hostclass/pkg_repository b/vars/hostclass/pkg_repository
new file mode 100644
index 0000000..dbd49a7
--- /dev/null
+++ b/vars/hostclass/pkg_repository
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+allowed_tcp_ports='ssh http'