2
0

config.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. package worker
  2. import (
  3. "errors"
  4. "os"
  5. "path/filepath"
  6. "github.com/BurntSushi/toml"
  7. "github.com/imdario/mergo"
  8. )
  9. type providerEnum uint8
  10. const (
  11. provRsync providerEnum = iota
  12. provTwoStageRsync
  13. provCommand
  14. )
  15. func (p *providerEnum) UnmarshalText(text []byte) error {
  16. s := string(text)
  17. switch s {
  18. case `command`:
  19. *p = provCommand
  20. case `rsync`:
  21. *p = provRsync
  22. case `two-stage-rsync`:
  23. *p = provTwoStageRsync
  24. default:
  25. return errors.New("Invalid value to provierEnum")
  26. }
  27. return nil
  28. }
  29. // Config represents worker config options
  30. type Config struct {
  31. Global globalConfig `toml:"global"`
  32. Manager managerConfig `toml:"manager"`
  33. Server serverConfig `toml:"server"`
  34. Cgroup cgroupConfig `toml:"cgroup"`
  35. ZFS zfsConfig `toml:"zfs"`
  36. BtrfsSnapshot btrfsSnapshotConfig `toml:"btrfs_snapshot"`
  37. Docker dockerConfig `toml:"docker"`
  38. Include includeConfig `toml:"include"`
  39. MirrorsConf []mirrorConfig `toml:"mirrors"`
  40. Mirrors []mirrorConfig
  41. }
  42. type globalConfig struct {
  43. Name string `toml:"name"`
  44. LogDir string `toml:"log_dir"`
  45. MirrorDir string `toml:"mirror_dir"`
  46. Concurrent int `toml:"concurrent"`
  47. Interval int `toml:"interval"`
  48. Retry int `toml:"retry"`
  49. Timeout int `toml:"timeout"`
  50. ExecOnSuccess []string `toml:"exec_on_success"`
  51. ExecOnFailure []string `toml:"exec_on_failure"`
  52. }
  53. type managerConfig struct {
  54. APIBase string `toml:"api_base"`
  55. // this option overrides the APIBase
  56. APIList []string `toml:"api_base_list"`
  57. CACert string `toml:"ca_cert"`
  58. // Token string `toml:"token"`
  59. }
  60. func (mc managerConfig) APIBaseList() []string {
  61. if len(mc.APIList) > 0 {
  62. return mc.APIList
  63. }
  64. return []string{mc.APIBase}
  65. }
  66. type serverConfig struct {
  67. Hostname string `toml:"hostname"`
  68. Addr string `toml:"listen_addr"`
  69. Port int `toml:"listen_port"`
  70. SSLCert string `toml:"ssl_cert"`
  71. SSLKey string `toml:"ssl_key"`
  72. }
  73. type cgroupConfig struct {
  74. Enable bool `toml:"enable"`
  75. BasePath string `toml:"base_path"`
  76. Group string `toml:"group"`
  77. Subsystem string `toml:"subsystem"`
  78. }
  79. type dockerConfig struct {
  80. Enable bool `toml:"enable"`
  81. Volumes []string `toml:"volumes"`
  82. Options []string `toml:"options"`
  83. }
  84. type zfsConfig struct {
  85. Enable bool `toml:"enable"`
  86. Zpool string `toml:"zpool"`
  87. }
  88. type btrfsSnapshotConfig struct {
  89. Enable bool `toml:"enable"`
  90. SnapshotPath string `toml:"snapshot_path"`
  91. }
  92. type includeConfig struct {
  93. IncludeMirrors string `toml:"include_mirrors"`
  94. }
  95. type includedMirrorConfig struct {
  96. Mirrors []mirrorConfig `toml:"mirrors"`
  97. }
  98. type mirrorConfig struct {
  99. Name string `toml:"name"`
  100. Provider providerEnum `toml:"provider"`
  101. Upstream string `toml:"upstream"`
  102. Interval int `toml:"interval"`
  103. Retry int `toml:"retry"`
  104. Timeout int `toml:"timeout"`
  105. MirrorDir string `toml:"mirror_dir"`
  106. MirrorSubDir string `toml:"mirror_subdir"`
  107. LogDir string `toml:"log_dir"`
  108. Env map[string]string `toml:"env"`
  109. Role string `toml:"role"`
  110. // These two options over-write the global options
  111. ExecOnSuccess []string `toml:"exec_on_success"`
  112. ExecOnFailure []string `toml:"exec_on_failure"`
  113. // These two options the global options
  114. ExecOnSuccessExtra []string `toml:"exec_on_success_extra"`
  115. ExecOnFailureExtra []string `toml:"exec_on_failure_extra"`
  116. Command string `toml:"command"`
  117. FailOnMatch string `toml:"fail_on_match"`
  118. SizePattern string `toml:"size_pattern"`
  119. UseIPv6 bool `toml:"use_ipv6"`
  120. UseIPv4 bool `toml:"use_ipv4"`
  121. ExcludeFile string `toml:"exclude_file"`
  122. Username string `toml:"username"`
  123. Password string `toml:"password"`
  124. RsyncNoTimeo bool `toml:"rsync_no_timeout"`
  125. RsyncTimeout int `toml:"rsync_timeout"`
  126. RsyncOptions []string `toml:"rsync_options"`
  127. RsyncOverride []string `toml:"rsync_override"`
  128. Stage1Profile string `toml:"stage1_profile"`
  129. MemoryLimit string `toml:"memory_limit"`
  130. DockerImage string `toml:"docker_image"`
  131. DockerVolumes []string `toml:"docker_volumes"`
  132. DockerOptions []string `toml:"docker_options"`
  133. SnapshotPath string `toml:"snapshot_path"`
  134. ChildMirrors []mirrorConfig `toml:"mirrors"`
  135. }
  136. // LoadConfig loads configuration
  137. func LoadConfig(cfgFile string) (*Config, error) {
  138. if _, err := os.Stat(cfgFile); err != nil {
  139. return nil, err
  140. }
  141. cfg := new(Config)
  142. if _, err := toml.DecodeFile(cfgFile, cfg); err != nil {
  143. logger.Errorf(err.Error())
  144. return nil, err
  145. }
  146. if cfg.Include.IncludeMirrors != "" {
  147. includedFiles, err := filepath.Glob(cfg.Include.IncludeMirrors)
  148. if err != nil {
  149. logger.Errorf(err.Error())
  150. return nil, err
  151. }
  152. for _, f := range includedFiles {
  153. var incMirCfg includedMirrorConfig
  154. if _, err := toml.DecodeFile(f, &incMirCfg); err != nil {
  155. logger.Errorf(err.Error())
  156. return nil, err
  157. }
  158. cfg.MirrorsConf = append(cfg.MirrorsConf, incMirCfg.Mirrors...)
  159. }
  160. }
  161. for _, m := range cfg.MirrorsConf {
  162. if err := recursiveMirrors(cfg, nil, m); err != nil {
  163. return nil, err
  164. }
  165. }
  166. return cfg, nil
  167. }
  168. func recursiveMirrors(cfg *Config, parent *mirrorConfig, mirror mirrorConfig) error {
  169. var curMir mirrorConfig
  170. if parent != nil {
  171. curMir = *parent
  172. }
  173. curMir.ChildMirrors = nil
  174. if err := mergo.Merge(&curMir, mirror, mergo.WithOverride); err != nil {
  175. return err
  176. }
  177. if mirror.ChildMirrors == nil {
  178. cfg.Mirrors = append(cfg.Mirrors, curMir)
  179. } else {
  180. for _, m := range mirror.ChildMirrors {
  181. if err := recursiveMirrors(cfg, &curMir, m); err != nil {
  182. return err
  183. }
  184. }
  185. }
  186. return nil
  187. }