Add deploy script for scouting webserver
This patch lets folks do this to deploy the webserver:
$ bazel run //scouting/deploy
It will copy the webserver to the scouting server, install it, and
start it. You can find a summary in the new README.md file.
Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: I997738db483dc0e7d01a336ef4dde150ccfed070
diff --git a/scouting/BUILD b/scouting/BUILD
index 0ed540b..a769426 100644
--- a/scouting/BUILD
+++ b/scouting/BUILD
@@ -33,6 +33,7 @@
"//scouting/www:index.html",
"//scouting/www:zonejs_copy",
],
+ visibility = ["//scouting/deploy:__pkg__"],
)
protractor_ts_test(
diff --git a/scouting/deploy/BUILD b/scouting/deploy/BUILD
new file mode 100644
index 0000000..ed4b9cd
--- /dev/null
+++ b/scouting/deploy/BUILD
@@ -0,0 +1,60 @@
+load("@rules_pkg//pkg:pkg.bzl", "pkg_deb", "pkg_tar")
+load("@rules_pkg//pkg:mappings.bzl", "pkg_files")
+
+pkg_files(
+ name = "systemd_files",
+ srcs = [
+ "scouting.service",
+ ],
+ prefix = "etc/systemd/system",
+)
+
+pkg_tar(
+ name = "server_files",
+ srcs = [
+ "//scouting",
+ ],
+ include_runfiles = True,
+ package_dir = "opt/frc971/scouting_server",
+ strip_prefix = ".",
+)
+
+pkg_tar(
+ name = "deploy_tar",
+ srcs = [
+ ":systemd_files",
+ ],
+ deps = [
+ ":server_files",
+ ],
+)
+
+pkg_deb(
+ name = "frc971-scouting-server",
+ architecture = "amd64",
+ data = ":deploy_tar",
+ description = "The FRC971 scouting web server.",
+ # TODO(phil): What's a good email address for this?
+ maintainer = "frc971@frc971.org",
+ package = "frc971-scouting-server",
+ postinst = "postinst",
+ predepends = [
+ "systemd",
+ ],
+ prerm = "prerm",
+ version = "1",
+)
+
+py_binary(
+ name = "deploy",
+ srcs = [
+ "deploy.py",
+ ],
+ args = [
+ "--deb",
+ "$(location :frc971-scouting-server)",
+ ],
+ data = [
+ ":frc971-scouting-server",
+ ],
+)
diff --git a/scouting/deploy/README.md b/scouting/deploy/README.md
new file mode 100644
index 0000000..6d223da
--- /dev/null
+++ b/scouting/deploy/README.md
@@ -0,0 +1,37 @@
+Deploying the scouting application
+================================================================================
+The scouting application is deployed to `scouting.frc971.org` via `bazel`:
+```console
+$ bazel run //scouting/deploy
+(Reading database ... 119978 files and directories currently installed.)
+Preparing to unpack .../frc971-scouting-server_1_amd64.deb ...
+Removed /etc/systemd/system/multi-user.target.wants/scouting.service.
+Unpacking frc971-scouting-server (1) over (1) ...
+Setting up frc971-scouting-server (1) ...
+Created symlink /etc/systemd/system/multi-user.target.wants/scouting.service → /etc/systemd/system/scouting.service.
+Connection to scouting.frc971.org closed.
+```
+
+You will need SSH access to the scouting server. You can customize the SSH host
+with the `--host` argument.
+
+The Blue Alliance API key
+--------------------------------------------------------------------------------
+You need to set up an API key on the scouting server so that the scraping logic
+can use it. It needs to live in `/var/frc971/scouting/tba_config.json` and look
+as follows:
+```json
+{
+ "api_key": "..."
+}
+```
+
+Starting and stopping the application
+--------------------------------------------------------------------------------
+When you SSH into the scouting server, use `systemctl` to manage
+`scouting.service` like any other service.
+```console
+$ sudo systemctl stop scouting.service
+$ sudo systemctl start scouting.service
+$ sudo systemctl restart scouting.service
+```
diff --git a/scouting/deploy/deploy.py b/scouting/deploy/deploy.py
new file mode 100644
index 0000000..c9886fb
--- /dev/null
+++ b/scouting/deploy/deploy.py
@@ -0,0 +1,34 @@
+import argparse
+from pathlib import Path
+import subprocess
+import sys
+
+def main(argv):
+ """Installs the scouting application on the scouting server."""
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "--deb",
+ type=str,
+ required=True,
+ help="The .deb file to deploy.",
+ )
+ parser.add_argument(
+ "--host",
+ type=str,
+ default="scouting.frc971.org",
+ help="The SSH host to install the scouting web server to.",
+ )
+ args = parser.parse_args(argv[1:])
+ deb = Path(args.deb)
+
+ # Copy the .deb to the scouting server, install it, and delete it again.
+ subprocess.run(["rsync", "-L", args.deb, f"{args.host}:/tmp/{deb.name}"],
+ check=True, stdin=sys.stdin)
+ subprocess.run(f"ssh -tt {args.host} sudo dpkg -i /tmp/{deb.name}",
+ shell=True, check=True, stdin=sys.stdin)
+ subprocess.run(f"ssh {args.host} rm -f /tmp/{deb.name}",
+ shell=True, check=True, stdin=sys.stdin)
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv))
diff --git a/scouting/deploy/postinst b/scouting/deploy/postinst
new file mode 100644
index 0000000..a7a8b16
--- /dev/null
+++ b/scouting/deploy/postinst
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# This script runs after the frc971-scouting-server package is installed. This
+# script is responsible for making sure the webserver has everything it needs,
+# then starts the webserver.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+# Create a directory for the database to live in.
+mkdir -p /var/frc971/scouting/
+
+# Create an empty The Blue Alliance configuration file.
+if [[ ! -e /var/frc971/scouting/tba_config.json ]]; then
+ echo '{}' > /var/frc971/scouting/tba_config.json
+fi
+
+# Make sure it's all usable by the user.
+chown -R www-data:www-data /var/frc971/scouting/
+
+systemctl daemon-reload
+systemctl enable scouting.service
+systemctl start scouting.service || :
diff --git a/scouting/deploy/prerm b/scouting/deploy/prerm
new file mode 100644
index 0000000..31e3fbc
--- /dev/null
+++ b/scouting/deploy/prerm
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# This script gets run before the frc971-scouting-server package gets removed
+# or upgraded. This script is responsible for stopping the webserver before the
+# underlying files are removed by dpkg.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+systemctl stop scouting.service
+systemctl disable scouting.service
+systemctl daemon-reload
diff --git a/scouting/deploy/scouting.service b/scouting/deploy/scouting.service
new file mode 100644
index 0000000..2990f42
--- /dev/null
+++ b/scouting/deploy/scouting.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=FRC971 Scouting Server
+After=systemd-networkd-wait-online.service
+
+[Service]
+User=www-data
+Group=www-data
+Type=simple
+WorkingDirectory=/opt/frc971/scouting_server
+ExecStart=/opt/frc971/scouting_server/scouting/scouting \
+ -port 8080 \
+ -database /var/frc971/scouting/scouting.db \
+ -tba_config /var/frc971/scouting/tba_config.json
+Restart=always
+
+[Install]
+WantedBy=multi-user.target