maoueh/nugrant

Default Params related error

Closed this issue · 6 comments

I have these defaults on my Vagrantfile:

config.user.defaults = {
    php: {
      folders: [],
      ports: [],
      networks: {
        private: [
          ip_address: '192.168.100.10'
        ]
      },
      cpus: 1,
      memory: 1024
    },
    ruby: {
      folders: [],
      ports: [],
      networks: {
        private: [
          ip_address: '192.168.100.20'
        ]
      },
      cpus: 1,
      memory: 1024
    }
  }

And here i define my vms:

  config.user.each do |node_id, node_config|
    config.vm.define node_id do |node|
      node_config.ports.each do |item|
        node.vm.network :forwarded_port, guest: item['guest'], host: item['host']
      end

      node_config.networks.private.each do |item|
        node.vm.network :private_network, ip: item['ip_address']
      end

      node_config.folders.each do |item|
        node.vm.synced_folder item['host'], item['guest']
      end

      node.vm.provider :virtualbox do |vb|
        vb.name = "#{node_id}-box"
        vb.cpus = node_config.cpus
        vb.memory = node_config.memory
      end

      node.vm.hostname = "#{node_id}-box.dev"
      node.vm.provision :hostmanager

      node.vm.provision :ansible do |ans|
        ans.playbook = "provisioning/#{node_id}.yml"
      end
    end
  end

The .vagrantuser file is empty.

When i run vagrant up i get this error:

Bringing machine 'php' up with 'virtualbox' provider...
Bringing machine 'ruby' up with 'virtualbox' provider...
==> php: Couldn't find Cheffile at ./Cheffile.
==> php: Clearing any previously set network interfaces...
/opt/vagrant/embedded/gems/gems/vagrant-1.6.5/lib/vagrant/util/network_ip.rb:24:in `ip_parts': undefined method `split' for nil:NilClass (NoMethodError)
    from /opt/vagrant/embedded/gems/gems/vagrant-1.6.5/lib/vagrant/util/network_ip.rb:8:in `network_address'
    from /opt/vagrant/embedded/gems/gems/vagrant-1.6.5/plugins/providers/virtualbox/action/network.rb:254:in `hostonly_config'
...

The output of the vagrant user parameters command is:

vagrant user parameters
/home/pablocrivella/.vagrant.d/gems/gems/nugrant-2.1.0/lib/nugrant/vagrant/v2/command/env.rb:5: warning: already initialized constant EnvExporter
/home/pablocrivella/.vagrant.d/gems/gems/nugrant-2.1.0/lib/nugrant/vagrant/v2/action/auto_export.rb:5: warning: previous definition of EnvExporter was here
# Vm 'php'
 All Parameters
 --------------------------------------------------
 config:
   user:
     php:
       folders: []
       ports: []
       networks:
         private:
         - :ip_address: 192.168.100.10
       cpus: 1
       memory: 1024
     ruby:
       folders: []
       ports: []
       networks:
         private:
         - :ip_address: 192.168.100.20
       cpus: 1
       memory: 1024


# Vm 'ruby'
 All Parameters
 --------------------------------------------------
 config:
   user:
     php:
       folders: []
       ports: []
       networks:
         private:
         - :ip_address: 192.168.100.10
       cpus: 1
       memory: 1024
     ruby:
       folders: []
       ports: []
       networks:
         private:
         - :ip_address: 192.168.100.20
       cpus: 1
       memory: 1024

Note the colon at the beginning of :ip_address:.

If i change that part of the defaults to use the old ruby hash syntax like this:

config.user.defaults = {
    php: {
      folders: [],
      ports: [],
      networks: {
        private: [
          'ip_address' => '192.168.100.10'
        ]
      },
      cpus: 1,
      memory: 1024
    },
    ruby: {
      folders: [],
      ports: [],
      networks: {
        private: [
          'ip_address' => '192.168.100.20'
        ]
      },
      cpus: 1,
      memory: 1024
    }
  }

I can run vagrant up with no issues.

The updated output of the vagrant user parameters command now is:

vagrant user parameters
/home/pablocrivella/.vagrant.d/gems/gems/nugrant-2.1.0/lib/nugrant/vagrant/v2/command/env.rb:5: warning: already initialized constant EnvExporter
/home/pablocrivella/.vagrant.d/gems/gems/nugrant-2.1.0/lib/nugrant/vagrant/v2/action/auto_export.rb:5: warning: previous definition of EnvExporter was here
# Vm 'php'
 All Parameters
 --------------------------------------------------
 config:
   user:
     php:
       folders: []
       ports: []
       networks:
         private:
         - ip_address: 192.168.100.10
       cpus: 1
       memory: 1024
     ruby:
       folders: []
       ports: []
       networks:
         private:
         - ip_address: 192.168.100.20
       cpus: 1
       memory: 1024


# Vm 'ruby'
 All Parameters
 --------------------------------------------------
 config:
   user:
     php:
       folders: []
       ports: []
       networks:
         private:
         - ip_address: 192.168.100.10
       cpus: 1
       memory: 1024
     ruby:
       folders: []
       ports: []
       networks:
         private:
         - ip_address: 192.168.100.20
       cpus: 1
       memory: 1024

P.S. I also had problems accessing the default params using symbols instead of strings, when i have values on the .vagrantuser file.

I thought there was an error in code for the new ruby hash syntax, but that's not the case actually. The problem here is that hashes inside arrays are not access insensitive (i.e. you cannot access the values by either using string or symbol).

This means that when accessing hashes defined in arrays, you must use (for now) the right type of key it was defined with.

So, with private: [ ip_address: '192.168.100.10' ] (or private: [ :ip_address => '192.168.100.10' ]), that means it must be retrieved like this: item[:ip_address]. And with private: [ 'ip_address' => '192.168.100.10' ], then it must be retrieved like this: item['ip_address'].

I guess the problem you had about accessing the default params using symbols instead of strings is probably related to this also, i.e. that you probably tried to access an hash contained in an array using the wrong original key type.

That being said, this is something I want to do, just not sure yet when I will implement this.

@pablocrivella Thanks for your links. I had already investigated this implementation (and two others). In general, there were two problems. First, they are usually not recursively enabling indifferent access meaning they work on the first level of keys but not deeply.

Also, I wanted to enable method access (like config.user.node[0].ip) for this project. It was sometimes problematic with some of the implementations I checked. In the end, I decided to go with a custom implementation fulfilling all my requirements.

Indifferent access was already working, just not for hashes inside arrays which were to converted to Bag (the class implementing all this). I released 2.1.3 which solves the issue.

Thank you for all your reports so far.

Best regards,
Matt

I released 2.1.2, not 2.1.3.

Great @maoueh, thank you!
My work-around until now was making everything a symbol on the params file 😅

---
:ruby:
  :memory: 2048
  :folders:
    -
      :host: /Users/pablocrivella/Workspace/rails-apps/
      :guest: /home/vagrant/apps/