From 55c1fe26fba88210f0b24fcdeaf3cff6f779e741 Mon Sep 17 00:00:00 2001 From: Hamidreza Ghavami Date: Fri, 5 May 2023 22:49:42 +0430 Subject: add import db api route --- web/service/server.go | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) (limited to 'web/service/server.go') diff --git a/web/service/server.go b/web/service/server.go index 1108926b..06ce08c5 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "io/fs" + "mime/multipart" "net/http" "os" "os/exec" @@ -14,7 +15,9 @@ import ( "strings" "time" "x-ui/config" + "x-ui/database" "x-ui/logger" + "x-ui/util/common" "x-ui/util/sys" "x-ui/xray" @@ -73,7 +76,8 @@ type Release struct { } type ServerService struct { - xrayService XrayService + xrayService XrayService + inboundService InboundService } func (s *ServerService) GetStatus(lastStatus *Status) *Status { @@ -395,6 +399,91 @@ func (s *ServerService) GetDb() ([]byte, error) { return fileContents, nil } +func (s *ServerService) ImportDB(file multipart.File) error { + // Check if the file is a SQLite database + isValidDb, err := database.IsSQLiteDB(file) + if err != nil { + return common.NewErrorf("Error checking db file format: %v", err) + } + if !isValidDb { + return common.NewError("Invalid db file format") + } + + // Save the file as temporary file + tempPath := fmt.Sprintf("%s.temp", config.GetDBPath()) + tempFile, err := os.Create(tempPath) + if err != nil { + return common.NewErrorf("Error creating temporary db file: %v", err) + } + defer tempFile.Close() + + // Reset the file reader to the beginning + _, err = file.Seek(0, 0) + if err != nil { + defer os.Remove(tempPath) + return common.NewErrorf("Error resetting file reader: %v", err) + } + + // Save temp file + _, err = io.Copy(tempFile, file) + if err != nil { + defer os.Remove(tempPath) + return common.NewErrorf("Error saving db: %v", err) + } + + // Check if we can init db or not + err = database.InitDB(tempPath) + if err != nil { + defer os.Remove(tempPath) + return common.NewErrorf("Error checking db: %v", err) + } + + // Stop Xray if its running + if s.xrayService.IsXrayRunning() { + err := s.StopXrayService() + if err != nil { + defer os.Remove(tempPath) + return common.NewErrorf("Failed to stop Xray: %v", err) + } + } + + // Backup db for fallback + fallbackPath := fmt.Sprintf("%s.backup", config.GetDBPath()) + err = os.Rename(config.GetDBPath(), fallbackPath) + if err != nil { + defer os.Remove(tempPath) + return common.NewErrorf("Error backup temporary db file: %v", err) + } + + // Move temp to DB path + err = os.Rename(tempPath, config.GetDBPath()) + if err != nil { + defer os.Remove(tempPath) + defer os.Rename(fallbackPath, config.GetDBPath()) + return common.NewErrorf("Error moving db file: %v", err) + } + + // Migrate DB + err = database.InitDB(config.GetDBPath()) + if err != nil { + defer os.Rename(fallbackPath, config.GetDBPath()) + return common.NewErrorf("Error migrating db: %v", err) + } + s.inboundService.MigrationRequirements() + s.inboundService.RemoveOrphanedTraffics() + + // remove fallback file + defer os.Remove(fallbackPath) + + // Start Xray + err = s.RestartXrayService() + if err != nil { + return common.NewErrorf("Imported DB but Failed to start Xray: %v", err) + } + + return nil +} + func (s *ServerService) GetNewX25519Cert() (interface{}, error) { // Run the command cmd := exec.Command(xray.GetBinaryPath(), "x25519") -- cgit v1.2.3 From 26f160fb89f1356f9ec69e2bdfad32d5b543325a Mon Sep 17 00:00:00 2001 From: Hamidreza Ghavami Date: Sat, 6 May 2023 00:22:39 +0430 Subject: add MigrateDB func for a single source of truth --- web/service/server.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'web/service/server.go') diff --git a/web/service/server.go b/web/service/server.go index 06ce08c5..36d79b8b 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -469,8 +469,7 @@ func (s *ServerService) ImportDB(file multipart.File) error { defer os.Rename(fallbackPath, config.GetDBPath()) return common.NewErrorf("Error migrating db: %v", err) } - s.inboundService.MigrationRequirements() - s.inboundService.RemoveOrphanedTraffics() + s.inboundService.MigrateDB() // remove fallback file defer os.Remove(fallbackPath) -- cgit v1.2.3 From 6c087ceb1a0f9edbdd2809eb91ac1165dc57e53d Mon Sep 17 00:00:00 2001 From: Hamidreza Ghavami Date: Sat, 6 May 2023 02:22:45 +0430 Subject: fix import db and always restart xray --- web/service/server.go | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) (limited to 'web/service/server.go') diff --git a/web/service/server.go b/web/service/server.go index 36d79b8b..a9e10ea2 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -411,6 +411,8 @@ func (s *ServerService) ImportDB(file multipart.File) error { // Save the file as temporary file tempPath := fmt.Sprintf("%s.temp", config.GetDBPath()) + // remove temp file before return + defer os.Remove(tempPath) tempFile, err := os.Create(tempPath) if err != nil { return common.NewErrorf("Error creating temporary db file: %v", err) @@ -420,60 +422,48 @@ func (s *ServerService) ImportDB(file multipart.File) error { // Reset the file reader to the beginning _, err = file.Seek(0, 0) if err != nil { - defer os.Remove(tempPath) return common.NewErrorf("Error resetting file reader: %v", err) } // Save temp file _, err = io.Copy(tempFile, file) if err != nil { - defer os.Remove(tempPath) return common.NewErrorf("Error saving db: %v", err) } // Check if we can init db or not err = database.InitDB(tempPath) if err != nil { - defer os.Remove(tempPath) return common.NewErrorf("Error checking db: %v", err) } - // Stop Xray if its running - if s.xrayService.IsXrayRunning() { - err := s.StopXrayService() - if err != nil { - defer os.Remove(tempPath) - return common.NewErrorf("Failed to stop Xray: %v", err) - } - } + // Stop Xray + s.StopXrayService() // Backup db for fallback fallbackPath := fmt.Sprintf("%s.backup", config.GetDBPath()) + // remove fallback file before return + defer os.Remove(fallbackPath) err = os.Rename(config.GetDBPath(), fallbackPath) if err != nil { - defer os.Remove(tempPath) return common.NewErrorf("Error backup temporary db file: %v", err) } // Move temp to DB path err = os.Rename(tempPath, config.GetDBPath()) if err != nil { - defer os.Remove(tempPath) - defer os.Rename(fallbackPath, config.GetDBPath()) + os.Rename(fallbackPath, config.GetDBPath()) return common.NewErrorf("Error moving db file: %v", err) } // Migrate DB err = database.InitDB(config.GetDBPath()) if err != nil { - defer os.Rename(fallbackPath, config.GetDBPath()) + os.Rename(fallbackPath, config.GetDBPath()) return common.NewErrorf("Error migrating db: %v", err) } s.inboundService.MigrateDB() - // remove fallback file - defer os.Remove(fallbackPath) - // Start Xray err = s.RestartXrayService() if err != nil { -- cgit v1.2.3 From 83c853ffb6b896c8a6d1eef4e0354ba1201ebf13 Mon Sep 17 00:00:00 2001 From: Hamidreza Ghavami Date: Sat, 6 May 2023 04:47:57 +0430 Subject: update ImportDB and enhancement --- web/service/server.go | 54 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 14 deletions(-) (limited to 'web/service/server.go') diff --git a/web/service/server.go b/web/service/server.go index a9e10ea2..d8a2239b 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -409,23 +409,33 @@ func (s *ServerService) ImportDB(file multipart.File) error { return common.NewError("Invalid db file format") } + // Reset the file reader to the beginning + _, err = file.Seek(0, 0) + if err != nil { + return common.NewErrorf("Error resetting file reader: %v", err) + } + // Save the file as temporary file tempPath := fmt.Sprintf("%s.temp", config.GetDBPath()) - // remove temp file before return - defer os.Remove(tempPath) + // Remove the existing fallback file (if any) before creating one + _, err = os.Stat(tempPath) + if err == nil { + errRemove := os.Remove(tempPath) + if errRemove != nil { + return common.NewErrorf("Error removing existing temporary db file: %v", errRemove) + } + } + // Create the temporary file tempFile, err := os.Create(tempPath) if err != nil { return common.NewErrorf("Error creating temporary db file: %v", err) } defer tempFile.Close() - // Reset the file reader to the beginning - _, err = file.Seek(0, 0) - if err != nil { - return common.NewErrorf("Error resetting file reader: %v", err) - } + // Remove temp file before returning + defer os.Remove(tempPath) - // Save temp file + // Save uploaded file to temporary file _, err = io.Copy(tempFile, file) if err != nil { return common.NewErrorf("Error saving db: %v", err) @@ -440,26 +450,42 @@ func (s *ServerService) ImportDB(file multipart.File) error { // Stop Xray s.StopXrayService() - // Backup db for fallback + // Backup the current database for fallback fallbackPath := fmt.Sprintf("%s.backup", config.GetDBPath()) - // remove fallback file before return - defer os.Remove(fallbackPath) + // Remove the existing fallback file (if any) + _, err = os.Stat(fallbackPath) + if err == nil { + errRemove := os.Remove(fallbackPath) + if errRemove != nil { + return common.NewErrorf("Error removing existing fallback db file: %v", errRemove) + } + } + // Move the current database to the fallback location err = os.Rename(config.GetDBPath(), fallbackPath) if err != nil { - return common.NewErrorf("Error backup temporary db file: %v", err) + return common.NewErrorf("Error backing up temporary db file: %v", err) } + // Remove the temporary file before returning + defer os.Remove(fallbackPath) + // Move temp to DB path err = os.Rename(tempPath, config.GetDBPath()) if err != nil { - os.Rename(fallbackPath, config.GetDBPath()) + errRename := os.Rename(fallbackPath, config.GetDBPath()) + if errRename != nil { + return common.NewErrorf("Error moving db file and restoring fallback: %v", errRename) + } return common.NewErrorf("Error moving db file: %v", err) } // Migrate DB err = database.InitDB(config.GetDBPath()) if err != nil { - os.Rename(fallbackPath, config.GetDBPath()) + errRename := os.Rename(fallbackPath, config.GetDBPath()) + if errRename != nil { + return common.NewErrorf("Error migrating db and restoring fallback: %v", errRename) + } return common.NewErrorf("Error migrating db: %v", err) } s.inboundService.MigrateDB() -- cgit v1.2.3