Description of problem: (This is not a dup of https://bugzilla.redhat.com/show_bug.cgi?id=1367863) Vagrant's internal algorithm for choosing a provider is more complex and powerful than just falling back to Virtualbox. By setting VAGRANT_DEFAULT_PROVIDER in /usr/bin/vagrant, Fedora short-circuits that logic unnecessarily and to the detriment of users. I think this is something that has actually changed in modern Vagrant since Fedora started setting LIBVIRT_DEFAULT_PROVIDER. At the time it may have been the best approach, but no longer. The full algorithm works like this: > 1. The --provider flag on a vagrant up is chosen above all else, if it is > present. > > 2. If the VAGRANT_DEFAULT_PROVIDER environmental variable is set, it > takes next priority and will be the provider chosen. > > 3. Vagrant will go through all of the config.vm.provider calls in the > Vagrantfile and try each in order. It will choose the first provider > that is usable. For example, if you configure Hyper-V, it will never > be chosen on Mac this way. It must be both configured and usable. > > 4. Vagrant will go through all installed provider plugins (including the > ones that come with Vagrant), and find the first plugin that reports > it is usable. There is a priority system here: systems that are known > better have a higher priority than systems that are worse. For > example, if you have the VMware provider installed, it will always > take priority over VirtualBox. > > 5. If Vagrant still has not found any usable providers, it will error. That's from https://www.vagrantup.com/docs/providers/basic_usage.html#default-provider By setting VAGRANT_DEFAULT_PROVIDER, Fedora prevents steps 3 and 4 from ever happening. This is important, because those steps would actually fall back to libvirt *automatically* on Fedora, without needing to set VAGRANT_DEFAULT_PROVIDER. As an experiment, I commented out the setting of VAGRANT_DEFAULT_PROVIDER in /usr/bin/vagrant and ran on Fedora with a completely empty Vagrantfile. It fell back to libvirt because that's what the algorithm found as a usable provider. So it already has the desirable behavior on Fedora without forcing. Why does it matter to me? I use a mix of vagrant-libvirt and vagrant-docker projects. It shouldn't be necessary to explicitly use --provider or to override VAGRANT_DEFAULT_PROVIDER in Vagrantfile. (The latter option is particularly undesirable, because Vagrantfiles are often a shared resource checked into version control, and by design are intended to work on multiple providers.) Rather Vagrant should just be doing the right thing, which it would if... Fedora would stop setting VAGRANT_DEFAULT_PROVIDER in /usr/bin/vagrant :-) Version-Release number of selected component (if applicable): 1.8.5-2.fc25 How reproducible: every time! Steps to Reproduce: 1. Make a Vagrantfile with config.vm.provider :docker 2. Run vagrant up Actual results: tries to use vagrant-libvirt Expected results: should have used vagrant-docker according to Vagrant's internal algorithm
This looks like a good idea to me. Let me test it. Thanks!
(In reply to Aron Griffis from comment #0) > > 4. Vagrant will go through all installed provider plugins (including the > > ones that come with Vagrant), and find the first plugin that reports > > it is usable. There is a priority system here: systems that are known > > better have a higher priority than systems that are worse. For > > example, if you have the VMware provider installed, it will always > > take priority over VirtualBox. > > My biggest concern is precisely this^^. We really want to prefer libvirt and we don't want to use VirtualBox neither VMware unless there is no other option. To my knowledge, there is no better way to tweak the priorities then using this env variable. > It shouldn't be necessary to explicitly use --provider or to > override VAGRANT_DEFAULT_PROVIDER in Vagrantfile. (The latter option is > particularly undesirable, because Vagrantfiles are often a shared resource > checked into version control, and by design are intended to work on multiple > providers.) You don't have to tweak Vagrantfile, you can always do: ~~~ $ export VAGRANT_DEFAULT_PROVIDER=my-favorite-provider $ vagrant up ~~~
(In reply to Aron Griffis from comment #0) > > 3. Vagrant will go through all of the config.vm.provider calls in the > > Vagrantfile and try each in order. It will choose the first provider > > that is usable. For example, if you configure Hyper-V, it will never > > be chosen on Mac this way. It must be both configured and usable. Actually this is also concern, for the same reasons as #4, since in no way I want to see people installing VirtualBox or VMware which are completely unsupported on Fedora instead of using libvirt which is first class citizen.
(In reply to Vít Ondruch from comment #3) > (In reply to Aron Griffis from comment #0) > > > 3. Vagrant will go through all of the config.vm.provider calls in the > > > Vagrantfile and try each in order. It will choose the first provider > > > that is usable. For example, if you configure Hyper-V, it will never > > > be chosen on Mac this way. It must be both configured and usable. > > Actually this is also concern, for the same reasons as #4, since in no way I > want to see people installing VirtualBox or VMware which are completely > unsupported on Fedora instead of using libvirt which is first class citizen. Out of curiosity, what is the order of preference, or place, with libvirt? Let me investigate, if we can we make it the first one(for Vagrant 1.9). That would IMHO help. Aron said that docker use-case is his 'priority'. I think we could support that. In case there is VMWare or VirtualBox installed it is not supported Vagrant use-case either way, right? (with or without the libvirt enforcing) So this change would not affect that.
Pavel/Vít, Thanks for jumping on this, I really appreciate it! Vit wrote: > We really want to prefer libvirt and we don't want to use VirtualBox > neither VMware unless there is no other option. To my knowledge, there is > no better way to tweak the priorities then using this env variable. So just to be clear, I think the situation we want is: * Vagrantfile works with libvirt or virtualbox * User runs "vagrant up" * Even if the user has virtualbox installed, libvirt gets priority and the situation I would like to avoid is: * Vagrantfile implicitly depends on foo provider * User has installed foo provider * User runs "vagrant up" * Fedora's vagrant blindly tries to use libvirt In my case foo is the docker provider, but I think the above scenario holds for Virtualbox too. If the Vagrantfile implicitly depends on Virtualbox and the user has installed Virtualbox, there's no sense in Fedora making life harder for the user. After all, the point is to help the user use vagrant-libvirt in the cases where it works, not force it on them in the cases where it doesn't. Looking at the provider plugins, it appears they are able to declare their own priority. Here's the snippet from plugins/providers/virtualbox/plugin.rb provider(:virtualbox, priority: 6) do require File.expand_path("../provider", __FILE__) Provider end It appears that libvirt doesn't set a priority provider('libvirt', parallel: true, box_optional: true) do require_relative 'provider' Provider end and the docker provider doesn't either provider(:docker, box_optional: true, parallel: true, defaultable: false) do require_relative 'provider' init! Provider end Fixing that seems like the best approach to me. Then a Vagrantfile that doesn't specify any config.vm.provider would default to libvirt, and a Vagrantfile with config.vm.provider would use the first usable match—in my case that would be docker. For the poor user that truly needs virtualbox, that scenario would work too without needing to specify --provider or VAGRANT_DEFAULT_PROVIDER
(In reply to Aron Griffis from comment #5) > provider(:virtualbox, priority: 6) do But what does this actually mean? What is the priority of provider which does not explicitly set the priority? Anyway, I'd like to see this resolved upstream ...
(In reply to Vít Ondruch from comment #6) > (In reply to Aron Griffis from comment #5) > > provider(:virtualbox, priority: 6) do > > But what does this actually mean? What is the priority of provider which > does not explicitly set the priority? I didn't get that far in my research. I'll make some time to dig further. > Anyway, I'd like to see this resolved upstream ... What are you referring to? It seems like upstream doesn't have an issue to resolve; it already works the way they intend. The issue is Fedora's, because (1) we want it to behave differently from the upstream default, (2) we're already patching for that purpose, and (3) the current patch has undesirable side effects. Possibly upstream for both vagrant and vagrant-libvirt would be interested in patches to set priorities on their provider plugins, but I'm not actually sure about that. From upstream's perspective, only their preferred plugins need priorities set. Since Fedora has different preferences, it seems like that needs to be in Fedora's patches. Did I misunderstand your statement?
(In reply to Aron Griffis from comment #7) > Possibly upstream for both vagrant and vagrant-libvirt would be interested > in patches to set priorities on their provider plugins, This was more or less my point. Based on this conversation, I think the right way would be to have a way to specify my priorities (or system wide priorities) for the providers independently of upstream desire.
(In reply to Vít Ondruch from comment #8) > Based on this conversation, I think the > right way would be to have a way to specify my priorities (or system wide > priorities) for the providers independently of upstream desire. Something like VAGRANT_PREFERRED_PROVIDERS=libvirt,docker and insert two steps in the sequence: 2.5. Vagrant will go through all of the config.vm.provider calls in the Vagrantfile and try each in order. It will choose the first provider that is usable and listed in VAGRANT_PREFERRED_PROVIDERS. 3.5. Vagrant will go through VAGRANT_PREFERRED_PROVIDERS and find the first plugin that reports it is usable. I like this solution because it cooperates elegantly with Vagrant's algorithm, and it's unlikely to cause any grief since Vagrant's algorithm remains intact. No need to patch provider plugins—this should be a pretty small patch against Vagrant proper, whether or not Vagrant upstream adopts it. (Note: I had just finished this comment when Pavel added the upstream issue, and I haven't read it yet...)
Sounds good. I have tested specifying priority setting for vagrant-libvirt and docker providers in `plugin.rb` on my system and it works as expected. I guess it could be an alternate solution. I was thinking we could specify the priority value in some vagrant or plugin config file. > 2.5. Vagrant will go through all of the config.vm.provider calls in the > Vagrantfile and try each in order. It will choose the first provider > that is usable and listed in VAGRANT_PREFERRED_PROVIDERS. I have tried to leverage setting the order in ~/.vagrant.d/Vagrantfile. The root Vagrantfile is however not able to override the order by specifying the `config.vm.provider` once more. > 3.5. Vagrant will go through VAGRANT_PREFERRED_PROVIDERS and find the first > plugin that reports it is usable. I am afraid I do not have time to implement it, but I will gladly test it when you have some patch. Thanks Aron.
(In reply to Pavel Valena from comment #10) > I am afraid I do not have time to implement it, but I will gladly test it > when you have some patch. https://github.com/mitchellh/vagrant/compare/master...agriffis:provider-priorities (It's easiest to review the three commits individually rather than looking at the entire diff at once.) In Fedora, I'd suggest having a new /etc/default/vagrant: PREFERRED_PROVIDERS=libvirt,docker Note that the docker provider marks itself as "defaultable: false" so it will never be used unless there is an explicit config stanza in Vagrantfile... this is good because the docker provider needs config to work properly. Then /usr/bin/vagrant gets these snippets: # somewhere near the top unset PREFERRED_PROVIDERS [[ -r /etc/default/vagrant ]] && source /etc/default/vagrant # replace setting of VAGRANT_DEFAULT_PROVIDER with this if [[ -z $VAGRANT_PREFERRED_PROVIDERS ]]; then export VAGRANT_PREFERRED_PROVIDERS="$PREFERRED_PROVIDERS" fi Let me know what you think!
I have commented on one commit, otherwise it looks fine to me. But I am far from Vagrant expert :). I will prepare a scratch build for testing on Fedora. However, like Vit said, it would be best if it got merged into upstream.
Pavel, thanks for reviewing and for preparing the scratch build! Regarding merging upstream, I agree. I'll open a PR to get comments.
(In reply to Aron Griffis from comment #11) > Let me know what you think! Interesting. I have never used /etc/default for anything before. And therefore I would appreciate one of these possibilities: 1) Add something like the guide from comment #11 somewhere along your changes. 2) Implement comment #11 in vagrant-installer [1]. Of course we are using our stub, but I guess upstream Vagrant users could be interested in this. Otherwise I am very positive about this change and appreciate it! [1] https://github.com/mitchellh/vagrant-installers/tree/master/substrate/launcher
(In reply to Vít Ondruch from comment #14) > (In reply to Aron Griffis from comment #11) > Interesting. I have never used /etc/default for anything before. And > therefore I would appreciate one of these possibilities: > > 1) Add something like the guide from comment #11 somewhere along your > changes. > 2) Implement comment #11 in vagrant-installer [1]. Of course we are using > our stub, but I guess upstream Vagrant users could be interested in this. I've just gotten very busy on a contract so I'm not sure when I can do this. I will try eventually, but it would be a big help if someone wants to look into what needs to be done in vagrant-installer. > Otherwise I am very positive about this change and appreciate it! Thanks Vít! I just created the upstream vagrant PR for comments: https://github.com/mitchellh/vagrant/pull/8558
The PR was merged upstream! https://github.com/mitchellh/vagrant/pull/8558 The next release, probably v1.9.7, will include support for VAGRANT_PREFERRED_PROVIDERS Now we just need Fedora's stub to set it as mentioned in comment #11. By the way, I looked at vagrant-installer as Vít mentioned in comment #14 but my first impression is that it's not a good fit for setting VAGRANT_PREFERRED_PROVIDERS since the purpose of the var is to express distro-level priorities. I think the best approach is to set it in the stub. I'll attach a patch against the current source rpm. I also took the liberty of fixing a couple spelling errors and removing an unnecessary eval.
Created attachment 1295321 [details] vagrant-1.9.1-2.fc26.diff
v1.9.7 is released! https://www.vagrantup.com/downloads.html
Pavel, will you have time to work on this? It would be nice to get it into Rawhide.
Aron, I was hoping to get whole v1.9.7 to rawhide[1], but it still needs work. Right now I do not have time to look more into it, but I hope I'll get some spare cycles soon. [1] https://bugzilla.redhat.com/show_bug.cgi?id=1427505
This is shipped with Vagrant 1.9.8 (also in F27). https://src.fedoraproject.org/rpms/vagrant/c/dfbe70f6ed7a9736ca05ef77104f65ff40ec2c7a?branch=master
Thanks again Pavel and Vít!