diff --git a/weed/admin/handlers/admin_handlers.go b/weed/admin/handlers/admin_handlers.go index 6ed8781f9..919526c4c 100644 --- a/weed/admin/handlers/admin_handlers.go +++ b/weed/admin/handlers/admin_handlers.go @@ -49,7 +49,7 @@ func NewAdminHandlers(adminServer *dash.AdminServer) *AdminHandlers { } // SetupRoutes configures all the routes for the admin interface -func (h *AdminHandlers) SetupRoutes(r *gin.Engine, authRequired bool, adminUser, adminPassword, readOnlyUser, readOnlyPassword string) { +func (h *AdminHandlers) SetupRoutes(r *gin.Engine, authRequired bool, adminUser, adminPassword, readOnlyUser, readOnlyPassword string, enableUI bool) { // Health check (no auth required) r.GET("/health", h.HealthCheck) @@ -61,6 +61,11 @@ func (h *AdminHandlers) SetupRoutes(r *gin.Engine, authRequired bool, adminUser, c.Redirect(http.StatusMovedPermanently, "/static/favicon.ico") }) + // Skip UI routes if UI is not enabled + if !enableUI { + return + } + if authRequired { // Authentication routes (no auth required) r.GET("/login", h.authHandlers.ShowLogin) diff --git a/weed/command/admin.go b/weed/command/admin.go index f07b76780..c47e759a8 100644 --- a/weed/command/admin.go +++ b/weed/command/admin.go @@ -210,8 +210,8 @@ func runAdmin(cmd *Command, args []string) bool { cancel() }() - // Start the admin server with all masters - err := startAdminServer(ctx, a) + // Start the admin server with all masters (UI enabled by default) + err := startAdminServer(ctx, a, true) if err != nil { fmt.Printf("Admin server error: %v\n", err) return false @@ -222,7 +222,7 @@ func runAdmin(cmd *Command, args []string) bool { } // startAdminServer starts the actual admin server -func startAdminServer(ctx context.Context, options AdminOptions) error { +func startAdminServer(ctx context.Context, options AdminOptions, enableUI bool) error { // Set Gin mode gin.SetMode(gin.ReleaseMode) @@ -307,7 +307,7 @@ func startAdminServer(ctx context.Context, options AdminOptions) error { // Create handlers and setup routes authRequired := *options.adminPassword != "" adminHandlers := handlers.NewAdminHandlers(adminServer) - adminHandlers.SetupRoutes(r, authRequired, *options.adminUser, *options.adminPassword, *options.readOnlyUser, *options.readOnlyPassword) + adminHandlers.SetupRoutes(r, authRequired, *options.adminUser, *options.adminPassword, *options.readOnlyUser, *options.readOnlyPassword, enableUI) // Server configuration addr := fmt.Sprintf(":%d", *options.port) diff --git a/weed/command/mini.go b/weed/command/mini.go index a75d631d8..f246a9d88 100644 --- a/weed/command/mini.go +++ b/weed/command/mini.go @@ -57,6 +57,8 @@ var ( createdInitialIAM bool // Track if initial IAM config was created from env vars // Track which port flags were explicitly passed on CLI before config file is applied explicitPortFlags map[string]bool + miniEnableWebDAV *bool + miniEnableAdminUI *bool ) func init() { @@ -135,6 +137,8 @@ func initMiniCommonFlags() { miniOptions.memprofile = cmdMini.Flag.String("memprofile", "", "memory profile output file") miniOptions.debug = cmdMini.Flag.Bool("debug", false, "serves runtime profiling data, e.g., http://localhost:6060/debug/pprof/goroutine?debug=2") miniOptions.debugPort = cmdMini.Flag.Int("debug.port", 6060, "http port for debugging") + miniEnableWebDAV = cmdMini.Flag.Bool("webdav", true, "enable WebDAV server") + miniEnableAdminUI = cmdMini.Flag.Bool("admin.ui", true, "enable Admin UI") } // initMiniMasterFlags initializes Master server flag options @@ -825,13 +829,17 @@ func startMiniServices(miniWhiteList []string, allServicesReady chan struct{}) { startS3Service() }, *miniS3Options.port) - go startMiniService("WebDAV", func() { - miniWebDavOptions.startWebDav() - }, *miniWebDavOptions.port) + if *miniEnableWebDAV { + go startMiniService("WebDAV", func() { + miniWebDavOptions.startWebDav() + }, *miniWebDavOptions.port) + } // Wait for both S3 and WebDAV to be ready waitForServiceReady("S3", *miniS3Options.port, bindIp) - waitForServiceReady("WebDAV", *miniWebDavOptions.port, bindIp) + if *miniEnableWebDAV { + waitForServiceReady("WebDAV", *miniWebDavOptions.port, bindIp) + } // Start Admin with worker (depends on master, filer, S3, WebDAV) go startMiniAdminWithWorker(allServicesReady) @@ -958,7 +966,7 @@ func startMiniAdminWithWorker(allServicesReady chan struct{}) { // Start admin server in background go func() { - if err := startAdminServer(ctx, miniAdminOptions); err != nil { + if err := startAdminServer(ctx, miniAdminOptions, *miniEnableAdminUI); err != nil { glog.Errorf("Admin server error: %v", err) } }() @@ -1097,31 +1105,6 @@ func startMiniWorker() { glog.Infof("Maintenance worker %s started successfully", workerInstance.ID()) } -const welcomeMessageTemplate = ` -╔═══════════════════════════════════════════════════════════════════════════════╗ -║ SeaweedFS Mini - All-in-One Mode ║ -╚═══════════════════════════════════════════════════════════════════════════════╝ - - All components are running and ready to use: - - Master UI: http://%s:%d - Filer UI: http://%s:%d - S3 Endpoint: http://%s:%d - WebDAV: http://%s:%d - Admin UI: http://%s:%d - Volume Server: http://%s:%d - - Optimized Settings: - • Volume size limit: %dMB - • Volume max: auto (based on free disk space) - • Pre-stop seconds: 1 (faster shutdown) - • Master peers: none (single master mode) - • Admin UI for management and maintenance tasks - - Data Directory: %s - - Press Ctrl+C to stop all components -` const credentialsInstructionTemplate = ` To create S3 credentials, you have two options: @@ -1145,21 +1128,50 @@ const credentialsCreatedMessage = ` // printWelcomeMessage prints the welcome message after all services are running func printWelcomeMessage() { - fmt.Printf(welcomeMessageTemplate, - *miniIp, *miniMasterOptions.port, - *miniIp, *miniFilerOptions.port, - *miniIp, *miniS3Options.port, - *miniIp, *miniWebDavOptions.port, - *miniIp, *miniAdminOptions.port, - *miniIp, *miniOptions.v.port, - *miniMasterOptions.volumeSizeLimitMB, - *miniDataFolders, - ) + var sb strings.Builder + + sb.WriteString("╔═══════════════════════════════════════════════════════════════════════════════╗\n") + sb.WriteString("║ SeaweedFS Mini - All-in-One Mode ║\n") + sb.WriteString("╚═══════════════════════════════════════════════════════════════════════════════╝\n\n") + sb.WriteString(" All enabled components are running and ready to use:\n\n") + fmt.Fprintf(&sb, " Master UI: http://%s:%d\n", *miniIp, *miniMasterOptions.port) + fmt.Fprintf(&sb, " Filer UI: http://%s:%d\n", *miniIp, *miniFilerOptions.port) + fmt.Fprintf(&sb, " S3 Endpoint: http://%s:%d\n", *miniIp, *miniS3Options.port) + + if *miniEnableWebDAV { + fmt.Fprintf(&sb, " WebDAV: http://%s:%d\n", *miniIp, *miniWebDavOptions.port) + } + if *miniEnableAdminUI { + fmt.Fprintf(&sb, " Admin UI: http://%s:%d\n", *miniIp, *miniAdminOptions.port) + } + + fmt.Fprintf(&sb, " Volume Server: http://%s:%d\n\n", *miniIp, *miniOptions.v.port) + + sb.WriteString(" Optimized Settings:\n") + fmt.Fprintf(&sb, " • Volume size limit: %dMB\n", *miniMasterOptions.volumeSizeLimitMB) + sb.WriteString(" • Volume max: auto (based on free disk space)\n") + sb.WriteString(" • Pre-stop seconds: 1 (faster shutdown)\n") + sb.WriteString(" • Master peers: none (single master mode)\n") + + if *miniEnableAdminUI { + sb.WriteString(" • Admin UI for management and maintenance tasks\n") + } + + fmt.Fprintf(&sb, "\n Data Directory: %s\n\n", *miniDataFolders) + sb.WriteString(" Press Ctrl+C to stop all components") if createdInitialIAM { - fmt.Print(credentialsCreatedMessage) + sb.WriteString(credentialsCreatedMessage) + } else if *miniEnableAdminUI { + fmt.Fprintf(&sb, credentialsInstructionTemplate, *miniIp, *miniAdminOptions.port) } else { - fmt.Printf(credentialsInstructionTemplate, *miniIp, *miniAdminOptions.port) + sb.WriteString("\n To create S3 credentials, use environment variables:\n\n") + sb.WriteString(" export AWS_ACCESS_KEY_ID=your-access-key\\n") + sb.WriteString(" export AWS_SECRET_ACCESS_KEY=your-secret-key\\n") + sb.WriteString(" weed mini -dir=/data\\n") + sb.WriteString(" This will create initial credentials for the 'mini' user.\\n") } + + fmt.Print(sb.String()) fmt.Println("") }