config.go 6.2 KB

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