diff options
author | Krasimir Angelov <kangelov@gitlab.com> | 2019-12-12 10:34:13 +0300 |
---|---|---|
committer | Krasimir Angelov <kangelov@gitlab.com> | 2020-01-10 05:38:30 +0300 |
commit | e0ba15e77cfe922ece762f487269cb4e626ca290 (patch) | |
tree | 75a135ef0f813b21c2a3490a9ee766725c117ce2 /internal/source | |
parent | 86d619069f226d40d3d0ba97a243db384f133d5f (diff) |
Watch a file to configure which domains should use new gitlab source
Instead of passing domains once in an ENV variable we now watcn a config
file (specified with `GITLAB_SOURCE_CONFIG_FILE`, defaults to
`.gitlab-source-config.yml` and update ednabled/broken domains when it's
content change.
This way we can control this without having to restart Pages.
Related to https://gitlab.com/gitlab-org/gitlab-pages/issues/266.
Diffstat (limited to 'internal/source')
-rw-r--r-- | internal/source/domains.go | 23 | ||||
-rw-r--r-- | internal/source/domains/gitlabsourceconfig/gitlabsourceconfig.go | 85 | ||||
-rw-r--r-- | internal/source/domains_test.go | 6 |
3 files changed, 96 insertions, 18 deletions
diff --git a/internal/source/domains.go b/internal/source/domains.go index 85d06152..22187855 100644 --- a/internal/source/domains.go +++ b/internal/source/domains.go @@ -2,27 +2,20 @@ package source import ( "errors" - "os" - "strings" + "time" "gitlab.com/gitlab-org/gitlab-pages/internal/domain" "gitlab.com/gitlab-org/gitlab-pages/internal/source/disk" + "gitlab.com/gitlab-org/gitlab-pages/internal/source/domains/gitlabsourceconfig" "gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab" ) -var newSourceDomains []string -var brokenSourceDomain string +var gitlabSourceConfig gitlabsourceconfig.GitlabSourceConfig func init() { - testDomains := os.Getenv("GITLAB_NEW_SOURCE_DOMAINS") - if testDomains != "" { - newSourceDomains = strings.Split(testDomains, ",") - } - - brokenDomain := os.Getenv("GITLAB_NEW_SOURCE_BROKEN_DOMAIN") - if brokenDomain != "" { - brokenSourceDomain = brokenDomain - } + // Start watching the config file for domains that will use the new `gitlab` source, + // to be removed once we switch completely to using it. + go gitlabsourceconfig.WatchForGitlabSourceConfigChange(&gitlabSourceConfig, 1*time.Minute) } // Domains struct represents a map of all domains supported by pages. It is @@ -57,7 +50,7 @@ func NewDomains(config Config) (*Domains, error) { // for some subset of domains, to test / PoC the new GitLab Domains Source that // we plan to use to replace the disk source. func (d *Domains) GetDomain(name string) (*domain.Domain, error) { - if name == brokenSourceDomain { + if name == gitlabSourceConfig.Domains.Broken { return nil, errors.New("broken test domain used") } @@ -82,7 +75,7 @@ func (d *Domains) source(domain string) Source { return d.disk } - for _, name := range newSourceDomains { + for _, name := range gitlabSourceConfig.Domains.Enabled { if domain == name { return d.gitlab } diff --git a/internal/source/domains/gitlabsourceconfig/gitlabsourceconfig.go b/internal/source/domains/gitlabsourceconfig/gitlabsourceconfig.go new file mode 100644 index 00000000..4eda31aa --- /dev/null +++ b/internal/source/domains/gitlabsourceconfig/gitlabsourceconfig.go @@ -0,0 +1,85 @@ +package gitlabsourceconfig + +import ( + "bytes" + "io/ioutil" + "os" + "time" + + log "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" +) + +// GitlabSourceDomains holds the domains to be used with the gitlab source +type GitlabSourceDomains struct { + Enabled []string + Broken string +} + +// GitlabSourceConfig holds the configuration for the gitlab source +type GitlabSourceConfig struct { + Domains GitlabSourceDomains +} + +// UpdateFromYaml updates the config +// We use new variable here (instead of using `config` directly) +// because if `content` is empty `yaml.Unmarshal` does not update +// the fields already set. +func (config *GitlabSourceConfig) UpdateFromYaml(content []byte) error { + updated := GitlabSourceConfig{} + + err := yaml.Unmarshal(content, &updated) + if err != nil { + return err + } + + *config = updated + + log.WithFields(log.Fields{ + "Enabled domains": config.Domains.Enabled, + "Broken domain": config.Domains.Broken, + }).Info("gitlab source config updated") + + return nil +} + +// WatchForGitlabSourceConfigChange polls the filesystem and updates test domains if needed. +func WatchForGitlabSourceConfigChange(config *GitlabSourceConfig, interval time.Duration) { + var lastContent []byte + + gitlabSourceConfigFile := os.Getenv("GITLAB_SOURCE_CONFIG_FILE") + if gitlabSourceConfigFile == "" { + gitlabSourceConfigFile = ".gitlab-source-config.yml" + } + + for { + content, err := readConfig(gitlabSourceConfigFile) + if err != nil { + log.WithError(err).Warn("Failed to read gitlab source config file") + + time.Sleep(interval) + continue + } + + if !bytes.Equal(lastContent, content) { + lastContent = content + + err = config.UpdateFromYaml(content) + if err != nil { + log.WithError(err).Warn("Failed to update gitlab source config") + } + } + + time.Sleep(interval) + } +} + +func readConfig(configfile string) ([]byte, error) { + content, err := ioutil.ReadFile(configfile) + + if err != nil && !os.IsNotExist(err) { + return nil, err + } + + return content, nil +} diff --git a/internal/source/domains_test.go b/internal/source/domains_test.go index 378f8c89..5fea6ae3 100644 --- a/internal/source/domains_test.go +++ b/internal/source/domains_test.go @@ -41,11 +41,11 @@ func TestDomainSources(t *testing.T) { } func TestGetDomain(t *testing.T) { - newSourceDomains = []string{"new-source-test.gitlab.io"} - brokenSourceDomain = "pages-broken-poc.gitlab.io" + gitlabSourceConfig.Domains.Enabled = []string{"new-source-test.gitlab.io"} + gitlabSourceConfig.Domains.Broken = "pages-broken-poc.gitlab.io" t.Run("when requesting a test domain", func(t *testing.T) { - testDomain := newSourceDomains[0] + testDomain := gitlabSourceConfig.Domains.Enabled[0] newSource := NewMockSource() newSource.On("GetDomain", testDomain). |