add tester ui, and restructure folders

This commit is contained in:
2026-05-13 17:00:00 -03:00
parent 7c5aa14409
commit 6652cb26e6
17 changed files with 2656 additions and 1251 deletions

View File

@@ -2,9 +2,27 @@ FROM python:3.13-slim
WORKDIR /app
# Function-specific deps first. Each function carries its own requirements.txt
# (so a real AWS deploy zips the function folder verbatim). Locally, the pod
# installs the union of all of them.
COPY functions/ ./functions/
RUN set -e; \
for r in functions/*/requirements.txt; do \
[ -f "$r" ] && pip install --no-cache-dir -r "$r"; \
done
# Runner deps (FastAPI + uvicorn). Lives only in the runner pod; NOT bundled
# with any function zip for AWS.
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY lambda_function.py invoke.py seed.py ./
# Shared modules (Lambda-Layer equivalent) and generic tooling.
COPY shared/ ./shared/
COPY invoke.py runner.py ./
CMD ["sleep", "infinity"]
# uvicorn --reload restarts on .py change → every code edit produces a fresh
# cold start, matching how AWS Lambda's container lifecycle works when you
# redeploy. Watching the whole /app tree picks up function-folder edits too.
CMD ["uvicorn", "runner:app", \
"--host", "0.0.0.0", "--port", "8000", \
"--reload", "--reload-dir", "/app"]

View File

@@ -23,9 +23,16 @@ docker_build(
dockerfile='Dockerfile.lambda',
ignore=['.git', 'def', '.venv', 'docs', '__pycache__', '.pytest_cache'],
live_update=[
sync('../lambda_function.py', '/app/lambda_function.py'),
# Whole functions/ directory — new files appear in the tester's
# function list automatically; edits to existing files cause uvicorn
# to drop them from the warm-cache so the next invoke is cold (the
# `reset_modules` endpoint also lets you force it manually).
sync('../functions', '/app/functions'),
sync('../invoke.py', '/app/invoke.py'),
sync('../seed.py', '/app/seed.py'),
# runner.py change → uvicorn --reload restarts the process → all
# function modules drop out of the cache, next invocation cold.
sync('../runner.py', '/app/runner.py'),
],
)
@@ -45,7 +52,18 @@ k8s_resource('lambda', resource_deps=['minio'])
k8s_resource('docs')
k8s_resource('gateway', resource_deps=['docs', 'minio'])
# Hot-reload gateway Caddy on Caddyfile edit. configMapGenerator uses
# disableNameSuffixHash so the Deployment template doesn't change → kustomize
# won't roll the pod on its own. This local_resource closes the loop.
local_resource(
'gateway-reload',
cmd='kubectl --context kind-eth -n eth rollout restart deployment/gateway',
deps=['k8s/base/Caddyfile'],
resource_deps=['gateway'],
auto_init=False,
)
k8s_resource(
objects=['eth:namespace', 'eth-config:configmap'],
objects=['eth:namespace', 'eth-config:configmap', 'gateway-config:configmap'],
new_name='infra',
)

View File

@@ -1,3 +1,12 @@
#!/usr/bin/env bash
# Invoke a function from functions/ directly via `python invoke.py`.
# Usage:
# ctrl/invoke.sh # default: first function found
# ctrl/invoke.sh lambda_function # specific function
# ctrl/invoke.sh lambda_function '{"key":"val"}' # with event payload
#
# For the same invocation through the FastAPI tester (with cold/warm + memory
# metrics) use the Lambda Tester tab at http://eth.local.ar or POST to
# http://eth.local.ar/runner/invoke/<name>.
set -euo pipefail
kubectl --context kind-eth -n eth exec -i deploy/lambda -- python invoke.py "$@"

View File

@@ -4,6 +4,22 @@
}
eth.local.ar:80 {
# API surface for the local Lambda tester (FastAPI in the lambda pod).
# Path-based is fine for our own API — no SPA assumes ownership of `/`,
# and a single origin means no CORS headaches with the frontend at /.
handle_path /runner/* {
reverse_proxy lambda:8000
}
# Everything else → static docs viewer (the frontend lives here too).
handle {
reverse_proxy docs:80
}
}
docs.eth.local.ar:80 {
# Serve /docs.html for the root path; everything else (graphs, viewer.html) passes through.
rewrite / /docs.html
reverse_proxy docs:80
}

View File

@@ -12,10 +12,14 @@ resources:
- gateway.yaml
# Generate the gateway Caddyfile ConfigMap from the standalone file.
# Hash suffix is on by default — when Caddyfile changes, the ConfigMap gets
# a new hashed name, kustomize rewrites the Deployment volume reference,
# and the gateway pod restarts automatically with the new config.
# Hash suffix disabled so the name stays static — lets Tilt group it under
# the 'infra' resource (no "uncategorized" pill). Trade-off: pod doesn't
# auto-restart on Caddyfile change; the Tiltfile has a local_resource
# 'gateway-reload' that does `kubectl rollout restart` whenever Caddyfile
# is edited, so the experience is the same in practice.
configMapGenerator:
- name: gateway-config
files:
- Caddyfile
options:
disableNameSuffixHash: true

View File

@@ -16,8 +16,14 @@ spec:
containers:
- name: lambda
image: eth-lambda
command: ["sleep", "infinity"]
# The container runs the FastAPI runner (see runner.py + Dockerfile).
# The CMD comes from the Dockerfile (uvicorn). Container also stays
# exec-able for `bash ctrl/seed.sh` / `bash ctrl/invoke.sh` which
# spawn separate python processes alongside uvicorn.
workingDir: /app
ports:
- name: http
containerPort: 8000
envFrom:
- configMapRef:
name: eth-config
@@ -25,14 +31,33 @@ spec:
- name: documents
mountPath: /mnt/documents
readOnly: true
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 3
periodSeconds: 5
resources:
requests:
memory: 128Mi
cpu: 100m
limits:
memory: 512Mi
memory: 1Gi
volumes:
- name: documents
hostPath:
path: /mnt/documents
type: Directory
---
apiVersion: v1
kind: Service
metadata:
name: lambda
namespace: eth
spec:
selector:
app: lambda
ports:
- name: http
port: 8000
targetPort: 8000

View File

@@ -1,3 +1,8 @@
#!/usr/bin/env bash
# Uploads the host's /mnt/documents tree into the in-cluster MinIO. Lives
# inside the sign_pdfs function folder because it's specific to *this*
# function's data shape (bucket "my-company-reports-bucket", prefix "2026/04/").
# Other functions will have their own seed scripts in their own folders.
set -euo pipefail
kubectl --context kind-eth -n eth exec -i deploy/lambda -- python seed.py /mnt/documents
kubectl --context kind-eth -n eth exec -i deploy/lambda -- \
python functions/sign_pdfs/seed.py /mnt/documents