From ed6a2920616a2c0e6fa546676188e62783bbc713 Mon Sep 17 00:00:00 2001 From: feiniks <36756310+feiniks@users.noreply.github.com> Date: Tue, 5 Nov 2024 17:42:24 +0800 Subject: [PATCH] Read database config from seafile.conf and env (#713) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Read database config from seafile.conf and env * Go read database config from seafile.conf and env * Delete ccnet.conf * Don't need ccnet_db_name config * Add ccnet db name env * Delete unix_socket and don't return error when failed to read from seafile.conf --------- Co-authored-by: 杨赫然 --- ci/run.py | 2 + ci/serverctl.py | 33 +--- common/group-mgr.c | 5 +- common/seaf-utils.c | 274 +++++++++++++++++-------------- common/user-mgr.c | 8 +- fileserver/fileop.go | 6 +- fileserver/fileserver.go | 316 ++++++++++++++++++------------------ fileserver/option/option.go | 13 +- fuse/seafile-session.c | 18 -- fuse/seafile-session.h | 1 - server/gc/seafile-session.h | 1 - server/seafile-session.c | 42 +---- server/seafile-session.h | 1 - 13 files changed, 327 insertions(+), 393 deletions(-) diff --git a/ci/run.py b/ci/run.py index 89e32d2..9d67c69 100755 --- a/ci/run.py +++ b/ci/run.py @@ -64,6 +64,8 @@ def make_build_env(): _env_add('JWT_PRIVATE_KEY', '@%ukmcl$k=9u-grs4azdljk(sn0kd!=mzc17xd7x8#!u$1x@kl') + _env_add('SEAFILE_MYSQL_DB_CCNET_DB_NAME', 'ccnet') + # Prepend the seafile-server/python to PYTHONPATH so we don't need to "make # install" each time after editing python files. _env_add('PYTHONPATH', join(SeafileServer().projectdir, 'python')) diff --git a/ci/serverctl.py b/ci/serverctl.py index 007f57e..26662ff 100755 --- a/ci/serverctl.py +++ b/ci/serverctl.py @@ -55,40 +55,8 @@ class ServerCtl(object): os.mkdir (self.seafile_conf_dir, 0o755) os.mkdir (self.ccnet_conf_dir, 0o755) - self.init_ccnet() self.init_seafile() - def init_ccnet(self): - if self.db == 'mysql': - self.add_ccnet_db_conf() - else: - self.add_ccnet_sqlite_db_conf() - - def add_ccnet_sqlite_db_conf(self): - ccnet_conf = join(self.central_conf_dir, 'ccnet.conf') - ccnet_db_conf = '''\ -[Database] -''' - with open(ccnet_conf, 'a+') as fp: - fp.write('\n') - fp.write(ccnet_db_conf) - - def add_ccnet_db_conf(self): - ccnet_conf = join(self.central_conf_dir, 'ccnet.conf') - ccnet_db_conf = '''\ -[Database] -ENGINE = mysql -HOST = 127.0.0.1 -PORT = 3306 -USER = seafile -PASSWD = seafile -DB = ccnet -CONNECTION_CHARSET = utf8 -''' - with open(ccnet_conf, 'a+') as fp: - fp.write('\n') - fp.write(ccnet_db_conf) - def init_seafile(self): seafile_conf = join(self.central_conf_dir, 'seafile.conf') if self.fileserver == 'go_fileserver': @@ -265,6 +233,7 @@ connection_charset = utf8 'SEAFILE_CENTRAL_CONF_DIR': self.central_conf_dir, 'CCNET_CONF_DIR': self.ccnet_conf_dir, 'SEAFILE_CONF_DIR': self.seafile_conf_dir, + 'SEAFILE_MYSQL_DB_CCNET_DB_NAME': 'ccnet', }) return envs diff --git a/common/group-mgr.c b/common/group-mgr.c index 2c1f915..adb1495 100644 --- a/common/group-mgr.c +++ b/common/group-mgr.c @@ -40,10 +40,11 @@ ccnet_group_manager_init (CcnetGroupManager *manager) int ccnet_group_manager_prepare (CcnetGroupManager *manager) { - if (!g_key_file_has_key (manager->session->ccnet_config, "GROUP", "TABLE_NAME", NULL)) + const char *table_name = g_getenv("SEAFILE_MYSQL_DB_GROUP_TABLE_NAME"); + if (!table_name) manager->priv->table_name = g_strdup ("Group"); else - manager->priv->table_name = g_key_file_get_string (manager->session->ccnet_config, "GROUP", "TABLE_NAME", NULL); + manager->priv->table_name = g_strdup (table_name); return open_db(manager); } diff --git a/common/seaf-utils.c b/common/seaf-utils.c index df0bead..0a00b84 100644 --- a/common/seaf-utils.c +++ b/common/seaf-utils.c @@ -60,90 +60,185 @@ sqlite_db_start (SeafileSession *session) #define MYSQL_DEFAULT_PORT 3306 -static int -mysql_db_start (SeafileSession *session) -{ - char *host, *user, *passwd, *db, *unix_socket, *charset; +typedef struct DBOption { + char *user; + char *passwd; + char *host; + char *ca_path; + char *charset; + char *ccnet_db_name; + char *seafile_db_name; + gboolean use_ssl; + gboolean skip_verify; int port; - gboolean use_ssl = FALSE; - gboolean skip_verify = FALSE; - char *ca_path = NULL; - int max_connections = 0; - GError *error = NULL; + int max_connections; +} DBOption; - unix_socket = seaf_key_file_get_string (session->config, - "database", "unix_socket", NULL); +static void +db_option_free (DBOption *option) +{ + if (!option) + return; + g_free (option->user); + g_free (option->passwd); + g_free (option->host); + g_free (option->ca_path); + g_free (option->charset); + g_free (option->ccnet_db_name); + g_free (option->seafile_db_name); + g_free (option); +} - host = seaf_key_file_get_string (session->config, "database", "host", NULL); - if (!host && !unix_socket) { - seaf_warning ("DB host not set in config.\n"); - return -1; +static int +load_db_option_from_env (DBOption *option) +{ + const char *env_user, *env_passwd, *env_host, *env_ccnet_db, *env_seafile_db; + + env_user = g_getenv("SEAFILE_MYSQL_DB_USER"); + env_passwd = g_getenv("SEAFILE_MYSQL_DB_PASSWORD"); + env_host = g_getenv("SEAFILE_MYSQL_DB_HOST"); + env_ccnet_db = g_getenv("SEAFILE_MYSQL_DB_CCNET_DB_NAME"); + env_seafile_db = g_getenv("SEAFILE_MYSQL_DB_SEAFILE_DB_NAME"); + + if (env_user) { + g_free (option->user); + option->user = g_strdup (env_user); + } + if (env_passwd) { + g_free (option->passwd); + option->passwd = g_strdup (env_passwd); + } + if (env_host) { + g_free (option->host); + option->host = g_strdup (env_host); + } + if (env_ccnet_db) { + g_free (option->ccnet_db_name); + option->ccnet_db_name = g_strdup (env_ccnet_db); + } else if (!option->ccnet_db_name) { + option->ccnet_db_name = g_strdup ("ccnet_db"); + seaf_message ("Failed to read SEAFILE_MYSQL_DB_CCNET_DB_NAME, use ccnet_db by default"); + } + if (env_seafile_db) { + g_free (option->seafile_db_name); + option->seafile_db_name = g_strdup (env_seafile_db); + } else if (!option->seafile_db_name) { + option->seafile_db_name = g_strdup ("seafile_db"); + seaf_message ("Failed to read SEAFILE_MYSQL_DB_SEAFILE_DB_NAME, use seafile_db by default"); } - port = g_key_file_get_integer (session->config, "database", "port", &error); + return 0; +} + +static DBOption * +load_db_option (SeafileSession *session) +{ + GError *error = NULL; + int ret = 0; + DBOption *option = g_new0 (DBOption, 1); + + option->host = seaf_key_file_get_string (session->config, "database", "host", NULL); + + option->port = g_key_file_get_integer (session->config, "database", "port", &error); if (error) { g_clear_error (&error); - port = MYSQL_DEFAULT_PORT; + option->port = MYSQL_DEFAULT_PORT; } - user = seaf_key_file_get_string (session->config, "database", "user", NULL); - if (!user && !unix_socket) { - seaf_warning ("DB user not set in config.\n"); - return -1; - } + option->user = seaf_key_file_get_string (session->config, "database", "user", NULL); - passwd = seaf_key_file_get_string (session->config, "database", "password", NULL); - if (!passwd && !unix_socket) { - seaf_warning ("DB passwd not set in config.\n"); - return -1; - } + option->passwd = seaf_key_file_get_string (session->config, "database", "password", NULL); - db = seaf_key_file_get_string (session->config, "database", "db_name", NULL); - if (!db) { - seaf_warning ("DB name not set in config.\n"); - return -1; - } + option->seafile_db_name = seaf_key_file_get_string (session->config, "database", "db_name", NULL); - use_ssl = g_key_file_get_boolean (session->config, + option->use_ssl = g_key_file_get_boolean (session->config, "database", "use_ssl", NULL); - skip_verify = g_key_file_get_boolean (session->config, + option->skip_verify = g_key_file_get_boolean (session->config, "database", "skip_verify", NULL); - if (use_ssl && !skip_verify) { - ca_path = seaf_key_file_get_string (session->config, + if (option->use_ssl && !option->skip_verify) { + option->ca_path = seaf_key_file_get_string (session->config, "database", "ca_path", NULL); - if (!ca_path) { + if (!option->ca_path) { seaf_warning ("ca_path is required if use ssl and don't skip verify.\n"); - return -1; + ret = -1; + goto out; } } - charset = seaf_key_file_get_string (session->config, + option->charset = seaf_key_file_get_string (session->config, "database", "connection_charset", NULL); - max_connections = g_key_file_get_integer (session->config, + option->max_connections = g_key_file_get_integer (session->config, "database", "max_connections", &error); - if (error || max_connections < 0) { + if (error || option->max_connections < 0) { if (error) g_clear_error (&error); - max_connections = DEFAULT_MAX_CONNECTIONS; + option->max_connections = DEFAULT_MAX_CONNECTIONS; } - session->db = seaf_db_new_mysql (host, port, user, passwd, db, unix_socket, use_ssl, skip_verify, ca_path, charset, max_connections); + load_db_option_from_env (option); + + if (!option->host) { + seaf_warning ("DB host not set in config.\n"); + ret = -1; + goto out; + } + + if (!option->user) { + seaf_warning ("DB user not set in config.\n"); + ret = -1; + goto out; + } + + if (!option->passwd) { + seaf_warning ("DB passwd not set in config.\n"); + ret = -1; + goto out; + } + + if (!option->ccnet_db_name) { + seaf_warning ("ccnet_db_name not set in config.\n"); + ret = -1; + goto out; + } + if (!option->seafile_db_name) { + seaf_warning ("db_name not set in config.\n"); + ret = -1; + goto out; + } + +out: + if (ret < 0) { + db_option_free (option); + return NULL; + } + + return option; +} + +static int +mysql_db_start (SeafileSession *session) +{ + DBOption *option = NULL; + + option = load_db_option (session); + if (!option) { + seaf_warning ("Failed to load database config.\n"); + return -1; + } + + session->db = seaf_db_new_mysql (option->host, option->port, option->user, option->passwd, option->seafile_db_name, + NULL, option->use_ssl, option->skip_verify, option->ca_path, option->charset, option->max_connections); if (!session->db) { + db_option_free (option); seaf_warning ("Failed to start mysql db.\n"); return -1; } - g_free (host); - g_free (user); - g_free (passwd); - g_free (db); - g_free (unix_socket); - g_free (charset); - + db_option_free (option); return 0; } @@ -267,80 +362,23 @@ ccnet_init_sqlite_database (SeafileSession *session) static int ccnet_init_mysql_database (SeafileSession *session) { - char *host, *user, *passwd, *db, *unix_socket, *charset; - int port; - gboolean use_ssl = FALSE; - gboolean skip_verify = FALSE; - char *ca_path = NULL; - int max_connections = 0; + DBOption *option = NULL; - host = ccnet_key_file_get_string (session->ccnet_config, "Database", "HOST"); - user = ccnet_key_file_get_string (session->ccnet_config, "Database", "USER"); - passwd = ccnet_key_file_get_string (session->ccnet_config, "Database", "PASSWD"); - db = ccnet_key_file_get_string (session->ccnet_config, "Database", "DB"); - unix_socket = ccnet_key_file_get_string (session->ccnet_config, - "Database", "UNIX_SOCKET"); - - if (!host && !unix_socket) { - seaf_warning ("DB host not set in config.\n"); - return -1; - } - if (!user && !unix_socket) { - seaf_warning ("DB user not set in config.\n"); - return -1; - } - if (!passwd && !unix_socket) { - seaf_warning ("DB passwd not set in config.\n"); - return -1; - } - if (!db) { - seaf_warning ("DB name not set in config.\n"); + option = load_db_option (session); + if (!option) { + seaf_warning ("Failed to load database config.\n"); return -1; } - GError *error = NULL; - port = g_key_file_get_integer (session->ccnet_config, "Database", "PORT", &error); - if (error) { - g_clear_error (&error); - port = MYSQL_DEFAULT_PORT; - } - - use_ssl = g_key_file_get_boolean (session->ccnet_config, "Database", "USE_SSL", NULL); - skip_verify = g_key_file_get_boolean (session->ccnet_config, "Database", "SKIP_VERIFY", NULL); - if (use_ssl && !skip_verify) { - ca_path = seaf_key_file_get_string (session->ccnet_config, - "Database", "CA_PATH", NULL); - if (!ca_path) { - seaf_warning ("ca_path is required if use ssl and don't skip verify.\n"); - return -1; - } - } - - charset = ccnet_key_file_get_string (session->ccnet_config, - "Database", "CONNECTION_CHARSET"); - - max_connections = g_key_file_get_integer (session->ccnet_config, - "Database", "MAX_CONNECTIONS", - &error); - if (error || max_connections < 0) { - max_connections = DEFAULT_MAX_CONNECTIONS; - if (error) - g_clear_error (&error); - } - - session->ccnet_db = seaf_db_new_mysql (host, port, user, passwd, db, unix_socket, use_ssl, skip_verify, ca_path, charset, max_connections); + session->ccnet_db = seaf_db_new_mysql (option->host, option->port, option->user, option->passwd, option->ccnet_db_name, + NULL, option->use_ssl, option->skip_verify, option->ca_path, option->charset, option->max_connections); if (!session->ccnet_db) { + db_option_free (option); seaf_warning ("Failed to open ccnet database.\n"); return -1; } - g_free (host); - g_free (user); - g_free (passwd); - g_free (db); - g_free (unix_socket); - g_free (charset); - + db_option_free (option); return 0; } @@ -353,7 +391,7 @@ load_ccnet_database_config (SeafileSession *session) char *engine; gboolean create_tables = FALSE; - engine = ccnet_key_file_get_string (session->ccnet_config, "Database", "ENGINE"); + engine = ccnet_key_file_get_string (session->config, "database", "type"); if (!engine || strcasecmp (engine, "sqlite") == 0) { seaf_message ("Use database sqlite\n"); ret = ccnet_init_sqlite_database (session); @@ -375,8 +413,8 @@ load_ccnet_database_config (SeafileSession *session) ret = -1; } if (ret == 0) { - if (g_key_file_has_key (session->ccnet_config, "Database", "CREATE_TABLES", NULL)) - create_tables = g_key_file_get_boolean (session->ccnet_config, "Database", "CREATE_TABLES", NULL); + if (g_key_file_has_key (session->config, "database", "create_tables", NULL)) + create_tables = g_key_file_get_boolean (session->config, "database", "create_tables", NULL); session->ccnet_create_tables = create_tables; } diff --git a/common/user-mgr.c b/common/user-mgr.c index d8b9cf4..b7beb6f 100644 --- a/common/user-mgr.c +++ b/common/user-mgr.c @@ -141,12 +141,7 @@ ccnet_user_manager_prepare (CcnetUserManager *manager) return -1; #endif - int iter = g_key_file_get_integer (manager->session->ccnet_config, - "USER", "PASSWORD_HASH_ITERATIONS", - NULL); - if (iter <= 0) - iter = DEFAULT_PASSWD_HASH_ITER; - manager->passwd_hash_iter = iter; + manager->passwd_hash_iter = DEFAULT_PASSWD_HASH_ITER; manager->userdb_path = g_build_filename (manager->session->ccnet_dir, "user-db", NULL); @@ -191,7 +186,6 @@ ccnet_user_manager_set_max_users (CcnetUserManager *manager, gint64 max_users) static int try_load_ldap_settings (CcnetUserManager *manager) { GKeyFile *config = manager->session->ccnet_config; - manager->ldap_host = ccnet_key_file_get_string (config, "LDAP", "HOST"); if (!manager->ldap_host) return 0; diff --git a/fileserver/fileop.go b/fileserver/fileop.go index 5e93212..48268d7 100644 --- a/fileserver/fileop.go +++ b/fileserver/fileop.go @@ -2077,11 +2077,7 @@ func updateBranch(repoID, originRepoID, newCommitID, oldCommitID, secondParentID var commitID string name := "master" - if strings.EqualFold(dbType, "mysql") { - sqlStr = "SELECT commit_id FROM Branch WHERE name = ? AND repo_id = ? FOR UPDATE" - } else { - sqlStr = "SELECT commit_id FROM Branch WHERE name = ? AND repo_id = ?" - } + sqlStr = "SELECT commit_id FROM Branch WHERE name = ? AND repo_id = ? FOR UPDATE" row = trans.QueryRowContext(ctx, sqlStr, name, repoID) if err := row.Scan(&commitID); err != nil { diff --git a/fileserver/fileserver.go b/fileserver/fileserver.go index 2af6832..7088758 100644 --- a/fileserver/fileserver.go +++ b/fileserver/fileserver.go @@ -42,7 +42,6 @@ var rpcPipePath string var pidFilePath string var logFp *os.File -var dbType string var seafileDB, ccnetDB *sql.DB var logToStdout bool @@ -92,91 +91,158 @@ func (f *LogFormatter) Format(entry *log.Entry) ([]byte, error) { } func loadCcnetDB() { - ccnetConfPath := filepath.Join(centralDir, "ccnet.conf") + dbOpt, err := loadDBOption() + if err != nil { + log.Fatalf("Failed to load database: %v", err) + } + + var dsn string + timeout := "&readTimeout=60s" + "&writeTimeout=60s" + if dbOpt.UseTLS && dbOpt.SkipVerify { + dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify%s", dbOpt.User, dbOpt.Password, dbOpt.Host, dbOpt.Port, dbOpt.CcnetDbName, timeout) + } else if dbOpt.UseTLS && !dbOpt.SkipVerify { + registerCA(dbOpt.CaPath) + dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=custom%s", dbOpt.User, dbOpt.Password, dbOpt.Host, dbOpt.Port, dbOpt.CcnetDbName, timeout) + } else { + dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t%s", dbOpt.User, dbOpt.Password, dbOpt.Host, dbOpt.Port, dbOpt.CcnetDbName, dbOpt.UseTLS, timeout) + } + ccnetDB, err = sql.Open("mysql", dsn) + if err != nil { + log.Fatalf("Failed to open database: %v", err) + } + ccnetDB.SetConnMaxLifetime(5 * time.Minute) + ccnetDB.SetMaxOpenConns(8) + ccnetDB.SetMaxIdleConns(8) +} + +func loadDBOption() (*DBOption, error) { + dbOpt, err := loadDBOptionFromFile() + if err != nil { + log.Warnf("failed to load database config: %v", err) + } + dbOpt = loadDBOptionFromEnv(dbOpt) + + if dbOpt.Host == "" { + return nil, fmt.Errorf("no database host in seafile.conf.") + } + if dbOpt.User == "" { + return nil, fmt.Errorf("no database user in seafile.conf.") + } + if dbOpt.Password == "" { + return nil, fmt.Errorf("no database password in seafile.conf.") + } + + return dbOpt, nil +} + +type DBOption struct { + User string + Password string + Host string + Port int + CcnetDbName string + SeafileDbName string + CaPath string + UseTLS bool + SkipVerify bool +} + +func loadDBOptionFromEnv(dbOpt *DBOption) *DBOption { + user := os.Getenv("SEAFILE_MYSQL_DB_USER") + password := os.Getenv("SEAFILE_MYSQL_DB_PASSWORD") + host := os.Getenv("SEAFILE_MYSQL_DB_HOST") + ccnetDbName := os.Getenv("SEAFILE_MYSQL_DB_CCNET_DB_NAME") + seafileDbName := os.Getenv("SEAFILE_MYSQL_DB_SEAFILE_DB_NAME") + + if dbOpt == nil { + dbOpt = new(DBOption) + } + if user != "" { + dbOpt.User = user + } + if password != "" { + dbOpt.Password = password + } + if host != "" { + dbOpt.Host = host + } + if dbOpt.Port == 0 { + dbOpt.Port = 3306 + } + if ccnetDbName != "" { + dbOpt.CcnetDbName = ccnetDbName + } else if dbOpt.CcnetDbName == "" { + dbOpt.CcnetDbName = "ccnet_db" + log.Infof("Failed to read SEAFILE_MYSQL_DB_CCNET_DB_NAME, use ccnet_db by default") + } + if seafileDbName != "" { + dbOpt.SeafileDbName = seafileDbName + } else if dbOpt.SeafileDbName == "" { + dbOpt.SeafileDbName = "seafile_db" + log.Infof("Failed to read SEAFILE_MYSQL_DB_SEAFILE_DB_NAME, use seafile_db by default") + } + return dbOpt +} + +func loadDBOptionFromFile() (*DBOption, error) { + dbOpt := new(DBOption) + + seafileConfPath := filepath.Join(centralDir, "seafile.conf") opts := ini.LoadOptions{} opts.SpaceBeforeInlineComment = true - config, err := ini.LoadSources(opts, ccnetConfPath) + config, err := ini.LoadSources(opts, seafileConfPath) if err != nil { - log.Fatalf("Failed to load ccnet.conf: %v", err) + return nil, fmt.Errorf("failed to load seafile.conf: %v", err) } - section, err := config.GetSection("Database") + section, err := config.GetSection("database") if err != nil { - log.Fatal("No database section in ccnet.conf.") + return nil, fmt.Errorf("no database section in seafile.conf.") } - var dbEngine string = "sqlite" - key, err := section.GetKey("ENGINE") + dbEngine := "" + key, err := section.GetKey("type") if err == nil { dbEngine = key.String() } - - if strings.EqualFold(dbEngine, "mysql") { - unixSocket := "" - if key, err = section.GetKey("UNIX_SOCKET"); err == nil { - unixSocket = key.String() - } - host := "" - if key, err = section.GetKey("HOST"); err == nil { - host = key.String() - } else if unixSocket == "" { - log.Fatal("No database host in ccnet.conf.") - } - // user is required. - if key, err = section.GetKey("USER"); err != nil { - log.Fatal("No database user in ccnet.conf.") - } - user := key.String() - password := "" - if key, err = section.GetKey("PASSWD"); err == nil { - password = key.String() - } else if unixSocket == "" { - log.Fatal("No database password in ccnet.conf.") - } - if key, err = section.GetKey("DB"); err != nil { - log.Fatal("No database db_name in ccnet.conf.") - } - dbName := key.String() - port := 3306 - if key, err = section.GetKey("PORT"); err == nil { - port, _ = key.Int() - } - useTLS := false - if key, err = section.GetKey("USE_SSL"); err == nil { - useTLS, _ = key.Bool() - } - skipVerify := false - if key, err = section.GetKey("SKIP_VERIFY"); err == nil { - skipVerify, _ = key.Bool() - } - var dsn string - timeout := "&readTimeout=60s" + "&writeTimeout=60s" - if unixSocket == "" { - if useTLS && skipVerify { - dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify%s", user, password, host, port, dbName, timeout) - } else if useTLS && !skipVerify { - capath := "" - if key, err = section.GetKey("CA_PATH"); err == nil { - capath = key.String() - } - registerCA(capath) - dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=custom%s", user, password, host, port, dbName, timeout) - } else { - dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t%s", user, password, host, port, dbName, useTLS, timeout) - } - } else { - dsn = fmt.Sprintf("%s:%s@unix(%s)/%s?readTimeout=60s&writeTimeout=60s", user, password, unixSocket, dbName) - } - ccnetDB, err = sql.Open("mysql", dsn) - if err != nil { - log.Fatalf("Failed to open database: %v", err) - } - ccnetDB.SetConnMaxLifetime(5 * time.Minute) - ccnetDB.SetMaxOpenConns(8) - ccnetDB.SetMaxIdleConns(8) - } else { - log.Fatalf("Unsupported database %s.", dbEngine) + if dbEngine != "mysql" { + return nil, fmt.Errorf("unsupported database %s.", dbEngine) } + if key, err = section.GetKey("host"); err == nil { + dbOpt.Host = key.String() + } + // user is required. + if key, err = section.GetKey("user"); err == nil { + dbOpt.User = key.String() + } + + if key, err = section.GetKey("password"); err == nil { + dbOpt.Password = key.String() + } + + if key, err = section.GetKey("db_name"); err == nil { + dbOpt.SeafileDbName = key.String() + } + port := 3306 + if key, err = section.GetKey("port"); err == nil { + port, _ = key.Int() + } + dbOpt.Port = port + useTLS := false + if key, err = section.GetKey("use_ssl"); err == nil { + useTLS, _ = key.Bool() + } + dbOpt.UseTLS = useTLS + skipVerify := false + if key, err = section.GetKey("skip_verify"); err == nil { + skipVerify, _ = key.Bool() + } + dbOpt.SkipVerify = skipVerify + if key, err = section.GetKey("ca_path"); err == nil { + dbOpt.CaPath = key.String() + } + + return dbOpt, nil } // registerCA registers CA to verify server cert. @@ -195,95 +261,29 @@ func registerCA(capath string) { } func loadSeafileDB() { - seafileConfPath := filepath.Join(centralDir, "seafile.conf") - - opts := ini.LoadOptions{} - opts.SpaceBeforeInlineComment = true - config, err := ini.LoadSources(opts, seafileConfPath) + dbOpt, err := loadDBOption() if err != nil { - log.Fatalf("Failed to load seafile.conf: %v", err) + log.Fatalf("Failed to load database: %v", err) } - section, err := config.GetSection("database") - if err != nil { - log.Fatal("No database section in seafile.conf.") - } - - var dbEngine string = "sqlite" - key, err := section.GetKey("type") - if err == nil { - dbEngine = key.String() - } - if strings.EqualFold(dbEngine, "mysql") { - unixSocket := "" - if key, err = section.GetKey("unix_socket"); err == nil { - unixSocket = key.String() - } - host := "" - if key, err = section.GetKey("host"); err == nil { - host = key.String() - } else if unixSocket == "" { - log.Fatal("No database host in seafile.conf.") - } - // user is required. - if key, err = section.GetKey("user"); err != nil { - log.Fatal("No database user in seafile.conf.") - } - user := key.String() - - password := "" - if key, err = section.GetKey("password"); err == nil { - password = key.String() - } else if unixSocket == "" { - log.Fatal("No database password in seafile.conf.") - } - if key, err = section.GetKey("db_name"); err != nil { - log.Fatal("No database db_name in seafile.conf.") - } - dbName := key.String() - port := 3306 - if key, err = section.GetKey("port"); err == nil { - port, _ = key.Int() - } - useTLS := false - if key, err = section.GetKey("use_ssl"); err == nil { - useTLS, _ = key.Bool() - } - skipVerify := false - if key, err = section.GetKey("skip_verify"); err == nil { - skipVerify, _ = key.Bool() - } - - var dsn string - timeout := "&readTimeout=60s" + "&writeTimeout=60s" - if unixSocket == "" { - if useTLS && skipVerify { - dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify%s", user, password, host, port, dbName, timeout) - } else if useTLS && !skipVerify { - capath := "" - if key, err = section.GetKey("ca_path"); err == nil { - capath = key.String() - } - registerCA(capath) - dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=custom%s", user, password, host, port, dbName, timeout) - } else { - dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t%s", user, password, host, port, dbName, useTLS, timeout) - } - } else { - dsn = fmt.Sprintf("%s:%s@unix(%s)/%s?readTimeout=60s&writeTimeout=60s", user, password, unixSocket, dbName) - } - - seafileDB, err = sql.Open("mysql", dsn) - if err != nil { - log.Fatalf("Failed to open database: %v", err) - } - seafileDB.SetConnMaxLifetime(5 * time.Minute) - seafileDB.SetMaxOpenConns(8) - seafileDB.SetMaxIdleConns(8) + var dsn string + timeout := "&readTimeout=60s" + "&writeTimeout=60s" + if dbOpt.UseTLS && dbOpt.SkipVerify { + dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify%s", dbOpt.User, dbOpt.Password, dbOpt.Host, dbOpt.Port, dbOpt.SeafileDbName, timeout) + } else if dbOpt.UseTLS && !dbOpt.SkipVerify { + registerCA(dbOpt.CaPath) + dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=custom%s", dbOpt.User, dbOpt.Password, dbOpt.Host, dbOpt.Port, dbOpt.SeafileDbName, timeout) } else { - log.Fatalf("Unsupported database %s.", dbEngine) + dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t%s", dbOpt.User, dbOpt.Password, dbOpt.Host, dbOpt.Port, dbOpt.SeafileDbName, dbOpt.UseTLS, timeout) } - dbType = dbEngine + + seafileDB, err = sql.Open("mysql", dsn) + if err != nil { + log.Fatalf("Failed to open database: %v", err) + } + seafileDB.SetConnMaxLifetime(5 * time.Minute) + seafileDB.SetMaxOpenConns(8) + seafileDB.SetMaxIdleConns(8) } func writePidFile(pid_file_path string) error { diff --git a/fileserver/option/option.go b/fileserver/option/option.go index 2593de9..0943fa2 100644 --- a/fileserver/option/option.go +++ b/fileserver/option/option.go @@ -140,16 +140,9 @@ func LoadFileServerOptions(centralDir string) { } } - ccnetConfPath := filepath.Join(centralDir, "ccnet.conf") - config, err = ini.Load(ccnetConfPath) - if err != nil { - log.Fatalf("Failed to load ccnet.conf: %v", err) - } - GroupTableName = "Group" - if section, err := config.GetSection("GROUP"); err == nil { - if key, err := section.GetKey("TABLE_NAME"); err == nil { - GroupTableName = key.String() - } + GroupTableName = os.Getenv("SEAFILE_MYSQL_DB_GROUP_TABLE_NAME") + if GroupTableName == "" { + GroupTableName = "Group" } } diff --git a/fuse/seafile-session.c b/fuse/seafile-session.c index 7a6815f..3bf56ad 100644 --- a/fuse/seafile-session.c +++ b/fuse/seafile-session.c @@ -25,10 +25,8 @@ seafile_session_new(const char *central_config_dir, char *abs_ccnet_dir = NULL; char *tmp_file_dir; char *config_file_path; - char *config_file_ccnet; struct stat st; GKeyFile *config; - GKeyFile *ccnet_config; SeafileSession *session = NULL; abs_ccnet_dir = ccnet_expand_path (ccnet_dir); @@ -41,10 +39,6 @@ seafile_session_new(const char *central_config_dir, abs_central_config_dir ? abs_central_config_dir : abs_seafile_dir, "seafile.conf", NULL); - config_file_ccnet = g_build_filename( - abs_central_config_dir ? abs_central_config_dir : abs_ccnet_dir, - "ccnet.conf", NULL); - if (g_stat(abs_seafile_dir, &st) < 0 || !S_ISDIR(st.st_mode)) { seaf_warning ("Seafile data dir %s does not exist and is unable to create\n", abs_seafile_dir); @@ -72,25 +66,13 @@ seafile_session_new(const char *central_config_dir, g_key_file_free (config); goto onerror; } - ccnet_config = g_key_file_new (); - g_key_file_set_list_separator (ccnet_config, ','); - if (!g_key_file_load_from_file (ccnet_config, config_file_ccnet, - G_KEY_FILE_KEEP_COMMENTS, NULL)) - { - seaf_warning ("Can't load ccnet config file %s.\n", config_file_ccnet); - g_key_file_free (ccnet_config); - g_free (config_file_ccnet); - goto onerror; - } g_free (config_file_path); - g_free (config_file_ccnet); session = g_new0(SeafileSession, 1); session->seaf_dir = abs_seafile_dir; session->ccnet_dir = abs_ccnet_dir; session->tmp_file_dir = tmp_file_dir; session->config = config; - session->ccnet_config = ccnet_config; session->excluded_users = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); diff --git a/fuse/seafile-session.h b/fuse/seafile-session.h index f535f91..7552cf0 100644 --- a/fuse/seafile-session.h +++ b/fuse/seafile-session.h @@ -23,7 +23,6 @@ struct _SeafileSession { char *tmp_file_dir; /* Config that's only loaded on start */ GKeyFile *config; - GKeyFile *ccnet_config; SeafDB *db; SeafDB *ccnet_db; SeafDB *seahub_db; diff --git a/server/gc/seafile-session.h b/server/gc/seafile-session.h index f98e310..79fbfd7 100644 --- a/server/gc/seafile-session.h +++ b/server/gc/seafile-session.h @@ -21,7 +21,6 @@ struct _SeafileSession { char *tmp_file_dir; /* Config that's only loaded on start */ GKeyFile *config; - GKeyFile *ccnet_config; SeafDB *db; SeafDB *ccnet_db; char *seahub_pk; diff --git a/server/seafile-session.c b/server/seafile-session.c index c31131b..0487264 100644 --- a/server/seafile-session.c +++ b/server/seafile-session.c @@ -105,12 +105,11 @@ load_fileserver_config (SeafileSession *session) } static int -load_config (SeafileSession *session, const char *config_file_path, const char *config_file_ccnet) +load_config (SeafileSession *session, const char *config_file_path) { int ret = 0; GError *error = NULL; GKeyFile *config = NULL; - GKeyFile *ccnet_config = NULL; gboolean notif_enabled = FALSE; char *notif_server = NULL; int notif_port = 8083; @@ -126,18 +125,7 @@ load_config (SeafileSession *session, const char *config_file_path, const char * goto out; } - ccnet_config = g_key_file_new (); - g_key_file_set_list_separator (ccnet_config, ','); - if (!g_key_file_load_from_file (ccnet_config, config_file_ccnet, - G_KEY_FILE_KEEP_COMMENTS, NULL)) - { - seaf_warning ("Can't load ccnet config file %s.\n", config_file_ccnet); - ret = -1; - goto out; - } - session->config = config; - session->ccnet_config = ccnet_config; session->cloud_mode = g_key_file_get_boolean (config, "general", "cloud_mode", @@ -189,8 +177,6 @@ out: if (ret < 0) { if (config) g_key_file_free (config); - if (ccnet_config) - g_key_file_free (ccnet_config); } return ret; } @@ -205,7 +191,6 @@ seafile_session_new(const char *central_config_dir, char *abs_ccnet_dir = NULL; char *tmp_file_dir; char *config_file_path = NULL; - char *config_file_ccnet = NULL; SeafileSession *session = NULL; abs_ccnet_dir = ccnet_expand_path (ccnet_dir); @@ -237,16 +222,12 @@ seafile_session_new(const char *central_config_dir, abs_central_config_dir ? abs_central_config_dir : abs_seafile_dir, "seafile.conf", NULL); - config_file_ccnet = g_build_filename( - abs_central_config_dir ? abs_central_config_dir : abs_ccnet_dir, - "ccnet.conf", NULL); - session = g_new0(SeafileSession, 1); session->seaf_dir = abs_seafile_dir; session->ccnet_dir = abs_ccnet_dir; session->tmp_file_dir = tmp_file_dir; - if (load_config (session, config_file_path, config_file_ccnet) < 0) { + if (load_config (session, config_file_path) < 0) { goto onerror; } @@ -346,7 +327,6 @@ seafile_session_new(const char *central_config_dir, onerror: g_free (config_file_path); - g_free (config_file_ccnet); free (abs_seafile_dir); free (abs_ccnet_dir); g_free (tmp_file_dir); @@ -364,9 +344,7 @@ seafile_repair_session_new(const char *central_config_dir, char *abs_ccnet_dir = NULL; char *tmp_file_dir; char *config_file_path; - char *config_file_ccnet; GKeyFile *config; - GKeyFile *ccnet_config; SeafileSession *session = NULL; gboolean notif_enabled = FALSE; int notif_port = 8083; @@ -387,10 +365,6 @@ seafile_repair_session_new(const char *central_config_dir, abs_central_config_dir ? abs_central_config_dir : abs_seafile_dir, "seafile.conf", NULL); - config_file_ccnet = g_build_filename( - abs_central_config_dir ? abs_central_config_dir : abs_ccnet_dir, - "ccnet.conf", NULL); - GError *error = NULL; config = g_key_file_new (); if (!g_key_file_load_from_file (config, config_file_path, @@ -400,25 +374,13 @@ seafile_repair_session_new(const char *central_config_dir, g_free (config_file_path); goto onerror; } - ccnet_config = g_key_file_new (); - g_key_file_set_list_separator (ccnet_config, ','); - if (!g_key_file_load_from_file (ccnet_config, config_file_ccnet, - G_KEY_FILE_KEEP_COMMENTS, NULL)) - { - seaf_warning ("Can't load ccnet config file %s.\n", config_file_ccnet); - g_key_file_free (ccnet_config); - g_free (config_file_ccnet); - goto onerror; - } g_free (config_file_path); - g_free (config_file_ccnet); session = g_new0(SeafileSession, 1); session->seaf_dir = abs_seafile_dir; session->ccnet_dir = abs_ccnet_dir; session->tmp_file_dir = tmp_file_dir; session->config = config; - session->ccnet_config = ccnet_config; session->is_repair = TRUE; if (load_database_config (session) < 0) { diff --git a/server/seafile-session.h b/server/seafile-session.h index 42c7359..a5574b9 100644 --- a/server/seafile-session.h +++ b/server/seafile-session.h @@ -45,7 +45,6 @@ struct _SeafileSession { char *tmp_file_dir; /* Config that's only loaded on start */ GKeyFile *config; - GKeyFile *ccnet_config; SeafDB *db; CcnetDB *ccnet_db; char *seahub_pk;