purpleidea / mgmt

Next generation distributed, event-driven, parallel config management!
https://purpleidea.com/tags/mgmtconfig/
GNU General Public License v3.0
3.47k stars 308 forks source link

engine: resources: file: Add File -> Owner/Group Auto Edges #764

Open cianyleow opened 1 month ago

cianyleow commented 1 month ago

Adds auto edges between a file resource and relevant user/group resources if they are defined as an owner/group of the file.

purpleidea commented 1 month ago

Okay, here is what I think is happening, and also a suggestion on how to approach the problem.

Firstly, the file resource already does a good amount of fancy autoedges stuff. This is because it makes edges both with directories, and also with "fragments". (You don't need to know what fragments are.)

The way AutoEdges roughly works, is that a resource kind can have an AutoEdges method:

func (obj *FileRes) AutoEdges() (engine.AutoEdge, error)

which returns a struct that has some magic machinery that we can run to build autoedges...

The problem is that you've added on some user and group data into the existing autoedge machinery, but that machinery was not ever expecting to be able to run that...

It likely fails because it ends as soon as the obj.data matches successfully once! See here:

https://github.com/purpleidea/mgmt/blob/201cf091d53e595966c0895f6dacd4da49ee7f4a/engine/resources/file.go#L1408

...this probably ends the whole process early!

So how would I fix this or approach this?

Firstly to get some confidence in the AutoEdges API, I'd try implementing this for just group. (User is slightly harder.)

Secondly instead of having the File resource machinery point to the User/Group, you can instead have the User/Group machinery point to the file! I suspect this might be slightly easier. The User already has machinery, but the Group doesn't, which is why I said it might be easier.

Seeing how the "machinery" works might be interesting... Basically it's a back and forth conversation where the AutoEdges engine asks (via Next()) hey, are there some things I should try? and after they are tried, the engine tells the machinery (via Test()) which of those worked!

Using the obj.data tries one at a time, where as you likely want to try all of the edges you built together...

Alternate future things to think about:

If @frebib lands his autoedges patch, things might change a bit. So getting that in first is ideal, but we won't block on that.

We could also consider changing the API to instead be:

func (obj *FileRes) AutoEdges() ([]engine.AutoEdge, error) # note this is a list of machinery now

but I don't think that's needed yet.

I hope this helped, please let me know if you have more questions!