Resolve relative paths on configuration loading

This moves the concern of resolving the files relative to the config
file into the configuration loading itself.
It also fixes #921 which did not load the cert and token files relatively.
This commit is contained in:
Fabian Reinartz 2015-08-05 18:04:34 +02:00
parent e324910ff2
commit 7a67472fc1
5 changed files with 41 additions and 16 deletions

View file

@ -21,7 +21,6 @@ import (
_ "net/http/pprof" // Comment this line to disable pprof endpoint. _ "net/http/pprof" // Comment this line to disable pprof endpoint.
"os" "os"
"os/signal" "os/signal"
"path/filepath"
"strings" "strings"
"syscall" "syscall"
"text/template" "text/template"
@ -77,7 +76,6 @@ func Main() int {
NotificationHandler: notificationHandler, NotificationHandler: notificationHandler,
QueryEngine: queryEngine, QueryEngine: queryEngine,
ExternalURL: cfg.web.ExternalURL, ExternalURL: cfg.web.ExternalURL,
BaseDir: filepath.Dir(cfg.configFile),
}) })
flags := map[string]string{} flags := map[string]string{}

View file

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/url" "net/url"
"path/filepath"
"regexp" "regexp"
"strings" "strings"
"time" "time"
@ -45,7 +46,12 @@ func LoadFromFile(filename string) (*Config, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return Load(string(content)) cfg, err := Load(string(content))
if err != nil {
return nil, err
}
resolveFilepaths(filepath.Dir(filename), cfg)
return cfg, nil
} }
// The defaults applied before parsing the respective config sections. // The defaults applied before parsing the respective config sections.
@ -113,6 +119,30 @@ type Config struct {
original string original string
} }
// resolveFilepaths joins all relative paths in a configuration
// with a given base directory.
func resolveFilepaths(baseDir string, cfg *Config) {
join := func(fp string) string {
if len(fp) > 0 && !filepath.IsAbs(fp) {
fp = filepath.Join(baseDir, fp)
}
return fp
}
for i, rf := range cfg.RuleFiles {
cfg.RuleFiles[i] = join(rf)
}
for _, scfg := range cfg.ScrapeConfigs {
scfg.BearerTokenFile = join(scfg.BearerTokenFile)
if scfg.ClientCert != nil {
scfg.ClientCert.Cert = join(scfg.ClientCert.Cert)
scfg.ClientCert.Key = join(scfg.ClientCert.Key)
}
}
}
func checkOverflow(m map[string]interface{}, ctx string) error { func checkOverflow(m map[string]interface{}, ctx string) error {
if len(m) > 0 { if len(m) > 0 {
var keys []string var keys []string

View file

@ -27,9 +27,9 @@ var expectedConf = &Config{
}, },
RuleFiles: []string{ RuleFiles: []string{
"first.rules", "testdata/first.rules",
"second.rules", "/absolute/second.rules",
"my/*.rules", "testdata/my/*.rules",
}, },
ScrapeConfigs: []*ScrapeConfig{ ScrapeConfigs: []*ScrapeConfig{
@ -43,6 +43,8 @@ var expectedConf = &Config{
MetricsPath: DefaultScrapeConfig.MetricsPath, MetricsPath: DefaultScrapeConfig.MetricsPath,
Scheme: DefaultScrapeConfig.Scheme, Scheme: DefaultScrapeConfig.Scheme,
BearerTokenFile: "testdata/valid_token_file",
TargetGroups: []*TargetGroup{ TargetGroups: []*TargetGroup{
{ {
Targets: []clientmodel.LabelSet{ Targets: []clientmodel.LabelSet{
@ -167,8 +169,8 @@ var expectedConf = &Config{
Scheme: "http", Scheme: "http",
ClientCert: &ClientCert{ ClientCert: &ClientCert{
Cert: "valid_cert_file", Cert: "testdata/valid_cert_file",
Key: "valid_key_file", Key: "testdata/valid_key_file",
}, },
BearerToken: "avalidtoken", BearerToken: "avalidtoken",
}, },

View file

@ -10,7 +10,7 @@ global:
rule_files: rule_files:
- "first.rules" - "first.rules"
- "second.rules" - "/absolute/second.rules"
- "my/*.rules" - "my/*.rules"
scrape_configs: scrape_configs:
@ -45,6 +45,8 @@ scrape_configs:
replacement: foo-${1} replacement: foo-${1}
# action defaults to 'replace' # action defaults to 'replace'
bearer_token_file: valid_token_file
- job_name: service-x - job_name: service-x

View file

@ -104,7 +104,6 @@ type Manager struct {
notificationHandler *notification.NotificationHandler notificationHandler *notification.NotificationHandler
externalURL *url.URL externalURL *url.URL
baseDir string
} }
// ManagerOptions bundles options for the Manager. // ManagerOptions bundles options for the Manager.
@ -116,7 +115,6 @@ type ManagerOptions struct {
SampleAppender storage.SampleAppender SampleAppender storage.SampleAppender
ExternalURL *url.URL ExternalURL *url.URL
BaseDir string
} }
// NewManager returns an implementation of Manager, ready to be started // NewManager returns an implementation of Manager, ready to be started
@ -131,7 +129,6 @@ func NewManager(o *ManagerOptions) *Manager {
queryEngine: o.QueryEngine, queryEngine: o.QueryEngine,
notificationHandler: o.NotificationHandler, notificationHandler: o.NotificationHandler,
externalURL: o.ExternalURL, externalURL: o.ExternalURL,
baseDir: o.BaseDir,
} }
return manager return manager
} }
@ -330,10 +327,6 @@ func (m *Manager) ApplyConfig(conf *config.Config) bool {
var files []string var files []string
for _, pat := range conf.RuleFiles { for _, pat := range conf.RuleFiles {
if !filepath.IsAbs(pat) {
pat = filepath.Join(m.baseDir, pat)
}
fs, err := filepath.Glob(pat) fs, err := filepath.Glob(pat)
if err != nil { if err != nil {
// The only error can be a bad pattern. // The only error can be a bad pattern.