Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/cla-assistant.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ jobs:
uses: ctfpilot/ci/.github/workflows/cla-assistant.yml@v1.3.0
secrets: inherit
with:
repository: <repository-name>
repository: error-fallback
23 changes: 13 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,30 @@ on:

jobs:
release:
name: Release
uses: ctfpilot/ci/.github/workflows/release.yml@v1.3.0
permissions:
contents: write
packages: write
id-token: write
name: Release
uses: ctfpilot/ci/.github/workflows/release.yml@v1.3.0
secrets:
RELEASE_GH_TOKEN: ${{ secrets.RELEASE_GH_TOKEN }}
with:
repository: ctfpilot/<repository-name>
repository: ctfpilot/error
ENVIRONMENT: Release

update-develop:
if: github.ref == 'refs/heads/main'
name: "Update Develop Branch"
docker:
name: Docker build and push
needs:
- release
uses: ctfpilot/ci/.github/workflows/develop-update.yml@v1.3.0
uses: ctfpilot/ci/.github/workflows/docker.yml@v1.3.0
if: needs.release.outputs.version != '' && needs.release.outputs.version != null
permissions:
contents: read
pull-requests: write
issues: write
packages: write
id-token: write
with:
repository: ctfpilot/<repository-name>
repository: ctfpilot/error
semver: ${{ needs.release.outputs.version }}
arguments: |
VERSION=${{ needs.release.outputs.version }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public/
47 changes: 47 additions & 0 deletions .releaserc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"branches": [
"main",
{
"name": "develop",
"prerelease": "r"
}
],
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "conventionalcommits"
}
],
[
"@semantic-release/release-notes-generator",
{
"preset": "conventionalcommits"
}
],
[
"@semantic-release/github",
{
"successComment": false,
"assets": [
]
}
],
[
"@semantic-release/exec",
{
"prepareCmd": "echo ${nextRelease.version} > version.txt && cp template/k8s.yml k8s/k8s.yml && sed -i 's/{ .Version }/${nextRelease.version}/g' k8s/k8s.yml",
"publishCmd": "echo 'Published version ${nextRelease.version}'"
}
],
[
"@semantic-release/git",
{
"assets": [
"k8s/k8s.yml"
],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
]
}
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM python:3.14-slim AS builder

WORKDIR /app

COPY src/ /app/src

RUN python3 src/generator.py

FROM joseluisq/static-web-server

COPY --from=builder /app/public/ /public

ENV SERVER_CACHE_CONTROL_HEADERS=false
33 changes: 27 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
# CTF Pilot's Template Repository
# CTF Pilot's Error Fallback

## Template information
**Error fallback webserver**

This repository, is a template repository for open-source projects within CTF Pilot.
This repository contains a webserver, which is used as the fallback webserver for errors.
It allows for custom error pages to be shown when errors occur in the CTF Pilot ecosystem.

It provices a EUPL-1.2 License, release system and other standard files.
## How to run

Please remove this section, and replace with relevant information.
Replace `<repository-name>` with the repository name in `.github/workflows/cla-assistant.yml`and `.github/workflows/release.yml`.
For Kubernetes environments, deploy the deployment file provided in `k8s`.
This can be done with `kubectl`:

```sh
kubectl apply -f k8s/k8s.yml
```

The service can also be run locally, using the provided Docker compose file:

```sh
docker compose up -d
```

### Development

In order to generate the pages, run the [`generator.py`](./src/generator.py) script in `src`:

```sh
python3 src/generator.py
```

*This is done automatically in the Docker container build process.*

## Contributing

Expand Down
6 changes: 6 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:
error-fallback:
build: .
ports:
- "8080:80"
restart: always
63 changes: 63 additions & 0 deletions k8s/k8s.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: error-fallback
labels:
app.kubernetes.io/part-of: ctfpilot
app.kubernetes.io/name: error-fallback
app.kubernetes.io/version: 1.0.0-r.1
app.kubernetes.io/component: challenges
ctfpilot.com/component: error-fallback

spec:
# HA setup
replicas: 3
selector:
matchLabels:
ctfpilot.com/component: error-fallback

template:
metadata:
labels:
ctfpilot.com/component: error-fallback
spec:
enableServiceLinks: false
automountServiceAccountToken: false
containers:
- name: instancing-fallback
image: ctfpilot/error-fallback:1.0.0-r.1
imagePullPolicy: Always
ports:
- name: http
containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "10m"
limits:
memory: "256Mi"
cpu: "100m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: error-fallback
labels:
app.kubernetes.io/part-of: ctfpilot
app.kubernetes.io/name: error-fallback
app.kubernetes.io/version: 1.0.0-r.1
app.kubernetes.io/component: challenges
ctfpilot.com/component: error-fallback
spec:
selector:
ctfpilot.com/component: error-fallback
ports:
- name: http
port: 80
targetPort: http
29 changes: 29 additions & 0 deletions src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Error page generation

In order to generate the error pages, run the `generator.py` script in `src`:

```sh
python3 src/generator.py
```

This will generate the error pages based on the layouts and content defined in the `layouts` and `content` folders respectively.

## Templating

A custom templating system is used to insert content into the layouts.
Placeholders in the layout files are defined using the format `/**PLACEHOLDER_NAME**/`.
The generator script replaces these placeholders with the corresponding content.

The placeholders used are:

- `/**ERROR_HTML**/`: The main HTML content for the error page. Inserted from `content`.
- `/**ERROR_JS**/`: Any JavaScript code to be included in the error page. Inserted from `js`.
- `/**ERROR_CSS**/`: Any CSS styles to be included in the error page . Inserted from `css`.

For `error` layout pages, an additional placeholder is used:

- `/**ERROR_CODE**/`: The error code for the error page (e.g., 404, 500). Replaced with the filename part of the content file.

The templating use multiple layouts, which are defined in the `layouts` folder.
Each content file in the `content` folder should be prefixed with the layout name, followed by an underscore.
For example, a content file named `error_404.html` will use the `error` layout, and produce a page named `404.html`.
4 changes: 4 additions & 0 deletions src/content/error_404.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<h1>Not found</h1>
<p>
The page you are looking for could not be found.
</p>
7 changes: 7 additions & 0 deletions src/content/error_500.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<h1>Error</h1>
<p>
An unexpected error has occurred.
</p>
<p>
Go back to the <a href="/">home page</a>.<br />
</p>
4 changes: 4 additions & 0 deletions src/content/error_502.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<h1>Bad gateway</h1>
<p>
The service did not answer correctly.
</p>
5 changes: 5 additions & 0 deletions src/content/error_503.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<h1>No service available</h1>
<p>
The service is currently unavailable. Please try again later. <br />
The service may be restarting or undergoing maintenance.
</p>
5 changes: 5 additions & 0 deletions src/content/error_504.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<h1>Gateway timeout</h1>
<p>
The service was unable to respond in a timely manner. <br />
The service may be restarting or undergoing maintenance.
</p>
4 changes: 4 additions & 0 deletions src/content/error_index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<h1>Error</h1>
<p>
An unexpected error has occurred.
</p>
64 changes: 64 additions & 0 deletions src/css/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
:root {
--header-font: "Hack", monospace, sans-serif;
--body-font: "Hack", monospace, sans-serif;

--light-theme-color: #eebc1d;
--dark-theme-color: #eebc1d;
--text-light: #232323;
--text-dark: #f9f9f9;
--bg-light: #f9f9f9;
--bg-dark: #232323;

--theme-color: var(--light-theme-color);
--bg-color: var(--bg-light);
--text-color: var(--text-light);
}

@media (prefers-color-scheme: dark) {
:root {
--theme-color: var(--dark-theme-color);
--bg-color: var(--bg-dark);
--text-color: var(--text-dark);
}
}

html,
body {
background-color: var(--bg-color);
color: var(--text-color) !important;
font-family: var(--body-font) !important;
margin: 0;
padding: 0;
}

main {
padding: 2rem;
}

h1,
h2,
h3,
h4,
h5 {
font-family: var(--header-font) !important;
}

a {
color: var(--theme-color);
filter: brightness(100%);
transition: filter 0.2s;
}

a:hover {
filter: brightness(95%);
transition: filter 0.2s;
}

.container {
display: flex;
justify-content: center;
text-align: center;
height: 100vh;
overflow-y: hidden;
align-items: center;
}
Loading
Loading