Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/main: Prevent to load syncthing along with new config file (fixes #4921) #5164

Closed
wants to merge 1 commit into from

Conversation

bahadir60
Copy link
Contributor

@bahadir60 bahadir60 commented Sep 5, 2018

Purpose

Don't let syncthing running along with a future config file.

Current

In cmd/main.go checks configuration version at disk and current configuration version which defined in config.go. If they are not same archived disk version. However future configuration file which store on disk means newer configuration schema may not be compatible for Syncthing.

After Code

  1. If config.xml version is bigger than config.CurrentVersion, don't let to run Syncthing and give information about versions and suggest to use -downgradeConfig flag. Also, if compatible config was stored in disk, suggest to use it.

  2. If -downgradeConfig flag used, first checking needed to use flag. If no needed, info to user. Flag makes a new config based on disk config and store old one.

Documentation

Adding -downgradeConfig flag to 2.1.1. Synopsis and 2.1.3. Options on page "https://docs.syncthing.net/users/syncthing.html?highlight=flag" will be suitable.

@bahadir60
Copy link
Contributor Author

I also check the Sycnthing version wheather downgrade or not and if downgrade logged it.

Copy link
Member

@calmh calmh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM in principle, but I still think we should have something like --allow-configuration-downgrade that will allow Syncthing to make a "best effort" start in this case.

@@ -741,6 +741,10 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
curParts := strings.Split(Version, "-")
if prevParts[0] != curParts[0] {
if prevVersion != "" {
//Check Syncthing version is wheather downgrading
if upgrade.CompareVersions(curParts[0], prevParts[0]) == upgrade.Older || upgrade.CompareVersions(curParts[0], prevParts[0]) == upgrade.MajorOlder {
l.Infof("Current Syncthing Version: %s, Loading Syncthing Version: %s: (Syncthing Version Mismatch)", prevVersion, Version)
Copy link
Member

@calmh calmh Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is a valid check, I'd go with making it a warning and tweak the wording. How about

l.Warnf("Downgrade detected: %s to %s", prevVersion, Version)

Making it a warning will mean it's also popped up in the GUI.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely change the wording, I didn't understand what the original text tried to say (also agree on warning).

@@ -965,6 +969,12 @@ func loadConfigAtStartup() *config.Wrapper {
}

if cfg.RawCopy().OriginalVersion != config.CurrentVersion {
//check config version
if cfg.RawCopy().OriginalVersion > config.CurrentVersion {
l.Fatalf("Current Configuration Version: %d, Loading Configuration Version: %d (Configuration Version Mismatch)", cfg.RawCopy().OriginalVersion, config.CurrentVersion)
Copy link
Member

@calmh calmh Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to adjust the wording here as well to something more sentence like.

l.Fatalf("Configuration version on disk not understood by this version of Syncthing; loaded %d > current %d", ...OriginalVersion, config.CurrentVersion)

Oh, and the os.Exit is unnecessary because a Fatalf will never return.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe mention that there may be a copy of a config with the compatible version that we created on previous update. As a deluxe variant (just proposition, not necessary), even check if it is there.

@@ -741,6 +741,10 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
curParts := strings.Split(Version, "-")
if prevParts[0] != curParts[0] {
if prevVersion != "" {
//Check Syncthing version is wheather downgrading
if upgrade.CompareVersions(curParts[0], prevParts[0]) == upgrade.Older || upgrade.CompareVersions(curParts[0], prevParts[0]) == upgrade.MajorOlder {
l.Infof("Current Syncthing Version: %s, Loading Syncthing Version: %s: (Syncthing Version Mismatch)", prevVersion, Version)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the line below should probably go i to an else

@@ -741,6 +741,10 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
curParts := strings.Split(Version, "-")
if prevParts[0] != curParts[0] {
if prevVersion != "" {
//Check Syncthing version is wheather downgrading
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto about spaces

//check config version
if cfg.RawCopy().OriginalVersion > config.CurrentVersion {
l.Fatalf("Current Configuration Version: %d, Loading Configuration Version: %d (Configuration Version Mismatch)", cfg.RawCopy().OriginalVersion, config.CurrentVersion)
//Config version is not compatible with installed version
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space after slashes

@@ -741,6 +741,10 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
curParts := strings.Split(Version, "-")
if prevParts[0] != curParts[0] {
if prevVersion != "" {
//Check Syncthing version is wheather downgrading
if upgrade.CompareVersions(curParts[0], prevParts[0]) == upgrade.Older || upgrade.CompareVersions(curParts[0], prevParts[0]) == upgrade.MajorOlder {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally not necessary, just noticed: I'd add a upgrade.Relation.IsOlder convenience function (there is some other place where essentially this condition is used).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not want to change upgrade package like adding methods. But upgrade.Relation.IsOlder is a good suggestion I will try that thanx

@@ -741,6 +741,10 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
curParts := strings.Split(Version, "-")
if prevParts[0] != curParts[0] {
if prevVersion != "" {
//Check Syncthing version is wheather downgrading
if upgrade.CompareVersions(curParts[0], prevParts[0]) == upgrade.Older || upgrade.CompareVersions(curParts[0], prevParts[0]) == upgrade.MajorOlder {
l.Infof("Current Syncthing Version: %s, Loading Syncthing Version: %s: (Syncthing Version Mismatch)", prevVersion, Version)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely change the wording, I didn't understand what the original text tried to say (also agree on warning).

@@ -965,6 +969,12 @@ func loadConfigAtStartup() *config.Wrapper {
}

if cfg.RawCopy().OriginalVersion != config.CurrentVersion {
//check config version
if cfg.RawCopy().OriginalVersion > config.CurrentVersion {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define a local variable in the if above and reuse here to avoid copying twice.

Copy link
Contributor Author

@bahadir60 bahadir60 Sep 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change it as Jacob' suggests for wording. Thanks for local variable suggestion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still to be addressed.

@@ -965,6 +969,12 @@ func loadConfigAtStartup() *config.Wrapper {
}

if cfg.RawCopy().OriginalVersion != config.CurrentVersion {
//check config version
if cfg.RawCopy().OriginalVersion > config.CurrentVersion {
l.Fatalf("Current Configuration Version: %d, Loading Configuration Version: %d (Configuration Version Mismatch)", cfg.RawCopy().OriginalVersion, config.CurrentVersion)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe mention that there may be a copy of a config with the compatible version that we created on previous update. As a deluxe variant (just proposition, not necessary), even check if it is there.

@bahadir60
Copy link
Contributor Author

bahadir60 commented Sep 5, 2018

@imsodin As you know old config files are stored for a month time. My worry is about some part of the configuration will may be changed during that time, like devices or folders. But may be I will merge @calmh ' suggestion (for adding --allow-configuration-downgrade that will allow Syncthing to make a "best effort" start) and yours' when working on --allow-configuration-downgrade part. Thanx for your comment.

@bahadir60 bahadir60 force-pushed the bh-4921 branch 3 times, most recently from 22f449a to da3c340 Compare October 9, 2018 18:51
@bahadir60
Copy link
Contributor Author

Based on comments, added -allow-configuration-downgrade flag.

@imsodin
Copy link
Member

imsodin commented Oct 10, 2018

I don't understand the point of a separate downgradeConfig function. I'd just add a allowConfigDowngrade parameter to loadConfigAtStartup.

@bahadir60
Copy link
Contributor Author

Imsodin, thanks your comment. I didn't want to a heavy function so that I separated it. Now I've got it together.

cmd/syncthing/main.go Outdated Show resolved Hide resolved
cmd/syncthing/main.go Outdated Show resolved Hide resolved
// Check config version
if cfg.RawCopy().OriginalVersion > config.CurrentVersion {
// Config version is not compatible with installed version
if allowDowngrade {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invert the condition so you can fail early and then the entire following block doesn't need to be indented.

// Config version is not compatible with installed version
if allowDowngrade {
l.Infof("Current Configuration Version: %d, Loading Configuration Version: %d (Configuration Version Mismatch)", configVersion, config.CurrentVersion)
l.Infof("Configuration downgrading...")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a very slow operation, so I wouldn't log anything in advance, but at the end, when it is clear whether the downgrade worked or not.

cmd/syncthing/main.go Show resolved Hide resolved
@bahadir60
Copy link
Contributor Author

@imsodin based on your comments I made changes thanx

Copy link
Member

@imsodin imsodin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear: I am deep in nit-pick territory with my current comments ;)

// Read configuration second time, Unmarshal to configuration struct and Change Version
var cfgConfig config.Configuration
var buf bytes.Buffer
err = json.NewEncoder(&buf).Encode(cfgXML)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just replace cfgXML with cfg.RawCopy() and remove the line with cfgXML := cfg.RawCopy() above.

}
l.Infof("Use `-downgradeConfig' flag to downgrade your config.")
l.Fatalf("Current Configuration Version: %d, Loading Configuration Version: %d (Configuration Version Mismatch)", configVersion, config.CurrentVersion)
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the else. If the conditoin above is true, l.Fatalf aborts execution anyway.

cfgXML := cfg.RawCopy()

// Read configuration second time, Unmarshal to configuration struct and Change Version
var cfgConfig config.Configuration
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Propositions: newConfig, downgradedConfig, ...


cfgConfig.Version = config.CurrentVersion
cfgConfig.OriginalVersion = config.CurrentVersion
cfgConfigWrapper := config.Wrap(cfgFile, cfgConfig)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need a new wrapper instead of cfg.Replace(cfgConfig)?

l.Infoln("Detected upgrade from", prevVersion, "to", Version)
// Check Syncthing version
checkRelation := upgrade.CompareVersions(curParts[0], prevParts[0])
if checkRelation == upgrade.Older || checkRelation == upgrade.MajorOlder {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline the definition and I'd use <:
if relation := upgrade.CompareVersions(curParts[0], prevParts[0]); relation < 0

@@ -965,6 +969,12 @@ func loadConfigAtStartup() *config.Wrapper {
}

if cfg.RawCopy().OriginalVersion != config.CurrentVersion {
//check config version
if cfg.RawCopy().OriginalVersion > config.CurrentVersion {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still to be addressed.

@st-review
Copy link

🤖 beep boop

I'm going to close this pull request as it has been idle for more than 90 days.

This is not a rejection, merely a removal from the list of active pull requests that is periodically reviewed by humans. The pull request can be reopened when there is new activity, and merged once any remaining issues are resolved.

@st-review st-review closed this Feb 4, 2019
@st-review st-review added the frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion label Feb 4, 2020
@syncthing syncthing locked and limited conversation to collaborators Feb 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
frozen-due-to-age Issues closed and untouched for a long time, together with being locked for discussion
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants