diff --git a/Dockerfile b/Dockerfile index 5bed6c0..10dceb2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:stretch-slim +FROM python:3-slim RUN apt-get update && apt-get install gnupg -y RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 8756C4F765C9AC3CB6B85D62379CE192D401AB61 && \ @@ -8,13 +8,15 @@ RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 8756C4F765 rm -rf /var/lib/apt/lists/* WORKDIR /seafile-client +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt -COPY start.sh /seafile-client/start.sh +COPY start.py /seafile-client/start.py -RUN chmod +x /seafile-client/start.sh && \ +RUN chmod +x /seafile-client/start.py && \ useradd -U -d /seafile-client -s /bin/bash seafile && \ usermod -G users seafile && \ chown seafile:seafile -R /seafile-client && \ su - seafile -c "seaf-cli init -d /seafile-client" -CMD ["./start.sh"] +CMD ["./start.py"] diff --git a/docker-compose.yaml b/docker-compose.yaml index 2dc447f..8af1c93 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -6,7 +6,7 @@ services: container_name: seafile-client environment: - LIBRARY_ID= - - SERVER_URL= + - SERVER_HOST= - SERVER_PORT= - USERNAME= - PASSWORD= diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f229360 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +requests diff --git a/start.py b/start.py new file mode 100755 index 0000000..2ad9859 --- /dev/null +++ b/start.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 + +import argparse +import os +import os.path +import pwd +import subprocess +import sys +import time + +import requests + +DEFAULT_USERNAME = "seafile" + + +def setup_uid(uid: int, gid: int): + user_pwinfo = pwd.getpwnam(DEFAULT_USERNAME) + if user_pwinfo.pw_uid != uid or user_pwinfo.pw_gid != gid: + subprocess.call(["usermod", "-o", "-u", str(uid), "-g", str(gid), DEFAULT_USERNAME]) + + +def start_seaf_daemon(): + os.system(f'su - {DEFAULT_USERNAME} -c "seaf-cli start"') + time.sleep(10) + + +def create_dir(dir_path: str): + if not os.path.exists(dir_path): + os.mkdir(dir_path) + user_pwinfo = pwd.getpwnam(DEFAULT_USERNAME) + os.chown(dir_path, user_pwinfo.pw_uid, user_pwinfo.pw_gid) + else: + if not os.path.isdir(dir_path): + raise RuntimeError(f"Data dir {dir_path} is not a directory") + + +def tail_f(fpath): + os.system(f"tail -f {fpath}") + + +class SeafileClient: + def __init__(self, host: str, port: int, user: str, passwd: str): + self.url = f"https://{host}:{port}" + self.user = user + self.password = passwd + self.__token = None + + def __str__(self): + return f"SeafileClient({self.user}@{self.url})" + + @property + def token(self): + if self.__token is None: + url = f"{self.url}/api2/auth-token/" + r = requests.post(url, data={"username": self.user, + "password": self.password}) + if r.status_code != 200: + raise RuntimeError(f"Can't get token: {r.text}") + self.__token = r.json()['token'] + return self.__token + + def get_lib_name(self, lib_id: str) -> str: + url = f"{self.url}/api2/repos/{lib_id}" + auth_header = {"Authorization": f"Token {self.token}"} + r = requests.get(url, headers=auth_header) + if r.status_code != 200: + raise RuntimeError(r.text) + return r.json()['name'] + + def sync_lib(self, lib_id: str, data_dir: str): + lib_name = self.get_lib_name(lib_id) + lib_dir = os.path.join(data_dir, lib_name.replace(' ', '_')) + create_dir(lib_dir) + cmd = ['seaf-cli', 'sync', + '-l', lib_id, + '-s', self.url, + '-d', lib_dir, + '-u', self.user, + '-p', self.password] + cmd = ' '.join(cmd) + os.system(f'su - {DEFAULT_USERNAME} -c "{cmd}"') + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--uid", default=os.getenv("SEAFILE_UID"), type=int) + parser.add_argument("--gid", default=os.getenv("SEAFILE_GID"), type=int) + parser.add_argument("--data-dir", default=os.getenv("DATA_DIR")) + parser.add_argument("--host", default=os.getenv("SERVER_HOST")) + parser.add_argument("--port", default=os.getenv("SERVER_PORT"), type=int) + parser.add_argument("--username", default=os.getenv("USERNAME")) + parser.add_argument("--password", default=os.getenv("PASSWORD")) + parser.add_argument("--libs", default=os.getenv("LIBRARY_ID")) + args = parser.parse_args() + + setup_uid(args.uid, args.gid) + start_seaf_daemon() + create_dir(args.data_dir) + client = SeafileClient(args.host, args.port, args.username, args.password) + for lib_id in args.libs.split(sep=":"): + client.sync_lib(lib_id, args.data_dir) + tail_f("/seafile-client/.ccnet/logs/seafile.log") + + return 0 + + +if __name__ == "__main__": + sys.exit(main())