config.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package utils
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "path/filepath"
  6. "regexp"
  7. "strings"
  8. "github.com/compose-spec/compose-go/loader"
  9. "github.com/compose-spec/compose-go/types"
  10. "github.com/prometheus/common/log"
  11. )
  12. var SupportedFilenames = []string{"compose.yaml", "compose.yml", "docker-compose.yml", "docker-compose.yaml"}
  13. func GetConfigs(name string, configPaths []string) (string, []types.ConfigFile, error) {
  14. configPath, err := getConfigPaths(configPaths)
  15. if err != nil {
  16. return "", nil, err
  17. }
  18. if configPath == nil {
  19. return "", nil, nil
  20. }
  21. workingDir := filepath.Dir(configPath[0])
  22. if name == "" {
  23. name = os.Getenv("COMPOSE_PROJECT_NAME")
  24. }
  25. if name == "" {
  26. r := regexp.MustCompile(`[^a-z0-9\\-_]+`)
  27. name = r.ReplaceAllString(strings.ToLower(filepath.Base(workingDir)), "")
  28. }
  29. configs, err := parseConfigs(configPath)
  30. if err != nil {
  31. return "", nil, err
  32. }
  33. return workingDir, configs, nil
  34. }
  35. func getConfigPaths(configPaths []string) ([]string, error) {
  36. paths := []string{}
  37. pwd, err := os.Getwd()
  38. if err != nil {
  39. return nil, err
  40. }
  41. if len(configPaths) != 0 {
  42. for _, f := range configPaths {
  43. if f == "-" {
  44. paths = append(paths, f)
  45. continue
  46. }
  47. if !filepath.IsAbs(f) {
  48. f = filepath.Join(pwd, f)
  49. }
  50. if _, err := os.Stat(f); err != nil {
  51. return nil, err
  52. }
  53. paths = append(paths, f)
  54. }
  55. return paths, nil
  56. }
  57. sep := os.Getenv("COMPOSE_FILE_SEPARATOR")
  58. if sep == "" {
  59. sep = string(os.PathListSeparator)
  60. }
  61. f := os.Getenv("COMPOSE_FILE")
  62. if f != "" {
  63. return strings.Split(f, sep), nil
  64. }
  65. for {
  66. candidates := []string{}
  67. for _, n := range SupportedFilenames {
  68. f := filepath.Join(pwd, n)
  69. if _, err := os.Stat(f); err == nil {
  70. candidates = append(candidates, f)
  71. }
  72. }
  73. if len(candidates) > 0 {
  74. winner := candidates[0]
  75. if len(candidates) > 1 {
  76. log.Warnf("Found multiple config files with supported names: %s", strings.Join(candidates, ", "))
  77. log.Warnf("Using %s\n", winner)
  78. }
  79. return []string{winner}, nil
  80. }
  81. parent := filepath.Dir(pwd)
  82. if parent == pwd {
  83. return nil, nil
  84. }
  85. pwd = parent
  86. }
  87. }
  88. func parseConfigs(configPaths []string) ([]types.ConfigFile, error) {
  89. files := []types.ConfigFile{}
  90. for _, f := range configPaths {
  91. var (
  92. b []byte
  93. err error
  94. )
  95. if f == "-" {
  96. b, err = ioutil.ReadAll(os.Stdin)
  97. } else {
  98. if _, err := os.Stat(f); err != nil {
  99. return nil, err
  100. }
  101. b, err = ioutil.ReadFile(f)
  102. }
  103. if err != nil {
  104. return nil, err
  105. }
  106. config, err := loader.ParseYAML(b)
  107. if err != nil {
  108. return nil, err
  109. }
  110. files = append(files, types.ConfigFile{Filename: f, Config: config})
  111. }
  112. return files, nil
  113. }