Merge branch 'dev' of github.com:bunkerity/bunkerweb into dev

This commit is contained in:
florian 2024-03-20 17:01:35 +01:00
commit 189f2749d4
No known key found for this signature in database
GPG key ID: 93EE47CC3D061500
16 changed files with 121 additions and 66 deletions

View file

@ -43,3 +43,8 @@ sed -i "s@${OLD_VERSION}@${NEW_VERSION}@g" src/common/db/model.py
sed -i "s@${OLD_VERSION}@${NEW_VERSION}@g" .github/ISSUE_TEMPLATE/bug_report.yml
# pyproject
sed -i "s@${OLD_VERSION}@${NEW_VERSION}@g" pyproject.toml
# Dockerfiles
sed -i "s@LABEL version.*@LABEL version \"$NEW_VERSION\"@g" src/bw/Dockerfile
sed -i "s@LABEL version.*@LABEL version \"$NEW_VERSION\"@g" src/scheduler/Dockerfile
sed -i "s@LABEL version.*@LABEL version \"$NEW_VERSION\"@g" src/ui/Dockerfile
sed -i "s@LABEL version.*@LABEL version \"$NEW_VERSION\"@g" src/autoconf/Dockerfile

View file

@ -58,6 +58,10 @@ RUN apk add --no-cache bash && \
# Fix CVEs
# There are no CVEs to fix for this image
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
LABEL version "1.5.6"
LABEL url "https://www.bunkerweb.io"
VOLUME /data
WORKDIR /usr/share/bunkerweb/autoconf

View file

@ -70,6 +70,10 @@ RUN apk add --no-cache openssl pcre bash python3 yajl geoip libxml2 libgd curl &
# Fix CVEs
# There are no CVEs to fix for this image
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
LABEL version "1.5.6"
LABEL url "https://www.bunkerweb.io"
EXPOSE 8080/tcp 8443/tcp
USER nginx:nginx

View file

@ -69,16 +69,17 @@ class Job:
extract_path = cache_path.parent
if job_cache_file["file_name"].startswith("folder:"):
extract_path = Path(job_cache_file["file_name"].split("folder:", 1)[1].rsplit(".tgz", 1)[0])
ignored_dirs.add(extract_path)
ignored_dirs.add(extract_path.as_posix())
if job_cache_file["job_name"] != job_name:
continue
rmtree(extract_path, ignore_errors=True)
extract_path.mkdir(parents=True, exist_ok=True)
with tar_open(fileobj=BytesIO(job_cache_file["data"]), mode="r:gz") as tar:
try:
tar.extractall(extract_path, filter="fully_trusted")
except TypeError:
tar.extractall(extract_path)
with LOCK:
rmtree(extract_path, ignore_errors=True)
extract_path.mkdir(parents=True, exist_ok=True)
with tar_open(fileobj=BytesIO(job_cache_file["data"]), mode="r:gz") as tar:
try:
tar.extractall(extract_path, filter="fully_trusted")
except TypeError:
tar.extractall(extract_path)
continue
elif job_cache_file["job_name"] != job_name:
continue
@ -88,27 +89,29 @@ class Job:
self.logger.error(f"Exception while restoring cache file {job_cache_file['file_name']} :\n{e}")
ret = False
if not manual and self.job_path.is_dir():
for file in self.job_path.glob("**/*"):
skipped = False
for ignored_dir in ignored_dirs:
if file.as_posix().startswith(ignored_dir.as_posix()):
with LOCK:
if not manual and self.job_path.is_dir():
for file in self.job_path.rglob("*"):
skipped = False
if file.as_posix().startswith(tuple(ignored_dirs)):
skipped = True
break
if skipped:
continue
if skipped:
continue
self.logger.debug(f"Checking if {file} should be removed")
if file not in plugin_cache_files and file.is_file():
self.logger.debug(f"Removing non-cached file {file}")
file.unlink(missing_ok=True)
if file.parent.is_dir() and not list(file.parent.iterdir()):
self.logger.debug(f"Removing empty directory {file.parent}")
rmtree(file.parent, ignore_errors=True)
elif file.is_dir() and not list(file.iterdir()):
self.logger.debug(f"Removing empty directory {file}")
rmtree(file, ignore_errors=True)
self.logger.debug(f"Checking if {file} should be removed")
if file not in plugin_cache_files and file.is_file():
self.logger.debug(f"Removing non-cached file {file}")
file.unlink(missing_ok=True)
if file.parent.is_dir() and not list(file.parent.iterdir()):
self.logger.debug(f"Removing empty directory {file.parent}")
rmtree(file.parent, ignore_errors=True)
if file.parent == self.job_path:
break
elif file.is_dir() and not list(file.iterdir()):
self.logger.debug(f"Removing empty directory {file}")
rmtree(file, ignore_errors=True)
return ret

View file

@ -66,10 +66,10 @@ fi
# Create wizard config
if [ "$UI_WIZARD" != "" ] ; then
echo -ne 'DNS_RESOLVERS=8.8.8.8 8.8.4.4\nHTTP_PORT=80\nHTTPS_PORT=443\nAPI_LISTEN_IP=127.0.0.1\nMULTISITE=yes\nUI_HOST=http://127.0.0.1:7000\nSERVER_NAME=\n' > /etc/bunkerweb/variables.env
echo -ne 'DNS_RESOLVERS=9.9.9.9 8.8.8.8 8.8.4.4\nHTTP_PORT=80\nHTTPS_PORT=443\nAPI_LISTEN_IP=127.0.0.1\nMULTISITE=yes\nUI_HOST=http://127.0.0.1:7000\nSERVER_NAME=\n' > /etc/bunkerweb/variables.env
do_and_check_cmd chown nginx:nginx /etc/bunkerweb/variables.env
do_and_check_cmd chmod 660 /etc/bunkerweb/variables.env
echo "" > /etc/bunkerweb/ui.env
touch /etc/bunkerweb/ui.env
do_and_check_cmd chown nginx:nginx /etc/bunkerweb/ui.env
do_and_check_cmd chmod 660 /etc/bunkerweb/ui.env
do_and_check_cmd systemctl enable bunkerweb-ui

View file

@ -66,6 +66,10 @@ COPY --chown=root:scheduler --chmod=770 src/bw/misc/country.mmdb /var/tmp/bunker
# Fix CVEs
# There are no CVEs to fix for this image
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
LABEL version "1.5.6"
LABEL url "https://www.bunkerweb.io"
VOLUME /data
WORKDIR /usr/share/bunkerweb/scheduler

View file

@ -52,6 +52,7 @@ class JobScheduler(ApiCaller):
self.__lock = lock
self.__thread_lock = Lock()
self.__job_success = True
self.__job_reload = False
self.__semaphore = Semaphore(cpu_count() or 1)
@property
@ -187,7 +188,11 @@ class JobScheduler(ApiCaller):
with self.__thread_lock:
self.__job_success = False
if self.__job_success and ret >= 2:
if ret == 1:
with self.__thread_lock:
self.__job_reload = True
if self.__job_success and (ret < 0 or ret >= 2):
success = False
self.__logger.error(f"Error while executing job {name} from plugin {plugin}")
with self.__thread_lock:
@ -220,24 +225,25 @@ class JobScheduler(ApiCaller):
self.__logger.error(f"Exception while scheduling jobs for plugin {plugin} : {format_exc()}")
def run_pending(self) -> bool:
if self.__lock:
self.__lock.acquire()
threads = []
self.__job_success = True
self.__job_reload = False
jobs = [job for job in schedule_jobs if job.should_run]
success = True
reload = False
for job in jobs:
ret = job.run()
for job in schedule_jobs:
if not job.should_run:
continue
threads.append(Thread(target=self.__run_in_thread, args=((job.run,),)))
if not isinstance(ret, int):
ret = -1
for thread in threads:
thread.start()
if ret == 1:
reload = True
elif ret < 0 or ret >= 2:
success = False
for thread in threads:
thread.join()
if reload:
success = self.__job_success
self.__job_success = True
if self.__job_reload:
try:
if self.apis:
cache_path = join(sep, "var", "cache", "bunkerweb")
@ -247,28 +253,27 @@ class JobScheduler(ApiCaller):
self.__logger.error(f"Error while sending {cache_path} folder")
else:
self.__logger.info(f"Successfully sent {cache_path} folder")
if not self.__reload():
success = False
except:
except BaseException:
success = False
self.__logger.error(f"Exception while reloading after job scheduling : {format_exc()}")
self.__job_reload = False
if threads:
self.__logger.info("All scheduled jobs have been executed")
if self.__lock:
self.__lock.release()
return success
def run_once(self) -> bool:
threads = []
self.__job_success = True
self.__job_reload = False
for plugin, jobs in self.__jobs.items():
jobs_jobs = []
for job in jobs:
path = job["path"]
name = job["name"]
file = job["file"]
# Add job to the list of jobs to run in the order they are defined
jobs_jobs.append(partial(self.__job_wrapper, path, plugin, name, file))
# Add job to the list of jobs to run in the order they are defined
jobs_jobs = [partial(self.__job_wrapper, job["path"], plugin, job["name"], job["file"]) for job in jobs]
# Create a thread for each plugin
threads.append(Thread(target=self.__run_in_thread, args=(jobs_jobs,)))
@ -279,7 +284,7 @@ class JobScheduler(ApiCaller):
for thread in threads:
thread.join()
ret = self.__job_success is True
ret = self.__job_success
self.__job_success = True
return ret
@ -288,7 +293,7 @@ class JobScheduler(ApiCaller):
if self.__lock:
self.__lock.acquire()
job_plugin = None
job_plugin = ""
job_to_run = None
for plugin, jobs in self.__jobs.items():
for job in jobs:
@ -297,7 +302,7 @@ class JobScheduler(ApiCaller):
job_to_run = job
break
if not job_to_run:
if not job_plugin or not job_to_run:
self.__logger.warning(f"Job {job_name} not found")
return False

View file

@ -58,6 +58,10 @@ RUN apk add --no-cache bash libmagic && \
# Fix CVEs
# There are no CVEs to fix for this image
LABEL maintainer "Bunkerity <contact@bunkerity.com>"
LABEL version "1.5.6"
LABEL url "https://www.bunkerweb.io"
VOLUME /data
EXPOSE 7000

File diff suppressed because one or more lines are too long

View file

@ -88,6 +88,14 @@ class TabsSelect {
//close dropdown and change btn textcontent on mobile
this.setDropBtnText(tabAtt, text);
this.closeDropdown();
// Change URL fragment
if (window.location.pathname.endsWith("global_config")) {
window.history.replaceState(
null,
"",
`${window.location.pathname}#${tabAtt}`,
);
}
}
} catch (e) {}
@ -101,6 +109,24 @@ class TabsSelect {
}
} catch (err) {}
});
// If fragment exists, click on the corresponding tab
if (
window.location.hash &&
window.location.pathname.endsWith("global_config")
) {
const fragment = window.location.hash.substring(1);
if (fragment) {
const tab = this.tabContainer.querySelector(
`button[data-tab-select-handler='${fragment}']`,
);
tab.click();
// Scroll to the top of the page (with a delay to ensure the tab is clicked first)
setTimeout(() => {
window.scrollTo(0, 0);
}, 100);
}
}
}
resetTabsStyle() {

View file

@ -125,7 +125,7 @@
<input data-ban-add-inp type="hidden" name="data" value="" />
<!-- action button -->
<div class="w-full justify-center flex mt-6 mb-4">
<button data-bans-modal-close type="button" class="close-btn mr-3 text-base">Close</button>
<button data-bans-modal-close type="button" class="dark:bg-slate-800 close-btn mr-3 text-base">Close</button>
<button disabled data-bans-modal-submit type="submit" class="valid-btn">Add</button>
</div>
<!-- end action button-->

View file

@ -273,7 +273,7 @@
</div>
<!-- editor-->
<div class="mt-4 w-full justify-end flex">
<button type="button" data-{{ current_endpoint }}-modal-close class="close-btn text-xs mr-2">
<button type="button" data-{{ current_endpoint }}-modal-close class="dark:bg-slate-800 close-btn text-xs mr-2">
Close
</button>
<button data-{{ current_endpoint }}-modal-submit type="submit" class="valid-btn text-xs">

View file

@ -9,14 +9,14 @@
aria-expanded="false"
aria-label="Open flash action sidebar"
data-flash-sidebar-open
class="transition scale-90 sm:scale-100 dark:brightness-95 p-3 text-xl bg-white shadow-sm cursor-pointer rounded-circle text-slate-700">
class="transition scale-90 sm:scale-100 dark:bg-slate-750 dark:brightness-95 dark:hover:brightness-105 hover:brightness-75 p-3 text-xl bg-white shadow-sm cursor-pointer rounded-circle text-slate-700">
<svg class="fill-yellow-500 -translate-y-0.4 h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512">
<path d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v18.8c0 47-17.3 92.4-48.5 127.6l-7.4 8.3c-8.4 9.4-10.4 22.9-5.3 34.4S19.4 416 32 416H416c12.6 0 24-7.4 29.2-18.9s3.1-25-5.3-34.4l-7.4-8.3C401.3 319.2 384 273.9 384 226.8V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm45.3 493.3c12-12 18.7-28.3 18.7-45.3H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7z" />
</svg>
</button>
<div class="dark:brightness-95 px-2 translate-x-2 bottom-0 right-0 absolute rounded-full bg-white">
<div class="dark:bg-slate-700 dark:brightness-95 px-2 translate-x-2 bottom-0 right-0 absolute rounded-full bg-white">
<p data-flash-count class="mb-0 text-sm text-bold text-red-500">
{% if messages %}
{{ messages|length }}

View file

@ -43,7 +43,7 @@
res = await response.json();
if (res.reloading === false) {
clearInterval(reloading);
window.location.replace("{{ next }}");
window.location.replace("{{ next }}" + (window.location.hash ? window.location.hash : ""));
}
}
}

View file

@ -3,7 +3,7 @@
aria-controls="sidebar-news"
aria-expanded="false"
aria-label="Open news sidebar"
class="transition-all scale-90 sm:scale-100 dark:brightness-95 dark:hover:brightness-105 hover:brightness-75 fixed p-3 text-xl bg-white shadow-sm cursor-pointer top-[4.5rem] right-5 sm:right-40 xl:right-6 z-990 rounded-circle text-slate-700">
class="transition-all scale-90 sm:scale-100 dark:bg-slate-750 dark:brightness-95 dark:hover:brightness-105 hover:brightness-75 fixed p-3 text-xl bg-white shadow-sm cursor-pointer top-[4.5rem] right-5 sm:right-40 xl:right-6 z-990 rounded-circle text-slate-700">
<svg class="fill-sky-500 h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512">

View file

@ -91,7 +91,7 @@
<div class="flex justify-center">
<button data-services-modal-close
type="button"
class="close-btn mb-4 mr-3 text-base">Close</button>
class="dark:bg-slate-800 close-btn mb-4 mr-3 text-base">Close</button>
<button data-services-modal-submit type="submit" class="mb-4 valid-btn">Save</button>
</div>
<!-- end action button-->
@ -118,7 +118,7 @@
<div class="w-full justify-center flex mt-10">
<button data-services-modal-close
type="button"
class="close-btn mb-4 mr-3 text-base">Close</button>
class="dark:bg-slate-800 close-btn mb-4 mr-3 text-base">Close</button>
<button type="submit" class="delete-btn mb-4 mr-3 text-base">Delete</button>
</div>
<!-- end action button-->