Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Freeze or dup global state data structures #5060

Closed
c10l opened this issue Dec 24, 2014 · 9 comments
Closed

Freeze or dup global state data structures #5060

c10l opened this issue Dec 24, 2014 · 9 comments

Comments

@c10l
Copy link

c10l commented Dec 24, 2014

For some reason, two plugins are interfering with each other in a very odd manner.

Vagrant-Butcher has a method to check whether a chef-client provisioner is running as it's only relevant if so.

Vagrant-Cachier uses a similar method to learn if it needs to cache Chef cookbooks.

Vagrant has recently (I reckon on 1.7.0) made changes to that object and a fix was put in place on Butcher, but Cachier hasn't been fixed yet.

Now, for some reason, if you have both plugins installed, Butcher never does anything. Uninstalling Cachier "fixes" the problem.

More information on this bug report: c10l/vagrant-butcher#57

I reckon the internals of one plugin should not interfere on the internals of another, and I have no idea why this is happening.

Thanks!

@sethvargo
Copy link
Contributor

@cassianoleal are you able to provide debug output or any additional information? I'm not familiar with the inner workings of either of those plugins, so the possibilities for collision are endless...

@c10l
Copy link
Author

c10l commented Dec 25, 2014

Sure thing -- https://gist.github.com/Yserz/96ce0cd7e478a5b57dba

I couldn't find any useful information there though, and @Yserz was able to pinpoint the issue and monkey patch a fix through trial and error.

As far as I can tell, both my fix for Vagrant-Butcher and the monkey patch he applied on Vagrant-Cachier deal only with locally scoped variables and methods and should not have interfered with each other.

It's easy to reproduce the issue as well:

  • Install vagrant-butcher on a clean Vagrant;
  • vagrant up, then vagrant destroy a VM that uses the chef-client provisioner. You should see Butcher deleting the node and client from the Chef Server with these messages:
==> default: Chef node 'name' successfully butchered from the server...
==> default: Chef client 'name' successfully butchered from the server...

@sethvargo
Copy link
Contributor

@c10l
Copy link
Author

c10l commented Dec 25, 2014

Yes, hence the fix mentioned in the OP. That doesn't explain why cachier's lack of a fix interferes with butcher.

@sethvargo
Copy link
Contributor

@cassianoleal I believe the problem here is the use of keep_if:

[1] pry(main)> list = %w(a b c d)
=> ["a", "b", "c", "d"]
[2] pry(main)> result = list.keep_if { |i| i == "a" }
=> ["a"]
[3] pry(main)> result
=> ["a"]
[4] pry(main)> list
=> ["a"]

As you can see, keep_if is actually modifying the given object - it's an alias for select!.

Vagrant cachier should use select instead and then it won't be modifying the list of provisioners. The issue is that it's actually modifying global state in Vagrant.

@mitchellh do you think we should dup or freeze machine.config.vm.provisioners? That shouldn't be a thing that plugins should modify.

/cc @fgrehm

c10l pushed a commit to c10l/vagrant-cachier that referenced this issue Dec 25, 2014
Using [Array#keep_if](http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-keep_if) on a Vagrant core object can lead to unpredictable behaviour down the line as it modifies the object instead of creating a new one.

An example of such interference is described on c10l/vagrant-butcher#57. The problem with `keep_if` was identified by @sethvargo on this issue: hashicorp/vagrant#5060 (comment)
@c10l
Copy link
Author

c10l commented Dec 25, 2014

I guess you're right. I've opened a pull request on vagrant-cachier to replace keep_if with select: fgrehm/vagrant-cachier#135

Thanks for your help, I'll close this issue now. :)

@sethvargo
Copy link
Contributor

@cassianoleal I'm going to re-open this. There's still a "bug" here in the sense that we need to freeze or dup these mutable data structures.

@sethvargo sethvargo reopened this Dec 25, 2014
@sethvargo sethvargo changed the title Plugins interfere on each other's ability to run Freeze or dup global state Dec 25, 2014
@sethvargo sethvargo changed the title Freeze or dup global state Freeze or dup global state data structures Dec 25, 2014
@c10l
Copy link
Author

c10l commented Dec 25, 2014

Fair enough! :)

@mitchellh
Copy link
Contributor

I'd say we'll keep this a plugin issue. It is quite rare this happens and it would be hard to track down every mutable data structure. Let's just solve it on per-issue basis.

@ghost ghost locked and limited conversation to collaborators Apr 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants