cmd/syncthing: Environment handling for upgrade restarts (fixes #3970)
This commit is contained in:
parent
9fda9642d3
commit
204f125ab3
|
@ -412,6 +412,34 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---BEGIN TEMPORARY HACK---
|
||||||
|
//
|
||||||
|
// Remove once v0.14.21-v0.14.22 are rare enough. Those versions,
|
||||||
|
// essentially:
|
||||||
|
//
|
||||||
|
// 1. os.Setenv("STMONITORED", "yes")
|
||||||
|
// 2. os.Setenv("STNORESTART", "")
|
||||||
|
//
|
||||||
|
// where the intention was for 2 to cancel out 1 instead of setting
|
||||||
|
// STNORESTART to the empty value. We check for exactly this combination
|
||||||
|
// and pretend that neither was set. Looking through os.Environ lets us
|
||||||
|
// distinguish. Luckily, we weren't smart enough to use os.Unsetenv.
|
||||||
|
|
||||||
|
matches := 0
|
||||||
|
for _, str := range os.Environ() {
|
||||||
|
if str == "STNORESTART=" {
|
||||||
|
matches++
|
||||||
|
}
|
||||||
|
if str == "STMONITORED=yes" {
|
||||||
|
matches++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if matches == 2 {
|
||||||
|
innerProcess = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---END TEMPORARY HACK---
|
||||||
|
|
||||||
if innerProcess || options.noRestart {
|
if innerProcess || options.noRestart {
|
||||||
syncthingMain(options)
|
syncthingMain(options)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -35,7 +35,6 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func monitorMain(runtimeOptions RuntimeOptions) {
|
func monitorMain(runtimeOptions RuntimeOptions) {
|
||||||
os.Setenv("STMONITORED", "yes")
|
|
||||||
l.SetPrefix("[monitor] ")
|
l.SetPrefix("[monitor] ")
|
||||||
|
|
||||||
var dst io.Writer = os.Stdout
|
var dst io.Writer = os.Stdout
|
||||||
|
@ -69,6 +68,8 @@ func monitorMain(runtimeOptions RuntimeOptions) {
|
||||||
sigHup := syscall.Signal(1)
|
sigHup := syscall.Signal(1)
|
||||||
signal.Notify(restartSign, sigHup)
|
signal.Notify(restartSign, sigHup)
|
||||||
|
|
||||||
|
childEnv := childEnv()
|
||||||
|
first := true
|
||||||
for {
|
for {
|
||||||
if t := time.Since(restarts[0]); t < loopThreshold {
|
if t := time.Since(restarts[0]); t < loopThreshold {
|
||||||
l.Warnf("%d restarts in %v; not retrying further", countRestarts, t)
|
l.Warnf("%d restarts in %v; not retrying further", countRestarts, t)
|
||||||
|
@ -79,6 +80,7 @@ func monitorMain(runtimeOptions RuntimeOptions) {
|
||||||
restarts[len(restarts)-1] = time.Now()
|
restarts[len(restarts)-1] = time.Now()
|
||||||
|
|
||||||
cmd := exec.Command(args[0], args[1:]...)
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
|
cmd.Env = childEnv
|
||||||
|
|
||||||
stderr, err := cmd.StderrPipe()
|
stderr, err := cmd.StderrPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -96,10 +98,6 @@ func monitorMain(runtimeOptions RuntimeOptions) {
|
||||||
l.Fatalln(err)
|
l.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the next child process know that this is not the first time
|
|
||||||
// it's starting up.
|
|
||||||
os.Setenv("STRESTART", "yes")
|
|
||||||
|
|
||||||
stdoutMut.Lock()
|
stdoutMut.Lock()
|
||||||
stdoutFirstLines = make([]string, 0, 10)
|
stdoutFirstLines = make([]string, 0, 10)
|
||||||
stdoutLastLines = make([]string, 0, 50)
|
stdoutLastLines = make([]string, 0, 50)
|
||||||
|
@ -149,7 +147,6 @@ func monitorMain(runtimeOptions RuntimeOptions) {
|
||||||
// Restart the monitor process to release the .old
|
// Restart the monitor process to release the .old
|
||||||
// binary as part of the upgrade process.
|
// binary as part of the upgrade process.
|
||||||
l.Infoln("Restarting monitor...")
|
l.Infoln("Restarting monitor...")
|
||||||
os.Setenv("STNORESTART", "")
|
|
||||||
if err = restartMonitor(args); err != nil {
|
if err = restartMonitor(args); err != nil {
|
||||||
l.Warnln("Restart:", err)
|
l.Warnln("Restart:", err)
|
||||||
}
|
}
|
||||||
|
@ -161,6 +158,13 @@ func monitorMain(runtimeOptions RuntimeOptions) {
|
||||||
|
|
||||||
l.Infoln("Syncthing exited:", err)
|
l.Infoln("Syncthing exited:", err)
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
|
if first {
|
||||||
|
// Let the next child process know that this is not the first time
|
||||||
|
// it's starting up.
|
||||||
|
childEnv = append(childEnv, "STRESTART=yes")
|
||||||
|
first = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,3 +413,19 @@ func (f *autoclosedFile) closerLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the desired child environment, properly filtered and added to.
|
||||||
|
func childEnv() []string {
|
||||||
|
var env []string
|
||||||
|
for _, str := range os.Environ() {
|
||||||
|
if strings.HasPrefix("STNORESTART=", str) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix("STMONITORED=", str) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
env = append(env, str)
|
||||||
|
}
|
||||||
|
env = append(env, "STMONITORED=yes")
|
||||||
|
return env
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue