diff --git a/service/updaterequest.go b/service/updaterequest.go index c07eade..3bdd01f 100644 --- a/service/updaterequest.go +++ b/service/updaterequest.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "log" "net" + "os" ) type UpdateRequest struct { @@ -30,13 +31,41 @@ func (ur *UpdateRequest) PrettyPrint() string { return string(s) } +func (ur *UpdateRequest) MergeOldStateFile() { + filename := ur.Config.GetStateFileName() + + if _, err := os.Stat(filename); err != nil { + log.Printf("No old state file %s found, skip merging: %v", filename, err) + } + + // We have a state file present, load it and merge into current state + // so that we don't loose any IPv4/v6 data during partial updates. + + oldState, err := LoadStateFile(ur.Config) + if err != nil { + log.Printf("Failed to load old state file %s to merge while saving, skipping it: %v", + filename, err) + return + } + + if ur.IPv4 == nil { + ur.IPv4 = oldState.IPv4 + } + if ur.IPv6 == nil { + ur.IPv6 = oldState.IPv6 + ur.IPv6Net = oldState.IPv6Net + } +} + func (ur *UpdateRequest) SaveStateFile() error { + ur.MergeOldStateFile() + + filename := ur.Config.GetStateFileName() data, err := json.MarshalIndent(ur, "", " ") if err != nil { return fmt.Errorf("failed to convert state for user %s to JSON: %v", ur.UserName, err) } - filename := ur.Config.GetStateFileName() if err = ioutil.WriteFile(filename, data, 0640); err != nil { return fmt.Errorf("failed to to write sate file for user %s to file %s: %v", ur.UserName, filename, err)