engine: Add a mapper function for comparing two res graphs
This gives us a simple mapping between a new resource and an old one. We compare by kind and name because those two values are our uniqueness constraint in the resource graphs.
This commit is contained in:
@@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/purpleidea/mgmt/pgraph"
|
"github.com/purpleidea/mgmt/pgraph"
|
||||||
|
"github.com/purpleidea/mgmt/util/errwrap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResCmp compares two resources by checking multiple aspects. This is the main
|
// ResCmp compares two resources by checking multiple aspects. This is the main
|
||||||
@@ -341,3 +342,55 @@ func EdgeCmpFn(e1, e2 pgraph.Edge) (bool, error) {
|
|||||||
}
|
}
|
||||||
return edge1.Cmp(edge2) == nil, nil
|
return edge1.Cmp(edge2) == nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResGraphMapper compares two graphs, and gives us a mapping from new to old
|
||||||
|
// based on the resource kind and name only. This allows us to know which
|
||||||
|
// previous resource might have data to pass on to the new version in the next
|
||||||
|
// generation.
|
||||||
|
// FIXME: Optimize this for performance since it runs a lot...
|
||||||
|
func ResGraphMapper(oldGraph, newGraph *pgraph.Graph) (map[RecvableRes]RecvableRes, error) {
|
||||||
|
mapper := make(map[RecvableRes]RecvableRes) // new -> old based on name and kind only?
|
||||||
|
cmp := func(r1, r2 Res) error {
|
||||||
|
if r1.Kind() != r2.Kind() {
|
||||||
|
return fmt.Errorf("kind differs")
|
||||||
|
}
|
||||||
|
if r1.Name() != r2.Name() {
|
||||||
|
return fmt.Errorf("name differs")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: run this as a topological sort or reverse topological sort?
|
||||||
|
for v := range newGraph.Adjacency() { // loop through the vertices (resources)
|
||||||
|
r, ok := v.(RecvableRes)
|
||||||
|
if !ok {
|
||||||
|
continue // skip
|
||||||
|
}
|
||||||
|
fn := func(vv pgraph.Vertex) (bool, error) {
|
||||||
|
rr, ok := vv.(Res)
|
||||||
|
if !ok {
|
||||||
|
return false, fmt.Errorf("not a Res")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cmp(rr, r); err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
vertex, err := oldGraph.VertexMatchFn(fn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errwrap.Wrapf(err, "VertexMatchFn failed")
|
||||||
|
}
|
||||||
|
if vertex == nil {
|
||||||
|
continue // skip (error?)
|
||||||
|
}
|
||||||
|
res, ok := vertex.(RecvableRes)
|
||||||
|
if !ok {
|
||||||
|
continue // skip (error?)
|
||||||
|
}
|
||||||
|
|
||||||
|
mapper[r] = res
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapper, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user