ansible-community / molecule-plugins

Collection on molecule plugins
MIT License
101 stars 67 forks source link

bug: `driver.provider.name` Overrided by `VAGRANT_DEFAULT_PROVIDER` #155

Open hswong3i opened 1 year ago

hswong3i commented 1 year ago

In case environment variable VAGRANT_DEFAULT_PROVIDER is defined (see https://www.vagrantup.com/docs/other/environmental-variables#vagrant_default_provider), our driver.provider.name will have no effect and always start with above default provider as specifiied.

With python-vagrant up() (see https://github.com/pycontribs/python-vagrant/blob/main/src/vagrant/__init__.py#L310-L318) we could specify the target provider with provider option, where our current wrapper only provide the provision option.

See https://github.com/ansible-community/molecule-vagrant/pull/174

konstruktoid commented 1 year ago

Isn't this expected behaviour? https://developer.hashicorp.com/vagrant/docs/other/environmental-variables#vagrant_default_provider: "By setting this, you will force Vagrant to use this provider for any new Vagrant environments."

hswong3i commented 1 year ago

Isn't this expected behaviour? https://developer.hashicorp.com/vagrant/docs/other/environmental-variables#vagrant_default_provider: "By setting this, you will force Vagrant to use this provider for any new Vagrant environments."

Let's reference original code (see https://github.com/hashicorp/vagrant/blob/2092df529ae73bd0ae4d01e2d35c8952b9620988/lib/vagrant/environment.rb#L319-L332):

      # Implement the algorithm from
      # https://www.vagrantup.com/docs/providers/basic_usage.html#default-provider
      # with additional steps 2.5 and 3.5 from
      # https://bugzilla.redhat.com/show_bug.cgi?id=1444492
      # to allow system-configured provider priorities.
      #
      # 1. The --provider flag on a vagrant up is chosen above all else, if it is
      #    present.
      #
      # (Step 1 is done by the caller; this method is only called if --provider
      # wasn't given.)
      #
      # 2. If the VAGRANT_DEFAULT_PROVIDER environmental variable is set, it
      #    takes next priority and will be the provider chosen.

Corresponding detail official documents (see https://developer.hashicorp.com/vagrant/docs/providers/basic_usage#default-provider):

Vagrant attempts to find the default provider in the following order:

  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.
    1. 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.
    2. 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.
    3. If Vagrant still has not found any usable providers, it will error.

With python-vagrant, it do able to specify the provider option to Vagrant CLI if it is not omitted (see https://github.com/pycontribs/python-vagrant/blob/main/src/vagrant/__init__.py#L312-L338):

    def up(
        self,
        vm_name=None,
        no_provision=False,
        provider=None,
        provision=None,
        provision_with=None,
        stream_output=False,
    ) -> Optional[Iterator[str]]:
        """
        Invoke `vagrant up` to start a box or boxes, possibly streaming the
        command output.
        vm_name=None: name of VM.
        provision_with: optional list of provisioners to enable.
        provider: Back the machine with a specific provider
        no_provision: if True, disable provisioning.  Same as 'provision=False'.
        provision: optional boolean.  Enable or disable provisioning.  Default
          behavior is to use the underlying vagrant default.
        stream_output: if True, return a generator that yields each line of the
          output of running the command.  Consume the generator or the
          subprocess might hang.  if False, None is returned and the command
          is run to completion without streaming the output.  Defaults to
          False.
        Note: If provision and no_provision are not None, no_provision will be
        ignored.
        returns: None or a generator yielding lines of output.
        """

Within our current Molecule Vagrant plugin implementation, we suppose providing provider option in molecule.yaml could take effect correctly (see https://github.com/ansible-community/molecule-plugins/blob/main/src/molecule_plugins/vagrant/driver.py#L92-L99):

    Change the provider passed to Vagrant.

    .. code-block:: yaml

        driver:
          name: vagrant
          provider:
            name: parallels

But the real behavior as mentioned in this PR, we DIDN'T pass this provider option to corresponding python-vagrant up() correctly, therefore we are now bugged with no effect :-(

apatard commented 1 year ago

as I said in the past always forcing it is wrong too. It should always be possible to not force the provider, for cases where things are "just" working. I had some commits from molecule-vagrant to do that in a "better" way (https://github.com/apatard/molecule-vagrant/commits/ensure_provider2) but I've not done an updated PR done since the vagrant CI has yet to be fixed first.

electrocucaracha commented 11 months ago

I faced with this issue, but I don't have full knowledge of this source code, so shouldn't be better to just modify this line like this

"provider": os.environ.get("VAGRANT_DEFAULT_PROVIDER", self._module.params["provider_name"]),

So VAGRANT_DEFAULT_PROVIDER var get precedence over whatever is defined on driver.provider.name