summaryrefslogtreecommitdiff
path: root/buildscripts/build/build.sh
blob: 5930c00f92fd2e3168a47bf0417c76230707720f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/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}/src/chessh/buildscripts/build"

server_name="chessh.linux.usu.edu"
load_balancer_nginx_site_file="/etc/nginx/sites-enabled/${server_name}.conf"
ha_proxy_cfg_file="/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;
}
"

ha_proxy_cfg="
global
	log /dev/log 	local0
	log /dev/log	local1 notice
	maxconn 2500
	user haproxy
	group haproxy
	daemon
defaults
	log 	global
	mode	tcp
	timeout connect 10s
	timeout client 36h
	timeout server 36h
	option 	dontlognull
listen ssh
	bind 	0.0.0.0:${ssh_port}
	balance	leastconn
	mode	tcp

$(echo "${server_node_ids[@]}" | python3 -c "print(\"\\n\".join([f\"\\tserver pi{i} 192.168.100.{i}:${ssh_port} check inter 30s fall 5 rise 1 \" for i in input().split()]))")
"

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_loadbalancer_conf() {
    dead_files=("/etc/nginx/sites-enabled/default" "/etc/nginx/nginx.conf" "$load_balancer_nginx_site_file" "$ha_proxy_cfg_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

    printf "$ha_proxy_cfg" | sudo tee $ha_proxy_cfg_file

    sudo systemctl restart haproxy
}

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_conn\nRELEASE_NODE=chessh@192.168.100.${node_id}\nRELEASE_DISTRIBUTION=name\nRELEASE_COOKIE=chessh\n" >> $temp_file
    printf "CLUSTER_NODES=$(printf "chessh@192.168.100.%s," ${server_node_ids[@]})\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_loadbalancer_conf
build_server_nodes
build_frontend_nodes