Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion core/actioncontext/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func WithProps(ctx context.Context, props Properties) context.Context {
if props.Rollback {
ctx = actionrollback.NewContext(ctx)
}
if props.PG {
if props.PG && pg.FromContext(ctx) == nil {
ctx = pg.NewContext(ctx)
}
return ctx
Expand Down
90 changes: 70 additions & 20 deletions core/naming/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/opensvc/om3/v3/util/file"
"github.com/opensvc/om3/v3/util/hostname"
"github.com/opensvc/om3/v3/util/xmap"
"github.com/opensvc/om3/v3/util/xstrings"
)

type (
Expand Down Expand Up @@ -100,6 +99,10 @@ func NewPathFromStrings(namespace, kind, name string) (Path, error) {
return path, fmt.Errorf("%w: invalid kind %s", ErrInvalid, kind)
case KindNscfg:
name = "namespace"
case KindSvc:
if namespace == NsRoot && name == "namespace" {
return path, fmt.Errorf("%w: the 'namespace' svc name is reserved in the root ns", ErrInvalid)
}
}

if name == "" {
Expand Down Expand Up @@ -156,6 +159,13 @@ func (t Path) String() string {
if t.Kind == KindInvalid {
return ""
}
if t.Kind == KindNscfg {
if t.Namespace == NsRoot {
return Separator
} else {
return t.Namespace + Separator
}
}
if t.Namespace != "" && t.Namespace != NsRoot {
s += t.Namespace + Separator
}
Expand Down Expand Up @@ -408,12 +418,16 @@ func (t Path) VarDir() string {
if t.IsZero() {
return filepath.Join(rawconfig.Paths.Var, "node")
}

switch t.Namespace {
case "", NsRoot:
s = filepath.Join(rawconfig.Paths.Var, t.Kind.String(), t.Name)
default:
s = filepath.Join(rawconfig.Paths.VarNs, t.String())
if t.Kind == KindNscfg {
s = filepath.Join(rawconfig.Paths.VarNs, t.FQN())
} else {

s = filepath.Join(rawconfig.Paths.VarNs, t.String())
}
}
return s
}
Expand Down Expand Up @@ -464,11 +478,21 @@ func (t Path) ConfigFile() string {
if s == "" {
return ""
}
switch t.Namespace {
case "", NsRoot:
s = fmt.Sprintf("%s/%s.conf", rawconfig.Paths.Etc, s)
switch t.Kind {
case KindCcfg:
s = fmt.Sprintf("%s/cluster.conf", rawconfig.Paths.Etc)
case KindNscfg:
if t.Namespace == "" || t.Namespace == NsRoot {
s = fmt.Sprintf("%s/namespace.conf", rawconfig.Paths.Etc)
} else {
s = fmt.Sprintf("%s/%s/namespace.conf", rawconfig.Paths.EtcNs, t.Namespace)
}
default:
s = fmt.Sprintf("%s/%s.conf", rawconfig.Paths.EtcNs, s)
if t.Namespace == "" || t.Namespace == NsRoot {
s = fmt.Sprintf("%s/%s.conf", rawconfig.Paths.Etc, s)
} else {
s = fmt.Sprintf("%s/%s.conf", rawconfig.Paths.EtcNs, s)
}
}
return filepath.FromSlash(s)
}
Expand All @@ -484,8 +508,9 @@ func InstalledPaths() (Paths, error) {
matches := make([]string, 0)
patterns := []string{
fmt.Sprintf("%s/*.conf", rawconfig.Paths.Etc), // root svc
fmt.Sprintf("%s/*/*.conf", rawconfig.Paths.Etc), // root other
fmt.Sprintf("%s/*/*/*.conf", rawconfig.Paths.EtcNs), // namespaces
fmt.Sprintf("%s/*/*.conf", rawconfig.Paths.Etc), // root other-kind
fmt.Sprintf("%s/*/*.conf", rawconfig.Paths.EtcNs), // namespaces nscfg
fmt.Sprintf("%s/*/*/*.conf", rawconfig.Paths.EtcNs), // namespaces other-kind
}
for _, pattern := range patterns {
m, err := filepath.Glob(pattern)
Expand All @@ -494,21 +519,14 @@ func InstalledPaths() (Paths, error) {
}
matches = append(matches, m...)
}
replacements := []string{
fmt.Sprintf("%s/", rawconfig.Paths.EtcNs),
fmt.Sprintf("%s/", rawconfig.Paths.Etc),
}

envNamespace := env.Namespace()
envKind := ParseKind(env.Kind())

for _, ps := range matches {
for _, r := range replacements {
ps = strings.Replace(ps, r, "", 1)
ps = strings.Replace(ps, r, "", 1)
}
ps = xstrings.TrimLast(ps, 5) // strip trailing .conf
p, err := ParsePath(ps)
p, err := ConfigFilePath(ps)
if err != nil {
continue
l = append(l, p)
}
if envKind != KindInvalid && envKind != p.Kind {
continue
Expand All @@ -520,3 +538,35 @@ func InstalledPaths() (Paths, error) {
}
return l, nil
}

// ConfigFilePath return the object path owning the config file pass as
// argument.
//
// e.g.
// * /etc/opensvc/namespace.conf => path.T{Namespace: "root", Kind: KindNscfg, Name: "namespace"}
// * /etc/opensvc/sec/namespace.conf => path.T{Namespace: "root", Kind: KindSec, Name: "namespace"}
// * /etc/opensvc/namespaces/test/namespace.conf => path.T{Namespace: "test", Kind: KindNscfg, Name: "namespace"}
// * /etc/opensvc/namespaces/test/svc/namespace.conf => path.T{Namespace: "test", Kind: KindSvc, Name: "namespace"}
func ConfigFilePath(filename string) (Path, error) {
svcName := strings.TrimPrefix(filename, rawconfig.Paths.Etc+"/")
if svcName == "namespace.conf" {
return Path{
Namespace: NsRoot, Kind: KindNscfg, Name: "namespace"}, nil
}
if svcName == "cluster.conf" {
return Path{Namespace: NsRoot, Kind: KindCcfg, Name: "cluster"}, nil
}
svcName = strings.TrimPrefix(svcName, "namespaces/")
svcName = strings.TrimSuffix(svcName, ".conf")
elements := strings.Split(svcName, "/")
if len(elements) == 2 && elements[1] == "namespace" {
if ParseKind(elements[0]) == KindInvalid {
// ns1/namespace => ns1/
svcName = strings.TrimSuffix(svcName, "namespace")
}
}
if len(svcName) == 0 {
return Path{}, fmt.Errorf("skipped null filename")
}
return ParsePath(svcName)
}
92 changes: 92 additions & 0 deletions core/naming/path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ func TestNewPath(t *testing.T) {
output: "",
ok: false,
},
"reserved svc name": {
name: "namespace",
namespace: "root",
kind: "svc",
output: "",
ok: false,
},
"empty name": {
name: "",
namespace: NsRoot,
Expand All @@ -102,6 +109,20 @@ func TestNewPath(t *testing.T) {
output: "cluster",
ok: true,
},
"root nscfg": {
name: "namespace",
namespace: NsRoot,
kind: "nscfg",
output: "/",
ok: true,
},
"non-root nscfg": {
name: "namespace",
namespace: "test",
kind: "nscfg",
output: "test/",
ok: true,
},
"zero value": {
name: "",
namespace: "",
Expand Down Expand Up @@ -227,6 +248,12 @@ func TestParsePath(t *testing.T) {
kind: "nscfg",
ok: true,
},
"ns1/nscfg/namespace": {
name: "namespace",
namespace: "ns1",
kind: "nscfg",
ok: true,
},
"cluster": {
name: "cluster",
namespace: NsRoot,
Expand Down Expand Up @@ -531,6 +558,20 @@ func TestConfigFile(t *testing.T) {
cf: "/etc/opensvc/cluster.conf",
root: "",
},
"root namespace": {
name: "namespace",
namespace: "",
kind: "nscfg",
cf: "/etc/opensvc/namespace.conf",
root: "",
},
"non-root namespace": {
name: "namespace",
namespace: "test",
kind: "nscfg",
cf: "/etc/opensvc/namespaces/test/namespace.conf",
root: "",
},
"namespaced, dev install": {
name: "svc1",
namespace: "ns1",
Expand Down Expand Up @@ -591,3 +632,54 @@ func TestNsNames(t *testing.T) {
assert.Equal(t, "root", NsRoot)
assert.Equal(t, "system", NsSys)
}

func TestConfigFilePath(t *testing.T) {
tests := map[string]struct {
filename string
expected Path
ok bool
}{
"cluster.conf in /etc/opensvc/": {
filename: "/etc/opensvc/cluster.conf",
expected: Path{Namespace: NsRoot, Kind: KindCcfg, Name: "cluster"},
ok: true,
},
"namespace.conf in /etc/opensvc/": {
filename: "/etc/opensvc/namespace.conf",
expected: Path{Namespace: NsRoot, Kind: KindNscfg, Name: "namespace"},
ok: true,
},
"namespace.conf in /etc/opensvc/sec/": {
filename: "/etc/opensvc/sec/namespace.conf",
expected: Path{Namespace: NsRoot, Kind: KindSec, Name: "namespace"},
ok: true,
},
"namespace.conf in /etc/opensvc/test/": {
filename: "/etc/opensvc/test/namespace.conf",
expected: Path{Namespace: "test", Kind: KindNscfg, Name: "namespace"},
ok: true,
},
"namespace.conf in /etc/opensvc/test/svc/": {
filename: "/etc/opensvc/test/svc/namespace.conf",
expected: Path{Namespace: "test", Kind: KindSvc, Name: "namespace"},
ok: true,
},
}
for testName, test := range tests {
t.Run(testName, func(t *testing.T) {
_ = testhelper.SetupEnvWithoutCreateMandatoryDirectories(testhelper.Env{
TestingT: t,
Root: "",
})
path, err := ConfigFilePath(test.filename)
if test.ok {
assert.NoError(t, err)
assert.Equal(t, test.expected.Namespace, path.Namespace)
assert.Equal(t, test.expected.Kind, path.Kind)
assert.Equal(t, test.expected.Name, path.Name)
} else {
assert.Error(t, err)
}
})
}
}
28 changes: 28 additions & 0 deletions core/object/actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,34 @@ func (t *actor) PG() *pg.Config {
return t.pg
}

func (t *actor) registerNamespacePG(ctx context.Context) error {
nscfgPath := naming.Path{
Namespace: t.path.Namespace,
Kind: naming.KindNscfg,
Name: "namespace",
}
nscfgObj, err := NewNscfg(nscfgPath, WithVolatile(true))
if err != nil {
return fmt.Errorf("new nscfg %s: %w", nscfgPath, err)
}
mgr := pg.FromContext(ctx)
if mgr != nil {
mgr.Register(nscfgObj.PGConfig())
}
return nil
}

func (t *actor) registerObjectPG(ctx context.Context) error {
if t.pg == nil {
return nil
}
mgr := pg.FromContext(ctx)
if mgr != nil {
mgr.Register(t.pg.WithLogger(t.log))
}
return nil
}

func (t *actor) init(referrer xconfig.Referrer, path naming.Path, opts ...funcopt.O) error {
if err := t.core.init(referrer, path, opts...); err != nil {
return err
Expand Down
10 changes: 9 additions & 1 deletion core/object/core_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,14 @@ func (t *actor) action(ctx context.Context, fn resourceset.DoFunc) error {
t.announceIdle(ctxWithTimeout)
return err
}
if action.PG {
if pgErr := t.registerNamespacePG(ctxWithTimeout); pgErr != nil {
t.log.Warnf("register namespace pg: %s", pgErr)
}
if pgErr := t.registerObjectPG(ctxWithTimeout); pgErr != nil {
t.log.Warnf("register object pg: %s", pgErr)
}
}
if err := t.ResourceSets().Do(ctxWithTimeout, resourceSelector, barrier, "link-"+action.Name, progressWrap(linkWrap(encapWrap(fn)))); errors.Is(err, resource.ErrBarrier) {
// pass
} else if err != nil {
Expand All @@ -770,7 +778,7 @@ func (t *actor) action(ctx context.Context, fn resourceset.DoFunc) error {
defer cancelCtxWithTimeout()

if action.Order.IsDesc() {
t.CleanPG(ctxWithTimeout)
t.PGClean(ctxWithTimeout)
}
err := t.postStartStopStatusEval(ctxWithTimeout)
if err == nil {
Expand Down
Loading
Loading