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
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -210,8 +210,8 @@ func runAdmin(cmd *Command, args []string) bool {
|
|||||||
cancel()
|
cancel()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Start the admin server with all masters
|
// Start the admin server with all masters (UI enabled by default)
|
||||||
err := startAdminServer(ctx, a)
|
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)
|
||||||
|
|||||||
@@ -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() {
|
if *miniEnableWebDAV {
|
||||||
miniWebDavOptions.startWebDav()
|
go startMiniService("WebDAV", func() {
|
||||||
}, *miniWebDavOptions.port)
|
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,
|
var sb strings.Builder
|
||||||
*miniIp, *miniMasterOptions.port,
|
|
||||||
*miniIp, *miniFilerOptions.port,
|
sb.WriteString("╔═══════════════════════════════════════════════════════════════════════════════╗\n")
|
||||||
*miniIp, *miniS3Options.port,
|
sb.WriteString("║ SeaweedFS Mini - All-in-One Mode ║\n")
|
||||||
*miniIp, *miniWebDavOptions.port,
|
sb.WriteString("╚═══════════════════════════════════════════════════════════════════════════════╝\n\n")
|
||||||
*miniIp, *miniAdminOptions.port,
|
sb.WriteString(" All enabled components are running and ready to use:\n\n")
|
||||||
*miniIp, *miniOptions.v.port,
|
fmt.Fprintf(&sb, " Master UI: http://%s:%d\n", *miniIp, *miniMasterOptions.port)
|
||||||
*miniMasterOptions.volumeSizeLimitMB,
|
fmt.Fprintf(&sb, " Filer UI: http://%s:%d\n", *miniIp, *miniFilerOptions.port)
|
||||||
*miniDataFolders,
|
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("")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user