Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

load configuration only from one directory #3587

Merged
merged 2 commits into from
Apr 26, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .drone.star
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions .make/release.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
12 changes: 12 additions & 0 deletions changelog/unreleased/change-load-config-from-only-one-dir.md
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions docs/helpers/configenvextractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
wkloucek marked this conversation as resolved.
Show resolved Hide resolved
out, err := exec.Command("go", "run", intermediateCodePath).Output()
if err != nil {
log.Fatal(err)
Expand Down
13 changes: 7 additions & 6 deletions docs/ocis/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<extension name>.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:

Expand Down
17 changes: 9 additions & 8 deletions docs/ocis/deployment/systemd.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
41 changes: 37 additions & 4 deletions ocis-pkg/config/defaults/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 ""
}
}
76 changes: 10 additions & 66 deletions ocis-pkg/config/helpers.go
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
7 changes: 5 additions & 2 deletions ocis/docker/Dockerfile.linux.amd64
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions ocis/docker/Dockerfile.linux.arm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions ocis/docker/Dockerfile.linux.arm64
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down