Skip to content

Commit

Permalink
search for configuration file in various paths, print paths if config…
Browse files Browse the repository at this point in the history
…uration is not found (#1993) (#2276)
  • Loading branch information
aler9 committed Sep 16, 2023
1 parent ed77560 commit e35eb4b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 45 deletions.
52 changes: 27 additions & 25 deletions internal/conf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package conf
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"os"
"sort"
Expand Down Expand Up @@ -32,50 +31,53 @@ func getSortedKeys(paths map[string]*PathConf) []string {
return ret
}

func loadFromFile(fpath string, conf *Conf) (bool, error) {
if fpath == "mediamtx.yml" {
// give priority to the legacy configuration file, in order not to break
// existing setups
if _, err := os.Stat("rtsp-simple-server.yml"); err == nil {
fpath = "rtsp-simple-server.yml"
func firstThatExists(paths []string) string {
for _, pa := range paths {
_, err := os.Stat(pa)
if err == nil {
return pa

Check warning on line 38 in internal/conf/conf.go

View check run for this annotation

Codecov / codecov/patch

internal/conf/conf.go#L36-L38

Added lines #L36 - L38 were not covered by tests
}
}
return ""
}

// mediamtx.yml is optional
// other configuration files are not
if fpath == "mediamtx.yml" || fpath == "rtsp-simple-server.yml" {
if _, err := os.Stat(fpath); errors.Is(err, os.ErrNotExist) {
// load defaults
func loadFromFile(fpath string, defaultConfPaths []string, conf *Conf) (string, error) {
if fpath == "" {
fpath = firstThatExists(defaultConfPaths)

// when the configuration file is not explicitly set,
// it is optional. Load defaults.
if fpath == "" {
conf.UnmarshalJSON(nil) //nolint:errcheck
return false, nil
return "", nil
}
}

byts, err := os.ReadFile(fpath)
if err != nil {
return true, err
return "", err

Check warning on line 58 in internal/conf/conf.go

View check run for this annotation

Codecov / codecov/patch

internal/conf/conf.go#L58

Added line #L58 was not covered by tests
}

if key, ok := os.LookupEnv("RTSP_CONFKEY"); ok { // legacy format
byts, err = decrypt.Decrypt(key, byts)
if err != nil {
return true, err
return "", err

Check warning on line 64 in internal/conf/conf.go

View check run for this annotation

Codecov / codecov/patch

internal/conf/conf.go#L64

Added line #L64 was not covered by tests
}
}

if key, ok := os.LookupEnv("MTX_CONFKEY"); ok {
byts, err = decrypt.Decrypt(key, byts)
if err != nil {
return true, err
return "", err

Check warning on line 71 in internal/conf/conf.go

View check run for this annotation

Codecov / codecov/patch

internal/conf/conf.go#L71

Added line #L71 was not covered by tests
}
}

err = yaml.Load(byts, conf)
if err != nil {
return true, err
return "", err
}

return true, nil
return fpath, nil
}

func contains(list []headers.AuthMethod, item headers.AuthMethod) bool {
Expand Down Expand Up @@ -183,30 +185,30 @@ type Conf struct {
}

// Load loads a Conf.
func Load(fpath string) (*Conf, bool, error) {
func Load(fpath string, defaultConfPaths []string) (*Conf, string, error) {
conf := &Conf{}

found, err := loadFromFile(fpath, conf)
fpath, err := loadFromFile(fpath, defaultConfPaths, conf)
if err != nil {
return nil, false, err
return nil, "", err
}

err = env.Load("RTSP", conf) // legacy prefix
if err != nil {
return nil, false, err
return nil, "", err

Check warning on line 198 in internal/conf/conf.go

View check run for this annotation

Codecov / codecov/patch

internal/conf/conf.go#L198

Added line #L198 was not covered by tests
}

err = env.Load("MTX", conf)
if err != nil {
return nil, false, err
return nil, "", err

Check warning on line 203 in internal/conf/conf.go

View check run for this annotation

Codecov / codecov/patch

internal/conf/conf.go#L203

Added line #L203 was not covered by tests
}

err = conf.Check()
if err != nil {
return nil, false, err
return nil, "", err
}

return conf, found, nil
return conf, fpath, nil
}

// Clone clones the configuration.
Expand Down
24 changes: 12 additions & 12 deletions internal/conf/conf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ func TestConfFromFile(t *testing.T) {
require.NoError(t, err)
defer os.Remove(tmpf)

conf, hasFile, err := Load(tmpf)
conf, confPath, err := Load(tmpf, nil)
require.NoError(t, err)
require.Equal(t, true, hasFile)
require.Equal(t, tmpf, confPath)

require.Equal(t, LogLevel(logger.Debug), conf.LogLevel)

Expand Down Expand Up @@ -73,7 +73,7 @@ func TestConfFromFile(t *testing.T) {
require.NoError(t, err)
defer os.Remove(tmpf)

_, _, err = Load(tmpf)
_, _, err = Load(tmpf, nil)
require.NoError(t, err)
}()

Expand All @@ -82,7 +82,7 @@ func TestConfFromFile(t *testing.T) {
require.NoError(t, err)
defer os.Remove(tmpf)

_, _, err = Load(tmpf)
_, _, err = Load(tmpf, nil)
require.NoError(t, err)
}()

Expand All @@ -93,7 +93,7 @@ func TestConfFromFile(t *testing.T) {
require.NoError(t, err)
defer os.Remove(tmpf)

_, _, err = Load(tmpf)
_, _, err = Load(tmpf, nil)
require.NoError(t, err)
}()
}
Expand All @@ -109,9 +109,9 @@ func TestConfFromFileAndEnv(t *testing.T) {
require.NoError(t, err)
defer os.Remove(tmpf)

conf, hasFile, err := Load(tmpf)
conf, confPath, err := Load(tmpf, nil)
require.NoError(t, err)
require.Equal(t, true, hasFile)
require.Equal(t, tmpf, confPath)

require.Equal(t, Protocols{Protocol(gortsplib.TransportTCP): {}}, conf.Protocols)

Expand Down Expand Up @@ -142,9 +142,9 @@ func TestConfFromEnvOnly(t *testing.T) {
os.Setenv("MTX_PATHS_CAM1_SOURCE", "rtsp://testing")
defer os.Unsetenv("MTX_PATHS_CAM1_SOURCE")

conf, hasFile, err := Load("mediamtx.yml")
conf, confPath, err := Load("", nil)
require.NoError(t, err)
require.Equal(t, false, hasFile)
require.Equal(t, "", confPath)

pa, ok := conf.Paths["cam1"]
require.Equal(t, true, ok)
Expand Down Expand Up @@ -194,9 +194,9 @@ func TestConfEncryption(t *testing.T) {
require.NoError(t, err)
defer os.Remove(tmpf)

conf, hasFile, err := Load(tmpf)
conf, confPath, err := Load(tmpf, nil)
require.NoError(t, err)
require.Equal(t, true, hasFile)
require.Equal(t, tmpf, confPath)

_, ok := conf.Paths["path1"]
require.Equal(t, true, ok)
Expand Down Expand Up @@ -283,7 +283,7 @@ func TestConfErrors(t *testing.T) {
require.NoError(t, err)
defer os.Remove(tmpf)

_, _, err = Load(tmpf)
_, _, err = Load(tmpf, nil)
require.EqualError(t, err, ca.err)
})
}
Expand Down
34 changes: 26 additions & 8 deletions internal/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"fmt"
"os"
"os/signal"
"path/filepath"
"reflect"
"strings"
"time"

"github.com/alecthomas/kong"
Expand All @@ -23,9 +25,17 @@ import (

var version = "v0.0.0"

var defaultConfPaths = []string{
"rtsp-simple-server.yml",
"mediamtx.yml",
"/usr/local/etc/mediamtx.yml",
"/usr/etc/mediamtx.yml",
"/etc/mediamtx/mediamtx.yml",
}

var cli struct {
Version bool `help:"print version"`
Confpath string `arg:"" default:"mediamtx.yml"`
Confpath string `arg:"" default:""`
}

// Core is an instance of mediamtx.
Expand All @@ -34,7 +44,6 @@ type Core struct {
ctxCancel func()
confPath string
conf *conf.Conf
confFound bool
logger *logger.Logger
externalCmdPool *externalcmd.Pool
metrics *metrics
Expand Down Expand Up @@ -89,12 +98,11 @@ func New(args []string) (*Core, bool) {
p := &Core{
ctx: ctx,
ctxCancel: ctxCancel,
confPath: cli.Confpath,
chAPIConfigSet: make(chan *conf.Conf),
done: make(chan struct{}),
}

p.conf, p.confFound, err = conf.Load(p.confPath)
p.conf, p.confPath, err = conf.Load(cli.Confpath, defaultConfPaths)
if err != nil {
fmt.Printf("ERR: %s\n", err)
return nil, false
Expand Down Expand Up @@ -151,7 +159,7 @@ outer:
case <-confChanged:
p.Log(logger.Info, "reloading configuration (file changed)")

newConf, _, err := conf.Load(p.confPath)
newConf, _, err := conf.Load(p.confPath, nil)
if err != nil {
p.Log(logger.Error, "%s", err)
break outer
Expand Down Expand Up @@ -202,8 +210,17 @@ func (p *Core) createResources(initial bool) error {

if initial {
p.Log(logger.Info, "MediaMTX %s", version)
if !p.confFound {
p.Log(logger.Warn, "configuration file not found, using an empty configuration")

if p.confPath == "" {
list := make([]string, len(defaultConfPaths))
for i, pa := range defaultConfPaths {
a, _ := filepath.Abs(pa)
list[i] = a
}

p.Log(logger.Warn,
"configuration file not found (looked in %s), using an empty configuration",
strings.Join(list, ", "))
}

// on Linux, try to raise the number of file descriptors that can be opened
Expand Down Expand Up @@ -490,7 +507,7 @@ func (p *Core) createResources(initial bool) error {
}
}

if initial && p.confFound {
if initial && p.confPath != "" {
p.confWatcher, err = confwatcher.New(p.confPath)
if err != nil {
return err
Expand All @@ -505,6 +522,7 @@ func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
newConf.LogLevel != p.conf.LogLevel ||
!reflect.DeepEqual(newConf.LogDestinations, p.conf.LogDestinations) ||
newConf.LogFile != p.conf.LogFile

closeMetrics := newConf == nil ||
newConf.Metrics != p.conf.Metrics ||
newConf.MetricsAddress != p.conf.MetricsAddress ||
Expand Down

0 comments on commit e35eb4b

Please sign in to comment.