config.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. Copyright 2020 Docker Compose CLI authors
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package config
  14. import (
  15. "encoding/json"
  16. "io/ioutil"
  17. "os"
  18. "path/filepath"
  19. "github.com/pkg/errors"
  20. "github.com/docker/compose-cli/api/context/store"
  21. )
  22. var configDir string
  23. // WithDir sets the config directory path in the context
  24. func WithDir(path string) {
  25. configDir = path
  26. }
  27. // Dir returns the config directory path
  28. func Dir() string {
  29. return configDir
  30. }
  31. // LoadFile loads the docker configuration
  32. func LoadFile(dir string) (*File, error) {
  33. f := &File{}
  34. err := loadFile(configFilePath(dir), &f)
  35. if err != nil {
  36. return nil, err
  37. }
  38. return f, nil
  39. }
  40. // WriteCurrentContext writes the selected current context to the Docker
  41. // configuration file. Note, the validity of the context is not checked.
  42. func WriteCurrentContext(dir string, name string) error {
  43. m := map[string]interface{}{}
  44. path := configFilePath(dir)
  45. err := loadFile(path, &m)
  46. if err != nil {
  47. return err
  48. }
  49. // Match existing CLI behavior
  50. if name == store.DefaultContextName {
  51. delete(m, currentContextKey)
  52. } else {
  53. m[currentContextKey] = name
  54. }
  55. return writeFile(path, m)
  56. }
  57. func writeFile(path string, content map[string]interface{}) error {
  58. d, err := json.MarshalIndent(content, "", "\t")
  59. if err != nil {
  60. return errors.Wrap(err, "unable to marshal config")
  61. }
  62. err = ioutil.WriteFile(path, d, 0644)
  63. return errors.Wrap(err, "unable to write config file")
  64. }
  65. func loadFile(path string, dest interface{}) error {
  66. data, err := ioutil.ReadFile(path)
  67. if err != nil {
  68. if os.IsNotExist(err) {
  69. // Not an error if there is no config, we're just using defaults
  70. return nil
  71. }
  72. return errors.Wrap(err, "unable to read config file")
  73. }
  74. err = json.Unmarshal(data, dest)
  75. return errors.Wrap(err, "unable to unmarshal config file "+path)
  76. }
  77. func configFilePath(dir string) string {
  78. return filepath.Join(dir, ConfigFileName)
  79. }
  80. // File contains the current context from the docker configuration file
  81. type File struct {
  82. CurrentContext string `json:"currentContext,omitempty"`
  83. }