+#!/bin/bash -l
+# Copyright (C) 2016 Ian Kelling
+# This program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
+
+set -x
+
+
+# lj is test server
+case $HOSTNAME in
+ lj)
+ domain=phab.iank.bid
+ alt_domain=fastmail.wiki
+ ;;
+ lk)
+ domain=phab.iankelling.org
+ alt_domain=iankellingusercontent.org
+ ;;
+esac
+
+
+pass=`cat /p/c/machine_specific/$HOSTNAME/phabricator_admin`
+webroot=/usr/share/phabricator/webroot
+user=iank
+name="Ian Kelling"
+email=ian@iankelling.org
+ssh_port=222
+
+fbin() { bin=$1; shift; sudo /usr/share/phabricator/bin/$bin "$@"; }
+fsetd() { fbin config set --database "$@"; }
+
+# phabricator complained about wanting arcanist first
+pi arcanist/unstable mercurial
+
+for x in /a/bin/bash_unpublished/*; do source $x; done
+
+# duplicated in mediawiki setup. todo fix that.
+s DEBIAN_FRONTEND=noninteractive pi mysql-server
+cd # mysql_secure_installation writes some temp files to the current dir,
+# so we need to make sure it's writable.
+if echo exit|mysql -u root -p"$dbpass"; then
+ echo -e "$dbpass\nn\n\n\n\n" | mysql_secure_installation
+else
+ echo -e "\n\n$dbpass\n$dbpass\n\n\n\n\n" | mysql_secure_installation
+fi
+
+mysql -u root -p$dbpass <<EOF
+grant all privileges on \`phabricator\\_%\`.* to 'phabricator'@localhost identified by '$pass';
+EOF
+
+phab-sel() {
+ s debconf-set-selections<<EOF
+phabricator phabricator/pwd_check password $pass
+phabricator phabricator/phabricator_mysql_pwd password $pass
+phabricator phabricator/webserver select None
+phabricator phabricator/phabricator_mysql_user string phabricator
+phabricator phabricator/mysql_host string localhost
+# Domain name or subdomain name used by phabricator:
+phabricator phabricator/domain_name string $domain
+EOF
+}
+phab-sel
+
+pi phabricator/unstable
+
+# debian sets http, but we want https
+s sed -i 's/http:/https:/' /usr/share/phabricator/conf/local/local.json
+
+
+acme-tiny-wrapper $domain
+acme-tiny-wrapper $alt_domain
+
+for x in $domain $alt_domain; do
+ apache-site -r $webroot - $x <<EOF
+RewriteEngine on
+RewriteRule ^/rsrc/(.*) - [L,QSA]
+RewriteRule ^/favicon.ico - [L,QSA]
+RewriteRule ^/php5-fcgi - [L]
+RewriteRule ^(.*)\$ /index.php?__path__=\$1 [B,L,QSA]
+<Directory "$webroot">
+ Require all granted
+</Directory>
+EOF
+done
+
+
+# Before I figured out how to setup the admin in the script,
+# this would limit the site to localhost,
+# and access it through an ssh tunnel until its secure.
+#phab-site -p 127.0.0.1:443
+
+# settings are stored in conf/local/local.json.
+# some settings could also be stored in the database with
+# --database arg. database has higher priority than
+# the config file.
+
+# if you need to restart phabricator, just ser restart apache2
+# https://secure.phabricator.com/book/phabricator/article/restarting/
+
+# to reset things, you can do.
+# fbin storage destroy; pu phabricator; phab-sel; pi phabricator/unstable
+# # but under debian, prolly better to purge, cause db gets created on install
+
+
+# On first run went to the website, registered manually, then
+# went through the gui setup items to get the configuration below.
+
+
+#expect "*"
+#sleep 1
+
+# expect's exits with 0 by default on timeout of an expect command.
+# You can modify this, but it was simpler to use an irregular code to detect
+# actual success.
+sudo expect -d <<EOF
+# The expect lines use shell type globbing. They are not actually
+# needed, but they make the script likely to fail if the questions
+# content changes drastically, and make the script self documenting.
+
+# adds a short delay after each send for more reliable operation
+# (reference: comment in any autoexpect generated script)
+set force_conservative 0
+spawn "/usr/share/phabricator/bin/accountadmin"
+# If we've already set our user, detect different prompt and exit
+# expect basics: when the last alternative matches, there is no need
+# to specify an action, we just continue.
+expect {
+ timeout {exit 1}
+ -nocase "enter a username" exit
+ -nocase "y/n"
+}
+send "y\r"
+expect -nocase timeout {exit 1} "username"
+send "$user\r"
+expect -nocase timeout {exit 1} "create*y/n"
+send "y\r"
+expect -nocase timeout {exit 1} "name"
+send "$name\r"
+expect -nocase timeout {exit 1} "email"
+send "$email\r"
+expect -nocase timeout {exit 1} "password"
+send "$pass\r"
+expect -nocase timeout {exit 1} "bot"
+send "n\r"
+expect -nocase timeout {exit 1} "admin"
+send "y\r"
+expect -nocase timeout {exit 1} "save"
+send "y\r"
+expect eof
+exit
+EOF
+
+
+
+# this tipped me over to using a debian package
+# https://secure.phabricator.com/T4181
+
+fsetd auth.require-approval false
+
+# phabricator recommends going from 16 to at least 32
+sudo sed -ri 's/(^\s*max_allowed_packet)[[:space:]=].*/\1 = 100M/' /etc/mysql/my.cnf
+
+
+setini() {
+ key="$1" value="$2" section="$3" file="$4"
+ sudo sed -ri "/ *\[$section\]/,/^ *\[[^]]+\]/{/^\s*$key[[:space:]=]/d};/ *\[$section\]/a $key = $value" "$file"
+}
+
+setd() { setini "$@" mysqld /etc/mysql/my.cnf; }
+
+# error instead of data corruption:
+setd sql_mode STRICT_ALL_TABLES
+setd ft_stopword_file /usr/share/phabricator/resources/sql/stopwords.txt
+setd ft_min_word_len 3
+# mysql full text search for word1 word2 will and them instead of or them:
+setd ft_boolean_syntax "' |-><()~*:\"\"&^'"
+# default is 128M. recommended starting point is 40% of ram.
+setd innodb_buffer_pool_size 1600M
+
+# this files stopwork, and min_word_len
+mysql -u root -p$dbpass <<'EOF'
+REPAIR TABLE phabricator_search.search_documentfield;
+EOF
+
+fsetd pygments.enabled true
+fbin config set security.alternate-file-domain https://$alt_domain
+
+setini opcache.validate_timestamps '"0"' opcache /etc/php5/apache2/php.ini
+setini post_max_size 100M PHP /etc/php5/apache2/php.ini
+
+fsetd metamta.default-address phabricator@$domain
+fsetd metamta.domain $domain
+
+
+ser restart mysql
+
+# Not sure if this is needed. while developing this script, mysql went down
+# for a bit and the daemons died.
+
+
+# todo, setup inbound email:
+# https://secure.phabricator.com/book/phabricator/article/configuring_inbound_email/
+
+
+# https://secure.phabricator.com/book/phabricator/article/diffusion_hosting/
+# unmatchable password, allows login only via ssh, sudo, etc.
+# this is standard.
+# I tried having no home dir, (-d /nonexistent),
+# but I got an error message on test sshing,
+sudo useradd -p '*' -m --system -s /bin/sh vcs || [[ $? == 9 ]]
+
+# you'd think the debian package would set this. todo: check on a fresh
+# machine
+fbin config set phd.user phabricator
+fbin config set diffusion.ssh-user vcs
+
+option="ALL=(phabricator) SETENV: NOPASSWD:"
+www_files=$(which git hg|sed ':a;N;s/\n/, /;ta')
+vcs_files=$(which git git-upload-pack git-receive-pack hg|sed ':a;N;s/\n/, /;ta')
+[[ $www_files && $vcs_files ]] || exit 1
+www_files="$www_files, /usr/lib/git-core/git-http-backend"
+sudo dd of=/etc/sudoers.d/phabricator <<EOF
+www-data $option $www_files
+vcs $option $vcs_files
+EOF
+
+# Found this due to red x in the ui after setting up a test repo.
+# todo: debian package should do this for us. see also:
+# https://phab.iank.bid/config/edit/environment.append-paths/
+sudo lnf /usr/lib/git-core/git-http-backend /usr/share/phabricator/support/bin
+
+fbin config set diffusion.allow-http-auth true
+
+# couldn't find a really appropriate place for it. It needs parent dir
+# permissions to be root:root.
+file=/usr/share/phabricator-local-ssh-hook.sh
+# from /usr/share/phabricator/resources/sshd/phabricator-ssh-hook.sh
+sudo dd of=$file <<'EOF'
+#!/bin/sh
+# For debugging, you can temporarily do:
+# exec >/tmp/plog 2>&1
+# This script executes as the vcs user
+if [ "$1" != vcs ]; then exit 1; fi
+exec "/usr/share/phabricator/bin/ssh-auth" $@
+EOF
+sudo chmod 755 $file
+
+sudo dd of=/etc/ssh/sshd_config.phabricator <<EOF
+AuthorizedKeysCommand $file
+AuthorizedKeysCommandUser vcs
+AllowUsers vcs
+
+Port $ssh_port
+Protocol 2
+PermitRootLogin no
+AllowAgentForwarding no
+AllowTcpForwarding no
+PrintMotd no
+PrintLastLog no
+PasswordAuthentication no
+AuthorizedKeysFile none
+
+PidFile /var/run/sshd-phabricator.pid
+EOF
+
+sudo dd of=/etc/systemd/system/phabricator-ssh.service <<'EOF'
+[Unit]
+Description=OpenBSD Secure Shell server for phabricator repos
+After=network.target auditd.service
+ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
+
+[Service]
+ExecStart=/usr/sbin/sshd -f /etc/ssh/sshd_config.phabricator
+ExecReload=/bin/kill -HUP $MAINPID
+KillMode=process
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+sudo systemctl daemon-reload
+
+# got this error upon ssh, figured out a solution.
+# [2016-06-10 06:40:15] EXCEPTION: (AphrontInvalidCredentialsQueryException) #1045: Access denied for user 'root'@'localhost' (using password: NO) at [<phutil>/src/aphront/storage/connection/mysql/AphrontBaseMySQLDatabaseConnection.php:306]
+# arcanist(), phabricator(), phutil()
+
+s usermod -a -G vcs www-data
+s usermod -a -G vcs ian
+s usermod -a -G vcs phabricator
+s chown root:vcs /usr/share/phabricator/conf/local/local.json
+fbin config set diffusion.ssh-port $ssh_port
+
+fsetd policy.allow-public true
+
+sgo phabricator-ssh
+
+ser restart apache2
+sgo phabricator
+
+
+# todo, finish next steps here:
+# notably, backup/restore
+# https://secure.phabricator.com/book/phabricator/article/configuration_guide/
+
+
+fbin auth recover iank
+
+cat <<EOF
+# go to link above, then
+# https://$domain/auth/config/new/
+# and add username/pass auth provider.
+EOF
+
+
+
+# beginnings of automating those last manual steps:
+
+
+# for setting the auto provider, we can use the api.
+#arc set-config default https://$domain
+#
+# but first we have to generate an api key by getting
+# https://phab.iank.bid/conduit/login/
+# to do that, we've got to login to the url login.
+# We've got to post to a url on the login page,
+# then record 2 cookies: phuser and phsid
+# It also does a 302 for us to do 2 more pages related to auth/login.
+
+# we need to post to the right url (didn't record it, with these params)
+#allowLogin:"1"
+#allowRegistration:"1"
+#allowLink:"1"
+#allowUnlink:"1"
+
+
+#Serve over HTTP
+#
+#
+# phabricator/ $ ./bin/repository edit rT --as iank --local-path ...
+
+#