Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get nickname from seahub database #663

Merged
merged 5 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ endif

MAKE_SERVER = server tools $(MAKE_CONTROLLER) $(MAKE_FUSE)

SUBDIRS = include lib common python $(MAKE_SERVER) doc
SUBDIRS = include lib common python $(MAKE_SERVER) doc scripts

DIST_SUBDIRS = include lib common python server tools controller fuse doc
DIST_SUBDIRS = include lib common python server tools controller fuse doc scripts

INTLTOOL = \
intltool-extract.in \
Expand Down
39 changes: 37 additions & 2 deletions common/merge-new.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,41 @@ merge_trees_recursive (const char *store_id, int version,
const char *basedir,
MergeOptions *opt);

static char *
get_nickname_by_modifier (GHashTable *email_to_nickname, const char *modifier)
{
const char *nickname;

if (!modifier) {
return NULL;
}

nickname = g_hash_table_lookup (email_to_nickname, modifier);
if (nickname) {
return g_strdup (nickname);
}

if (seaf->seahub_db) {
char *sql = "SELECT nickname from profile_profile WHERE user = ?";
nickname = seaf_db_statement_get_string(seaf->seahub_db, sql, 1, "string", modifier);
}

if (!nickname) {
nickname = modifier;
}
g_hash_table_insert (email_to_nickname, g_strdup(modifier), g_strdup(nickname));

return g_strdup (nickname);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

实际上返回的时候可以不复制 nickname,直接将 hash table 里面的 value 返回,以为这个 hash table 是不会被改变的。

}

static char *
merge_conflict_filename (const char *store_id, int version,
MergeOptions *opt,
const char *basedir,
const char *filename)
{
char *path = NULL, *modifier = NULL, *conflict_name = NULL;
char *nickname = NULL;
gint64 mtime;
SeafCommit *commit;

Expand All @@ -46,11 +74,14 @@ merge_conflict_filename (const char *store_id, int version,
seaf_commit_unref (commit);
}

conflict_name = gen_conflict_path (filename, modifier, mtime);
nickname = get_nickname_by_modifier (opt->email_to_nickname, modifier);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

应该在这个位置先检查 seahub_db 是否为 NULL,如果为 NULL 就表明不支持从 seahub_db 查找用户名称,按照原有的逻辑即可。


conflict_name = gen_conflict_path (filename, nickname, mtime);

out:
g_free (path);
g_free (modifier);
g_free (nickname);
return conflict_name;
}

Expand All @@ -61,6 +92,7 @@ merge_conflict_dirname (const char *store_id, int version,
const char *dirname)
{
char *modifier = NULL, *conflict_name = NULL;
char *nickname = NULL;
SeafCommit *commit;

commit = seaf_commit_manager_get_commit (seaf->commit_mgr,
Expand All @@ -74,10 +106,13 @@ merge_conflict_dirname (const char *store_id, int version,
modifier = g_strdup(commit->creator_name);
seaf_commit_unref (commit);

conflict_name = gen_conflict_path (dirname, modifier, (gint64)time(NULL));
nickname = get_nickname_by_modifier (opt->email_to_nickname, modifier);

conflict_name = gen_conflict_path (dirname, nickname, (gint64)time(NULL));

out:
g_free (modifier);
g_free (nickname);
return conflict_name;
}

Expand Down
2 changes: 2 additions & 0 deletions common/merge-new.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ typedef struct MergeOptions {
char merged_tree_root[41]; /* merge result */
int visit_dirs;
gboolean conflict;

GHashTable *email_to_nickname;
} MergeOptions;

int
Expand Down
100 changes: 100 additions & 0 deletions common/seaf-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,103 @@ load_ccnet_database_config (SeafileSession *session)
g_free (engine);
return ret;
}

static int
parse_seahub_db_config ()
{
char buf[1024];
GError *error = NULL;
int retcode = 0;
char *child_stdout = NULL;
char *child_stderr = NULL;

char *binary_path = g_find_program_in_path ("parse_seahub_db.py");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个字符串要释放一下吧。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

怎样保证能找到这个脚本呢?需要把脚本放在 bin 目录下面的话,需要记录一个任务告诉马宇航处理一下。


snprintf (buf,
sizeof(buf),
"python3 %s",
binary_path);
g_spawn_command_line_sync (buf,
&child_stdout,
&child_stderr,
&retcode,
&error);

if (error != NULL) {
seaf_warning ("Failed to run python parse_seahub_db.py : %s\n", error->message);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error 需要释放一下。

return -1;
}
if (retcode != 0) {
seaf_warning ("Failed to run python parse_seahub_db.py [%d]: %s\n", retcode, strerror(errno));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

应该可以使用 g_spawn_check_wait_status 把这个 wait status 转换为 GError 吧,这样处理更方便一些。你现在这样处理也是不对的,这个 retcode 是 waitpid 返回的。

return -1;
}

return 0;
}

int
load_seahub_database_config (SeafileSession *session)
{
int ret = 0;
json_t *object = NULL;
const char *engine = NULL, *name = NULL, *user = NULL, *password = NULL, *host = NULL, *charset = NULL;
int port;


char *json_file = g_build_filename ("/tmp", "seahub_db.json", NULL);

if (parse_seahub_db_config () < 0) {
seaf_warning ("Failed to parse seahub database config.\n");
ret = -1;
goto out;
}

object = json_load_file (json_file, 0, NULL);
if (!object) {
seaf_warning ("Failed to load seahub db json file: %s\n", json_file);
ret = -1;
goto out;
}

engine = json_object_get_string_member (object, "ENGINE");
name = json_object_get_string_member (object, "NAME");
user = json_object_get_string_member (object, "USER");
password = json_object_get_string_member (object, "PASSWORD");
host = json_object_get_string_member (object, "HOST");
charset = json_object_get_string_member (object, "CHARSET");
port = json_object_get_int_member (object, "PORT");
if (port <= 0) {
port = MYSQL_DEFAULT_PORT;
}

if (!engine || strstr (engine, "sqlite") != NULL) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sqlite 是不能支持多进程同时打开的吧,而且11版本之后 sqlite 已经不支持了。所以这里如果检测到 sqlite 就不用做 username 的转换了。

seaf_message ("Use database sqlite\n");
session->seahub_db = seaf_db_new_sqlite (name, DEFAULT_MAX_CONNECTIONS);
if (!session->seahub_db) {
seaf_warning ("Failed to open seahub database.\n");
ret = -1;
goto out;
}
}
#ifdef HAVE_MYSQL
else if (strstr (engine, "mysql") != NULL) {
seaf_message("Use database Mysql\n");
session->seahub_db = seaf_db_new_mysql (host, port, user, password, name, NULL, FALSE, FALSE, NULL, charset, DEFAULT_MAX_CONNECTIONS);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要检查必要的参数是否已经设置了。

if (!session->seahub_db) {
seaf_warning ("Failed to open seahub database.\n");
ret = -1;
goto out;
}
}
#endif
else {
seaf_warning ("Unknown database type: %s.\n", engine);
ret = -1;
}

out:
if (object)
json_decref (object);
g_free (json_file);
return ret;
}
3 changes: 3 additions & 0 deletions common/seaf-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ load_database_config (struct _SeafileSession *session);
int
load_ccnet_database_config (struct _SeafileSession *session);

int
load_seahub_database_config (SeafileSession *session);

#endif
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ AC_CONFIG_FILES(
controller/Makefile
tools/Makefile
doc/Makefile
scripts/Makefile
)

AC_OUTPUT
1 change: 1 addition & 0 deletions fileserver/fileop.go
Original file line number Diff line number Diff line change
Expand Up @@ -1770,6 +1770,7 @@ func genCommitNeedRetry(repo *repomgr.Repo, base *commitmgr.Commit, commit *comm
opt := new(mergeOptions)
opt.remoteRepoID = repoID
opt.remoteHead = commit.CommitID
opt.emailToNickname = make(map[string]string)

err := mergeTrees(repo.StoreID, roots, opt)
if err != nil {
Expand Down
50 changes: 49 additions & 1 deletion fileserver/fileserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/tls"
"crypto/x509"
"database/sql"
"encoding/json"
"flag"
"fmt"
"io"
Expand All @@ -14,6 +15,7 @@ import (
"os/signal"
"path/filepath"
"runtime/debug"
"strconv"
"strings"
"syscall"

Expand Down Expand Up @@ -41,7 +43,7 @@ var pidFilePath string
var logFp *os.File

var dbType string
var seafileDB, ccnetDB *sql.DB
var seafileDB, ccnetDB, seahubDB *sql.DB

// when SQLite is used, user and group db are separated.
var userDB, groupDB *sql.DB
Expand All @@ -58,6 +60,7 @@ func init() {

const (
timestampFormat = "[2006-01-02 15:04:05] "
seahubDBPath = "/tmp/seahub_db.json"
)

type LogFormatter struct{}
Expand Down Expand Up @@ -269,6 +272,49 @@ func loadSeafileDB() {
dbType = dbEngine
}

func loadSeahubDB() {
dbData, err := ioutil.ReadFile(seahubDBPath)
if err != nil {
log.Warnf("Failed to read seahub database json file: %v", err)
return
}

dbConfig := make(map[string]string)

err = json.Unmarshal(dbData, &dbConfig)
if err != nil {
log.Warnf("Failed to decode seahub database json file: %v", err)
return
}

dbEngine := dbConfig["ENGINE"]
dbName := dbConfig["NAME"]
user := dbConfig["USER"]
password := dbConfig["PASSWORD"]
host := dbConfig["HOST"]
portStr := dbConfig["PORT"]

if strings.Index(dbEngine, "mysql") >= 0 {
port, err := strconv.ParseInt(portStr, 10, 64)
if err != nil || port <= 0 {
port = 3306
}
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=%t", user, password, host, port, dbName, false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里也需要类似 C 部分改一下。

另外,怎样保证在 go fileserver 运行之前 seaf-server 已经解析好了 seahub_db.json 呢?而且把数据库密码这些敏感信息写入到 tmp 下面也有安全问题的,应该改为 seaf-server 和 go fileserver 都直接把 python 脚本的输出读取到内存里面,不需要临时文件。


seahubDB, err = sql.Open("mysql", dsn)
if err != nil {
log.Warnf("Failed to open database: %v", err)
}
} else if strings.Index(dbEngine, "sqlite") >= 0 {
seahubDB, err = sql.Open("sqlite3", dbName)
if err != nil {
log.Warnf("Failed to open database %s: %v", dbName, err)
}
} else {
log.Warnf("Unsupported database %s.", dbEngine)
}
}

func writePidFile(pid_file_path string) error {
file, err := os.OpenFile(pid_file_path, os.O_CREATE|os.O_WRONLY, 0664)
if err != nil {
Expand Down Expand Up @@ -367,6 +413,8 @@ func main() {
fp.Close()
}

loadSeahubDB()

repomgr.Init(seafileDB)

fsmgr.Init(centralDir, dataDir, option.FsCacheLimit)
Expand Down
36 changes: 31 additions & 5 deletions fileserver/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import (
)

type mergeOptions struct {
remoteRepoID string
remoteHead string
mergedRoot string
conflict bool
remoteRepoID string
remoteHead string
mergedRoot string
conflict bool
emailToNickname map[string]string
}

func mergeTrees(storeID string, roots []string, opt *mergeOptions) error {
Expand Down Expand Up @@ -335,7 +336,9 @@ func mergeConflictFileName(storeID string, opt *mergeOptions, baseDir, fileName
mtime = time.Now().Unix()
}

conflictName := genConflictPath(fileName, modifier, mtime)
nickname := getNickNameByModifier(opt.emailToNickname, modifier)

conflictName := genConflictPath(fileName, nickname, mtime)

return conflictName, nil
}
Expand Down Expand Up @@ -366,6 +369,29 @@ func genConflictPath(originPath, modifier string, mtime int64) string {
return conflictPath
}

func getNickNameByModifier(emailToNickname map[string]string, modifier string) string {
if modifier == "" {
return ""
}
nickname, ok := emailToNickname[modifier]
if ok {
return nickname
}
if seahubDB != nil {
sqlStr := "SELECT nickname from profile_profile WHERE user = ?"
row := seahubDB.QueryRow(sqlStr, modifier)
row.Scan(&nickname)
}

if nickname == "" {
nickname = modifier
}

emailToNickname[modifier] = nickname

return nickname
}

func getFileModifierMtime(repoID, storeID, head, filePath string) (string, int64, error) {
commit, err := commitmgr.Load(repoID, head)
if err != nil {
Expand Down
Loading
Loading