mirror of
https://github.com/9001/copyparty.git
synced 2025-08-18 01:22:13 -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
|
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):
|
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
|
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
|
# building
|
||||||
|
|
||||||
|
|
|
@ -1107,6 +1107,7 @@ class AuthSrv(object):
|
||||||
|
|
||||||
vfs.bubble_flags()
|
vfs.bubble_flags()
|
||||||
|
|
||||||
|
e2vs = []
|
||||||
t = "volumes and permissions:\n"
|
t = "volumes and permissions:\n"
|
||||||
for zv in vfs.all_vols.values():
|
for zv in vfs.all_vols.values():
|
||||||
if not self.warn_anonwrite:
|
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 = ", ".join("\033[35meverybody\033[0m" if x == "*" else x for x in u)
|
||||||
u = u if u else "\033[36m--none--\033[0m"
|
u = u if u else "\033[36m--none--\033[0m"
|
||||||
t += "\n| {}: {}".format(txt, u)
|
t += "\n| {}: {}".format(txt, u)
|
||||||
|
|
||||||
|
if "e2v" in zv.flags and zv.axs.uwrite:
|
||||||
|
e2vs.append(zv.vpath or "/")
|
||||||
|
|
||||||
t += "\n"
|
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:
|
if self.warn_anonwrite and not self.args.no_voldump:
|
||||||
self.log(t)
|
self.log(t)
|
||||||
|
|
||||||
|
@ -1133,7 +1142,7 @@ class AuthSrv(object):
|
||||||
zv, _ = vfs.get("/", "*", False, True)
|
zv, _ = vfs.get("/", "*", False, True)
|
||||||
if self.warn_anonwrite and os.getcwd() == zv.realpath:
|
if self.warn_anonwrite and os.getcwd() == zv.realpath:
|
||||||
self.warn_anonwrite = False
|
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)
|
self.log(t.format(zv.realpath), c=1)
|
||||||
except Pebkac:
|
except Pebkac:
|
||||||
self.warn_anonwrite = True
|
self.warn_anonwrite = True
|
||||||
|
|
|
@ -380,13 +380,18 @@ class HttpCli(object):
|
||||||
if not self._check_nonfatal(pex, post):
|
if not self._check_nonfatal(pex, post):
|
||||||
self.keepalive = False
|
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)
|
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:
|
if self.hint:
|
||||||
msg += "hint: {}\r\n".format(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)
|
msg = "<pre>" + html_escape(msg)
|
||||||
self.reply(msg.encode("utf-8", "replace"), status=pex.code, volsan=True)
|
self.reply(msg.encode("utf-8", "replace"), status=pex.code, volsan=True)
|
||||||
return self.keepalive
|
return self.keepalive
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
from __future__ import print_function, unicode_literals
|
from __future__ import print_function, unicode_literals
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import base64
|
||||||
import calendar
|
import calendar
|
||||||
|
import gzip
|
||||||
import os
|
import os
|
||||||
import shlex
|
import shlex
|
||||||
import signal
|
import signal
|
||||||
|
@ -27,7 +29,7 @@ from .mtag import HAVE_FFMPEG, HAVE_FFPROBE
|
||||||
from .tcpsrv import TcpSrv
|
from .tcpsrv import TcpSrv
|
||||||
from .th_srv import HAVE_PIL, HAVE_VIPS, HAVE_WEBP, ThumbSrv
|
from .th_srv import HAVE_PIL, HAVE_VIPS, HAVE_WEBP, ThumbSrv
|
||||||
from .up2k import Up2k
|
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):
|
class SvcHub(object):
|
||||||
|
@ -56,6 +58,7 @@ class SvcHub(object):
|
||||||
|
|
||||||
self.log_mutex = threading.Lock()
|
self.log_mutex = threading.Lock()
|
||||||
self.next_day = 0
|
self.next_day = 0
|
||||||
|
self.tstack = 0.0
|
||||||
|
|
||||||
if args.sss or args.s >= 3:
|
if args.sss or args.s >= 3:
|
||||||
args.ss = True
|
args.ss = True
|
||||||
|
@ -500,3 +503,15 @@ class SvcHub(object):
|
||||||
sck.sendall(b"READY=1")
|
sck.sendall(b"READY=1")
|
||||||
except:
|
except:
|
||||||
self.log("sd_notify", min_ex())
|
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.gid = 0
|
||||||
self.stop = False
|
self.stop = False
|
||||||
self.mutex = threading.Lock()
|
self.mutex = threading.Lock()
|
||||||
|
self.blocked: Optional[str] = None
|
||||||
self.pp: Optional[ProgressPrinter] = None
|
self.pp: Optional[ProgressPrinter] = None
|
||||||
self.rescan_cond = threading.Condition()
|
self.rescan_cond = threading.Condition()
|
||||||
self.need_rescan: set[str] = set()
|
self.need_rescan: set[str] = set()
|
||||||
|
@ -193,6 +194,14 @@ class Up2k(object):
|
||||||
def log(self, msg: str, c: Union[int, str] = 0) -> None:
|
def log(self, msg: str, c: Union[int, str] = 0) -> None:
|
||||||
self.log_func("up2k", msg + "\033[K", c)
|
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:
|
def get_state(self) -> str:
|
||||||
mtpq: Union[int, str] = 0
|
mtpq: Union[int, str] = 0
|
||||||
q = "select count(w) from mt where k = 't:mtp'"
|
q = "select count(w) from mt where k = 't:mtp'"
|
||||||
|
@ -416,6 +425,9 @@ class Up2k(object):
|
||||||
self.mtag = None
|
self.mtag = None
|
||||||
|
|
||||||
# e2ds(a) volumes first
|
# e2ds(a) volumes first
|
||||||
|
if next((zv for zv in vols if "e2ds" in zv.flags), None):
|
||||||
|
self._block("indexing")
|
||||||
|
|
||||||
for vol in vols:
|
for vol in vols:
|
||||||
if self.stop:
|
if self.stop:
|
||||||
break
|
break
|
||||||
|
@ -445,6 +457,9 @@ class Up2k(object):
|
||||||
self.volstate[vol.vpath] = t
|
self.volstate[vol.vpath] = t
|
||||||
|
|
||||||
# file contents verification
|
# file contents verification
|
||||||
|
if next((zv for zv in vols if "e2v" in zv.flags), None):
|
||||||
|
self._block("integrity verification")
|
||||||
|
|
||||||
for vol in vols:
|
for vol in vols:
|
||||||
if self.stop:
|
if self.stop:
|
||||||
break
|
break
|
||||||
|
@ -468,6 +483,9 @@ class Up2k(object):
|
||||||
|
|
||||||
self.volstate[vol.vpath] = t
|
self.volstate[vol.vpath] = t
|
||||||
|
|
||||||
|
if self.blocked:
|
||||||
|
self._unblock()
|
||||||
|
|
||||||
# open the rest + do any e2ts(a)
|
# open the rest + do any e2ts(a)
|
||||||
needed_mutagen = False
|
needed_mutagen = False
|
||||||
for vol in vols:
|
for vol in vols:
|
||||||
|
@ -1485,12 +1503,25 @@ class Up2k(object):
|
||||||
|
|
||||||
cur.connection.commit()
|
cur.connection.commit()
|
||||||
|
|
||||||
def handle_json(self, cj: dict[str, Any]) -> dict[str, Any]:
|
def _job_volchk(self, cj: dict[str, Any]) -> None:
|
||||||
with self.mutex:
|
|
||||||
if not self.register_vpath(cj["ptop"], cj["vcfg"]):
|
if not self.register_vpath(cj["ptop"], cj["vcfg"]):
|
||||||
if cj["ptop"] not in self.registry:
|
if cj["ptop"] not in self.registry:
|
||||||
raise Pebkac(410, "location unavailable")
|
raise Pebkac(410, "location unavailable")
|
||||||
|
|
||||||
|
def handle_json(self, cj: dict[str, Any]) -> dict[str, Any]:
|
||||||
|
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["name"] = sanitize_fn(cj["name"], "", [".prologue.html", ".epilogue.html"])
|
||||||
cj["poke"] = time.time()
|
cj["poke"] = time.time()
|
||||||
wark = self._get_wark(cj)
|
wark = self._get_wark(cj)
|
||||||
|
|
|
@ -2244,6 +2244,7 @@ html.y #bbox-overlay figcaption a {
|
||||||
max-width: none;
|
max-width: none;
|
||||||
}
|
}
|
||||||
#u2tab td {
|
#u2tab td {
|
||||||
|
word-wrap: break-word;
|
||||||
border: 1px solid rgba(128,128,128,0.8);
|
border: 1px solid rgba(128,128,128,0.8);
|
||||||
border-width: 0 0px 1px 0;
|
border-width: 0 0px 1px 0;
|
||||||
padding: .2em .3em;
|
padding: .2em .3em;
|
||||||
|
@ -2258,7 +2259,19 @@ html.y #bbox-overlay figcaption a {
|
||||||
#u2tab.up.ok td:nth-child(3),
|
#u2tab.up.ok td:nth-child(3),
|
||||||
#u2tab.up.bz td:nth-child(3),
|
#u2tab.up.bz td:nth-child(3),
|
||||||
#u2tab.up.q 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 {
|
#op_up2k.srch td.prog {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
|
Loading…
Reference in a new issue