engine: Improve the way we make a unique res path token

This is needed in the state directory.
This commit is contained in:
James Shubin
2019-09-06 03:30:55 -04:00
parent 011b496b3f
commit 34d572c523
2 changed files with 20 additions and 2 deletions

View File

@@ -25,6 +25,7 @@ import (
"github.com/purpleidea/mgmt/converger"
"github.com/purpleidea/mgmt/engine"
engineUtil "github.com/purpleidea/mgmt/engine/util"
"github.com/purpleidea/mgmt/pgraph"
"github.com/purpleidea/mgmt/util/errwrap"
"github.com/purpleidea/mgmt/util/semaphore"
@@ -180,8 +181,7 @@ func (obj *Engine) Commit() error {
return errwrap.Wrapf(err, "the Res did not Validate")
}
// FIXME: is res.Name() sufficiently unique to use as a UID here?
pathUID := fmt.Sprintf("%s-%s", res.Kind(), res.Name())
pathUID := engineUtil.ResPathUID(res)
statePrefix := fmt.Sprintf("%s/", path.Join(obj.statePrefix(), pathUID))
// don't create this unless it *will* be used

View File

@@ -23,6 +23,7 @@ import (
"encoding/base64"
"encoding/gob"
"fmt"
"os"
"os/user"
"reflect"
"strconv"
@@ -62,6 +63,23 @@ const (
DBusSignalJobRemoved = "JobRemoved"
)
// ResPathUID returns a unique resource UID based on its name and kind. It's
// safe to use as a token in a path, and as a result has no slashes in it.
func ResPathUID(res engine.Res) string {
// res.Name() is NOT sufficiently unique to use as a UID here, because:
// a name of: /tmp/mgmt/foo is /tmp-mgmt-foo and
// a name of: /tmp/mgmt-foo -> /tmp-mgmt-foo if we replace slashes.
// As a result, we base64 encode (but without slashes).
name := strings.Replace(res.Name(), "/", "-", -1) // TODO: use ReplaceAll in 1.12
if os.PathSeparator != '/' { // lol windows?
name = strings.Replace(name, string(os.PathSeparator), "-", -1) // TODO: use ReplaceAll in 1.12
}
b := []byte(res.Name())
encoded := base64.URLEncoding.EncodeToString(b)
// Add the safe name on so that it's easier to identify by name...
return fmt.Sprintf("%s-%s+%s", res.Kind(), encoded, name)
}
// ResToB64 encodes a resource to a base64 encoded string (after serialization).
func ResToB64(res engine.Res) (string, error) {
b := bytes.Buffer{}