/
config_helpers.go
104 lines (91 loc) · 3.05 KB
/
config_helpers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package server
import (
"fmt"
"io/ioutil"
"net/http"
"poule/configuration"
"github.com/Sirupsen/logrus"
"github.com/pkg/errors"
cron "gopkg.in/robfig/cron.v2"
yaml "gopkg.in/yaml.v2"
)
const (
// GitHubRawURLPrefix is the URL prefix for GitHub content retrieval.
GitHubRawURLPrefix = "https://raw.githubusercontent.com"
)
// FetchRepositoriesConfigs retrieves the repository specific configurations from GitHub.
func (s *Server) FetchRepositoriesConfigs() error {
for repository := range s.config.Repositories {
if err := s.refreshRepositoryConfiguration(repository); err != nil {
logrus.Warnf(err.Error())
continue
}
}
return nil
}
func (s *Server) refreshRepositoryConfiguration(repository string) error {
repoConfigFile, err := pouleConfigurationFromGitHub(repository)
if err != nil {
return errors.Wrapf(err, "failed to get configuration for repository %q", repository)
}
if len(repoConfigFile) == 0 {
return nil
}
return s.updateRepositoryConfiguration(repository, repoConfigFile)
}
func (s *Server) updateRepositoryConfiguration(repository string, configFile []byte) error {
var actions []configuration.Action
if err := yaml.Unmarshal([]byte(configFile), &actions); err != nil {
return errors.Wrapf(err, "failed to read configuration file for repository %q", repository)
}
// Stop any existing cron job for the repository.
if c, ok := s.repositoriesConfig[repository]; ok && c.Cron != nil {
c.Cron.Stop()
}
// Initialize a new cron schedule.
repositoryCron := cron.New()
for _, actionConfig := range actions {
if actionConfig.Schedule != "" {
logrus.Debugf("registering schedule %q for repository %q", actionConfig.Schedule, repository)
repositoryCron.AddFunc(actionConfig.Schedule, func() {
if err := executeActionOnAllItems(s.makeExecutionConfig(repository), actionConfig); err != nil {
logrus.WithFields(logrus.Fields{
"repository": repository,
}).Errorf("error executing scheduled task: %v", err)
}
})
}
}
repositoryCron.Start()
// Store the repository specific configuration.
s.repositoriesConfig[repository] = repositoryConfig{
Actions: actions,
Cron: repositoryCron,
}
logrus.Infof("updated configuration for repository %q", repository)
return nil
}
func (s *Server) makeExecutionConfig(repository string) *configuration.Config {
return &configuration.Config{
RunDelay: s.config.RunDelay,
DryRun: s.config.DryRun,
Token: s.config.Token,
TokenFile: s.config.TokenFile,
Repository: repository,
}
}
func pouleConfigurationFromGitHub(repository string) ([]byte, error) {
// Fetch a repository specific configuration from GitHub.
configURL := fmt.Sprintf("%s/%s/master/%s", GitHubRawURLPrefix, repository, configuration.PouleConfigurationFile)
resp, err := http.Get(configURL)
if err != nil {
return []byte{}, err
}
defer resp.Body.Close()
// If the file is not found, this is not an error.
if resp.StatusCode == http.StatusNotFound {
logrus.Debugf("configuration file missing for repository %q", repository)
return []byte{}, nil
}
return ioutil.ReadAll(resp.Body)
}