| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  | #!/usr/bin/env python | 
					
						
							|  |  |  | #coding: UTF-8 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import argparse | 
					
						
							|  |  |  | import glob | 
					
						
							|  |  |  | import logging | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import re | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | from collections import namedtuple | 
					
						
							|  |  |  | from contextlib import contextmanager | 
					
						
							|  |  |  | from os.path import abspath, basename, dirname, exists, join | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import requests | 
					
						
							|  |  |  | from tenacity import TryAgain, retry, stop_after_attempt, wait_fixed | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from utils import ( | 
					
						
							|  |  |  |     cd, chdir, debug, green, info, mkdirs, red, setup_logging, shell, warning | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | logger = logging.getLogger(__name__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ServerCtl(object): | 
					
						
							| 
									
										
										
										
											2021-01-04 11:41:53 +08:00
										 |  |  |     def __init__(self, topdir, projectdir, datadir, fileserver, db='sqlite3', seaf_server_bin='seaf-server', ccnet_server_bin='ccnet-server'): | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |         self.db = db | 
					
						
							| 
									
										
										
										
											2024-09-03 18:19:37 +08:00
										 |  |  |         self.topdir = topdir | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |         self.datadir = datadir | 
					
						
							|  |  |  |         self.central_conf_dir = join(datadir, 'conf') | 
					
						
							|  |  |  |         self.seafile_conf_dir = join(datadir, 'seafile-data') | 
					
						
							|  |  |  |         self.ccnet_conf_dir = join(datadir, 'ccnet') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.log_dir = join(datadir, 'logs') | 
					
						
							|  |  |  |         mkdirs(self.log_dir) | 
					
						
							|  |  |  |         self.ccnet_log = join(self.log_dir, 'ccnet.log') | 
					
						
							|  |  |  |         self.seafile_log = join(self.log_dir, 'seafile.log') | 
					
						
							| 
									
										
										
										
											2021-01-04 11:41:53 +08:00
										 |  |  |         self.fileserver_log = join(self.log_dir, 'fileserver.log') | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-29 19:30:13 +08:00
										 |  |  |         self.ccnet_server_bin = ccnet_server_bin | 
					
						
							|  |  |  |         self.seaf_server_bin = seaf_server_bin | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |         self.sql_dir = join(topdir, 'seafile-server', 'scripts', 'sql') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |         self.ccnet_proc = None | 
					
						
							|  |  |  |         self.seafile_proc = None | 
					
						
							| 
									
										
										
										
											2021-01-04 11:41:53 +08:00
										 |  |  |         self.fileserver_proc = None | 
					
						
							|  |  |  |         self.projectdir = projectdir | 
					
						
							|  |  |  |         self.fileserver = fileserver | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def setup(self): | 
					
						
							|  |  |  |         if self.db == 'mysql': | 
					
						
							|  |  |  |             create_mysql_dbs() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-11 09:20:47 +08:00
										 |  |  |         os.mkdir (self.central_conf_dir, 0o755) | 
					
						
							|  |  |  |         os.mkdir (self.seafile_conf_dir, 0o755) | 
					
						
							|  |  |  |         os.mkdir (self.ccnet_conf_dir, 0o755) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |         self.init_seafile() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def init_seafile(self): | 
					
						
							| 
									
										
										
										
											2020-05-11 09:20:47 +08:00
										 |  |  |         seafile_conf = join(self.central_conf_dir, 'seafile.conf') | 
					
						
							| 
									
										
										
										
											2021-01-04 11:41:53 +08:00
										 |  |  |         if self.fileserver == 'go_fileserver': | 
					
						
							|  |  |  |             seafile_fileserver_conf = '''\
 | 
					
						
							|  |  |  | [fileserver] | 
					
						
							|  |  |  | use_go_fileserver = true | 
					
						
							|  |  |  | port=8082 | 
					
						
							|  |  |  | '''
 | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             seafile_fileserver_conf = '''\
 | 
					
						
							| 
									
										
										
										
											2020-05-11 09:20:47 +08:00
										 |  |  | [fileserver] | 
					
						
							|  |  |  | port=8082 | 
					
						
							|  |  |  | '''
 | 
					
						
							|  |  |  |         with open(seafile_conf, 'a+') as fp: | 
					
						
							|  |  |  |             fp.write('\n') | 
					
						
							|  |  |  |             fp.write(seafile_fileserver_conf) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 11:09:21 +08:00
										 |  |  |         if self.db == 'mysql': | 
					
						
							|  |  |  |             self.add_seafile_db_conf() | 
					
						
							| 
									
										
										
										
											2019-03-27 16:14:00 +08:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self.add_seafile_sqlite_db_conf() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def add_seafile_sqlite_db_conf(self): | 
					
						
							|  |  |  |         seafile_conf = join(self.central_conf_dir, 'seafile.conf') | 
					
						
							|  |  |  |         seafile_db_conf = '''\
 | 
					
						
							|  |  |  | [database] | 
					
						
							|  |  |  | '''
 | 
					
						
							|  |  |  |         with open(seafile_conf, 'a+') as fp: | 
					
						
							|  |  |  |             fp.write('\n') | 
					
						
							|  |  |  |             fp.write(seafile_db_conf) | 
					
						
							| 
									
										
										
										
											2018-01-18 11:09:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def add_seafile_db_conf(self): | 
					
						
							|  |  |  |         seafile_conf = join(self.central_conf_dir, 'seafile.conf') | 
					
						
							|  |  |  |         seafile_db_conf = '''\
 | 
					
						
							|  |  |  | [database] | 
					
						
							|  |  |  | type = mysql | 
					
						
							|  |  |  | host = 127.0.0.1 | 
					
						
							|  |  |  | port = 3306 | 
					
						
							|  |  |  | user = seafile | 
					
						
							|  |  |  | password = seafile | 
					
						
							|  |  |  | db_name = seafile | 
					
						
							|  |  |  | connection_charset = utf8 | 
					
						
							|  |  |  | '''
 | 
					
						
							|  |  |  |         with open(seafile_conf, 'a+') as fp: | 
					
						
							|  |  |  |             fp.write('\n') | 
					
						
							|  |  |  |             fp.write(seafile_db_conf) | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @contextmanager | 
					
						
							|  |  |  |     def run(self): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             self.start() | 
					
						
							|  |  |  |             yield self | 
					
						
							|  |  |  |         except: | 
					
						
							|  |  |  |             self.print_logs() | 
					
						
							|  |  |  |             raise | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             self.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def print_logs(self): | 
					
						
							|  |  |  |         for logfile in self.ccnet_log, self.seafile_log: | 
					
						
							|  |  |  |             if exists(logfile): | 
					
						
							| 
									
										
										
										
											2019-07-01 16:41:41 +08:00
										 |  |  |                 shell(f'cat {logfile}') | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @retry(wait=wait_fixed(1), stop=stop_after_attempt(10)) | 
					
						
							|  |  |  |     def wait_ccnet_ready(self): | 
					
						
							| 
									
										
										
										
											2019-06-27 22:30:31 -07:00
										 |  |  |         if not exists(join(self.ccnet_conf_dir, 'ccnet-rpc.sock')): | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |             raise TryAgain | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def start(self): | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |         logger.info('Starting to create ccnet and seafile db tables') | 
					
						
							|  |  |  |         self.create_database_tables() | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |         logger.info('Starting seafile server') | 
					
						
							|  |  |  |         self.start_seafile() | 
					
						
							| 
									
										
										
										
											2021-01-04 11:41:53 +08:00
										 |  |  |         self.start_fileserver() | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |     def create_database_tables(self): | 
					
						
							|  |  |  |         if self.db == 'mysql': | 
					
						
							|  |  |  |            ccnet_sql_path = join(self.sql_dir, 'mysql', 'ccnet.sql') | 
					
						
							|  |  |  |            seafile_sql_path = join(self.sql_dir, 'mysql', 'seafile.sql') | 
					
						
							| 
									
										
										
										
											2019-07-01 16:41:41 +08:00
										 |  |  |            sql = f'USE ccnet; source {ccnet_sql_path}; USE seafile; source {seafile_sql_path};'.encode() | 
					
						
							| 
									
										
										
										
											2020-01-13 18:55:55 -08:00
										 |  |  |            shell('sudo mysql -u root -proot', inputdata=sql, wait=False) | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |         else: | 
					
						
							|  |  |  |            config_sql_path = join(self.sql_dir, 'sqlite', 'config.sql') | 
					
						
							|  |  |  |            groupmgr_sql_path = join(self.sql_dir, 'sqlite', 'groupmgr.sql') | 
					
						
							|  |  |  |            org_sql_path = join(self.sql_dir, 'sqlite', 'org.sql') | 
					
						
							|  |  |  |            user_sql_path = join(self.sql_dir, 'sqlite', 'user.sql') | 
					
						
							|  |  |  |            seafile_sql_path = join(self.sql_dir, 'sqlite', 'seafile.sql') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            misc_dir = join(self.ccnet_conf_dir, 'misc') | 
					
						
							| 
									
										
										
										
											2019-06-27 22:30:31 -07:00
										 |  |  |            os.mkdir (misc_dir, 0o755) | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |            groupmgr_dir = join(self.ccnet_conf_dir, 'GroupMgr') | 
					
						
							| 
									
										
										
										
											2019-06-27 22:30:31 -07:00
										 |  |  |            os.mkdir (groupmgr_dir, 0o755) | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |            orgmgr_dir = join(self.ccnet_conf_dir, 'OrgMgr') | 
					
						
							| 
									
										
										
										
											2019-06-27 22:30:31 -07:00
										 |  |  |            os.mkdir (orgmgr_dir, 0o755) | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |            usermgr_dir = join(self.ccnet_conf_dir, 'PeerMgr') | 
					
						
							| 
									
										
										
										
											2019-06-27 22:30:31 -07:00
										 |  |  |            os.mkdir (usermgr_dir, 0o755) | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |            config_db_path = join(misc_dir, 'config.db') | 
					
						
							|  |  |  |            groupmgr_db_path = join(groupmgr_dir, 'groupmgr.db') | 
					
						
							|  |  |  |            orgmgr_db_path = join(orgmgr_dir, 'orgmgr.db') | 
					
						
							|  |  |  |            usermgr_db_path = join(usermgr_dir, 'usermgr.db') | 
					
						
							|  |  |  |            seafile_db_path = join(self.seafile_conf_dir, 'seafile.db') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-01 16:41:41 +08:00
										 |  |  |            sql = f'.read {config_sql_path}'.encode() | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |            shell('sqlite3 ' + config_db_path, inputdata=sql, wait=False) | 
					
						
							| 
									
										
										
										
											2019-07-01 16:41:41 +08:00
										 |  |  |            sql = f'.read {groupmgr_sql_path}'.encode() | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |            shell('sqlite3 ' + groupmgr_db_path, inputdata=sql, wait=False) | 
					
						
							| 
									
										
										
										
											2019-07-01 16:41:41 +08:00
										 |  |  |            sql = f'.read {org_sql_path}'.encode() | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |            shell('sqlite3 ' + orgmgr_db_path, inputdata=sql, wait=False) | 
					
						
							| 
									
										
										
										
											2019-07-01 16:41:41 +08:00
										 |  |  |            sql = f'.read {user_sql_path}'.encode() | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |            shell('sqlite3 ' + usermgr_db_path, inputdata=sql, wait=False) | 
					
						
							| 
									
										
										
										
											2019-07-01 16:41:41 +08:00
										 |  |  |            sql = f'.read {seafile_sql_path}'.encode() | 
					
						
							| 
									
										
										
										
											2019-05-21 23:49:47 -07:00
										 |  |  |            shell('sqlite3 ' + seafile_db_path, inputdata=sql, wait=False) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |     def start_ccnet(self): | 
					
						
							|  |  |  |         cmd = [ | 
					
						
							| 
									
										
										
										
											2018-01-29 19:30:13 +08:00
										 |  |  |             self.ccnet_server_bin, | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |             "-F", | 
					
						
							|  |  |  |             self.central_conf_dir, | 
					
						
							|  |  |  |             "-c", | 
					
						
							|  |  |  |             self.ccnet_conf_dir, | 
					
						
							|  |  |  |             "-f", | 
					
						
							|  |  |  |             self.ccnet_log, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         self.ccnet_proc = shell(cmd, wait=False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def start_seafile(self): | 
					
						
							|  |  |  |         cmd = [ | 
					
						
							| 
									
										
										
										
											2018-01-29 19:30:13 +08:00
										 |  |  |             self.seaf_server_bin, | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |             "-F", | 
					
						
							|  |  |  |             self.central_conf_dir, | 
					
						
							|  |  |  |             "-c", | 
					
						
							|  |  |  |             self.ccnet_conf_dir, | 
					
						
							|  |  |  |             "-d", | 
					
						
							|  |  |  |             self.seafile_conf_dir, | 
					
						
							|  |  |  |             "-l", | 
					
						
							|  |  |  |             self.seafile_log, | 
					
						
							| 
									
										
										
										
											2019-07-16 12:00:45 +08:00
										 |  |  |             "-f", | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |         ] | 
					
						
							|  |  |  |         self.seafile_proc = shell(cmd, wait=False) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-04 11:41:53 +08:00
										 |  |  |     def start_fileserver(self): | 
					
						
							|  |  |  |         cmd = [ | 
					
						
							|  |  |  |             "./fileserver", | 
					
						
							|  |  |  |             "-F", | 
					
						
							|  |  |  |             self.central_conf_dir, | 
					
						
							|  |  |  |             "-d", | 
					
						
							|  |  |  |             self.seafile_conf_dir, | 
					
						
							|  |  |  |             "-l", | 
					
						
							|  |  |  |             self.fileserver_log, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |         fileserver_path = join(self.projectdir, 'fileserver') | 
					
						
							|  |  |  |         with cd(fileserver_path): | 
					
						
							|  |  |  |             shell("go build") | 
					
						
							|  |  |  |             self.fileserver_proc = shell(cmd, wait=False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |     def stop(self): | 
					
						
							|  |  |  |         if self.ccnet_proc: | 
					
						
							|  |  |  |             logger.info('Stopping ccnet server') | 
					
						
							| 
									
										
										
										
											2020-03-26 15:47:36 +08:00
										 |  |  |             self.ccnet_proc.kill() | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |         if self.seafile_proc: | 
					
						
							|  |  |  |             logger.info('Stopping seafile server') | 
					
						
							| 
									
										
										
										
											2020-03-26 15:47:36 +08:00
										 |  |  |             self.seafile_proc.kill() | 
					
						
							| 
									
										
										
										
											2021-01-04 11:41:53 +08:00
										 |  |  |         if self.fileserver_proc: | 
					
						
							|  |  |  |             logger.info('Stopping go fileserver') | 
					
						
							|  |  |  |             self.fileserver_proc.kill() | 
					
						
							|  |  |  |         if self.db == 'mysql': | 
					
						
							|  |  |  |             del_mysql_dbs() | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_seaserv_envs(self): | 
					
						
							|  |  |  |         envs = dict(os.environ) | 
					
						
							|  |  |  |         envs.update({ | 
					
						
							|  |  |  |             'SEAFILE_CENTRAL_CONF_DIR': self.central_conf_dir, | 
					
						
							|  |  |  |             'CCNET_CONF_DIR': self.ccnet_conf_dir, | 
					
						
							|  |  |  |             'SEAFILE_CONF_DIR': self.seafile_conf_dir, | 
					
						
							| 
									
										
										
										
											2024-11-05 17:42:24 +08:00
										 |  |  |             'SEAFILE_MYSQL_DB_CCNET_DB_NAME': 'ccnet', | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |         }) | 
					
						
							|  |  |  |         return envs | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def create_mysql_dbs(): | 
					
						
							| 
									
										
										
										
											2019-07-16 12:00:45 +08:00
										 |  |  |     sql = b'''\
 | 
					
						
							| 
									
										
										
										
											2018-01-18 11:09:21 +08:00
										 |  |  | create database `ccnet` character set = 'utf8'; | 
					
						
							|  |  |  | create database `seafile` character set = 'utf8'; | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | create user 'seafile'@'localhost' identified by 'seafile'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-18 11:09:21 +08:00
										 |  |  | GRANT ALL PRIVILEGES ON `ccnet`.* to `seafile`@localhost; | 
					
						
							|  |  |  | GRANT ALL PRIVILEGES ON `seafile`.* to `seafile`@localhost; | 
					
						
							| 
									
										
										
										
											2018-01-16 17:10:26 +08:00
										 |  |  |     '''
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-13 18:55:55 -08:00
										 |  |  |     shell('sudo mysql -u root -proot', inputdata=sql) | 
					
						
							| 
									
										
										
										
											2021-01-04 11:41:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | def del_mysql_dbs(): | 
					
						
							|  |  |  |     sql = b'''\
 | 
					
						
							|  |  |  | drop database `ccnet`; | 
					
						
							|  |  |  | drop database `seafile`; | 
					
						
							|  |  |  | drop user 'seafile'@'localhost'; | 
					
						
							|  |  |  |     '''
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     shell('sudo mysql -u root -proot', inputdata=sql) |