mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-10-31 18:30:56 +08:00 
			
		
		
		
	cmd: Only set memory/CPU limits on run (fix #6879)
This commit is contained in:
		| @ -171,6 +171,9 @@ func cmdStart(fl Flags) (int, error) { | |||||||
| func cmdRun(fl Flags) (int, error) { | func cmdRun(fl Flags) (int, error) { | ||||||
| 	caddy.TrapSignals() | 	caddy.TrapSignals() | ||||||
|  |  | ||||||
|  | 	logger := caddy.Log() | ||||||
|  | 	setResourceLimits(logger) | ||||||
|  |  | ||||||
| 	configFlag := fl.String("config") | 	configFlag := fl.String("config") | ||||||
| 	configAdapterFlag := fl.String("adapter") | 	configAdapterFlag := fl.String("adapter") | ||||||
| 	resumeFlag := fl.Bool("resume") | 	resumeFlag := fl.Bool("resume") | ||||||
| @ -196,18 +199,18 @@ func cmdRun(fl Flags) (int, error) { | |||||||
| 		config, err = os.ReadFile(caddy.ConfigAutosavePath) | 		config, err = os.ReadFile(caddy.ConfigAutosavePath) | ||||||
| 		if errors.Is(err, fs.ErrNotExist) { | 		if errors.Is(err, fs.ErrNotExist) { | ||||||
| 			// not a bad error; just can't resume if autosave file doesn't exist | 			// not a bad error; just can't resume if autosave file doesn't exist | ||||||
| 			caddy.Log().Info("no autosave file exists", zap.String("autosave_file", caddy.ConfigAutosavePath)) | 			logger.Info("no autosave file exists", zap.String("autosave_file", caddy.ConfigAutosavePath)) | ||||||
| 			resumeFlag = false | 			resumeFlag = false | ||||||
| 		} else if err != nil { | 		} else if err != nil { | ||||||
| 			return caddy.ExitCodeFailedStartup, err | 			return caddy.ExitCodeFailedStartup, err | ||||||
| 		} else { | 		} else { | ||||||
| 			if configFlag == "" { | 			if configFlag == "" { | ||||||
| 				caddy.Log().Info("resuming from last configuration", | 				logger.Info("resuming from last configuration", | ||||||
| 					zap.String("autosave_file", caddy.ConfigAutosavePath)) | 					zap.String("autosave_file", caddy.ConfigAutosavePath)) | ||||||
| 			} else { | 			} else { | ||||||
| 				// if they also specified a config file, user should be aware that we're not | 				// if they also specified a config file, user should be aware that we're not | ||||||
| 				// using it (doing so could lead to data/config loss by overwriting!) | 				// using it (doing so could lead to data/config loss by overwriting!) | ||||||
| 				caddy.Log().Warn("--config and --resume flags were used together; ignoring --config and resuming from last configuration", | 				logger.Warn("--config and --resume flags were used together; ignoring --config and resuming from last configuration", | ||||||
| 					zap.String("autosave_file", caddy.ConfigAutosavePath)) | 					zap.String("autosave_file", caddy.ConfigAutosavePath)) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @ -225,7 +228,7 @@ func cmdRun(fl Flags) (int, error) { | |||||||
| 	if pidfileFlag != "" { | 	if pidfileFlag != "" { | ||||||
| 		err := caddy.PIDFile(pidfileFlag) | 		err := caddy.PIDFile(pidfileFlag) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			caddy.Log().Error("unable to write PID file", | 			logger.Error("unable to write PID file", | ||||||
| 				zap.String("pidfile", pidfileFlag), | 				zap.String("pidfile", pidfileFlag), | ||||||
| 				zap.Error(err)) | 				zap.Error(err)) | ||||||
| 		} | 		} | ||||||
| @ -236,7 +239,7 @@ func cmdRun(fl Flags) (int, error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return caddy.ExitCodeFailedStartup, fmt.Errorf("loading initial config: %v", err) | 		return caddy.ExitCodeFailedStartup, fmt.Errorf("loading initial config: %v", err) | ||||||
| 	} | 	} | ||||||
| 	caddy.Log().Info("serving initial configuration") | 	logger.Info("serving initial configuration") | ||||||
|  |  | ||||||
| 	// if we are to report to another process the successful start | 	// if we are to report to another process the successful start | ||||||
| 	// of the server, do so now by echoing back contents of stdin | 	// of the server, do so now by echoing back contents of stdin | ||||||
| @ -272,15 +275,15 @@ func cmdRun(fl Flags) (int, error) { | |||||||
| 	switch runtime.GOOS { | 	switch runtime.GOOS { | ||||||
| 	case "windows": | 	case "windows": | ||||||
| 		if os.Getenv("HOME") == "" && os.Getenv("USERPROFILE") == "" && !hasXDG { | 		if os.Getenv("HOME") == "" && os.Getenv("USERPROFILE") == "" && !hasXDG { | ||||||
| 			caddy.Log().Warn("neither HOME nor USERPROFILE environment variables are set - please fix; some assets might be stored in ./caddy") | 			logger.Warn("neither HOME nor USERPROFILE environment variables are set - please fix; some assets might be stored in ./caddy") | ||||||
| 		} | 		} | ||||||
| 	case "plan9": | 	case "plan9": | ||||||
| 		if os.Getenv("home") == "" && !hasXDG { | 		if os.Getenv("home") == "" && !hasXDG { | ||||||
| 			caddy.Log().Warn("$home environment variable is empty - please fix; some assets might be stored in ./caddy") | 			logger.Warn("$home environment variable is empty - please fix; some assets might be stored in ./caddy") | ||||||
| 		} | 		} | ||||||
| 	default: | 	default: | ||||||
| 		if os.Getenv("HOME") == "" && !hasXDG { | 		if os.Getenv("HOME") == "" && !hasXDG { | ||||||
| 			caddy.Log().Warn("$HOME environment variable is empty - please fix; some assets might be stored in ./caddy") | 			logger.Warn("$HOME environment variable is empty - please fix; some assets might be stored in ./caddy") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										48
									
								
								cmd/main.go
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								cmd/main.go
									
									
									
									
									
								
							| @ -69,30 +69,6 @@ func Main() { | |||||||
| 		os.Exit(caddy.ExitCodeFailedStartup) | 		os.Exit(caddy.ExitCodeFailedStartup) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	logger := caddy.Log() |  | ||||||
|  |  | ||||||
| 	// Configure the maximum number of CPUs to use to match the Linux container quota (if any) |  | ||||||
| 	// See https://pkg.go.dev/runtime#GOMAXPROCS |  | ||||||
| 	undo, err := maxprocs.Set(maxprocs.Logger(logger.Sugar().Infof)) |  | ||||||
| 	defer undo() |  | ||||||
| 	if err != nil { |  | ||||||
| 		caddy.Log().Warn("failed to set GOMAXPROCS", zap.Error(err)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Configure the maximum memory to use to match the Linux container quota (if any) or system memory |  | ||||||
| 	// See https://pkg.go.dev/runtime/debug#SetMemoryLimit |  | ||||||
| 	_, _ = memlimit.SetGoMemLimitWithOpts( |  | ||||||
| 		memlimit.WithLogger( |  | ||||||
| 			slog.New(zapslog.NewHandler(logger.Core())), |  | ||||||
| 		), |  | ||||||
| 		memlimit.WithProvider( |  | ||||||
| 			memlimit.ApplyFallback( |  | ||||||
| 				memlimit.FromCgroup, |  | ||||||
| 				memlimit.FromSystem, |  | ||||||
| 			), |  | ||||||
| 		), |  | ||||||
| 	) |  | ||||||
|  |  | ||||||
| 	if err := defaultFactory.Build().Execute(); err != nil { | 	if err := defaultFactory.Build().Execute(); err != nil { | ||||||
| 		var exitError *exitError | 		var exitError *exitError | ||||||
| 		if errors.As(err, &exitError) { | 		if errors.As(err, &exitError) { | ||||||
| @ -488,6 +464,30 @@ func printEnvironment() { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func setResourceLimits(logger *zap.Logger) { | ||||||
|  | 	// Configure the maximum number of CPUs to use to match the Linux container quota (if any) | ||||||
|  | 	// See https://pkg.go.dev/runtime#GOMAXPROCS | ||||||
|  | 	undo, err := maxprocs.Set(maxprocs.Logger(logger.Sugar().Infof)) | ||||||
|  | 	defer undo() | ||||||
|  | 	if err != nil { | ||||||
|  | 		caddy.Log().Warn("failed to set GOMAXPROCS", zap.Error(err)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Configure the maximum memory to use to match the Linux container quota (if any) or system memory | ||||||
|  | 	// See https://pkg.go.dev/runtime/debug#SetMemoryLimit | ||||||
|  | 	_, _ = memlimit.SetGoMemLimitWithOpts( | ||||||
|  | 		memlimit.WithLogger( | ||||||
|  | 			slog.New(zapslog.NewHandler(logger.Core())), | ||||||
|  | 		), | ||||||
|  | 		memlimit.WithProvider( | ||||||
|  | 			memlimit.ApplyFallback( | ||||||
|  | 				memlimit.FromCgroup, | ||||||
|  | 				memlimit.FromSystem, | ||||||
|  | 			), | ||||||
|  | 		), | ||||||
|  | 	) | ||||||
|  | } | ||||||
|  |  | ||||||
| // StringSlice is a flag.Value that enables repeated use of a string flag. | // StringSlice is a flag.Value that enables repeated use of a string flag. | ||||||
| type StringSlice []string | type StringSlice []string | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Matthew Holt
					Matthew Holt