Skip to content

Commit

Permalink
feat: add flags to disable WebDAV and Admin UI in weed mini (#7971)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Chris Lu authored and GitHub committed Jan 5, 2026
1 parent 021d9fd commit d15f32a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 47 deletions.
7 changes: 6 additions & 1 deletion weed/admin/handlers/admin_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions weed/command/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)

Expand Down Expand Up @@ -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)
Expand Down
96 changes: 54 additions & 42 deletions weed/command/mini.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
}()
Expand Down Expand Up @@ -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:
Expand All @@ -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("")
}

0 comments on commit d15f32a

Please sign in to comment.