From c710e1f794037f195e9265f8b2c04b888177ccb9 Mon Sep 17 00:00:00 2001 From: Willy Kloucek Date: Tue, 26 Apr 2022 12:04:12 +0200 Subject: [PATCH] load configuration only from one directory --- .drone.star | 1 + .make/release.mk | 1 + .../change-load-config-from-only-one-dir.md | 12 +++ docs/helpers/configenvextractor.go | 1 + docs/ocis/config.md | 13 ++-- docs/ocis/deployment/systemd.md | 17 +++-- ocis-pkg/config/defaults/paths.go | 41 +++++++++- ocis-pkg/config/helpers.go | 76 +++---------------- ocis/docker/Dockerfile.linux.amd64 | 7 +- ocis/docker/Dockerfile.linux.arm | 7 +- ocis/docker/Dockerfile.linux.arm64 | 7 +- 11 files changed, 93 insertions(+), 90 deletions(-) create mode 100644 changelog/unreleased/change-load-config-from-only-one-dir.md diff --git a/.drone.star b/.drone.star index 0cf1343fc..a1657927f 100644 --- a/.drone.star +++ b/.drone.star @@ -1774,6 +1774,7 @@ def ocisServer(storage, accounts_hash_difficulty = 4, volumes = [], depends_on = "OCIS_URL": OCIS_URL, "PROXY_TLS": "true", "OCIS_BASE_DATA_PATH": "/mnt/data/ocis", + "OCIS_CONFIG_DIR": "/etc/ocis", # change default secrets "OCIS_JWT_SECRET": "Pive-Fumkiu4", "STORAGE_TRANSFER_SECRET": "replace-me-with-a-transfer-secret", diff --git a/.make/release.mk b/.make/release.mk index 30c3ac08f..d4dd4286d 100644 --- a/.make/release.mk +++ b/.make/release.mk @@ -11,6 +11,7 @@ release-dirs: # docker specific packaging flags DOCKER_LDFLAGS += -X "$(OCIS_REPO)/ocis-pkg/config/defaults.BaseDataPathType=path" -X "$(OCIS_REPO)/ocis-pkg/config/defaults.BaseDataPathValue=/var/lib/ocis" +DOCKER_LDFLAGS += -X "$(OCIS_REPO)/ocis-pkg/config/defaults.BaseConfigPathType=path" -X "$(OCIS_REPO)/ocis-pkg/config/defaults.BaseConfigPathValue=/etc/ocis" release-linux-docker-amd64: release-dirs GOOS=linux \ diff --git a/changelog/unreleased/change-load-config-from-only-one-dir.md b/changelog/unreleased/change-load-config-from-only-one-dir.md new file mode 100644 index 000000000..4352388f5 --- /dev/null +++ b/changelog/unreleased/change-load-config-from-only-one-dir.md @@ -0,0 +1,12 @@ +Change: Load configuration files just from one directory + +We've changed the configuration file loading behavior and are now only loading +configuration files from ONE single directory. This directory can be set on +compile time or via an environment variable on startup (`OCIS_CONFIG_DIR`). + +We are using following configuration default paths: + +- Docker images: `/etc/ocis/` +- Binary releases: `$HOME/.ocis/config/` + +https://github.com/owncloud/ocis/pull/3587 diff --git a/docs/helpers/configenvextractor.go b/docs/helpers/configenvextractor.go index bde518bcc..3f08ca0ce 100644 --- a/docs/helpers/configenvextractor.go +++ b/docs/helpers/configenvextractor.go @@ -57,6 +57,7 @@ func GenerateIntermediateCode(templatePath string, intermediateCodePath string, func RunIntermediateCode(intermediateCodePath string) { fmt.Println("Running intermediate go code for " + intermediateCodePath) os.Setenv("OCIS_BASE_DATA_PATH", "~/.ocis") + os.Setenv("OCIS_CONFIG_DIR", "~/.ocis/config") out, err := exec.Command("go", "run", intermediateCodePath).Output() if err != nil { log.Fatal(err) diff --git a/docs/ocis/config.md b/docs/ocis/config.md index f4ab30cf6..9ad125108 100644 --- a/docs/ocis/config.md +++ b/docs/ocis/config.md @@ -39,15 +39,16 @@ Let's explore the various flows with examples and workflows. Let's explore with examples this approach. -#### Expected loading locations: +#### Expected loading locations -- `$HOME/.ocis/config/` -- `/etc/ocis/` -- `.config/` +- docker images: `/etc/ocis/` +- binary releases: `$HOME/.ocis/config/` -followed by the extension name. When configuring the proxy, a valid full path that will get loaded is `$HOME/.ocis/config/proxy.yaml`. +followed by the `.yaml`, eg `proxy.yaml` for the extension configuration. You also can put an `ocis.yaml` config file to the expected loading location to use a single config file. -#### Only config files +You can set another directory as config path in the environment variable `OCIS_CONFIG_DIR`. It will then pick the same file names, but from the folder you configured. + +#### Only config files The following config files are present in the default loading locations: diff --git a/docs/ocis/deployment/systemd.md b/docs/ocis/deployment/systemd.md index 18de3fcd1..d37d380f4 100644 --- a/docs/ocis/deployment/systemd.md +++ b/docs/ocis/deployment/systemd.md @@ -10,17 +10,18 @@ geekdocFilePath: systemd.md {{< toc >}} ## Install the oCIS binary + Download the oCIS binary of your preferred version and for your CPU architecture and operating system from [download.owncloud.com](https://download.owncloud.com/ocis/ocis). Rename the downloaded binary to `ocis` and move it to `/usr/bin/`. As a next step, you need to mark it as executable with `chmod +x /usr/bin/ocis`. When you now run `ocis help` on your command line, you should see the available options for the oCIS command. - ## Systemd service definition Create the Systemd service definition for oCIS in the file `/etc/systemd/system/ocis.service` with following content: -``` + +```systemd [Unit] Description=OCIS server @@ -49,16 +50,16 @@ OCIS_INSECURE=false OCIS_LOG_LEVEL=error -GLAUTH_LDAPS_CERT=/etc/ocis/ldap/ldaps.crt -GLAUTH_LDAPS_KEY=/etc/ocis/ldap/ldaps.key -IDP_TRANSPORT_TLS_CERT=/etc/ocis/idp/server.crt -IDP_TRANSPORT_TLS_KEY=/etc/ocis/idp/server.key -PROXY_TRANSPORT_TLS_CERT=/etc/ocis/proxy/server.crt -PROXY_TRANSPORT_TLS_KEY=/etc/ocis/proxy/server.key +OCIS_CONFIG_DIR=/etc/ocis +OCIS_BASE_DATA_PATH=/var/lib/ocis ``` +Since we set `OCIS_CONFIG_DIR` to `/etc/ocis` you can also place configuration files in this directory. + Please change your `OCIS_URL` in order to reflect your actual deployment. If you are using self-signed certificates you need to set `OCIS_INSECURE=true` in `/etc/ocis/ocis.env`. +oCIS will store all data in `/var/lib/ocis`, because we configured it so by setting `OCIS_BASE_DATA_PATH`. Therefore you need to create that directory and make it accessible to the user, you use to start oCIS. + ## Starting the oCIS service diff --git a/ocis-pkg/config/defaults/paths.go b/ocis-pkg/config/defaults/paths.go index 9980daeda..fbbc2a637 100644 --- a/ocis-pkg/config/defaults/paths.go +++ b/ocis-pkg/config/defaults/paths.go @@ -10,16 +10,16 @@ const () var ( // switch between modes - BaseDataPathType = "homedir" - // don't read from this, only write + BaseDataPathType = "homedir" // or "path" + // default data path BaseDataPathValue = "/var/lib/ocis" ) func BaseDataPath() string { // It is not nice to have hidden / secrete configuration options - // But how can we update the base path for every occurence with a flageset option? - // This is currenlty not possible and needs a new configuration concept + // But how can we update the base path for every occurrence with a flagset option? + // This is currently not possible and needs a new configuration concept p := os.Getenv("OCIS_BASE_DATA_PATH") if p != "" { return p @@ -40,3 +40,36 @@ func BaseDataPath() string { return "" } } + +var ( + // switch between modes + BaseConfigPathType = "homedir" // or "path" + // default config path + BaseConfigPathValue = "/etc/ocis" +) + +func BaseConfigPath() string { + + // It is not nice to have hidden / secrete configuration options + // But how can we update the base path for every occurrence with a flagset option? + // This is currently not possible and needs a new configuration concept + p := os.Getenv("OCIS_CONFIG_DIR") + if p != "" { + return p + } + + switch BaseConfigPathType { + case "homedir": + dir, err := os.UserHomeDir() + if err != nil { + // fallback to BaseConfigPathValue for users without home + return BaseConfigPathValue + } + return path.Join(dir, ".ocis", "config") + case "path": + return BaseConfigPathValue + default: + log.Fatalf("BaseConfigPathType %s not found", BaseConfigPathType) + return "" + } +} diff --git a/ocis-pkg/config/helpers.go b/ocis-pkg/config/helpers.go index 6eac89847..b12803c52 100644 --- a/ocis-pkg/config/helpers.go +++ b/ocis-pkg/config/helpers.go @@ -1,87 +1,31 @@ package config import ( - "io/fs" - "os" - "path/filepath" - "strings" + "path" gofig "github.com/gookit/config/v2" gooyaml "github.com/gookit/config/v2/yaml" + "github.com/owncloud/ocis/ocis-pkg/config/defaults" ) var ( - defaultLocations = []string{ - filepath.Join(os.Getenv("HOME"), "/.ocis/config/"), - "/etc/ocis/", - ".config/", - } - - // supportedExtensions is determined by gookit/config. - supportedExtensions = []string{ - "yaml", - "yml", - } + // decoderConfigTagname sets the tag name to be used from the config structs + // currently we only support "yaml" because we only support config loading + // from yaml files and the yaml parser has no simple way to set a custom tag name to use + decoderConfigTagName = "yaml" ) -// DefaultConfigSources returns a slice with matched expected config files. It sugars coat several aspects of config file -// management by assuming there are 3 default locations a config file could be. -// It uses globbing to match a config file by name, and retrieve any supported extension supported by our drivers. -// It sanitizes the output depending on the list of drivers provided. -func DefaultConfigSources(filename string, drivers []string) []string { - var sources []string - - locations := []string{} - if v := os.Getenv("OCIS_CONFIG_DIR"); v != "" { - locations = append(locations, v) - // only use the configured config dir - locations = append(locations, os.Getenv("OCIS_CONFIG_DIR")) - } else { - // merge config from all default locations - locations = append(locations, defaultLocations...) - } - - for i := range locations { - dirFS := os.DirFS(locations[i]) - pattern := filename + ".*" - matched, _ := fs.Glob(dirFS, pattern) - if len(matched) > 0 { - // prepend path to results - for j := 0; j < len(matched); j++ { - matched[j] = filepath.Join(locations[i], matched[j]) - } - } - sources = append(sources, matched...) - } - - return sanitizeExtensions(sources, drivers, func(a, b string) bool { - return strings.HasSuffix(filepath.Base(a), b) - }) -} - -// sanitizeExtensions removes elements from "set" which extensions are not in "ext". -func sanitizeExtensions(set []string, ext []string, f func(a, b string) bool) []string { - var r []string - for i := 0; i < len(set); i++ { - for j := 0; j < len(ext); j++ { - if f(filepath.Base(set[i]), ext[j]) { - r = append(r, set[i]) - } - } - } - return r -} - // BindSourcesToStructs assigns any config value from a config file / env variable to struct `dst`. Its only purpose // is to solely modify `dst`, not dealing with the config structs; and do so in a thread safe manner. func BindSourcesToStructs(extension string, dst interface{}) (*gofig.Config, error) { - sources := DefaultConfigSources(extension, supportedExtensions) cnf := gofig.NewWithOptions(extension) cnf.WithOptions(func(options *gofig.Options) { - options.DecoderConfig.TagName = "yaml" + options.DecoderConfig.TagName = decoderConfigTagName }) cnf.AddDriver(gooyaml.Driver) - _ = cnf.LoadFiles(sources...) + + cfgFile := path.Join(defaults.BaseConfigPath(), extension+".yaml") + _ = cnf.LoadFiles([]string{cfgFile}...) err := cnf.BindStruct("", &dst) if err != nil { diff --git a/ocis/docker/Dockerfile.linux.amd64 b/ocis/docker/Dockerfile.linux.amd64 index 6729daf58..8d3391413 100644 --- a/ocis/docker/Dockerfile.linux.amd64 +++ b/ocis/docker/Dockerfile.linux.amd64 @@ -26,9 +26,12 @@ RUN addgroup -g 1000 -S ocis-group && \ RUN mkdir -p /var/lib/ocis && \ chown -R ocis-user:ocis-group /var/lib/ocis && \ - chmod -R 777 /var/lib/ocis + chmod -R 777 /var/lib/ocis && \ + mkdir -p /etc/ocis && \ + chown -R ocis-user:ocis-group /etc/ocis && \ + chmod -R 777 /etc/ocis -VOLUME [ "/var/lib/ocis" ] +VOLUME [ "/var/lib/ocis", "/etc/ocis" ] WORKDIR /var/lib/ocis USER 1000 diff --git a/ocis/docker/Dockerfile.linux.arm b/ocis/docker/Dockerfile.linux.arm index 922246bb0..cb6f757b8 100644 --- a/ocis/docker/Dockerfile.linux.arm +++ b/ocis/docker/Dockerfile.linux.arm @@ -26,9 +26,12 @@ RUN addgroup -g 1000 -S ocis-group && \ RUN mkdir -p /var/lib/ocis && \ chown -R ocis-user:ocis-group /var/lib/ocis && \ - chmod -R 777 /var/lib/ocis + chmod -R 777 /var/lib/ocis && \ + mkdir -p /etc/ocis && \ + chown -R ocis-user:ocis-group /etc/ocis && \ + chmod -R 777 /etc/ocis -VOLUME [ "/var/lib/ocis" ] +VOLUME [ "/var/lib/ocis", "/etc/ocis" ] WORKDIR /var/lib/ocis USER 1000 diff --git a/ocis/docker/Dockerfile.linux.arm64 b/ocis/docker/Dockerfile.linux.arm64 index 47ccad926..7601ed39e 100644 --- a/ocis/docker/Dockerfile.linux.arm64 +++ b/ocis/docker/Dockerfile.linux.arm64 @@ -26,9 +26,12 @@ RUN addgroup -g 1000 -S ocis-group && \ RUN mkdir -p /var/lib/ocis && \ chown -R ocis-user:ocis-group /var/lib/ocis && \ - chmod -R 777 /var/lib/ocis + chmod -R 777 /var/lib/ocis && \ + mkdir -p /etc/ocis && \ + chown -R ocis-user:ocis-group /etc/ocis && \ + chmod -R 777 /etc/ocis -VOLUME [ "/var/lib/ocis" ] +VOLUME [ "/var/lib/ocis", "/etc/ocis" ] WORKDIR /var/lib/ocis USER 1000