Merge branch 'dev' of github.com:bunkerity/bunkerweb into dev
This commit is contained in:
commit
b32f318919
|
@ -0,0 +1,16 @@
|
|||
FROM python:3.11.3-alpine
|
||||
|
||||
WORKDIR /tmp
|
||||
|
||||
COPY requirements.txt .
|
||||
|
||||
RUN MAKEFLAGS="-j $(nproc)" pip install --no-cache -r requirements.txt && \
|
||||
rm -f requirements.txt
|
||||
|
||||
WORKDIR /opt/tests
|
||||
|
||||
COPY main.py .
|
||||
|
||||
RUN apk add --no-cache curl
|
||||
|
||||
ENTRYPOINT [ "python3", "main.py" ]
|
|
@ -0,0 +1,27 @@
|
|||
version: "3.5"
|
||||
|
||||
services:
|
||||
tests:
|
||||
build: .
|
||||
environment:
|
||||
PYTHONUNBUFFERED: "1"
|
||||
GENERATE_SELF_SIGNED_SSL: "no"
|
||||
DISABLE_DEFAULT_SERVER: "no"
|
||||
REDIRECT_HTTP_TO_HTTPS: "no"
|
||||
AUTO_REDIRECT_HTTP_TO_HTTPS: "yes"
|
||||
ALLOWED_METHODS: "GET|POST|HEAD"
|
||||
MAX_CLIENT_SIZE: "5m"
|
||||
SERVE_FILES: "yes"
|
||||
SSL_PROTOCOLS: "TLSv1.2 TLSv1.3"
|
||||
HTTP2: "yes"
|
||||
LISTEN_HTTP: "yes"
|
||||
DENY_HTTP_STATUS: "403"
|
||||
extra_hosts:
|
||||
- "www.example.com:192.168.0.2"
|
||||
networks:
|
||||
bw-services:
|
||||
ipv4_address: 192.168.0.3
|
||||
|
||||
networks:
|
||||
bw-services:
|
||||
external: true
|
|
@ -0,0 +1,72 @@
|
|||
version: "3.5"
|
||||
|
||||
services:
|
||||
bw:
|
||||
image: bunkerity/bunkerweb:1.5.0-beta
|
||||
pull_policy: never
|
||||
labels:
|
||||
- "bunkerweb.INSTANCE"
|
||||
volumes:
|
||||
- ./index.html:/var/www/html/index.html
|
||||
environment:
|
||||
API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24 192.168.0.3"
|
||||
HTTP_PORT: "80"
|
||||
HTTPS_PORT: "443"
|
||||
USE_BUNKERNET: "no"
|
||||
USE_BLACKLIST: "no"
|
||||
LOG_LEVEL: "info"
|
||||
GENERATE_SELF_SIGNED_SSL: "no"
|
||||
USE_MODSECURITY: "no"
|
||||
|
||||
# ? MISC settings
|
||||
DISABLE_DEFAULT_SERVER: "no"
|
||||
REDIRECT_HTTP_TO_HTTPS: "no"
|
||||
AUTO_REDIRECT_HTTP_TO_HTTPS: "yes"
|
||||
ALLOWED_METHODS: "GET|POST|HEAD"
|
||||
MAX_CLIENT_SIZE: "5m"
|
||||
SERVE_FILES: "yes"
|
||||
SSL_PROTOCOLS: "TLSv1.2 TLSv1.3"
|
||||
HTTP2: "yes"
|
||||
LISTEN_HTTP: "yes"
|
||||
DENY_HTTP_STATUS: "403"
|
||||
networks:
|
||||
bw-universe:
|
||||
bw-services:
|
||||
ipv4_address: 192.168.0.2
|
||||
|
||||
bw-scheduler:
|
||||
image: bunkerity/bunkerweb-scheduler:1.5.0-beta
|
||||
pull_policy: never
|
||||
depends_on:
|
||||
- bw
|
||||
- bw-docker
|
||||
environment:
|
||||
DOCKER_HOST: "tcp://bw-docker:2375"
|
||||
LOG_LEVEL: "info"
|
||||
networks:
|
||||
- bw-universe
|
||||
- bw-docker
|
||||
|
||||
bw-docker:
|
||||
image: tecnativa/docker-socket-proxy
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
CONTAINERS: "1"
|
||||
networks:
|
||||
- bw-docker
|
||||
|
||||
networks:
|
||||
bw-universe:
|
||||
name: bw-universe
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 10.20.30.0/24
|
||||
bw-services:
|
||||
name: bw-services
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- subnet: 192.168.0.0/24
|
||||
bw-docker:
|
|
@ -0,0 +1,300 @@
|
|||
from os import getenv
|
||||
from subprocess import run
|
||||
from requests import ConnectionError, head, options, post
|
||||
from socket import create_connection
|
||||
from ssl import CERT_NONE, create_default_context
|
||||
from time import sleep
|
||||
from traceback import format_exc
|
||||
|
||||
try:
|
||||
ssl_generated = getenv("GENERATE_SELF_SIGNED_SSL", "no") == "yes"
|
||||
disabled_default_server = getenv("DISABLE_DEFAULT_SERVER", "no") == "yes"
|
||||
deny_http_status = getenv("DENY_HTTP_STATUS", "403")
|
||||
listen_http = getenv("LISTEN_HTTP", "no") == "yes"
|
||||
|
||||
error = False
|
||||
|
||||
print(
|
||||
"ℹ️ Sending a HEAD request to http://192.168.0.2 (default server) to test DISABLE_DEFAULT_SERVER",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
try:
|
||||
response = head("http://192.168.0.2")
|
||||
|
||||
if response.status_code != 403 and disabled_default_server:
|
||||
print(
|
||||
"❌ Request didn't get rejected, even if default server is disabled, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
elif response.status_code == 403:
|
||||
if not disabled_default_server:
|
||||
print(
|
||||
"❌ Request got rejected, even if the default server is enabled, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
if deny_http_status != "403":
|
||||
print(
|
||||
f"❌ Request got rejected, but the status code shouldn't be 403 as DENY_HTTP_STATUS is set to {deny_http_status}, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
print("✅ Request got rejected, as expected", flush=True)
|
||||
else:
|
||||
if not listen_http:
|
||||
print(
|
||||
"❌ Request didn't get rejected, even if the server is not listening on HTTP, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
if response.status_code not in (404, 301):
|
||||
response.raise_for_status()
|
||||
|
||||
print("✅ Request didn't get rejected, as expected", flush=True)
|
||||
except ConnectionError as e:
|
||||
if listen_http:
|
||||
if deny_http_status == "403" or not disabled_default_server:
|
||||
raise e
|
||||
|
||||
print(
|
||||
"✅ Request got rejected with the expected deny_http_status", flush=True
|
||||
)
|
||||
exit(0)
|
||||
else:
|
||||
print(
|
||||
"✅ Request got rejected because the server is not listening on HTTP, as expected",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
if ssl_generated:
|
||||
sleep(1)
|
||||
|
||||
ssl_protocols = getenv("SSL_PROTOCOLS", "TLSv1.2 TLSv1.3")
|
||||
|
||||
print(
|
||||
f"ℹ️ Creating a socket and wrapping it with SSL an SSL context to test SSL_PROTOCOLS",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
sock = create_connection(("www.example.com", 443))
|
||||
ssl_context = create_default_context()
|
||||
ssl_context.check_hostname = False
|
||||
ssl_context.verify_mode = CERT_NONE
|
||||
ssl_sock = ssl_context.wrap_socket(sock, server_hostname="www.example.com")
|
||||
|
||||
if ssl_sock.version() not in ssl_protocols.split(" "):
|
||||
print(
|
||||
f"❌ SSL_PROTOCOLS is set to {ssl_protocols}, but the socket is using {ssl_sock.version()}, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
print("✅ Socket is using the expected SSL protocol", flush=True)
|
||||
|
||||
if not listen_http:
|
||||
exit(0)
|
||||
else:
|
||||
print(
|
||||
f"ℹ️ Skipping SSL_PROTOCOLS test as SSL is disabled",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
sleep(1)
|
||||
|
||||
redirect_http_to_https = getenv("REDIRECT_HTTP_TO_HTTPS", "no") == "yes"
|
||||
auto_redirect_http_to_https = getenv("AUTO_REDIRECT_HTTP_TO_HTTPS", "no") == "yes"
|
||||
|
||||
print(
|
||||
f"ℹ️ Sending a HEAD request to http://www.example.com to test {'auto ' if auto_redirect_http_to_https else ''}redirect_http_to_https",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
response = head("http://www.example.com", headers={"Host": "www.example.com"})
|
||||
|
||||
if response.status_code == 403:
|
||||
print(
|
||||
"✅ Request got rejected, as expected because the server is not listening on HTTP",
|
||||
flush=True,
|
||||
)
|
||||
else:
|
||||
if response.status_code not in (404, 301):
|
||||
response.raise_for_status()
|
||||
|
||||
if (
|
||||
redirect_http_to_https or (auto_redirect_http_to_https and ssl_generated)
|
||||
) and response.status_code != 301:
|
||||
print(
|
||||
f"❌ Request didn't get redirected, even if {'auto ' if auto_redirect_http_to_https else ''}redirect_http_to_https is enabled, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
print("✅ Request got redirected to https, as expected", flush=True)
|
||||
|
||||
sleep(1)
|
||||
|
||||
allowed_methods = getenv("ALLOWED_METHODS", "GET|POST|HEAD")
|
||||
|
||||
print(
|
||||
f"ℹ️ Sending a OPTIONS request to http{'s' if ssl_generated else ''}://www.example.com to test ALLOWED_METHODS",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
response = options(
|
||||
f"http{'s' if ssl_generated else ''}://www.example.com",
|
||||
headers={"Host": "www.example.com"},
|
||||
)
|
||||
|
||||
if response.status_code == 405:
|
||||
if "OPTIONS" in allowed_methods:
|
||||
print(
|
||||
"❌ Request got rejected, even if OPTIONS is in allowed methods, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
print("✅ Request got rejected, as expected", flush=True)
|
||||
else:
|
||||
if response.status_code != 404:
|
||||
response.raise_for_status()
|
||||
|
||||
if "OPTIONS" not in allowed_methods:
|
||||
print(
|
||||
"❌ Request didn't get rejected, even if OPTIONS is not in allowed methods, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
print("✅ Request didn't get rejected, as expected", flush=True)
|
||||
|
||||
sleep(1)
|
||||
|
||||
max_client_size = getenv("MAX_CLIENT_SIZE", "5m")
|
||||
|
||||
print(
|
||||
f"ℹ️ Sending a POST request to http{'s' if ssl_generated else ''}://www.example.com with a 5+MB body to test MAX_CLIENT_SIZE",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
response = post(
|
||||
f"http{'s' if ssl_generated else ''}://www.example.com",
|
||||
headers={"Host": "www.example.com"},
|
||||
data="a" * 5242881,
|
||||
verify=not ssl_generated,
|
||||
)
|
||||
|
||||
if response.status_code in (413, 400):
|
||||
if max_client_size != "5m":
|
||||
print(
|
||||
f"❌ Request got rejected, but the status code shouldn't be 400 or 413 as MAX_CLIENT_SIZE is set to {max_client_size}, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
print("✅ Request got rejected, as expected", flush=True)
|
||||
else:
|
||||
if response.status_code != 404:
|
||||
response.raise_for_status()
|
||||
|
||||
if max_client_size == "5m":
|
||||
print(
|
||||
f"❌ Request didn't get rejected, even if MAX_CLIENT_SIZE is set to {max_client_size}, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
print("✅ Request didn't get rejected, as expected", flush=True)
|
||||
|
||||
sleep(1)
|
||||
|
||||
serve_files = getenv("SERVE_FILES", "no") == "yes"
|
||||
|
||||
print(
|
||||
f"ℹ️ Sending a HEAD request to http{'s' if ssl_generated else ''}://www.example.com/index.html to test the serve_files option",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
response = head(
|
||||
f"http{'s' if ssl_generated else ''}://www.example.com/index.html",
|
||||
headers={"Host": "www.example.com"},
|
||||
verify=not ssl_generated,
|
||||
)
|
||||
|
||||
if response.status_code != 404 and not serve_files:
|
||||
print(
|
||||
"❌ Request didn't get rejected, even if serve_files is disabled, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
elif response.status_code == 404:
|
||||
if serve_files:
|
||||
print(
|
||||
"❌ Request got rejected, even if serve_files is enabled, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
print("✅ Request got rejected, as expected", flush=True)
|
||||
else:
|
||||
response.raise_for_status()
|
||||
print("✅ Request didn't get rejected, as expected", flush=True)
|
||||
|
||||
sleep(1)
|
||||
|
||||
http2 = getenv("HTTP2", "no") == "yes"
|
||||
|
||||
print(
|
||||
f"ℹ️ Sending a GET request to http{'s' if ssl_generated else ''}://www.example.com with HTTP/2 to test HTTP2",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
proc = run(
|
||||
[
|
||||
"curl",
|
||||
"--insecure",
|
||||
"--http2",
|
||||
"-I",
|
||||
"-H",
|
||||
'"Host: www.example.com"',
|
||||
f"http{'s' if ssl_generated else ''}://www.example.com",
|
||||
"-w '%{response_code} %{http_version}'",
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
|
||||
status_code, http_version = (
|
||||
proc.stdout.splitlines()[-1].replace("'", "").strip().split(" ")
|
||||
)
|
||||
|
||||
if status_code not in ("200", "404"):
|
||||
print(
|
||||
f"❌ Request didn't get accepted, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
elif ssl_generated and http2 and http_version != "2":
|
||||
print(
|
||||
f"❌ Request didn't get accepted with HTTP/2, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
elif (not ssl_generated or not http2) and http_version != "1.1":
|
||||
print(
|
||||
f"❌ Request got accepted with HTTP/2, it shouldn't have, exiting ...",
|
||||
flush=True,
|
||||
)
|
||||
exit(1)
|
||||
|
||||
print(f"✅ Request got accepted with HTTP/{http_version}", flush=True)
|
||||
except SystemExit as e:
|
||||
exit(e.code)
|
||||
except:
|
||||
print(f"❌ Something went wrong, exiting ...\n{format_exc()}", flush=True)
|
||||
exit(1)
|
|
@ -0,0 +1 @@
|
|||
requests==2.30.0
|
|
@ -1 +1,139 @@
|
|||
# TODO
|
||||
#!/bin/bash
|
||||
|
||||
echo "🗃️ Building misc stack ..."
|
||||
|
||||
# Starting stack
|
||||
docker compose pull bw-docker
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🗃️ Pull failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
docker compose -f docker-compose.test.yml build
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🗃️ Build failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
manual=0
|
||||
end=0
|
||||
cleanup_stack () {
|
||||
exit_code=$?
|
||||
if [[ $end -eq 1 || $exit_code = 1 ]] || [[ $end -eq 0 && $exit_code = 0 ]] && [ $manual = 0 ] ; then
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@GENERATE_SELF_SIGNED_SSL: "yes"@GENERATE_SELF_SIGNED_SSL: "no"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@DISABLE_DEFAULT_SERVER: "yes"@DISABLE_DEFAULT_SERVER: "no"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@ALLOWED_METHODS: ".*"$@ALLOWED_METHODS: "GET|POST|HEAD"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@MAX_CLIENT_SIZE: "10m"@MAX_CLIENT_SIZE: "5m"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@SERVE_FILES: "no"@SERVE_FILES: "yes"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@SSL_PROTOCOLS: "TLSv1.2"@SSL_PROTOCOLS: "TLSv1.2 TLSv1.3"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@HTTP2: "no"@HTTP2: "yes"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@LISTEN_HTTP: "no"@LISTEN_HTTP: "yes"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@DENY_HTTP_STATUS: "444"@DENY_HTTP_STATUS: "403"@' {} \;
|
||||
if [[ $end -eq 1 && $exit_code = 0 ]] ; then
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "🗃️ Cleaning up current stack ..."
|
||||
|
||||
docker compose down -v --remove-orphans 2>/dev/null
|
||||
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🗃️ Down failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🗃️ Cleaning up current stack done ✅"
|
||||
}
|
||||
|
||||
# Cleanup stack on exit
|
||||
trap cleanup_stack EXIT
|
||||
|
||||
for test in "default" "ssl_generated" "tweaked" "deny_status_444" "TLSv1.2"
|
||||
do
|
||||
if [ "$test" = "default" ] ; then
|
||||
echo "🗃️ Running tests when misc settings have default values except MAX_CLIENT_SIZE which have the value \"5m\" ..."
|
||||
elif [ "$test" = "ssl_generated" ] ; then
|
||||
echo "🗃️ Running tests when misc settings have default values and the ssl is generated in self signed ..."
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@GENERATE_SELF_SIGNED_SSL: "no"@GENERATE_SELF_SIGNED_SSL: "yes"@' {} \;
|
||||
elif [ "$test" = "tweaked" ] ; then
|
||||
echo "🗃️ Running tests when misc settings have tweaked values ..."
|
||||
echo "ℹ️ Keeping the ssl generated in self signed ..."
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@DISABLE_DEFAULT_SERVER: "no"@DISABLE_DEFAULT_SERVER: "yes"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@ALLOWED_METHODS: ".*"$@ALLOWED_METHODS: "GET|POST|HEAD|OPTIONS"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@MAX_CLIENT_SIZE: "5m"@MAX_CLIENT_SIZE: "10m"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@SERVE_FILES: "yes"@SERVE_FILES: "no"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@HTTP2: "yes"@HTTP2: "no"@' {} \;
|
||||
elif [ "$test" = "deny_status_444" ] ; then
|
||||
echo "🗃️ Running tests when the server's deny status is set to 444 ..."
|
||||
echo "ℹ️ Keeping the ssl generated in self signed ..."
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@DENY_HTTP_STATUS: "403"@DENY_HTTP_STATUS: "444"@' {} \;
|
||||
elif [ "$test" = "TLSv1.2" ] ; then
|
||||
echo "🗃️ Running tests with only TLSv1.2 enabled and when the server is not listening on http ..."
|
||||
echo "ℹ️ Keeping the ssl generated in self signed ..."
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@DISABLE_DEFAULT_SERVER: "yes"@DISABLE_DEFAULT_SERVER: "no"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@SSL_PROTOCOLS: "TLSv1.2 TLSv1.3"@SSL_PROTOCOLS: "TLSv1.2"@' {} \;
|
||||
find . -type f -name 'docker-compose.*' -exec sed -i 's@LISTEN_HTTP: "yes"@LISTEN_HTTP: "no"@' {} \;
|
||||
fi
|
||||
|
||||
echo "🗃️ Starting stack ..."
|
||||
docker compose up -d 2>/dev/null
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🗃️ Up failed, retrying ... ⚠️"
|
||||
manual=1
|
||||
cleanup_stack
|
||||
manual=0
|
||||
docker compose up -d 2>/dev/null
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🗃️ Up failed ❌"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if stack is healthy
|
||||
echo "🗃️ Waiting for stack to be healthy ..."
|
||||
i=0
|
||||
while [ $i -lt 120 ] ; do
|
||||
containers=("misc-bw-1" "misc-bw-scheduler-1")
|
||||
healthy="true"
|
||||
for container in "${containers[@]}" ; do
|
||||
check="$(docker inspect --format "{{json .State.Health }}" $container | grep "healthy")"
|
||||
if [ "$check" = "" ] ; then
|
||||
healthy="false"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ "$healthy" = "true" ] ; then
|
||||
echo "🗃️ Docker stack is healthy ✅"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
i=$((i+1))
|
||||
done
|
||||
if [ $i -ge 120 ] ; then
|
||||
docker compose logs
|
||||
echo "🗃️ Docker stack is not healthy ❌"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start tests
|
||||
|
||||
docker compose -f docker-compose.test.yml up --abort-on-container-exit --exit-code-from tests 2>/dev/null
|
||||
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "🗃️ Test \"$test\" failed ❌"
|
||||
echo "🛡️ Showing BunkerWeb and BunkerWeb Scheduler logs ..."
|
||||
docker compose logs bw bw-scheduler
|
||||
exit 1
|
||||
else
|
||||
echo "🗃️ Test \"$test\" succeeded ✅"
|
||||
fi
|
||||
|
||||
manual=1
|
||||
cleanup_stack
|
||||
manual=0
|
||||
|
||||
echo " "
|
||||
done
|
||||
|
||||
end=1
|
||||
echo "🗃️ Tests are done ! ✅"
|
||||
|
|
Loading…
Reference in New Issue