config.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package config
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "strings"
  6. "github.com/rancherio/rancher-compose/librcompose/project"
  7. log "github.com/Sirupsen/logrus"
  8. "github.com/rancherio/os/util"
  9. "gopkg.in/yaml.v2"
  10. )
  11. func (c *Config) privilegedMerge(newConfig Config) error {
  12. err := c.overlay(newConfig)
  13. if err != nil {
  14. return err
  15. }
  16. for k, v := range newConfig.SystemContainers {
  17. c.SystemContainers[k] = v
  18. }
  19. return nil
  20. }
  21. func (c *Config) overlay(newConfig Config) error {
  22. newConfig.clearReadOnly()
  23. return util.Convert(&newConfig, c)
  24. }
  25. func (c *Config) clearReadOnly() {
  26. c.BootstrapContainers = make(map[string]*project.ServiceConfig, 0)
  27. c.SystemContainers = make(map[string]*project.ServiceConfig, 0)
  28. }
  29. func clearReadOnly(data map[interface{}]interface{}) map[interface{}]interface{} {
  30. newData := make(map[interface{}]interface{})
  31. for k, v := range data {
  32. newData[k] = v
  33. }
  34. delete(newData, "system_container")
  35. delete(newData, "bootstrap_container")
  36. return newData
  37. }
  38. func (c *Config) Import(bytes []byte) error {
  39. data, err := readConfig(bytes, PrivateConfigFile)
  40. if err != nil {
  41. return err
  42. }
  43. if err = saveToDisk(data); err != nil {
  44. return err
  45. }
  46. return c.Reload()
  47. }
  48. // This function only sets "non-empty" values
  49. func (c *Config) SetConfig(newConfig *Config) error {
  50. bytes, err := yaml.Marshal(newConfig)
  51. if err != nil {
  52. return err
  53. }
  54. return c.Merge(bytes)
  55. }
  56. func (c *Config) Merge(bytes []byte) error {
  57. data, err := readSavedConfig(bytes)
  58. if err != nil {
  59. return err
  60. }
  61. err = saveToDisk(data)
  62. if err != nil {
  63. return err
  64. }
  65. return c.Reload()
  66. }
  67. func LoadConfig() (*Config, error) {
  68. cfg := NewConfig()
  69. if err := cfg.Reload(); err != nil {
  70. return nil, err
  71. }
  72. if cfg.Debug {
  73. log.SetLevel(log.DebugLevel)
  74. if !util.Contains(cfg.UserDocker.Args, "-D") {
  75. cfg.UserDocker.Args = append(cfg.UserDocker.Args, "-D")
  76. }
  77. if !util.Contains(cfg.SystemDocker.Args, "-D") {
  78. cfg.SystemDocker.Args = append(cfg.SystemDocker.Args, "-D")
  79. }
  80. }
  81. return cfg, nil
  82. }
  83. func (c *Config) readArgs() error {
  84. log.Debug("Reading config args")
  85. parts := make([]string, len(os.Args))
  86. for _, arg := range os.Args[1:] {
  87. if strings.HasPrefix(arg, "--") {
  88. arg = arg[2:]
  89. }
  90. kv := strings.SplitN(arg, "=", 2)
  91. kv[0] = strings.Replace(kv[0], "-", ".", -1)
  92. parts = append(parts, strings.Join(kv, "="))
  93. }
  94. cmdLine := strings.Join(parts, " ")
  95. if len(cmdLine) == 0 {
  96. return nil
  97. }
  98. log.Debugf("Config Args %s", cmdLine)
  99. cmdLineObj := parseCmdline(strings.TrimSpace(cmdLine))
  100. return c.merge(cmdLineObj)
  101. }
  102. func (c *Config) merge(values map[interface{}]interface{}) error {
  103. values = clearReadOnly(values)
  104. return util.Convert(values, c)
  105. }
  106. func (c *Config) readFiles() error {
  107. data, err := readSavedConfig(nil)
  108. if err != nil {
  109. return err
  110. }
  111. return c.merge(data)
  112. }
  113. func (c *Config) readCmdline() error {
  114. log.Debug("Reading config cmdline")
  115. cmdLine, err := ioutil.ReadFile("/proc/cmdline")
  116. if err != nil {
  117. return err
  118. }
  119. if len(cmdLine) == 0 {
  120. return nil
  121. }
  122. log.Debugf("Config cmdline %s", cmdLine)
  123. cmdLineObj := parseCmdline(strings.TrimSpace(string(cmdLine)))
  124. return c.merge(cmdLineObj)
  125. }
  126. func Dump(private, full bool) (string, error) {
  127. files := []string{CloudConfigFile, ConfigFile}
  128. if private {
  129. files = append(files, PrivateConfigFile)
  130. }
  131. c := &Config{}
  132. if full {
  133. c = NewConfig()
  134. }
  135. data, err := readConfig(nil, files...)
  136. if err != nil {
  137. return "", err
  138. }
  139. err = c.merge(data)
  140. if err != nil {
  141. return "", err
  142. }
  143. err = c.readGlobals()
  144. if err != nil {
  145. return "", err
  146. }
  147. bytes, err := yaml.Marshal(c)
  148. return string(bytes), err
  149. }
  150. func (c *Config) configureConsole() error {
  151. if console, ok := c.SystemContainers[CONSOLE_CONTAINER]; ok {
  152. if c.Console.Persistent {
  153. console.Labels.MapParts()[REMOVE] = "false"
  154. } else {
  155. console.Labels.MapParts()[REMOVE] = "true"
  156. }
  157. }
  158. return nil
  159. }
  160. func (c *Config) readGlobals() error {
  161. return util.ShortCircuit(
  162. c.readCmdline,
  163. c.readArgs,
  164. c.configureConsole,
  165. )
  166. }
  167. func (c *Config) Reload() error {
  168. return util.ShortCircuit(
  169. c.readFiles,
  170. c.readGlobals,
  171. )
  172. }
  173. func (c *Config) Get(key string) (interface{}, error) {
  174. data := make(map[interface{}]interface{})
  175. err := util.Convert(c, &data)
  176. if err != nil {
  177. return nil, err
  178. }
  179. return getOrSetVal(key, data, nil), nil
  180. }
  181. func (c *Config) Set(key string, value interface{}) error {
  182. data, err := readSavedConfig(nil)
  183. if err != nil {
  184. return err
  185. }
  186. getOrSetVal(key, data, value)
  187. cfg := NewConfig()
  188. if err := util.Convert(data, cfg); err != nil {
  189. return err
  190. }
  191. err = saveToDisk(data)
  192. if err != nil {
  193. return err
  194. }
  195. return c.Reload()
  196. }
  197. func (d *DockerConfig) BridgeConfig() (string, string) {
  198. var name, cidr string
  199. args := append(d.Args, d.ExtraArgs...)
  200. for i, opt := range args {
  201. if opt == "-b" && i < len(args)-1 {
  202. name = args[i+1]
  203. }
  204. if opt == "--fixed-cidr" && i < len(args)-1 {
  205. cidr = args[i+1]
  206. }
  207. }
  208. if name == "" || name == "none" {
  209. return "", ""
  210. } else {
  211. return name, cidr
  212. }
  213. }
  214. func (r Repositories) ToArray() []string {
  215. result := make([]string, 0, len(r))
  216. for _, repo := range r {
  217. if repo.Url != "" {
  218. result = append(result, repo.Url)
  219. }
  220. }
  221. return result
  222. }