add tester ui, and restructure folders
This commit is contained in:
@@ -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"]
|
||||
|
||||
@@ -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',
|
||||
)
|
||||
|
||||
@@ -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 "$@"
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user