Init V4 community edition (#2265)

* Init V4 community edition

* Init V4 community edition
This commit is contained in:
AaronLiu
2025-04-20 17:31:25 +08:00
committed by GitHub
parent da4e44b77a
commit 21d158db07
597 changed files with 119415 additions and 41692 deletions

30
cmd/eject.go Normal file
View File

@@ -0,0 +1,30 @@
package cmd
import (
"github.com/cloudreve/Cloudreve/v4/application/constants"
"github.com/cloudreve/Cloudreve/v4/application/dependency"
"github.com/cloudreve/Cloudreve/v4/application/statics"
"github.com/spf13/cobra"
"os"
)
func init() {
rootCmd.AddCommand(ejectCmd)
}
var ejectCmd = &cobra.Command{
Use: "eject",
Short: "Eject all embedded static files",
Run: func(cmd *cobra.Command, args []string) {
dep := dependency.NewDependency(
dependency.WithConfigPath(confPath),
dependency.WithProFlag(constants.IsPro == "true"),
)
logger := dep.Logger()
if err := statics.Eject(dep.Logger(), dep.Statics()); err != nil {
logger.Error("Failed to eject static files: %s", err)
os.Exit(1)
}
},
}

69
cmd/migrate.go Normal file
View File

@@ -0,0 +1,69 @@
package cmd
import (
"os"
"path/filepath"
"github.com/cloudreve/Cloudreve/v4/application/constants"
"github.com/cloudreve/Cloudreve/v4/application/dependency"
"github.com/cloudreve/Cloudreve/v4/application/migrator"
"github.com/cloudreve/Cloudreve/v4/pkg/util"
"github.com/spf13/cobra"
)
var (
v3ConfPath string
forceReset bool
)
func init() {
rootCmd.AddCommand(migrateCmd)
migrateCmd.PersistentFlags().StringVar(&v3ConfPath, "v3-conf", "", "Path to the v3 config file")
migrateCmd.PersistentFlags().BoolVar(&forceReset, "force-reset", false, "Force reset migration state and start from beginning")
}
var migrateCmd = &cobra.Command{
Use: "migrate",
Short: "Migrate from v3 to v4",
Run: func(cmd *cobra.Command, args []string) {
dep := dependency.NewDependency(
dependency.WithConfigPath(confPath),
dependency.WithRequiredDbVersion(constants.BackendVersion),
dependency.WithProFlag(constants.IsPro == "true"),
)
logger := dep.Logger()
logger.Info("Migrating from v3 to v4...")
if v3ConfPath == "" {
logger.Error("v3 config file is required, please use -v3-conf to specify the path.")
os.Exit(1)
}
// Check if state file exists and warn about resuming
stateFilePath := filepath.Join(filepath.Dir(v3ConfPath), "migration_state.json")
if util.Exists(stateFilePath) && !forceReset {
logger.Info("Found existing migration state file at %s. Migration will resume from the last successful step.", stateFilePath)
logger.Info("If you want to start migration from the beginning, please use --force-reset flag.")
} else if forceReset && util.Exists(stateFilePath) {
logger.Info("Force resetting migration state. Will start from the beginning.")
if err := os.Remove(stateFilePath); err != nil {
logger.Error("Failed to remove migration state file: %s", err)
os.Exit(1)
}
}
migrator, err := migrator.NewMigrator(dep, v3ConfPath)
if err != nil {
logger.Error("Failed to create migrator: %s", err)
os.Exit(1)
}
if err := migrator.Migrate(); err != nil {
logger.Error("Failed to migrate: %s", err)
logger.Info("Migration failed but state has been saved. You can retry with the same command to resume from the last successful step.")
os.Exit(1)
}
logger.Info("Migration from v3 to v4 completed successfully.")
},
}

42
cmd/root.go Normal file
View File

@@ -0,0 +1,42 @@
package cmd
import (
"fmt"
"github.com/cloudreve/Cloudreve/v4/pkg/util"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"os"
)
var (
confPath string
)
func init() {
rootCmd.PersistentFlags().StringVarP(&confPath, "conf", "c", util.DataPath("conf.ini"), "Path to the config file")
rootCmd.PersistentFlags().BoolVarP(&util.UseWorkingDir, "use-working-dir", "w", false, "Use working directory, instead of executable directory")
}
var rootCmd = &cobra.Command{
Use: "cloudreve",
Short: "Cloudreve is a server-side self-hosted cloud storage platform",
Long: `Self-hosted file management and sharing system, supports multiple storage providers.
Complete documentation is available at https://docs.cloudreve.org/`,
Run: func(cmd *cobra.Command, args []string) {
// Do Stuff Here
},
}
func Execute() {
cmd, _, err := rootCmd.Find(os.Args[1:])
// redirect to default server cmd if no cmd is given
if err == nil && cmd.Use == rootCmd.Use && cmd.Flags().Parse(os.Args[1:]) != pflag.ErrHelp {
args := append([]string{"server"}, os.Args[1:]...)
rootCmd.SetArgs(args)
}
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

60
cmd/server.go Normal file
View File

@@ -0,0 +1,60 @@
package cmd
import (
"os"
"os/signal"
"syscall"
"github.com/cloudreve/Cloudreve/v4/application"
"github.com/cloudreve/Cloudreve/v4/application/constants"
"github.com/cloudreve/Cloudreve/v4/application/dependency"
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
"github.com/spf13/cobra"
)
var (
licenseKey string
)
func init() {
rootCmd.AddCommand(serverCmd)
serverCmd.PersistentFlags().StringVarP(&licenseKey, "license-key", "l", "", "License key of your Cloudreve Pro")
}
var serverCmd = &cobra.Command{
Use: "server",
Short: "Start a Cloudreve server with the given config file",
Run: func(cmd *cobra.Command, args []string) {
dep := dependency.NewDependency(
dependency.WithConfigPath(confPath),
dependency.WithProFlag(constants.IsProBool),
dependency.WithRequiredDbVersion(constants.BackendVersion),
dependency.WithLicenseKey(licenseKey),
)
server := application.NewServer(dep)
logger := dep.Logger()
server.PrintBanner()
// Graceful shutdown after received signal.
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)
go shutdown(sigChan, logger, server)
if err := server.Start(); err != nil {
logger.Error("Failed to start server: %s", err)
os.Exit(1)
}
defer func() {
<-sigChan
}()
},
}
func shutdown(sigChan chan os.Signal, logger logging.Logger, server application.Server) {
sig := <-sigChan
logger.Info("Signal %s received, shutting down server...", sig)
server.Close()
close(sigChan)
}