Distributed build tasks!!

This commit is contained in:
Logan Hunt 2023-01-31 15:59:33 -07:00
parent e3604eaeb8
commit 387ac72d1b
No known key found for this signature in database
GPG Key ID: 8AC6A4B840C0EC49
8 changed files with 333 additions and 3 deletions

2
buildscripts/build/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.env
keys/

179
buildscripts/build/build.sh Executable file
View File

@ -0,0 +1,179 @@
#!/usr/bin/bash
frontend_port=3000
server_port=8080
ssh_port=34355
frontend_node_ids=(2)
server_node_ids=(4 5 6)
build_dir="${HOME}/build"
#server_name="usufslc-pi-cluster.bluezone.usu.edu"
server_name="chessh.linux.usu.edu"
load_balancer_nginx_site_file="/etc/nginx/sites-enabled/${server_name}.conf"
ha_proxy_cfg="/etc/haproxy/haproxy.cfg"
ssl_cert_path="/etc/letsencrypt/live/${server_name}"
certbot_webroot_path="/var/www/html/${server_name}"
load_balancer_nginx_site="
upstream frontend {
$(printf "server 192.168.100.%s:${frontend_port};\n" ${frontend_node_ids[@]})
}
upstream api {
$(printf "server 192.168.100.%s:${server_port};\n" ${server_node_ids[@]})
}
server {
default_type application/octet-stream;
server_name ${server_name};
listen 443 ssl;
ssl_certificate ${ssl_cert_path}/fullchain.pem;
ssl_certificate_key ${ssl_cert_path}/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location ~ /.well-known {
allow all;
default_type "text/plain";
alias ${certbot_webroot_path};
}
location /api/ {
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_pass http://api/;
}
location / {
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_pass http://frontend/;
}
}
server {
if (\$host = ${server_name}) {
return 301 https://\$host\$request_uri;
}
server_name ${server_name};
listen 80;
return 404;
}
"
# TODO: Servers should pull server ids from array
ha_proxy_cfg="
global\n
log /dev/log local0\n
log /dev/log local1 notice\n
maxconn 2500\n
user haproxy\n
group haproxy\n
daemon\n
\n
defaults\n
log global\n
mode tcp\n
timeout connect 10s\n
timeout client 36h\n
timeout server 36h\n
option dontlognull\n
\n
listen ssh\n
bind *:${ssh_port}\n
balance leastconn\n
mode tcp\n
server hostA 192.168.100.4:${ssh_port} check inter 10s fall 2 rise 1\n
server hostB 192.168.100.5:${ssh_port} check inter 10s fall 2 rise 1\n
server hostC 192.168.100.6:${ssh_port} check inter 10s fall 2 rise 1\n
"
echo $ha_proxy_cfg
ssh_opts="-oStrictHostKeyChecking=no"
function make_pi_node_conn_str() {
echo "pi$(printf "%04d" $1)@192.168.100.${1}"
}
function copy_ssh_keys() {
if [ ! -d "${build_dir}/keys" ]
then
mkdir "${build_dir}/keys"
chmod 700 "${build_dir}/keys"
cd "${build_dir}/keys"
ssh-keygen -N "" -b 256 -t ecdsa -f ssh_host_ecdsa_key
ssh-keygen -N "" -b 1024 -t dsa -f ssh_host_dsa_key
ssh-keygen -N "" -b 2048 -t rsa -f ssh_host_rsa_key
fi
for node_id in "${server_node_ids[@]}"
do
node_conn=$(make_pi_node_conn_str $node_id)
scp -r $ssh_opts "${build_dir}/keys" $node_conn:~
done
}
function reload_nginx_confs() {
dead_files=("/etc/nginx/sites-enabled/default" "/etc/nginx/nginx.conf" "$load_balancer_nginx_site_file")
for file in "${dead_files[@]}"
do
[ -e $file ] && sudo rm $file
done
sudo cp "${build_dir}/nginx.conf" /etc/nginx/nginx.conf
echo $load_balancer_nginx_site | sudo tee $load_balancer_nginx_site_file
sudo systemctl restart nginx
}
function build_frontend() {
node_id=$1
node_conn=$(make_pi_node_conn_str $node_id)
scp $ssh_opts "${build_dir}/.env" $node_conn:~
scp $ssh_opts "${build_dir}/build_front.sh" $node_conn:~/
ssh $ssh_opts $node_conn "~/build_front.sh"
}
function build_frontend_nodes() {
for node_id in "${frontend_node_ids[@]}"
do
build_frontend $node_id
done
}
function build_server() {
node_id=$1
node_conn=$(make_pi_node_conn_str $node_id)
temp_file=$(mktemp)
cp "${build_dir}/.env" $temp_file
printf "\nNODE_ID=$node_id\n" >> $temp_file
scp $ssh_opts $temp_file $node_conn:~/.env
cp "${build_dir}/chessh.service" $temp_file
sed -i "s/\$BUILD_ENV/\/home\/pi$(printf "%04d" $1)\/.env/" $temp_file
scp -r $ssh_opts $temp_file $node_conn:~/chessh.service
scp $ssh_opts "${build_dir}/build_server.sh" $node_conn:~/
ssh $ssh_opts $node_conn "~/build_server.sh"
}
function build_server_nodes() {
copy_ssh_keys
for node_id in "${server_node_ids[@]}"
do
build_server $node_id
done
}
reload_nginx_confs
build_server_nodes
build_frontend_nodes

View File

@ -0,0 +1,62 @@
#!/usr/bin/bash
export $(cat ~/.env | xargs)
chessh_source="https://github.com/Simponic/chessh"
chessh_path="$HOME/src/chessh"
build_output="/var/www/html/chessh_front"
nginx_site="/etc/nginx/sites-enabled/chessh_front.conf"
front_port=3000
nginx_conf="
server {
listen ${front_port};
listen [::]:${front_port};
location / {
root ${build_output};
index index.html;
try_files \$uri \$uri/ /index.html;
}
}
"
# Grab deps
if [ $(which node) == "" ]
then
curl -sSL https://deb.nodesource.com/setup_16.x | sudo bash -
sudo apt install -y nodejs
fi
[ "$(which git)" != "" ] || sudo apt install -y git
[ "$(which nginx)" != "" ] || sudo apt install -y nginx
# Checkout source
if [ ! -d $chessh_path ]
then
mkdir -p $chessh_path
cd $chessh_path
git init
git remote add origin $chessh_source
git pull origin
git checkout main
git config pull.rebase true
else
cd $chessh_path
git pull origin main
fi
# Build
cd $chessh_path/front
npm ci
npm run build
# Copy to nginx root
sudo rm -rf $build_output
sudo mkdir -p $build_output
sudo cp -r $chessh_path/front/build/* $build_output
sudo chown -R www-data $build_output
# Copy nginx config
echo "$nginx_conf" | sudo tee $nginx_site
# Restart nginx
sudo systemctl restart nginx

View File

@ -0,0 +1,40 @@
#!/usr/bin/bash
export $(cat ~/.env | xargs)
chessh_source="https://github.com/Simponic/chessh"
chessh_path="$HOME/src/chessh"
# Grab deps
[ "$(which git)" != "" ] || sudo apt install -y git
if [ "$(which docker)" = "" ]
then
curl -sSL https://get.docker.com | sh
fi
# Checkout source
if [ ! -d $chessh_path ]
then
mkdir -p $chessh_path
cd $chessh_path
git init
git remote add origin $chessh_source
git pull origin
git checkout main
git config pull.rebase true
else
cd $chessh_path
git pull origin main
fi
# Build
cd $chessh_path
[ -d "$chessh_path/priv/keys" ] && cp ~/keys/* "$chessh_path/priv/keys/" || cp -r ~/keys "$chessh_path/priv"
sudo docker build . -t chessh/server
# Systemd service
cd $HOME
sudo mv chessh.service /etc/systemd/system/chessh.service
sudo systemctl daemon-reload
sudo systemctl enable --now chessh
sudo systemctl restart chessh

View File

@ -0,0 +1,19 @@
[Unit]
Description=CheSSH Server
After=docker.service
BindsTo=docker.service
ReloadPropagatedFrom=docker.service
WantedBy=default.target
[Service]
Restart=always
ExecStartPre=-/usr/bin/docker stop chessh-server
ExecStartPre=-/usr/bin/docker rm chessh-server
ExecStart=/usr/bin/docker run \
--env-file $BUILD_ENV \
--network=host \
--name chessh-server \
chessh/server
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,28 @@
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*.conf;
}

View File

@ -1,10 +1,10 @@
#!/bin/bash #!/bin/bash
env_file=.env.prod env_file=../../.env.prod
export $(cat $env_file | xargs) export $(cat $env_file | xargs)
docker build . -t chessh/server docker build ../.. -t chessh/server
cd front cd front
docker build \ docker build \

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
datestamp=$(date +%Y%m%d-%H%M) datestamp=$(date +%Y%m%d-%H%M)
env_file=.env.prod env_file=../../.env.prod
project_name=chessh project_name=chessh
container_names=("chessh-redis" "chessh-database" "chessh-server" "chessh-frontend") container_names=("chessh-redis" "chessh-database" "chessh-server" "chessh-frontend")