chef / chef-server

Chef Infra Server is a hub for configuration data; storing cookbooks, node policies and metadata of managed nodes.
https://www.chef.io/chef/
Apache License 2.0
288 stars 209 forks source link

Add Optimistic Concurrency Control / If-Match support to Node Objects (or all DB objects) #419

Open lamont-granquist opened 8 years ago

lamont-granquist commented 8 years ago

On the server side I think this is as simple as adding the webmachine generate_etag and last_modified hooks. It looks like bookshelf already does this. If erchef did this for node objects then client code could be modified to supply an If-Match header with the Etag in the PUT request which would then get rejected by the server if the object had been updated and the tag changed.

stevendanna commented 8 years ago

We've talked about something like this in the past. I'm :+1: on the general idea.

lamont-granquist commented 8 years ago

Yeah, I have some questions about how the client could usefully leverage this, but it seems like the servers should fully support Etags as part of useful extensions to the HTTP protocol and then client-side we can figure out how they can be made useful.

rafaltrojniak commented 8 years ago

Hello @stevendanna and @lamont-granquist . I would be happy to help here, if you just guide me where to start from.

I had done some Erlang development in the past, and quite much Ruby recently when using chef.

marcparadise commented 8 years ago

@rafaltrojniak I can probably help you get started here. There are a few pieces to be modified:

All of these components are contained within the chef-server repository. Also available is an integrated development VM which should keep it relatively simple. If you're available on IRC, we can talk further this week?

rafaltrojniak commented 8 years ago

Hello @marcparadise , sorry for not responding - notification got missed between other ones.

I had grabbed the repo and tried starting vagrant. Will try to move forward in the week.

Is there any module graph/guideline so I can find proper erlang(oc_erchef) module to modify ? It looks like big codebase and I feel lost :/

marcparadise commented 8 years ago

No worries. Yeah, it's a bit of a maze when coming in fresh. I'd have to refresh my memory on where etags fit into the webmachine flow, but the components involved at minimum would be:

Another approach is to add support for If-Unmodified-Since: we already capture a last-modified time every time we update the node object. If we provide to the client via Last-Modified header and th client hands it back to us on PUT, that might make it even simpler.

lamont-granquist commented 8 years ago

Is there any common "base class" (you'll have to translate from OO speak into something that might make sense in a functional erlang world) where we could fix this for all objects and not just node objects? And I do think that while we're adding generate_etag/1 support that we should add last_modifed/1 support while we're at it.

rafaltrojniak commented 8 years ago

Hello, Just got some learning and looked-over the code

I'll dig more into the code and I plan to :

@lamont-granquist With the node Proof Of Concept I'll try to extend that to other objects (like nodes, environments and so one). I'm just afraid that because of the splitting objects (different records/modules definition for them) that will lead to some duplication, or using of complicated callbacks. But we'll see.

rafaltrojniak commented 8 years ago

I had some troubles with firing up the Vagrant box and tried to work on some eunit tests on my box. Unfortunatelly neither main project or chef_object app eunit tests fail. Any idea why ?

[ chef_objects]$ make eunit
==> chef_objects (get-deps)
==> chef_objects (compile)
src/chef_client.erl:none: undefined parse transform 'mixer'
Compiling src/chef_client.erl failed:
ERROR: compile failed while processing /.../chef-server/src/oc_erchef/apps/chef_objects: rebar_abort
Makefile:51: recipe for target 'compile' failed
make: *** [compile] Error 1