@@ -975,11 +975,11 @@ func Version() (simple, full string) {
975
975
if CustomVersion != "" {
976
976
full = CustomVersion
977
977
simple = CustomVersion
978
- return
978
+ return simple , full
979
979
}
980
980
full = "unknown"
981
981
simple = "unknown"
982
- return
982
+ return simple , full
983
983
}
984
984
// find the Caddy module in the dependency list
985
985
for _ , dep := range bi .Deps {
@@ -1059,7 +1059,7 @@ func Version() (simple, full string) {
1059
1059
}
1060
1060
}
1061
1061
1062
- return
1062
+ return simple , full
1063
1063
}
1064
1064
1065
1065
// Event represents something that has happened or is happening.
@@ -1197,6 +1197,91 @@ var (
1197
1197
rawCfgMu sync.RWMutex
1198
1198
)
1199
1199
1200
+ // lastConfigFile and lastConfigAdapter remember the source config
1201
+ // file and adapter used when Caddy was started via the CLI "run" command.
1202
+ // These are consulted by the SIGUSR1 handler to attempt reloading from
1203
+ // the same source. They are intentionally not set for other entrypoints
1204
+ // such as "caddy start" or subcommands like file-server.
1205
+ var (
1206
+ lastConfigMu sync.RWMutex
1207
+ lastConfigFile string
1208
+ lastConfigAdapter string
1209
+ )
1210
+
1211
+ // reloadFromSourceFunc is the type of stored callback
1212
+ // which is called when we receive a SIGUSR1 signal.
1213
+ type reloadFromSourceFunc func (file , adapter string ) error
1214
+
1215
+ // reloadFromSourceCallback is the stored callback
1216
+ // which is called when we receive a SIGUSR1 signal.
1217
+ var reloadFromSourceCallback reloadFromSourceFunc
1218
+
1219
+ // errReloadFromSourceUnavailable is returned when no reload-from-source callback is set.
1220
+ var errReloadFromSourceUnavailable = errors .New ("reload from source unavailable in this process" ) //nolint:unused
1221
+
1222
+ // SetLastConfig records the given source file and adapter as the
1223
+ // last-known external configuration source. Intended to be called
1224
+ // only when starting via "caddy run --config <file> --adapter <adapter>".
1225
+ func SetLastConfig (file , adapter string , fn reloadFromSourceFunc ) {
1226
+ lastConfigMu .Lock ()
1227
+ lastConfigFile = file
1228
+ lastConfigAdapter = adapter
1229
+ reloadFromSourceCallback = fn
1230
+ lastConfigMu .Unlock ()
1231
+ }
1232
+
1233
+ // ClearLastConfigIfDifferent clears the recorded last-config if the provided
1234
+ // source file/adapter do not match the recorded last-config. If both srcFile
1235
+ // and srcAdapter are empty, the last-config is cleared.
1236
+ func ClearLastConfigIfDifferent (srcFile , srcAdapter string ) {
1237
+ if (srcFile != "" || srcAdapter != "" ) && lastConfigMatches (srcFile , srcAdapter ) {
1238
+ return
1239
+ }
1240
+ SetLastConfig ("" , "" , nil )
1241
+ }
1242
+
1243
+ // getLastConfig returns the last-known config file and adapter.
1244
+ func getLastConfig () (file , adapter string , fn reloadFromSourceFunc ) {
1245
+ lastConfigMu .RLock ()
1246
+ f , a , cb := lastConfigFile , lastConfigAdapter , reloadFromSourceCallback
1247
+ lastConfigMu .RUnlock ()
1248
+ return f , a , cb
1249
+ }
1250
+
1251
+ // lastConfigMatches returns true if the provided source file and/or adapter
1252
+ // matches the recorded last-config. Matching rules (in priority order):
1253
+ // 1. If srcAdapter is provided and differs from the recorded adapter, no match.
1254
+ // 2. If srcFile exactly equals the recorded file, match.
1255
+ // 3. If both sides can be made absolute and equal, match.
1256
+ // 4. If basenames are equal, match.
1257
+ func lastConfigMatches (srcFile , srcAdapter string ) bool {
1258
+ lf , la , _ := getLastConfig ()
1259
+
1260
+ // If adapter is provided, it must match.
1261
+ if srcAdapter != "" && srcAdapter != la {
1262
+ return false
1263
+ }
1264
+
1265
+ // Quick equality check.
1266
+ if srcFile == lf {
1267
+ return true
1268
+ }
1269
+
1270
+ // Try absolute path comparison.
1271
+ sAbs , sErr := filepath .Abs (srcFile )
1272
+ lAbs , lErr := filepath .Abs (lf )
1273
+ if sErr == nil && lErr == nil && sAbs == lAbs {
1274
+ return true
1275
+ }
1276
+
1277
+ // Final fallback: basename equality.
1278
+ if filepath .Base (srcFile ) == filepath .Base (lf ) {
1279
+ return true
1280
+ }
1281
+
1282
+ return false
1283
+ }
1284
+
1200
1285
// errSameConfig is returned if the new config is the same
1201
1286
// as the old one. This isn't usually an actual, actionable
1202
1287
// error; it's mostly a sentinel value.
0 commit comments