Bug 1444492 - Stop setting VAGRANT_DEFAULT_PROVIDER, it's not necessary
Summary: Stop setting VAGRANT_DEFAULT_PROVIDER, it's not necessary
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: vagrant
Version: 25
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Pavel Valena
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On: 1427505
Blocks:
TreeView+ depends on / blocked
 
Reported: 2017-04-21 12:47 UTC by Aron Griffis
Modified: 2017-09-27 12:03 UTC (History)
6 users (show)

Fixed In Version: vagrant-1.9.8-1.fc28
Clone Of:
Environment:
Last Closed: 2017-09-27 10:47:05 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
vagrant-1.9.1-2.fc26.diff (3.04 KB, patch)
2017-07-07 14:00 UTC, Aron Griffis
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Github mitchellh vagrant pull 8558 0 None None None 2017-05-10 13:37:51 UTC
Github vagrant-libvirt vagrant-libvirt issues 773 0 None None None 2017-05-02 10:56:17 UTC

Description Aron Griffis 2017-04-21 12:47:25 UTC
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

Comment 1 Pavel Valena 2017-04-21 13:00:17 UTC
This looks like a good idea to me. Let me test it.

Thanks!

Comment 2 Vít Ondruch 2017-04-21 13:14:20 UTC
(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
~~~

Comment 3 Vít Ondruch 2017-04-21 13:19:38 UTC
(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.

Comment 4 Pavel Valena 2017-04-21 13:36:53 UTC
(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.

Comment 5 Aron Griffis 2017-04-23 01:51:29 UTC
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

Comment 6 Vít Ondruch 2017-04-24 08:01:45 UTC
(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 ...

Comment 7 Aron Griffis 2017-04-24 19:56:55 UTC
(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?

Comment 8 Vít Ondruch 2017-04-25 06:31:23 UTC
(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.

Comment 9 Aron Griffis 2017-05-02 12:00:29 UTC
(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...)

Comment 10 Pavel Valena 2017-05-02 12:46:06 UTC
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.

Comment 11 Aron Griffis 2017-05-02 21:28:41 UTC
(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!

Comment 12 Pavel Valena 2017-05-03 09:27:18 UTC
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.

Comment 13 Aron Griffis 2017-05-03 12:23:23 UTC
Pavel, thanks for reviewing and for preparing the scratch build!

Regarding merging upstream, I agree. I'll open a PR to get comments.

Comment 14 Vít Ondruch 2017-05-03 14:17:45 UTC
(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

Comment 15 Aron Griffis 2017-05-04 15:30:03 UTC
(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

Comment 16 Aron Griffis 2017-07-07 13:59:21 UTC
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.

Comment 17 Aron Griffis 2017-07-07 14:00:19 UTC
Created attachment 1295321 [details]
vagrant-1.9.1-2.fc26.diff

Comment 18 Aron Griffis 2017-07-09 00:12:03 UTC
v1.9.7 is released! https://www.vagrantup.com/downloads.html

Comment 19 Aron Griffis 2017-07-24 17:33:56 UTC
Pavel, will you have time to work on this? It would be nice to get it into Rawhide.

Comment 20 Pavel Valena 2017-07-24 17:56:39 UTC
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

Comment 21 Pavel Valena 2017-09-27 10:47:05 UTC
This is shipped with Vagrant 1.9.8 (also in F27).

https://src.fedoraproject.org/rpms/vagrant/c/dfbe70f6ed7a9736ca05ef77104f65ff40ec2c7a?branch=master

Comment 22 Aron Griffis 2017-09-27 12:03:29 UTC
Thanks again Pavel and Vít!


Note You need to log in before you can comment on or make changes to this bug.