mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Merge branch 'dev' into staging
This commit is contained in:
commit
fa171fbdfb
8 changed files with 101 additions and 49 deletions
|
|
@ -12,6 +12,7 @@ from contextlib import suppress
|
|||
|
||||
from os import getenv
|
||||
|
||||
|
||||
def print_md_table(settings) -> MarkdownTableWriter:
|
||||
writer = MarkdownTableWriter(
|
||||
headers=["Setting", "Default", "Context", "Multiple", "Description"],
|
||||
|
|
@ -101,9 +102,8 @@ for pro in glob(f"v{version}/*/plugin.json"):
|
|||
with open(pro, "r") as f:
|
||||
with suppress(Exception):
|
||||
pro_plugin = loads(f.read())
|
||||
if len(pro_plugin["settings"]) > 0:
|
||||
core_settings[pro_plugin["name"]] = pro_plugin
|
||||
core_settings[pro_plugin["name"]]["is_pro"] = True
|
||||
core_settings[pro_plugin["name"]] = pro_plugin
|
||||
core_settings[pro_plugin["name"]]["is_pro"] = True
|
||||
|
||||
# Print plugins and their settings
|
||||
for data in dict(sorted(core_settings.items())).values():
|
||||
|
|
@ -113,7 +113,8 @@ for data in dict(sorted(core_settings.items())).values():
|
|||
print(f"## {data['name']}{pro_crown}\n", file=doc)
|
||||
print(f"{stream_support(data['stream'])}\n", file=doc)
|
||||
print(f"{data['description']}\n", file=doc)
|
||||
print(print_md_table(data["settings"]), file=doc)
|
||||
if data["settings"]:
|
||||
print(print_md_table(data["settings"]), file=doc)
|
||||
|
||||
# Remove zip file
|
||||
Path(f"v{version}.zip").unlink()
|
||||
|
|
|
|||
|
|
@ -99,6 +99,25 @@ Backup your data to a custom location. Ensure the safety and availability of you
|
|||
|`BACKUP_SCHEDULE` |`daily` |global |no |The frequency of the backup |
|
||||
|`BACKUP_ROTATION` |`7` |global |no |The number of backups to keep |
|
||||
|
||||
## Backup S3 <img src='../assets/img/pro-icon.svg' alt='crow pro icon' height='24px' width='24px' style='transform : translateY(3px);'> (PRO)
|
||||
|
||||
|
||||
STREAM support :white_check_mark:
|
||||
|
||||
Automatically backup your data to an S3 bucket
|
||||
|
||||
| Setting |Default|Context|Multiple| Description |
|
||||
|-----------------------------|-------|-------|--------|--------------------------------------------|
|
||||
|`USE_BACKUP_S3` |`no` |global |no |Enable or disable the S3 backup feature |
|
||||
|`BACKUP_S3_SCHEDULE` |`daily`|global |no |The frequency of the backup |
|
||||
|`BACKUP_S3_ROTATION` |`7` |global |no |The number of backups to keep |
|
||||
|`BACKUP_S3_ENDPOINT` | |global |no |The S3 endpoint |
|
||||
|`BACKUP_S3_BUCKET` | |global |no |The S3 bucket |
|
||||
|`BACKUP_S3_REGION` | |global |no |The S3 region |
|
||||
|`BACKUP_S3_ACCESS_KEY_ID` | |global |no |The S3 access key ID |
|
||||
|`BACKUP_S3_ACCESS_KEY_SECRET`| |global |no |The S3 access key secret |
|
||||
|`BACKUP_S3_COMP_LEVEL` |`6` |global |no |The compression level of the backup zip file|
|
||||
|
||||
## Bad behavior
|
||||
|
||||
STREAM support :white_check_mark:
|
||||
|
|
@ -355,6 +374,7 @@ Automatic creation, renewal and configuration of Let's Encrypt certificates usin
|
|||
|`USE_LETS_ENCRYPT_DNS_WILDCARD` |`yes` |multisite|no |Create wildcard certificates for all domains using DNS challenges. |
|
||||
|`LETS_ENCRYPT_DNS_PROPAGATION` |`default`|multisite|no |The time to wait for DNS propagation in seconds. |
|
||||
|`LETS_ENCRYPT_DNS_CREDENTIAL_ITEM`| |multisite|yes |Configuration item that will be added to the credentials.ini file for the DNS provider.|
|
||||
|`LETS_ENCRYPT_DNS_CLEAR_OLD_CERTS`|`no` |global |no |Clear old certificates when renewing. |
|
||||
|
||||
## Limit
|
||||
|
||||
|
|
@ -384,6 +404,13 @@ Metrics collection and retrieve.
|
|||
|`METRICS_MEMORY_SIZE` |`16m` |global |no |Size of the internal storage for metrics. |
|
||||
|`METRICS_MAX_BLOCKED_REQUESTS`|`100` |global |no |Maximum number of blocked requests to store (per worker).|
|
||||
|
||||
## Migration <img src='../assets/img/pro-icon.svg' alt='crow pro icon' height='24px' width='24px' style='transform : translateY(3px);'> (PRO)
|
||||
|
||||
|
||||
STREAM support :white_check_mark:
|
||||
|
||||
Migration of BunkerWeb configuration between instances made easy via the web UI
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
STREAM support :warning:
|
||||
|
|
@ -656,4 +683,3 @@ Allow access based on internal and external IP/network/rDNS/ASN whitelists.
|
|||
|`WHITELIST_USER_AGENT_URLS`| |global |no |List of URLs, separated with spaces, containing good User-Agent to whitelist. |
|
||||
|`WHITELIST_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to whitelist. |
|
||||
|`WHITELIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to whitelist. |
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ RUN apk add --no-cache bash && \
|
|||
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
|
||||
LABEL version "1.5.7"
|
||||
LABEL url "https://www.bunkerweb.io"
|
||||
LABEL bunkerweb.type "autoconf"
|
||||
|
||||
VOLUME /data
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ RUN apk add --no-cache openssl pcre bash python3 yajl geoip libxml2 libgd curl &
|
|||
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
|
||||
LABEL version "1.5.7"
|
||||
LABEL url "https://www.bunkerweb.io"
|
||||
LABEL bunkerweb.type "bunkerweb"
|
||||
LABEL bunkerweb.INSTANCE "bunkerweb"
|
||||
|
||||
EXPOSE 8080/tcp 8443/tcp
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ COPY --chown=root:scheduler --chmod=770 src/bw/misc/country.mmdb /var/tmp/bunker
|
|||
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
|
||||
LABEL version "1.5.7"
|
||||
LABEL url "https://www.bunkerweb.io"
|
||||
LABEL bunkerweb.type "scheduler"
|
||||
|
||||
VOLUME /data
|
||||
|
||||
|
|
|
|||
|
|
@ -578,59 +578,68 @@ if __name__ == "__main__":
|
|||
|
||||
# infinite schedule for the jobs
|
||||
logger.info("Executing job scheduler ...")
|
||||
errors = 0
|
||||
while RUN and not NEED_RELOAD:
|
||||
SCHEDULER.run_pending()
|
||||
sleep(1)
|
||||
current_time = datetime.now()
|
||||
|
||||
while DB_LOCK_FILE.is_file() and DB_LOCK_FILE.stat().st_ctime + 30 > current_time.timestamp():
|
||||
logger.debug("Database is locked, waiting for it to be unlocked (timeout: 30s) ...")
|
||||
try:
|
||||
SCHEDULER.run_pending()
|
||||
sleep(1)
|
||||
current_time = datetime.now()
|
||||
|
||||
DB_LOCK_FILE.unlink(missing_ok=True)
|
||||
while DB_LOCK_FILE.is_file() and DB_LOCK_FILE.stat().st_ctime + 30 > current_time.timestamp():
|
||||
logger.debug("Database is locked, waiting for it to be unlocked (timeout: 30s) ...")
|
||||
sleep(1)
|
||||
|
||||
changes = db.check_changes()
|
||||
DB_LOCK_FILE.unlink(missing_ok=True)
|
||||
|
||||
if isinstance(changes, str):
|
||||
logger.error(f"An error occurred when checking for changes in the database : {changes}")
|
||||
stop(1)
|
||||
changes = db.check_changes()
|
||||
|
||||
# check if the plugins have changed since last time
|
||||
if changes["pro_plugins_changed"]:
|
||||
logger.info("Pro plugins changed, generating ...")
|
||||
PRO_PLUGINS_NEED_GENERATION = True
|
||||
CONFIG_NEED_GENERATION = True
|
||||
RUN_JOBS_ONCE = True
|
||||
NEED_RELOAD = True
|
||||
if isinstance(changes, str):
|
||||
logger.error(f"An error occurred when checking for changes in the database : {changes}")
|
||||
stop(1)
|
||||
|
||||
if changes["external_plugins_changed"]:
|
||||
logger.info("External plugins changed, generating ...")
|
||||
PLUGINS_NEED_GENERATION = True
|
||||
CONFIG_NEED_GENERATION = True
|
||||
RUN_JOBS_ONCE = True
|
||||
NEED_RELOAD = True
|
||||
# check if the plugins have changed since last time
|
||||
if changes["pro_plugins_changed"]:
|
||||
logger.info("Pro plugins changed, generating ...")
|
||||
PRO_PLUGINS_NEED_GENERATION = True
|
||||
CONFIG_NEED_GENERATION = True
|
||||
RUN_JOBS_ONCE = True
|
||||
NEED_RELOAD = True
|
||||
|
||||
# check if the custom configs have changed since last time
|
||||
if changes["custom_configs_changed"]:
|
||||
logger.info("Custom configs changed, generating ...")
|
||||
CONFIGS_NEED_GENERATION = True
|
||||
CONFIG_NEED_GENERATION = True
|
||||
NEED_RELOAD = True
|
||||
if changes["external_plugins_changed"]:
|
||||
logger.info("External plugins changed, generating ...")
|
||||
PLUGINS_NEED_GENERATION = True
|
||||
CONFIG_NEED_GENERATION = True
|
||||
RUN_JOBS_ONCE = True
|
||||
NEED_RELOAD = True
|
||||
|
||||
# check if the config have changed since last time
|
||||
if changes["config_changed"]:
|
||||
logger.info("Config changed, generating ...")
|
||||
CONFIG_NEED_GENERATION = True
|
||||
RUN_JOBS_ONCE = True
|
||||
NEED_RELOAD = True
|
||||
# check if the custom configs have changed since last time
|
||||
if changes["custom_configs_changed"]:
|
||||
logger.info("Custom configs changed, generating ...")
|
||||
CONFIGS_NEED_GENERATION = True
|
||||
CONFIG_NEED_GENERATION = True
|
||||
NEED_RELOAD = True
|
||||
|
||||
# check if the instances have changed since last time
|
||||
if changes["instances_changed"]:
|
||||
logger.info("Instances changed, generating ...")
|
||||
INSTANCES_NEED_GENERATION = True
|
||||
CONFIGS_NEED_GENERATION = True
|
||||
CONFIG_NEED_GENERATION = True
|
||||
NEED_RELOAD = True
|
||||
# check if the config have changed since last time
|
||||
if changes["config_changed"]:
|
||||
logger.info("Config changed, generating ...")
|
||||
CONFIG_NEED_GENERATION = True
|
||||
RUN_JOBS_ONCE = True
|
||||
NEED_RELOAD = True
|
||||
|
||||
# check if the instances have changed since last time
|
||||
if changes["instances_changed"]:
|
||||
logger.info("Instances changed, generating ...")
|
||||
INSTANCES_NEED_GENERATION = True
|
||||
CONFIGS_NEED_GENERATION = True
|
||||
CONFIG_NEED_GENERATION = True
|
||||
NEED_RELOAD = True
|
||||
except BaseException:
|
||||
logger.debug(format_exc())
|
||||
if errors > 5:
|
||||
logger.error(f"An error occurred when executing the scheduler : {format_exc()}")
|
||||
stop(1)
|
||||
errors += 1
|
||||
sleep(5)
|
||||
|
||||
if NEED_RELOAD:
|
||||
CHANGES.clear()
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ COPY --from=builder --chown=0:101 /usr/share/bunkerweb /usr/share/bunkerweb
|
|||
WORKDIR /usr/share/bunkerweb
|
||||
|
||||
# Add ui user, install runtime dependencies, create data folders and set permissions
|
||||
RUN apk add --no-cache bash libmagic && \
|
||||
RUN apk add --no-cache bash libmagic mariadb-client postgresql-client sqlite && \
|
||||
addgroup -g 101 ui && \
|
||||
adduser -h /var/cache/nginx -g ui -s /bin/sh -G ui -D -H -u 101 ui && \
|
||||
echo "Docker" > INTEGRATION && \
|
||||
|
|
@ -66,6 +66,7 @@ RUN apk add --no-cache bash libmagic && \
|
|||
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
|
||||
LABEL version "1.5.7"
|
||||
LABEL url "https://www.bunkerweb.io"
|
||||
LABEL bunkerweb.type "ui"
|
||||
|
||||
VOLUME /data
|
||||
|
||||
|
|
|
|||
|
|
@ -340,6 +340,9 @@ def run_action(plugin: str, function_name: str = ""):
|
|||
if message or not isinstance(res, dict) and not res:
|
||||
return {"status": "ko", "code": 500, "message": message or "The plugin did not return a valid response"}
|
||||
|
||||
if isinstance(res, Response):
|
||||
return res
|
||||
|
||||
return {"status": "ok", "code": 200, "data": res}
|
||||
|
||||
|
||||
|
|
@ -1625,11 +1628,19 @@ def custom_plugin(plugin: str):
|
|||
)
|
||||
|
||||
action_result = run_action(plugin)
|
||||
|
||||
if isinstance(action_result, Response):
|
||||
app.logger.info(f"Plugin {plugin} action executed successfully")
|
||||
return action_result
|
||||
|
||||
# case error
|
||||
if action_result["status"] == "ko":
|
||||
return error_message(action_result["message"]), action_result["code"]
|
||||
|
||||
app.logger.info(f"Plugin {plugin} action executed successfully")
|
||||
|
||||
if request.content_type == "application/x-www-form-urlencoded":
|
||||
return redirect(f"{url_for('plugins')}/{plugin}", code=303)
|
||||
return jsonify({"message": "ok", "data": action_result["data"]}), 200
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue