Browse Source

feat: add flags to disable WebDAV and Admin UI in weed mini (#7971)

* feat: add flags to disable WebDAV and Admin UI in weed mini

- Add -webdav flag (default: true) to optionally disable WebDAV server
- Add -admin.ui flag (default: true) to optionally disable Admin UI only (server still runs)
- Conditionally skip WebDAV service startup based on flag
- Pass disableUI flag to SetupRoutes to skip UI route registration
- Admin server still runs for gRPC and API access when UI is disabled

Addresses issue from https://github.com/seaweedfs/seaweedfs/pull/7833#issuecomment-3711924150

* refactor: use positive enableUI parameter instead of disableUI across admin server and handlers

* docs: update mini welcome message to list enabled components

* chore: remove unused welcomeMessageTemplate constant

* docs: split S3 credential message into separate sb.WriteString calls
pull/7972/head
Chris Lu 7 days ago
committed by GitHub
parent
commit
d15f32ae46
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 7
      weed/admin/handlers/admin_handlers.go
  2. 8
      weed/command/admin.go
  3. 96
      weed/command/mini.go

7
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 // 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) // Health check (no auth required)
r.GET("/health", h.HealthCheck) 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") c.Redirect(http.StatusMovedPermanently, "/static/favicon.ico")
}) })
// Skip UI routes if UI is not enabled
if !enableUI {
return
}
if authRequired { if authRequired {
// Authentication routes (no auth required) // Authentication routes (no auth required)
r.GET("/login", h.authHandlers.ShowLogin) r.GET("/login", h.authHandlers.ShowLogin)

8
weed/command/admin.go

@ -210,8 +210,8 @@ func runAdmin(cmd *Command, args []string) bool {
cancel() 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 { if err != nil {
fmt.Printf("Admin server error: %v\n", err) fmt.Printf("Admin server error: %v\n", err)
return false return false
@ -222,7 +222,7 @@ func runAdmin(cmd *Command, args []string) bool {
} }
// startAdminServer starts the actual admin server // 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 // Set Gin mode
gin.SetMode(gin.ReleaseMode) gin.SetMode(gin.ReleaseMode)
@ -307,7 +307,7 @@ func startAdminServer(ctx context.Context, options AdminOptions) error {
// Create handlers and setup routes // Create handlers and setup routes
authRequired := *options.adminPassword != "" authRequired := *options.adminPassword != ""
adminHandlers := handlers.NewAdminHandlers(adminServer) 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 // Server configuration
addr := fmt.Sprintf(":%d", *options.port) addr := fmt.Sprintf(":%d", *options.port)

96
weed/command/mini.go

@ -57,6 +57,8 @@ var (
createdInitialIAM bool // Track if initial IAM config was created from env vars 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 // Track which port flags were explicitly passed on CLI before config file is applied
explicitPortFlags map[string]bool explicitPortFlags map[string]bool
miniEnableWebDAV *bool
miniEnableAdminUI *bool
) )
func init() { func init() {
@ -135,6 +137,8 @@ func initMiniCommonFlags() {
miniOptions.memprofile = cmdMini.Flag.String("memprofile", "", "memory profile output file") 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.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") 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 // initMiniMasterFlags initializes Master server flag options
@ -825,13 +829,17 @@ func startMiniServices(miniWhiteList []string, allServicesReady chan struct{}) {
startS3Service() startS3Service()
}, *miniS3Options.port) }, *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 // Wait for both S3 and WebDAV to be ready
waitForServiceReady("S3", *miniS3Options.port, bindIp) 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) // Start Admin with worker (depends on master, filer, S3, WebDAV)
go startMiniAdminWithWorker(allServicesReady) go startMiniAdminWithWorker(allServicesReady)
@ -958,7 +966,7 @@ func startMiniAdminWithWorker(allServicesReady chan struct{}) {
// Start admin server in background // Start admin server in background
go func() { go func() {
if err := startAdminServer(ctx, miniAdminOptions); err != nil {
if err := startAdminServer(ctx, miniAdminOptions, *miniEnableAdminUI); err != nil {
glog.Errorf("Admin server error: %v", err) glog.Errorf("Admin server error: %v", err)
} }
}() }()
@ -1097,31 +1105,6 @@ func startMiniWorker() {
glog.Infof("Maintenance worker %s started successfully", workerInstance.ID()) 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 = ` const credentialsInstructionTemplate = `
To create S3 credentials, you have two options: To create S3 credentials, you have two options:
@ -1145,21 +1128,50 @@ const credentialsCreatedMessage = `
// printWelcomeMessage prints the welcome message after all services are running // printWelcomeMessage prints the welcome message after all services are running
func printWelcomeMessage() { 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 { if createdInitialIAM {
fmt.Print(credentialsCreatedMessage)
sb.WriteString(credentialsCreatedMessage)
} else if *miniEnableAdminUI {
fmt.Fprintf(&sb, credentialsInstructionTemplate, *miniIp, *miniAdminOptions.port)
} else { } 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("") fmt.Println("")
} }
Loading…
Cancel
Save