Skip to content

Commit

Permalink
✨ setup script
Browse files Browse the repository at this point in the history
  • Loading branch information
haliphax committed Apr 2, 2024
1 parent 76c654e commit a64b7b7
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 43 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,12 @@ jobs:

build:
name: Build
needs: validate
needs: changes
if: needs.changes.outputs.src == 'true' || github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Check out
uses: actions/checkout@v4

- name: Build docker image
run: docker compose -f docker/docker-compose.yml build
run: docker build -t xthulu -f docker/Dockerfile .
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,19 @@ character sets (UTF-8) and [terminal capabilities][] are taken advantage of.

## Setup

```shell
# in the project root
etc/setup.sh
```

<details>
<summary>Manual steps</summary>

---

If you want to perform the steps in the setup script manually for some reason,
here they are:

### Create a configuration file and generate host keys

```shell
Expand All @@ -98,7 +111,8 @@ ssh-keygen -f ssh_host_key -t rsa -b 4096 -N ""

```shell
# in the docker/ directory
docker compose build
docker compose build base-image
docker compose pull --ignore-buildable
```

### Create and seed the database
Expand All @@ -120,6 +134,10 @@ etc/user.sh db create --seed
etc/build-web.sh
```

---

</details>

### Start the services

```shell
Expand Down
3 changes: 3 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# configuration common to all services using the xthulu image
x-xthulu-common: &xthulu-common
build:
pull: false
environment:
TERM: xterm-256color
image: xthulu
Expand Down Expand Up @@ -43,6 +45,7 @@ services:
user:
entrypoint: /usr/local/bin/python3 -m userland
depends_on:
- base-image
- cache
- db
image: xthulu
Expand Down
31 changes: 31 additions & 0 deletions etc/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# set up the system for the first time

set -eo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")/../data"

if [[ -f "config.toml" ]]; then
echo "config.toml already exists; skipping"
else
echo "creating config.toml from config.example.toml"
cp config.example.toml config.toml
fi

if [[ -f "ssh_host_key" ]]; then
echo "ssh_host_key already exists; skipping"
else
echo "generating ssh_host_key"
ssh-keygen -f ssh_host_key -t rsa -b 4096 -N ""
fi

cd ../docker
echo "building base image"
docker compose build base-image
echo "pulling service images"
docker compose pull --ignore-buildable
cd ../etc
echo "initializing database"
./cli.sh db create --seed
./user.sh db create --seed
echo "building static web site"
./build-web.sh
29 changes: 4 additions & 25 deletions userland/cli/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
from inspect import isclass

# 3rd party
from click import confirm, echo, group, option
from click import echo, group, option

# api
from xthulu.resources import Resources

db = Resources().db


async def _get_models():
db = Resources().db
await db.set_bind(db.bind)
models = import_module("...models", __name__)

Expand All @@ -23,8 +24,6 @@ async def _get_models():
if not (isclass(model) and issubclass(model, db.Model)):
continue

print(f"- {model.__name__}")

yield model


Expand All @@ -46,6 +45,7 @@ def create(seed_data=False):

async def f():
async for model in _get_models():
print(f"- {model.__name__}")
await model.gino.create()

get_event_loop().run_until_complete(f())
Expand Down Expand Up @@ -91,24 +91,3 @@ def seed():
"""Initialize database with seed data."""

_seed()


@cli.command()
@option(
"--yes",
"confirmed",
default=False,
flag_value=True,
help="Skip confirmation.",
)
def destroy(confirmed=False):
"""Drop database tables."""

async def f():
async for model in _get_models():
await model.gino.drop()

if confirmed or confirm(
"Are you sure you want to drop the userland tables?"
):
get_event_loop().run_until_complete(f())
35 changes: 20 additions & 15 deletions xthulu/cli/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
# local
from ..resources import Resources

db = Resources().db


@group("db")
def cli():
Expand All @@ -29,12 +31,11 @@ def create(seed_data=False):

import_module("...models", __name__)
loop = get_event_loop()
res = Resources()

async def f():
await res.db.set_bind(res.db.bind)
await db.set_bind(db.bind)
echo("Creating database and tables")
await res.db.gino.create_all()
await db.gino.create_all()

loop.run_until_complete(f())

Expand All @@ -53,29 +54,33 @@ async def f():
def destroy(confirmed=False):
"""Drop database tables."""

import_module("...models", __name__)
loop = get_event_loop()
res = Resources()

async def f():
await res.db.set_bind(res.db.bind)
import_module("...models", __name__)

# try to load userland models for destruction
try:
from userland.cli.db import _get_models

async for _ in _get_models():
pass
except ImportError:
pass

await db.set_bind(db.bind)
echo("Dropping database tables")
await res.db.gino.drop_all()
await db.gino.drop_all()

if confirmed or confirm(
"Are you sure you want to destroy the database tables?"
):
loop.run_until_complete(f())
get_event_loop().run_until_complete(f())


def _seed():
from ..models import User

loop = get_event_loop()
res = Resources()

async def f():
await res.db.set_bind(res.db.bind)
await db.set_bind(db.bind)

echo("Creating guest user")
pwd, salt = User.hash_password("guest")
Expand All @@ -95,7 +100,7 @@ async def f():
salt=salt,
)

loop.run_until_complete(f())
get_event_loop().run_until_complete(f())


@cli.command()
Expand Down

0 comments on commit a64b7b7

Please sign in to comment.