Skip to content

Commit

Permalink
cmd/syncthing: Add --skip-port-probing (fixes syncthing#8090) (syncth…
Browse files Browse the repository at this point in the history
…ing#8099)

* cmd/syncthing: Remove unnecessary function arguments.

The openGUI() function does not need a device ID to work, and there is
only one caller anyway which uses EmptyDeviceID.

The loadOrDefaultConfig() function is always called with the same
dummy values.

* cmd/syncthing: Avoid misleading info messages from monitor process.

In order to check whether panic reporting is enabled, the monitor
process utilizes the loadOrDefaultConfig() function.  In case there is
no config file yet, info messages may be logged during creation if the
config Wrapper, which is discarded immediately after.

Stop using the DefaultConfig() utility function from lib/syncthing and
directly generate a minimal config instead to avoid these.

Add comments to loadOrDefaultConfig() explaining its limited purpose.

* cmd/syncthing/generate: Always write updated config file.

Previously, an existing config file was left untouched unless either
of the --gui-user or --gui-password options was given.  Remove that
condition and simplify the checking code.

* lib/config: Factor out ProbeFreePorts().

* cmd/syncthing: Add option --skip-port-probing.

Applies to both the "generate" and "serve" subcommands, as well as the
deprecated --generate option, just as the --no-default-folder flag.
  • Loading branch information
acolomb authored Jan 7, 2022
1 parent 368094e commit 5237337
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 16 deletions.
1 change: 1 addition & 0 deletions cmd/syncthing/cmdutil/options_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ type CommonOptions struct {
ConfDir string `name:"config" placeholder:"PATH" help:"Set configuration directory (config and keys)"`
HomeDir string `name:"home" placeholder:"PATH" help:"Set configuration and data directory"`
NoDefaultFolder bool `env:"STNODEFAULTFOLDER" help:"Don't create the \"default\" folder on first startup"`
SkipPortProbing bool `help:"Don't try to find free ports for GUI and listen addresses on first startup"`
}
6 changes: 3 additions & 3 deletions cmd/syncthing/generate/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ func (c *CLI) Run() error {
c.GUIPassword = string(password)
}

if err := Generate(c.ConfDir, c.GUIUser, c.GUIPassword, c.NoDefaultFolder); err != nil {
if err := Generate(c.ConfDir, c.GUIUser, c.GUIPassword, c.NoDefaultFolder, c.SkipPortProbing); err != nil {
return fmt.Errorf("Failed to generate config and keys: %w", err)
}
return nil
}

func Generate(confDir, guiUser, guiPassword string, noDefaultFolder bool) error {
func Generate(confDir, guiUser, guiPassword string, noDefaultFolder, skipPortProbing bool) error {
dir, err := fs.ExpandTilde(confDir)
if err != nil {
return err
Expand Down Expand Up @@ -92,7 +92,7 @@ func Generate(confDir, guiUser, guiPassword string, noDefaultFolder bool) error
cfgFile := locations.Get(locations.ConfigFile)
cfg, _, err := config.Load(cfgFile, myID, events.NoopLogger)
if fs.IsNotExist(err) {
if cfg, err = syncthing.DefaultConfig(cfgFile, myID, events.NoopLogger, noDefaultFolder); err != nil {
if cfg, err = syncthing.DefaultConfig(cfgFile, myID, events.NoopLogger, noDefaultFolder, skipPortProbing); err != nil {
return fmt.Errorf("create config: %w", err)
}
} else if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions cmd/syncthing/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func (options serveOptions) Run() error {
}

if options.GenerateDir != "" {
if err := generate.Generate(options.GenerateDir, "", "", options.NoDefaultFolder); err != nil {
if err := generate.Generate(options.GenerateDir, "", "", options.NoDefaultFolder, options.SkipPortProbing); err != nil {
l.Warnln("Failed to generate config and keys:", err)
os.Exit(svcutil.ExitError.AsInt())
}
Expand Down Expand Up @@ -551,7 +551,7 @@ func syncthingMain(options serveOptions) {
evLogger := events.NewLogger()
earlyService.Add(evLogger)

cfgWrapper, err := syncthing.LoadConfigAtStartup(locations.Get(locations.ConfigFile), cert, evLogger, options.AllowNewerConfig, options.NoDefaultFolder)
cfgWrapper, err := syncthing.LoadConfigAtStartup(locations.Get(locations.ConfigFile), cert, evLogger, options.AllowNewerConfig, options.NoDefaultFolder, options.SkipPortProbing)
if err != nil {
l.Warnln("Failed to initialize config:", err)
os.Exit(svcutil.ExitError.AsInt())
Expand Down
10 changes: 4 additions & 6 deletions lib/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,16 @@ func New(myID protocol.DeviceID) Configuration {
return cfg
}

func NewWithFreePorts(myID protocol.DeviceID) (Configuration, error) {
cfg := New(myID)

func (cfg *Configuration) ProbeFreePorts() error {
port, err := getFreePort("127.0.0.1", DefaultGUIPort)
if err != nil {
return Configuration{}, errors.Wrap(err, "get free port (GUI)")
return errors.Wrap(err, "get free port (GUI)")
}
cfg.GUI.RawAddress = fmt.Sprintf("127.0.0.1:%d", port)

port, err = getFreePort("0.0.0.0", DefaultTCPPort)
if err != nil {
return Configuration{}, errors.Wrap(err, "get free port (BEP)")
return errors.Wrap(err, "get free port (BEP)")
}
if port == DefaultTCPPort {
cfg.Options.RawListenAddresses = []string{"default"}
Expand All @@ -136,7 +134,7 @@ func NewWithFreePorts(myID protocol.DeviceID) (Configuration, error) {
}
}

return cfg, nil
return nil
}

type xmlConfiguration struct {
Expand Down
13 changes: 8 additions & 5 deletions lib/syncthing/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,12 @@ func GenerateCertificate(certFile, keyFile string) (tls.Certificate, error) {
return tlsutil.NewCertificate(certFile, keyFile, tlsDefaultCommonName, deviceCertLifetimeDays)
}

func DefaultConfig(path string, myID protocol.DeviceID, evLogger events.Logger, noDefaultFolder bool) (config.Wrapper, error) {
newCfg, err := config.NewWithFreePorts(myID)
if err != nil {
func DefaultConfig(path string, myID protocol.DeviceID, evLogger events.Logger, noDefaultFolder, skipPortProbing bool) (config.Wrapper, error) {
newCfg := config.New(myID)

if skipPortProbing {
l.Infoln("Using default network port numbers instead of probing for free ports")
} else if err := newCfg.ProbeFreePorts(); err != nil {
return nil, err
}

Expand All @@ -84,11 +87,11 @@ func DefaultConfig(path string, myID protocol.DeviceID, evLogger events.Logger,
// creates a default one, without the default folder if noDefaultFolder is ture.
// Otherwise it checks the version, and archives and upgrades the config if
// necessary or returns an error, if the version isn't compatible.
func LoadConfigAtStartup(path string, cert tls.Certificate, evLogger events.Logger, allowNewerConfig, noDefaultFolder bool) (config.Wrapper, error) {
func LoadConfigAtStartup(path string, cert tls.Certificate, evLogger events.Logger, allowNewerConfig, noDefaultFolder, skipPortProbing bool) (config.Wrapper, error) {
myID := protocol.NewDeviceID(cert.Certificate[0])
cfg, originalVersion, err := config.Load(path, myID, evLogger)
if fs.IsNotExist(err) {
cfg, err = DefaultConfig(path, myID, evLogger, noDefaultFolder)
cfg, err = DefaultConfig(path, myID, evLogger, noDefaultFolder, skipPortProbing)
if err != nil {
return nil, errors.Wrap(err, "failed to generate default config")
}
Expand Down

0 comments on commit 5237337

Please sign in to comment.