Read the local library list as JSON instead of splitting columns

get_local_libraries unpacked "line.rsplit(maxsplit=3)" into three names, but
maxsplit=3 yields up to four fields. seaf-cli prints "name id path" separated
by whitespace, so any library whose name contains a space produced a fourth
field and raised ValueError, which nothing caught.

The failure only appeared after the first run: the list is empty until a
library has been synced, so a container would work when it was set up and then
crash on every restart.

seaf-cli list --json returns name, id and path as structured fields, which
display output cannot represent unambiguously for names or paths containing
whitespace. Its exit code is now checked and unreadable output is reported as
a daemon error instead of a traceback.

The image smoke check asserts that the installed seaf-cli offers --json and
--token, so a future version bump that drops either fails the build rather
than the container.
This commit is contained in:
Maxim Shulga committed 2026-08-02 17:29:51 -07:00
1 parent 8043ac1409
commit b75863ba51
4 files changed
+73 -9

No files matched your search

+11 -8
View File
@@ -1,4 +1,5 @@
import argparse
import json
import logging
import os
import subprocess
@@ -271,16 +272,18 @@ class SeafileClient:
prev_status[library] = cur_status[library]
def get_local_libraries(self) -> set:
cmd = ["seaf-cli", "list"]
# The display output is whitespace separated, so a library name or a
# path containing a space cannot be parsed back apart. Ask for JSON.
cmd = ["seaf-cli", "list", "--json"]
_lg.info("Listing local libraries: %s", " ".join(cmd))
out = subprocess.check_output(self.__gen_cmd(cmd))
out = out.decode().splitlines()[1:] # first line is a header
out = self.__run(cmd, stdout=subprocess.PIPE).stdout
local_libs = set()
for line in out:
lib_name, lib_id, lib_path = line.rsplit(maxsplit=3)
local_libs.add(lib_id)
return local_libs
try:
libraries = json.loads(out.decode())
except (UnicodeDecodeError, ValueError) as err:
raise DaemonError(f"Cannot read the library list from seaf-cli: {err}")
return {lib["id"] for lib in libraries}
def configure(self, args: argparse.Namespace, check_for_daemon: bool = True):
need_restart = False