Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local_team_servers := $(shell vagrant status | grep -E -o 'team[0-9]+')
local_team_servers = $(shell vagrant status | grep -E -o 'team[0-9]+')

ci:
@bash ./scripts/ci.sh
Expand All @@ -20,7 +20,7 @@ connect-aws:

provision-local:
# Don't re-provision DB at the same time, since it throws off team server tests
@vagrant provision db
@vagrant provision hub
@vagrant provision $(local_team_servers)

provision-aws:
Expand Down
34 changes: 17 additions & 17 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,26 @@ Vagrant.configure("2") do |config|
config.vbguest.auto_update = false
end

# DB server static IP
db_addr = "10.0.1.10"
ip_bytes = db_addr.split(".")
# hub server static IP
hub_addr = "10.0.1.10"
ip_bytes = hub_addr.split(".")

config.vm.define "db" do |db|
db.vm.box = box
config.vm.define "hub" do |hub|
hub.vm.box = box

db.vm.network "private_network", ip: db_addr
db.vm.network "forwarded_port", guest: 5432, host: 5432, protocol: "tcp" # DB
db.vm.network "forwarded_port", guest: 8000, host: 8000, protocol: "tcp" # Dummy web app
db.vm.network "forwarded_port", guest: 8080, host: 8080, protocol: "tcp" # Score dashboard
hub.vm.network "private_network", ip: hub_addr
hub.vm.network "forwarded_port", guest: 5432, host: 5432, protocol: "tcp" # hub
hub.vm.network "forwarded_port", guest: 8000, host: 8000, protocol: "tcp" # Dummy web app
hub.vm.network "forwarded_port", guest: 8080, host: 8080, protocol: "tcp" # Score dashboard

db.vm.synced_folder ".", "/vagrant", disabled: true
hub.vm.synced_folder ".", "/vagrant", disabled: true

db.vm.provision "file", source: "./scripts", destination: "/tmp/scripts"
db.vm.provision "file", source: "./services", destination: "/tmp/services"
db.vm.provision "file", source: "./score-server", destination: "/tmp/score-server"
db.vm.provision "file", source: "./dummy-web-app", destination: "/tmp/dummy-web-app"
hub.vm.provision "file", source: "./scripts", destination: "/tmp/scripts"
hub.vm.provision "file", source: "./services", destination: "/tmp/services"
hub.vm.provision "file", source: "./score-server", destination: "/tmp/score-server"
hub.vm.provision "file", source: "./dummy-web-app", destination: "/tmp/dummy-web-app"

db.vm.provision "shell",
hub.vm.provision "shell",
inline: <<-SCRIPT
#!/usr/bin/env bash
set -euo pipefail
Expand All @@ -52,7 +52,7 @@ Vagrant.configure("2") do |config|

rm -rf /root/{score-server,services,dummy-web-app}
sudo cp -r /tmp/{score-server,services,dummy-web-app} /root/
bash /tmp/scripts/init-db.sh
bash /tmp/scripts/init-hub.sh
SCRIPT
end

Expand Down Expand Up @@ -81,7 +81,7 @@ Vagrant.configure("2") do |config|
sudo systemctl restart ssh

export team_name="Team-#{i}"
export db_addr='#{db_addr}'
export hub_addr='#{hub_addr}'
bash /tmp/scripts/init.sh
bats -F pretty /.ws/scripts/test.bats
SCRIPT
Expand Down
4 changes: 2 additions & 2 deletions instructions/challenge_2.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ following:
- Once there, the app there needs to be named `run-app`, not `app`

- To ensure both locations always have the same version (e.g. during hotfixes),
make a reference from the binary location to the target location without
copying the actual file. This way, any update or change will reflect in both
make a reference from the binary location to the target location *without
copying the actual file*. This way, any update or change will reflect in both
places at once without needing to manually sync them.
4 changes: 2 additions & 2 deletions instructions/challenge_3.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ Create that service, and get it running. You need to make sure it runs *even if
the system reboots* -- meaning that if the server is restarted for any reason,
the app service needs to start again *without you starting it manually*.

If for any reason you need to check out more detailed logs of the service, you
can also use the separate `journalctl` command to inspect them.
If for any reason you need to check out more detailed logs of the service you're
creating, you can also use the separate `journalctl` command to inspect them.
4 changes: 2 additions & 2 deletions instructions/challenge_4.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ look at the `/opt/app` directory again, you may have noticed that there is a
correctly-installed app binary.

Once you do that, be sure to check the `systemd` and/or `journald` logs of the
new `app-deb.service` to make sure it's running successfully! (and, just like
the last one, that it would keep running after a reboot)
new `app-deb.service` to make sure it's running successfully (and, just like
the last one, that it would keep running after a reboot).
2 changes: 1 addition & 1 deletion instructions/challenge_6.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ dissappeared while on a golfing trip a few weeks past. We were told that the
code was about ready to deploy, just hadn't gotten the chance to merge it into
the main branch. See if you can figure out how to get it up and running.

The name of the app is 'carrot-cruncher'. The last dev got the repo set up
The name of the app is "carrot-cruncher". The last dev got the repo set up
somewhere on disk, but they never said where... hopefully you'll able to find
it. When you do, supposedly there was a new working branch pushed to the remote
repo, so you'll need to figure out how to authenticate to that repo.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Package fetchserver implements server-side and template-rendering logic for
// the score fetcher service
package fetchserver
// Package hubserver implements server-side and template-rendering logic for
// the Hub server's score retrieval & display services
package hubserver

import (
"bytes"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package fetchserver
package hubserver

import (
"reflect"
Expand Down
3 changes: 3 additions & 0 deletions score-server/internal/team-server/serve.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Package teamserver implements score-serving functionality on each workshop
// team's server, which is retrieved by the Hub server
package teamserver
1 change: 1 addition & 0 deletions score-server/internal/team-server/serve_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package teamserver
4 changes: 2 additions & 2 deletions score-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import (
"net"
"net/http"

fetchserver "github.com/opensourcecorp/workshops/linux/score-server/pkg/fetch-server"
hubserver "github.com/opensourcecorp/workshops/linux/score-server/internal/hub-server"
"github.com/sirupsen/logrus"
)

func main() {
http.HandleFunc("/", fetchserver.Root)
http.HandleFunc("/", hubserver.Root)

addr := net.JoinHostPort("0.0.0.0", "8080")
logrus.Infof("Starting server on %s\n", addr)
Expand Down
7 changes: 5 additions & 2 deletions scripts/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ if [[ "$(</tmp/go-modules wc -l)" -gt 0 ]] ; then
printf '> Installing CI checks for Go...\n'
for pkg in \
honnef.co/go/tools/cmd/staticcheck@latest \
github.com/mgechev/revive@latest \
github.com/kisielk/errcheck@latest \
; do
go install "${pkg}"
Expand All @@ -39,9 +40,11 @@ while read -r module ; do
cd "${mod_dir}"
printf '>> Running go vet...\n'
go vet ./...
printf '>> Running linter...\n'
printf '>> Running staticcheck linter...\n'
staticcheck ./...
printf '>> Running error checker...\n'
printf '>> Running revive linter...\n'
revive --set_exit_status ./...
printf '>> Running error-checker...\n'
errcheck ./...
)
done < /tmp/go-modules
Expand Down
File renamed without changes.
18 changes: 9 additions & 9 deletions scripts/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ if [[ -z "${team_name}" ]]; then
log-fatal 'Env var "team_name" not set at runtime'
fi

if [[ -z "${db_addr}" ]]; then
log-fatal 'Env var "db_addr" not set at runtime'
if [[ -z "${hub_addr}" ]]; then
log-fatal 'Env var "hub_addr" not set at runtime'
fi

###
Expand Down Expand Up @@ -84,13 +84,13 @@ ufw default allow incoming
ufw default allow outgoing
ufw deny out 8000
log-info 'Adding file for teams to know which IP to use for one of the networking challenges'
printf '%s\n' "${db_addr}" > /home/appuser/.remote-ip.txt
printf '%s\n' "${hub_addr}" > /home/appuser/.remote-ip.txt

###
log-info 'Writing out vars to env file(s) for systemd services'
rm -f "${wsroot}"/env && touch "${wsroot}"/env
{
printf 'db_addr=%s\n' "${db_addr}"
printf 'hub_addr=%s\n' "${hub_addr}"
printf 'team_name=%s\n' "$(hostname)"
} >> "${wsroot}"/env

Expand All @@ -103,24 +103,24 @@ systemctl enable linux-workshop-admin.timer
systemctl start linux-workshop-admin.timer

###
_db_init() {
_hub_init() {
# shellcheck disable=SC1091
source /usr/local/share/ezlog/src/main.sh
log-info 'Waiting for DB to be reachable...'
until timeout 2s psql -U postgres -h "${db_addr}" -c 'SELECT NOW();' > /dev/null ; do
until timeout 2s psql -U postgres -h "${hub_addr}" -c 'SELECT NOW();' > /dev/null ; do
log-info 'Still waiting for DB to be reachable...'
sleep 5
done
log-info 'Successfully reached DB, trying to initialize with base values so team appears on dashboard...'
# until-loop because DB can be reachable before schema is made
until psql -U postgres -h "${db_addr}" -c "INSERT INTO scoring (timestamp, team_name, last_challenge_completed, score) VALUES (NOW(), '$(hostname)', 0, 0);" > /dev/null ; do
until psql -U postgres -h "${hub_addr}" -c "INSERT INTO scoring (timestamp, team_name, last_challenge_completed, score) VALUES (NOW(), '$(hostname)', 0, 0);" > /dev/null ; do
log-info 'Issue with setting base values; trying again...'
sleep 1
done
log-info 'Successfully initialized with base values'
}
export -f _db_init
timeout 180s bash -c _db_init
export -f _hub_init
timeout 180s bash -c _hub_init

###
log-info 'Dumping the first instruction(s) to the appuser homedir'
Expand Down
8 changes: 4 additions & 4 deletions scripts/linux-workshop-admin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ _score-for-challenge() {
log-info "Providing instruction to user for Challenge ${next_challenge}"
cp "${wsroot}/instructions/challenge_${next_challenge}.md" /home/appuser/
# Also broadcast message to user when challenge is complete
wall "Congrats on finishing Challenge ${which_challenge}! Be sure to check your home directory for any new instruction files! (hit any key to dismiss this message)"
wall "Congrats on finishing Challenge ${which_challenge}! Be sure to check your home directory for any new instruction files! (hit Enter to dismiss this message)"
else
log-info 'Team is done with the workshop!'
cp "${wsroot}/instructions/congrats.md" /home/appuser/
# This check suppresses an infinite loop of congratulations, lol
if [[ ! -f "${wsroot}"/team_has_been_congratulated ]] ; then
wall "Congratulations -- you have completed ALL CHALLENGES! Be sure to read congrats.md in your home directory! (hit any key to dismiss this message)"
wall "Congratulations -- you have completed ALL CHALLENGES! Be sure to read congrats.md in your home directory! (hit Enter to dismiss this message)"
touch "${wsroot}"/team_has_been_congratulated
fi
fi
Expand All @@ -67,7 +67,7 @@ _get-last-challenge-completed() {
# _accrue-points adds monotonically-increasing point values, the rate of which
# will increase over time at aggregate since this is called per-challenge.
_accrue-points() {
psql -U postgres -h "${db_addr:-NOT_SET}" -c "
psql -U postgres -h "${hub_addr:-NOT_SET}" -c "
INSERT INTO scoring (
timestamp,
team_name,
Expand Down Expand Up @@ -131,7 +131,7 @@ _check-debfile-service-running() {
}

_check-webapp-reachable() {
if timeout 1s curl -fsSL "${db_addr:-NOT_SET}:8000" > /dev/null ; then
if timeout 1s curl -fsSL "${hub_addr:-NOT_SET}:8000" > /dev/null ; then
_score-for-challenge 5
else
log-error "web app is not reachable"
Expand Down
6 changes: 3 additions & 3 deletions scripts/provision-ec2-team-parallelizer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ source "${HOME}/.local/ezlog/src/main.sh"

server_num="${1:-NOT_SET}"

if [[ -z "${db_priv_ip:-NOT_SET}" ]] ; then
log-fatal 'db_priv_ip not provided to team server provisioning script'
if [[ -z "${hub_priv_ip:-NOT_SET}" ]] ; then
log-fatal 'hub_priv_ip not provided to team server provisioning script'
fi
if [[ -z "${team_server_ips:-NOT_SET}" ]] ; then
log-fatal 'team_server_ips not provided to team server provisioning script'
Expand All @@ -32,7 +32,7 @@ log-info "Adding files to Team server ${server_num} at ${server_ip}..."
scp -P 2332 -r -o StrictHostKeyChecking=accept-new ../scripts ../services ../instructions ../dummy-app-src admin@"${server_ip}":/tmp

log-info "Running init on Team server ${server_num} at ${server_ip}..."
ssh -p 2332 admin@"${server_ip}" "export team_name=Team-${server_num} && export db_addr=${db_priv_ip} && sudo -E bash /tmp/scripts/init.sh"
ssh -p 2332 admin@"${server_ip}" "export team_name=Team-${server_num} && export hub_addr=${hub_priv_ip} && sudo -E bash /tmp/scripts/init.sh"

log-info "Running tests on Team server ${server_num} at ${server_ip}..."
ssh -p 2332 admin@"${server_ip}" "sudo -E bats /.ws/scripts/test.bats"
Expand Down
22 changes: 11 additions & 11 deletions scripts/provision-ec2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -euo pipefail
################################################################################
# Root script to provision AWS EC2 instances for the workshop.
#
# The DB server is provisioned first, and then each team server is provisioned
# The Hub server is provisioned first, and then each team server is provisioned
# in parallel by the neighbor script.
################################################################################

Expand All @@ -31,25 +31,25 @@ log-info 'Getting Terraform outputs...'
(cd ../terraform && terraform output -json) > "${outputs_file}"

log-info 'Determining IP addresses of DB server...'
db_pub_ip="$(jq -rc '.db_pub_ip.value' ${outputs_file})"
db_priv_ip="$(jq -rc '.db_priv_ip.value' ${outputs_file})"
log-info "DB IPs: Public ${db_pub_ip}, Private ${db_priv_ip}"
hub_pub_ip="$(jq -rc '.hub_pub_ip.value' ${outputs_file})"
hub_priv_ip="$(jq -rc '.hub_priv_ip.value' ${outputs_file})"
log-info "Hub IPs: Public ${hub_pub_ip}, Private ${hub_priv_ip}"

log-info 'Determining IP addresses of Team servers...'
num_teams="$(jq '[.instance_ips.value[]] | length' ${outputs_file})"
team_server_ips="$(jq -c '[.instance_ips.value[]]' ${outputs_file})"
log-info "${num_teams} teams, with IPs of: ${team_server_ips}"

# Provision the DB server first, so that if it fails we know we're about to have
# Provision the Hub server first, so that if it fails we know we're about to have
# a bad time overall
log-info 'Adding DB server init script...'
scp -P 2332 -o StrictHostKeyChecking=accept-new -r ../{scripts,services,score-server,dummy-web-app} "admin@${db_pub_ip}":/tmp
ssh -p 2332 admin@"${db_pub_ip}" -- 'sudo cp -r /tmp/{score-server,services,dummy-web-app} /root/'
log-info 'Running DB server init script...'
ssh -p 2332 admin@"${db_pub_ip}" 'sudo bash /tmp/scripts/init-db.sh'
log-info 'Adding Hub server init script...'
scp -P 2332 -o StrictHostKeyChecking=accept-new -r ../{scripts,services,score-server,dummy-web-app} "admin@${hub_pub_ip}":/tmp
ssh -p 2332 admin@"${hub_pub_ip}" -- 'sudo cp -r /tmp/{score-server,services,dummy-web-app} /root/'
log-info 'Running Hub server init script...'
ssh -p 2332 admin@"${hub_pub_ip}" 'sudo bash /tmp/scripts/init-hub.sh'

# Export needed vars so the subscript can see them
export db_priv_ip
export hub_priv_ip
export team_server_ips

# Parallelize provisioning of the team servers
Expand Down
8 changes: 4 additions & 4 deletions scripts/test.bats
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fi
# This file should have been populated on init
# shellcheck disable=SC1091
source "${wsroot}"/env || exit 1
[[ -n "${db_addr:-}" ]] || exit 1
[[ -n "${hub_addr:-}" ]] || exit 1

# setup* and teardown* are bats-specifically-named pre-/post-test hook
# functions. <setup|teardown>_file run once, period, and <setup|teardown> run
Expand Down Expand Up @@ -89,7 +89,7 @@ teardown_file() {
}

_reset-score() {
psql -U postgres -h "${db_addr}" -c "
psql -U postgres -h "${hub_addr}" -c "
DELETE FROM scoring WHERE team_name = '$(hostname)';
INSERT INTO scoring (timestamp, team_name, last_challenge_completed, score) VALUES (NOW(), '$(hostname)', 0, 0);
"
Expand All @@ -101,7 +101,7 @@ _get-score() {
# Need to stop again becaue starting the .service restarts the timer because
# of its 'Want' directive
systemctl stop linux-workshop-admin.timer
local score="$(psql -U postgres -h "${db_addr}" -tAc 'SELECT SUM(score) FROM scoring;')"
local score="$(psql -U postgres -h "${hub_addr}" -tAc 'SELECT SUM(score) FROM scoring;')"
printf '%s' "${score}"
}

Expand Down Expand Up @@ -288,7 +288,7 @@ _solve-challenge-7() {
sleep 1
printf 'DEBUG: Score from challenge 5: %s\n' "${score}"
counter=0
until timeout 1s curl -fsSL "${db_addr}:8000" ; do
until timeout 1s curl -fsSL "${hub_addr}:8000" ; do
printf 'Web app not reachable, trying again...\n' >&2
counter="$((counter + 1))"
if [[ "${counter}" -ge 30 ]] ; then
Expand Down
6 changes: 3 additions & 3 deletions terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ provider "aws" {
}

locals {
db_ip = "10.0.1.10"
hub_ip = "10.0.1.10"
region = var.aws_region
name = "${var.event_name}-osc-workshop-linux"
my_cidr = "${chomp(data.http.my_ip.response_body)}/32"
Expand Down Expand Up @@ -89,11 +89,11 @@ module "security_group" {
tags = local.tags
}

module "db" {
module "hub" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "~> 4.0"

name = "${local.name}-db"
name = "${local.name}-hub"

ami = data.aws_ami.latest.id
instance_type = "t3a.micro"
Expand Down
Loading
Loading