Skip to content

Commit

Permalink
Merge pull request #6071 from owncloud/fix-run-services
Browse files Browse the repository at this point in the history
[full-ci] add optional services and fix config slice parser
  • Loading branch information
micbar committed Apr 18, 2023
2 parents 5db4656 + 0f99a80 commit a470d38
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 25 deletions.
5 changes: 5 additions & 0 deletions changelog/unreleased/runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Enhancement: Add optional services to the runtime

Make it possible to start optional services in the ocis runtime. Instead of using `OCIS_RUN_SERVICES` to define all services we can now use `OCIS_ADD_RUN_SERVICES` to add a comma separated list of additional services which are not started in the single process by default.

https://github.com/owncloud/ocis/pull/6071
9 changes: 5 additions & 4 deletions ocis-pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ type Mode int

// Runtime configures the oCIS runtime when running in supervised mode.
type Runtime struct {
Port string `yaml:"port" env:"OCIS_RUNTIME_PORT"`
Host string `yaml:"host" env:"OCIS_RUNTIME_HOST"`
Services string `yaml:"services" env:"OCIS_RUN_EXTENSIONS;OCIS_RUN_SERVICES" desc:"A comma-separated list of service names. Will start only the listed services."`
Disabled string `yaml:"disabled_services" env:"OCIS_EXCLUDE_RUN_SERVICES" desc:"A comma-separated list of service names. Will start all services except of the ones listed. Has no effect when OCIS_RUN_SERVICES is set."`
Port string `yaml:"port" env:"OCIS_RUNTIME_PORT"`
Host string `yaml:"host" env:"OCIS_RUNTIME_HOST"`
Services []string `yaml:"services" env:"OCIS_RUN_EXTENSIONS;OCIS_RUN_SERVICES" desc:"A comma-separated list of service names. Will start only the listed services."`
Disabled []string `yaml:"disabled_services" env:"OCIS_EXCLUDE_RUN_SERVICES" desc:"A comma-separated list of service names. Will start all services except of the ones listed. Has no effect when OCIS_RUN_SERVICES is set."`
Additional []string `yaml:"add_services" env:"OCIS_ADD_RUN_SERVICES" desc:"A comma-separated list of service names. Will add the listed services to the default configuration. Has no effect when OCIS_RUN_SERVICES is set."`
}

// Config combines all available configuration parts.
Expand Down
2 changes: 1 addition & 1 deletion ocis-pkg/config/envdecode/envdecode.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ func decode(target interface{}, strict bool) (int, error) {
}

func decodeSlice(f *reflect.Value, env string) error {
parts := strings.Split(env, ";")
parts := strings.Split(env, ",")

values := parts[:0]
for _, x := range parts {
Expand Down
24 changes: 12 additions & 12 deletions ocis-pkg/config/envdecode/envdecode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ type testConfig struct {
UnmarshalerNumber unmarshalerNumber `env:"TEST_UNMARSHALER_NUMBER"`

DefaultInt int `env:"TEST_UNSET,asdf=asdf,default=1234"`
DefaultSliceInt []int `env:"TEST_UNSET,asdf=asdf,default=1;2;3"`
DefaultSliceInt []int `env:"TEST_UNSET,asdf=asdf,default=1"`
DefaultDuration time.Duration `env:"TEST_UNSET,asdf=asdf,default=24h"`
DefaultURL *url.URL `env:"TEST_UNSET,default=http://example.com"`
}
Expand Down Expand Up @@ -137,12 +137,12 @@ func TestDecode(t *testing.T) {
os.Setenv("TEST_DURATION", "10m")
os.Setenv("TEST_URL", "https://example.com")
os.Setenv("TEST_INVALID_INT64", "asdf")
os.Setenv("TEST_STRING_SLICE", "foo;bar")
os.Setenv("TEST_INT64_SLICE", int64AsString+";"+int64AsString)
os.Setenv("TEST_UINT16_SLICE", "60000;50000")
os.Setenv("TEST_FLOAT64_SLICE", piAsString+";"+piAsString)
os.Setenv("TEST_BOOL_SLICE", "true; false; true")
os.Setenv("TEST_DURATION_SLICE", "10m; 20m")
os.Setenv("TEST_STRING_SLICE", "foo,bar")
os.Setenv("TEST_INT64_SLICE", int64AsString+","+int64AsString)
os.Setenv("TEST_UINT16_SLICE", "60000,50000")
os.Setenv("TEST_FLOAT64_SLICE", piAsString+","+piAsString)
os.Setenv("TEST_BOOL_SLICE", "true, false, true")
os.Setenv("TEST_DURATION_SLICE", "10m, 20m")
os.Setenv("TEST_URL_SLICE", "https://example.com")
os.Setenv("TEST_DECODER_STRUCT", "{\"string\":\"foo\"}")
os.Setenv("TEST_DECODER_STRUCT_PTR", "{\"string\":\"foo\"}")
Expand Down Expand Up @@ -274,7 +274,7 @@ func TestDecode(t *testing.T) {
t.Fatalf("Expected 1234, got %d", tc.DefaultInt)
}

expectedDefaultSlice := []int{1, 2, 3}
expectedDefaultSlice := []int{1}
if !reflect.DeepEqual(tc.DefaultSliceInt, expectedDefaultSlice) {
t.Fatalf("Expected %d, got %d", expectedDefaultSlice, tc.DefaultSliceInt)
}
Expand Down Expand Up @@ -517,7 +517,7 @@ type testConfigExport struct {
DefaultDuration time.Duration `env:"TEST_DEFAULT_DURATION,default=24h"`
DefaultURL *url.URL `env:"TEST_DEFAULT_URL,default=http://example.com"`
DefaultIntSet int `env:"TEST_DEFAULT_INT_SET,default=99"`
DefaultIntSlice []int `env:"TEST_DEFAULT_INT_SLICE,default=99;33"`
DefaultIntSlice []int `env:"TEST_DEFAULT_INT_SLICE,default=99"`
}

type nestedConfigExport struct {
Expand Down Expand Up @@ -603,13 +603,13 @@ func TestExport(t *testing.T) {
os.Setenv("TEST_BOOL", "true")
os.Setenv("TEST_DURATION", "10m")
os.Setenv("TEST_URL", "https://example.com")
os.Setenv("TEST_STRING_SLICE", "foo;bar")
os.Setenv("TEST_STRING_SLICE", "foo,bar")
os.Setenv("TEST_NESTED_STRING", "nest_foo")
os.Setenv("TEST_NESTED_STRING_POINTER", "nest_foo_ptr")
os.Setenv("TEST_NESTED_TWICE_STRING", "nest_twice_foo")
os.Setenv("TEST_REQUIRED_INT", "101")
os.Setenv("TEST_DEFAULT_INT_SET", "102")
os.Setenv("TEST_DEFAULT_INT_SLICE", "1;2;3")
os.Setenv("TEST_DEFAULT_INT_SLICE", "1,2,3")

var tc testConfigExport
tc.NestedPtr = &nestedConfigExportPointer{}
Expand Down Expand Up @@ -769,7 +769,7 @@ func TestExport(t *testing.T) {
Field: "DefaultIntSlice",
EnvVar: "TEST_DEFAULT_INT_SLICE",
Value: "[1 2 3]",
DefaultValue: "99;33",
DefaultValue: "99",
HasDefault: true,
UsesEnv: true,
},
Expand Down
32 changes: 24 additions & 8 deletions ocis/pkg/runtime/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ import (
ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
antivirus "github.com/owncloud/ocis/v2/services/antivirus/pkg/command"
appProvider "github.com/owncloud/ocis/v2/services/app-provider/pkg/command"
appRegistry "github.com/owncloud/ocis/v2/services/app-registry/pkg/command"
audit "github.com/owncloud/ocis/v2/services/audit/pkg/command"
authbasic "github.com/owncloud/ocis/v2/services/auth-basic/pkg/command"
authmachine "github.com/owncloud/ocis/v2/services/auth-machine/pkg/command"
eventhistory "github.com/owncloud/ocis/v2/services/eventhistory/pkg/command"
Expand All @@ -34,6 +36,7 @@ import (
notifications "github.com/owncloud/ocis/v2/services/notifications/pkg/command"
ocdav "github.com/owncloud/ocis/v2/services/ocdav/pkg/command"
ocs "github.com/owncloud/ocis/v2/services/ocs/pkg/command"
policies "github.com/owncloud/ocis/v2/services/policies/pkg/command"
postprocessing "github.com/owncloud/ocis/v2/services/postprocessing/pkg/command"
proxy "github.com/owncloud/ocis/v2/services/proxy/pkg/command"
search "github.com/owncloud/ocis/v2/services/search/pkg/command"
Expand Down Expand Up @@ -65,6 +68,7 @@ type Service struct {
Supervisor *suture.Supervisor
ServicesRegistry serviceFuncMap
Delayed serviceFuncMap
Additional serviceFuncMap
Log log.Logger

serviceToken map[string][]suture.ServiceToken
Expand Down Expand Up @@ -96,6 +100,7 @@ func NewService(options ...Option) (*Service, error) {
s := &Service{
ServicesRegistry: make(serviceFuncMap),
Delayed: make(serviceFuncMap),
Additional: make(serviceFuncMap),
Log: l,

serviceToken: make(map[string][]suture.ServiceToken),
Expand Down Expand Up @@ -134,6 +139,11 @@ func NewService(options ...Option) (*Service, error) {
s.ServicesRegistry[opts.Config.EventHistory.Service.Name] = eventhistory.NewSutureService
s.ServicesRegistry[opts.Config.Userlog.Service.Name] = userlog.NewSutureService

// populate optional services
s.Additional[opts.Config.Antivirus.Service.Name] = antivirus.NewSutureService
s.Additional[opts.Config.Audit.Service.Name] = audit.NewSutureService
s.Additional[opts.Config.Policies.Service.Name] = policies.NewSutureService

// populate delayed services
s.Delayed[opts.Config.Sharing.Service.Name] = sharing.NewSutureService
s.Delayed[opts.Config.Proxy.Service.Name] = proxy.NewSutureService
Expand Down Expand Up @@ -212,6 +222,9 @@ func Start(o ...Option) error {
// schedule services that we are sure don't have interdependencies.
scheduleServiceTokens(s, s.ServicesRegistry)

// schedule services that are optional
scheduleServiceTokens(s, s.Additional)

// there are reasons not to do this, but we have race conditions ourselves. Until we resolve them, mind the following disclaimer:
// Calling ServeBackground will CORRECTLY start the supervisor running in a new goroutine. It is risky to directly run
// go supervisor.Serve()
Expand Down Expand Up @@ -245,9 +258,8 @@ func scheduleServiceTokens(s *Service, funcSet serviceFuncMap) {
// the runtime.
func (s *Service) generateRunSet(cfg *ociscfg.Config) {
runset = make(map[string]struct{})
if cfg.Runtime.Services != "" {
e := strings.Split(strings.ReplaceAll(cfg.Runtime.Services, " ", ""), ",")
for _, name := range e {
if cfg.Runtime.Services != nil {
for _, name := range cfg.Runtime.Services {
runset[name] = struct{}{}
}
return
Expand All @@ -261,12 +273,16 @@ func (s *Service) generateRunSet(cfg *ociscfg.Config) {
runset[name] = struct{}{}
}

if cfg.Runtime.Disabled != "" {
e := strings.Split(strings.ReplaceAll(cfg.Runtime.Disabled, " ", ""), ",")
for _, name := range e {
delete(runset, name)
}
// add additional services if explicitly added by config
for _, name := range cfg.Runtime.Additional {
runset[name] = struct{}{}
}

// remove services if explicitly excluded by config
for _, name := range cfg.Runtime.Disabled {
delete(runset, name)
}

}

// List running processes for the Service Controller.
Expand Down

0 comments on commit a470d38

Please sign in to comment.