diff --git a/internal/exec/engine.go b/internal/exec/engine.go index 8e2ad1327a..13c2916718 100644 --- a/internal/exec/engine.go +++ b/internal/exec/engine.go @@ -24,6 +24,7 @@ import ( "net/url" "os" "strconv" + "strings" "time" "github.com/coreos/go-systemd/v22/journal" @@ -108,7 +109,7 @@ func (e Engine) Run(stageName string) error { e.Fetcher.Offline = true } - cfg, err := e.acquireConfig() + cfg, err := e.acquireConfig(stageName) if err == resource.ErrNeedNet && stageName == "fetch-offline" { err = SignalNeedNet() if err != nil { @@ -116,7 +117,11 @@ func (e Engine) Run(stageName string) error { } return err } else if err == errors.ErrEmpty { - e.Logger.Info("%v: ignoring user-provided config", err) + e.Logger.Info("%v: ignoring user-provided config & writing empty cache config", err) + if err = renameio.WriteFile(e.ConfigCache, []byte("{}"), 0640); err != nil { + e.Logger.Crit("failed to empty write cached config: %v", err) + return err + } } else if err != nil { e.Logger.Crit("failed to acquire config: %v", err) return err @@ -162,11 +167,24 @@ func logStructuredJournalEntry(config string, src string, isReferenced bool) err return nil } -// acquireConfig returns the configuration, first checking a local cache -// before attempting to fetch it from the provider. -func (e *Engine) acquireConfig() (cfg types.Config, err error) { +// acquireConfig returns the configuration from a local cache. If one +// does not exist then it will attempt to fetch the configuration from +// the provider when in fetch stages. +func (e *Engine) acquireConfig(stageName string) (cfg types.Config, err error) { + cfg, err = e.acquireCachedConfig() + if err != nil { + if os.IsNotExist(err) && strings.HasPrefix(stageName, "fetch") { + e.Logger.Info("fetching provider config") + cfg, err = e.acquireProviderConfig() + return + } + } + return +} - // First try read the config @ e.ConfigCache. +// acquireCachedConfig returns the configuration from a local cache if +// available +func (e *Engine) acquireCachedConfig() (cfg types.Config, err error) { b, err := ioutil.ReadFile(e.ConfigCache) if err == nil { if err = json.Unmarshal(b, &cfg); err != nil { @@ -179,9 +197,13 @@ func (e *Engine) acquireConfig() (cfg types.Config, err error) { e.Logger.Crit("failed to update timeouts and CAs for fetcher: %v", err) return } - return } + return +} +// acquireProviderConfig attempts to fetch the configuration from the +// provider. +func (e *Engine) acquireProviderConfig() (cfg types.Config, err error) { // Create a new http client and fetcher with the timeouts set via the flags, // since we don't have a config with timeout values we can use timeout := int(e.FetchTimeout.Seconds()) @@ -222,7 +244,7 @@ func (e *Engine) acquireConfig() (cfg types.Config, err error) { } // Populate the config cache. - b, err = json.Marshal(cfg) + b, err := json.Marshal(cfg) if err != nil { e.Logger.Crit("failed to marshal cached config: %v", err) return