mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
sqlite diag
This commit is contained in:
parent
a11c1005a8
commit
3fa377a580
|
@ -1238,11 +1238,15 @@ if you want thumbnails, `apt -y install ffmpeg`
|
|||
|
||||
ideas for context to include in bug reports
|
||||
|
||||
in general, commandline arguments (and config file if any)
|
||||
|
||||
if something broke during an upload (replacing FILENAME with a part of the filename that broke):
|
||||
```
|
||||
journalctl -aS '48 hour ago' -u copyparty | grep -C10 FILENAME | tee bug.log
|
||||
```
|
||||
|
||||
if there's a wall of base64 in the log (thread stacks) then please include that, especially if you run into something freezing up or getting stuck, for example `OperationalError('database is locked')` -- alternatively you can visit `/?stack` to see the stacks live, so http://127.0.0.1:3923/?stack for example
|
||||
|
||||
|
||||
# building
|
||||
|
||||
|
|
|
@ -1107,6 +1107,7 @@ class AuthSrv(object):
|
|||
|
||||
vfs.bubble_flags()
|
||||
|
||||
e2vs = []
|
||||
t = "volumes and permissions:\n"
|
||||
for zv in vfs.all_vols.values():
|
||||
if not self.warn_anonwrite:
|
||||
|
@ -1124,8 +1125,16 @@ class AuthSrv(object):
|
|||
u = ", ".join("\033[35meverybody\033[0m" if x == "*" else x for x in u)
|
||||
u = u if u else "\033[36m--none--\033[0m"
|
||||
t += "\n| {}: {}".format(txt, u)
|
||||
|
||||
if "e2v" in zv.flags and zv.axs.uwrite:
|
||||
e2vs.append(zv.vpath or "/")
|
||||
|
||||
t += "\n"
|
||||
|
||||
if e2vs:
|
||||
t += "\n\033[33me2v enabled for the following volumes;\nuploads will be blocked until scan has finished:\n \033[0m"
|
||||
t += " ".join(e2vs) + "\n"
|
||||
|
||||
if self.warn_anonwrite and not self.args.no_voldump:
|
||||
self.log(t)
|
||||
|
||||
|
@ -1133,7 +1142,7 @@ class AuthSrv(object):
|
|||
zv, _ = vfs.get("/", "*", False, True)
|
||||
if self.warn_anonwrite and os.getcwd() == zv.realpath:
|
||||
self.warn_anonwrite = False
|
||||
t = "anyone can read/write the current directory: {}\n"
|
||||
t = "anyone can write to the current directory: {}\n"
|
||||
self.log(t.format(zv.realpath), c=1)
|
||||
except Pebkac:
|
||||
self.warn_anonwrite = True
|
||||
|
|
|
@ -380,13 +380,18 @@ class HttpCli(object):
|
|||
if not self._check_nonfatal(pex, post):
|
||||
self.keepalive = False
|
||||
|
||||
msg = str(ex) if pex == ex else min_ex()
|
||||
em = str(ex)
|
||||
msg = em if pex == ex else min_ex()
|
||||
self.log("{}\033[0m, {}".format(msg, self.vpath), 3)
|
||||
|
||||
msg = "{}\r\nURL: {}\r\n".format(str(ex), self.vpath)
|
||||
msg = "{}\r\nURL: {}\r\n".format(em, self.vpath)
|
||||
if self.hint:
|
||||
msg += "hint: {}\r\n".format(self.hint)
|
||||
|
||||
if "database is locked" in em:
|
||||
self.conn.hsrv.broker.say("log_stacks")
|
||||
msg += "hint: important info in the server log\r\n"
|
||||
|
||||
msg = "<pre>" + html_escape(msg)
|
||||
self.reply(msg.encode("utf-8", "replace"), status=pex.code, volsan=True)
|
||||
return self.keepalive
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
import calendar
|
||||
import gzip
|
||||
import os
|
||||
import shlex
|
||||
import signal
|
||||
|
@ -27,7 +29,7 @@ from .mtag import HAVE_FFMPEG, HAVE_FFPROBE
|
|||
from .tcpsrv import TcpSrv
|
||||
from .th_srv import HAVE_PIL, HAVE_VIPS, HAVE_WEBP, ThumbSrv
|
||||
from .up2k import Up2k
|
||||
from .util import ansi_re, min_ex, mp, start_log_thrs, start_stackmon
|
||||
from .util import ansi_re, min_ex, mp, start_log_thrs, start_stackmon, alltrace
|
||||
|
||||
|
||||
class SvcHub(object):
|
||||
|
@ -56,6 +58,7 @@ class SvcHub(object):
|
|||
|
||||
self.log_mutex = threading.Lock()
|
||||
self.next_day = 0
|
||||
self.tstack = 0.0
|
||||
|
||||
if args.sss or args.s >= 3:
|
||||
args.ss = True
|
||||
|
@ -500,3 +503,15 @@ class SvcHub(object):
|
|||
sck.sendall(b"READY=1")
|
||||
except:
|
||||
self.log("sd_notify", min_ex())
|
||||
|
||||
def log_stacks(self) -> None:
|
||||
td = time.time() - self.tstack
|
||||
if td < 300:
|
||||
self.log("stacks", "cooldown {}".format(td))
|
||||
return
|
||||
|
||||
self.tstack = time.time()
|
||||
zb = alltrace().encode("utf-8", "replace")
|
||||
zb = gzip.compress(zb)
|
||||
zs = base64.b64encode(zb).decode("ascii")
|
||||
self.log("stacks", zs)
|
||||
|
|
|
@ -98,6 +98,7 @@ class Up2k(object):
|
|||
self.gid = 0
|
||||
self.stop = False
|
||||
self.mutex = threading.Lock()
|
||||
self.blocked: Optional[str] = None
|
||||
self.pp: Optional[ProgressPrinter] = None
|
||||
self.rescan_cond = threading.Condition()
|
||||
self.need_rescan: set[str] = set()
|
||||
|
@ -193,6 +194,14 @@ class Up2k(object):
|
|||
def log(self, msg: str, c: Union[int, str] = 0) -> None:
|
||||
self.log_func("up2k", msg + "\033[K", c)
|
||||
|
||||
def _block(self, why: str) -> None:
|
||||
self.blocked = why
|
||||
self.log("uploads are temporarily blocked due to " + why, 3)
|
||||
|
||||
def _unblock(self) -> None:
|
||||
self.blocked = None
|
||||
self.log("uploads are now possible", 2)
|
||||
|
||||
def get_state(self) -> str:
|
||||
mtpq: Union[int, str] = 0
|
||||
q = "select count(w) from mt where k = 't:mtp'"
|
||||
|
@ -416,6 +425,9 @@ class Up2k(object):
|
|||
self.mtag = None
|
||||
|
||||
# e2ds(a) volumes first
|
||||
if next((zv for zv in vols if "e2ds" in zv.flags), None):
|
||||
self._block("indexing")
|
||||
|
||||
for vol in vols:
|
||||
if self.stop:
|
||||
break
|
||||
|
@ -445,6 +457,9 @@ class Up2k(object):
|
|||
self.volstate[vol.vpath] = t
|
||||
|
||||
# file contents verification
|
||||
if next((zv for zv in vols if "e2v" in zv.flags), None):
|
||||
self._block("integrity verification")
|
||||
|
||||
for vol in vols:
|
||||
if self.stop:
|
||||
break
|
||||
|
@ -468,6 +483,9 @@ class Up2k(object):
|
|||
|
||||
self.volstate[vol.vpath] = t
|
||||
|
||||
if self.blocked:
|
||||
self._unblock()
|
||||
|
||||
# open the rest + do any e2ts(a)
|
||||
needed_mutagen = False
|
||||
for vol in vols:
|
||||
|
@ -1485,11 +1503,24 @@ class Up2k(object):
|
|||
|
||||
cur.connection.commit()
|
||||
|
||||
def _job_volchk(self, cj: dict[str, Any]) -> None:
|
||||
if not self.register_vpath(cj["ptop"], cj["vcfg"]):
|
||||
if cj["ptop"] not in self.registry:
|
||||
raise Pebkac(410, "location unavailable")
|
||||
|
||||
def handle_json(self, cj: dict[str, Any]) -> dict[str, Any]:
|
||||
with self.mutex:
|
||||
if not self.register_vpath(cj["ptop"], cj["vcfg"]):
|
||||
if cj["ptop"] not in self.registry:
|
||||
raise Pebkac(410, "location unavailable")
|
||||
try:
|
||||
# bit expensive; 3.9=10x 3.11=2x
|
||||
if self.mutex.acquire(timeout=10):
|
||||
self._job_volchk(cj)
|
||||
self.mutex.release()
|
||||
else:
|
||||
t = "cannot receive uploads right now;\nserver busy with {}.\nPlease wait; the client will retry..."
|
||||
raise Pebkac(503, t.format(self.blocked or "[unknown]"))
|
||||
except TypeError:
|
||||
# py2
|
||||
with self.mutex:
|
||||
self._job_volchk(cj)
|
||||
|
||||
cj["name"] = sanitize_fn(cj["name"], "", [".prologue.html", ".epilogue.html"])
|
||||
cj["poke"] = time.time()
|
||||
|
|
|
@ -2244,6 +2244,7 @@ html.y #bbox-overlay figcaption a {
|
|||
max-width: none;
|
||||
}
|
||||
#u2tab td {
|
||||
word-wrap: break-word;
|
||||
border: 1px solid rgba(128,128,128,0.8);
|
||||
border-width: 0 0px 1px 0;
|
||||
padding: .2em .3em;
|
||||
|
@ -2258,7 +2259,19 @@ html.y #bbox-overlay figcaption a {
|
|||
#u2tab.up.ok td:nth-child(3),
|
||||
#u2tab.up.bz td:nth-child(3),
|
||||
#u2tab.up.q td:nth-child(3) {
|
||||
width: 19em;
|
||||
width: 18em;
|
||||
}
|
||||
@media (max-width: 65em) {
|
||||
#u2tab {
|
||||
font-size: .9em;
|
||||
}
|
||||
}
|
||||
@media (max-width: 50em) {
|
||||
#u2tab.up.ok td:nth-child(3),
|
||||
#u2tab.up.bz td:nth-child(3),
|
||||
#u2tab.up.q td:nth-child(3) {
|
||||
width: 16em;
|
||||
}
|
||||
}
|
||||
#op_up2k.srch td.prog {
|
||||
font-family: sans-serif;
|
||||
|
|
Loading…
Reference in a new issue