beetboxvm / beetbox

Pre-provisioned L*MP stack
http://beetbox.rtfd.org
92 stars 19 forks source link

0.6.3: Error loading a Vagrantfile: Message: NoMethodError: undefined method `[]' for nil:NilClass #423

Closed klonos closed 7 years ago

klonos commented 7 years ago

Problem/Motivation

I started having this issue after the release of 0.6.3. After composer require --dev beet/box, I run vagrant up.

Expected behaviour

no error

Actual behaviour

I get this error:

There was an error loading a Vagrantfile. The file being loaded
and the error message are shown below. This is usually caused by
a syntax error.

Path: /Users/greg/salsa/fgb/Vagrantfile
Line number: 15
Message: NoMethodError: undefined method `[]' for nil:NilClass

This happened with vagrant 1.9.3 and was not fixed by upgrading to 1.9.6

Steps to reproduce

composer require --dev beet/box vagrant up

Proposed changes

Workaround:

If you have already run composer require --dev beet/box: Manually edit the composer.json file and set "beet/box": "0.6.2" -> run composer update -> this will downgrade you to 0.6.2 -> vagrant up

If you have not run composer require --dev beet/box: Run composer require --dev beet/box:0.6.2 instead

(kudos to @salsa-nathan for the workarounds)

thom8 commented 7 years ago

@klonos I'm not able to replicate this issue after updating this project to 0.6.3 -- https://github.com/thom8/drupal8-vagrant

Are you able to trying building this project and see if you can replicate the issue?

If so could you post the Vagrantfile which is causing the issue.

leigit commented 7 years ago

for what its worth I had the same issue with 0.6.3 which was fixed by downgrading to 0.6.2.

leigit commented 7 years ago

below is the vagrant file:

-- mode: ruby --

vi: set ft=ruby :

require 'fileutils' require 'json' require 'yaml'

Vagrant.require_version '>= 1.8.5'

beet_root = ENV['BEET_ROOT_DIR'] || "#{dir}" config_dir = ENV['BEET_CONFIG_DIR'] || "#{beet_root}/.beetbox" project_config = "#{config_dir}/config.yml" local_config = "#{config_dir}/local.config.yml" composer_conf = JSON.parse(ENV['COMPOSER'] || File.read("#{beet_root}/composer.json")) vendor_dir = ENV['COMPOSER_VENDOR_DIR'] ||= composer_conf['config']['vendor-dir'] ||= 'vendor' default_config = "#{vendor_dir}/beet/box/provisioning/ansible/config/default.config.yml" default_config = "provisioning/ansible/config/default.config.yml" if !File.exist?(default_config)

Default vagrant config.

vconfig = YAML::load_file(default_config) vconfig['beet_domain'] = beetroot.split('/').last.gsub(/[.]/, '-') + ".local"

Create config directory.

FileUtils.mkdir_p config_dir

Create config.yml from composer config.

cconfig = composer_conf['extra']['beetbox'] rescue nil File.open(project_config, "w") { |f| f.write(cconfig.to_yaml) } if cconfig.is_a?(Hash)

Create default config file.

default_config = "---\nbeet_domain: #{vconfig['beet_domain']}\n" File.open(project_config, "w") { |f| f.write(default_config) } if !File.exist?(project_config)

Copy config from host.

host_config = "#{Dir.home}/.beetbox/config.yml" if File.exist?(host_config) FileUtils.cp(host_config, "#{config_dir}/host.config.yml") end

pconfig = YAML::load_file(project_config) || nil vconfig = vconfig.merge pconfig if !pconfig.nil?

Merge local.config.yml

if File.exist?(local_config) lconfig = YAML::load_file(local_config) || nil vconfig = vconfig.merge lconfig if !lconfig.nil? end

Replace variables in YAML config.

vconfig.each do |key, value| while vconfig[key].is_a?(String) && vconfig[key].match(/{{ . }}/) vconfig[key] = vconfig[key].gsub(/{{ (.?) }}/) { |match| match = vconfig[$1] } end end

hostname = vconfig['beet_domain'] branches = ['beetbox'] current_branch = 'beetbox'

Vagrant.configure("2") do |config|

Hosts file plugins.

if Vagrant.has_plugin?('vagrant-hostsupdater') config.hostsupdater.aliases = vconfig['beet_aliases'] elsif Vagrant.has_plugin?('vagrant-hostmanager') config.hostmanager.enabled = true config.hostmanager.manage_host = true config.hostmanager.aliases = vconfig['beet_aliases'] end

Multidev config.

if vconfig['beet_mode'] == 'multidev' branches = %x(git branch | tr -d ' ').split(/\n/).reject(&:empty?) branches.unshift("beetbox") current_branch = %x(git branch | grep '' | tr -d '* \n') vconfig['vagrant_ip'] = "0.0.0.0" branch_prefix = true end

Check for plugins and attempt to install if not (Windows only).

if Vagrant::Util::Platform.windows? %x(vagrant plugin install vagrant-hostsupdater) unless Vagrant.has_plugin?('vagrant-hostsupdater') raise 'Your config requires hostsupdater plugin.' unless Vagrant.has_plugin?('vagrant-hostsupdater') if vconfig['vagrant_ip'] == "0.0.0.0" %x(vagrant plugin install vagrant-auto_network) unless Vagrant.has_plugin?('vagrant-auto_network') raise 'Your config requires auto_network plugin.' unless Vagrant.has_plugin?('vagrant-auto_network') end end

Vagrant Cachier config.

if Vagrant.has_plugin?("vagrant-cachier")

Configure cached packages to be shared between instances of the same base box.

# More info on http://fgrehm.viewdocs.io/vagrant-cachier/usage
config.cache.scope = :box
config.cache.enable :generic, { "drush" => { cache_dir: "/home/vagrant/.drush/cache" }, }
config.cache.synced_folder_opts = {
  type: :nfs,
  mount_options: ['rw', 'vers=3', 'tcp', 'nolock']
}

end

branches.each do |branch| active_node = (branch == current_branch) ? true : false config.vm.define branch, autostart: active_node, primary: active_node do |node|

  node.vm.box = vconfig['vagrant_box']
  node.vm.box_version = vconfig['vagrant_box_version']
  node.vm.hostname = (branch_prefix) ? "#{branch}.#{hostname}" : hostname
  node.ssh.insert_key = false
  node.ssh.forward_agent = true

  # Network config.
  if vconfig['vagrant_ip'] == "0.0.0.0" && Vagrant.has_plugin?('vagrant-auto_network')
    node.vm.network :private_network, :ip => "0.0.0.0", :auto_network => true
  elsif vconfig['vagrant_ip'] == "0.0.0.0"
    node.vm.network :private_network, :type => "dhcp"
  else
    node.vm.network :private_network, ip: vconfig['vagrant_ip']
  end

  # Synced folders.
  node.vm.synced_folder ".", vconfig['beet_base'],
    type: "nfs",
    id: "beetbox"

  if vconfig['beet_debug']
    node.vm.synced_folder "./provisioning", "#{vconfig['beet_home']}/provisioning",
      type: "nfs",
      id: "debug"
    debug_mode = "BEET_DEBUG=true"
  end

  if vconfig['beet_provision']
    # Provision box
    beet_sh = "#{vconfig['beet_home']}/provisioning/beetbox.sh"
    beet_profile = ENV['BEET_PROFILE'] || "#{vconfig['beet_profile']}"
    beet_sh_playbook = ENV['BEET_PLAY'] || "#{vconfig['beet_provision_playbook']}"
    beet_sh_tags = ENV['BEET_TAGS'] || "#{vconfig['beet_provision_tags']}"
    local_provision = "sudo chmod +x #{beet_sh} && #{debug_mode} BEET_PROFILE=#{beet_profile} BEET_PLAYBOOK=#{beet_sh_playbook} BEET_TAGS=#{beet_sh_tags} #{beet_sh}"
    remote_provision = "sudo apt-get -y install curl && curl -fsSL http://bit.ly/beetbuild | bash -Ee"
    node.vm.provision "ansible", type: "shell" do |s|
      s.privileged = false
      s.inline = "if [ -f #{beet_sh} ]; then #{local_provision}; else #{remote_provision}; fi"
    end
  end

  # VirtualBox.
  node.vm.provider :virtualbox do |v|
    v.name = "#{node.vm.hostname}.#{Time.now.to_i}"
    v.memory = vconfig['vagrant_memory']
    v.cpus = vconfig['vagrant_cpus']
    v.linked_clone = true
    v.customize ["modifyvm", :id,
      "--natdnshostresolver1", "on",
      "--ioapic", "on",
      "--vrde", "off"
    ]
  end

  # VMware Fusion.
  config.vm.provider :vmware_fusion do |v, override|
    override.vm.box = "ubuntu/trusty64"
    v.gui = false
    v.vmx['memsize'] = vconfig['vagrant_memory']
    v.vmx['numvcpus'] = vconfig['vagrant_cpus']
  end

  # Parallels.
  config.vm.provider :parallels do |p, override|
    override.vm.box = "parallels/ubuntu-14.04"
    p.name = "#{node.vm.hostname}.#{Time.now.to_i}"
    p.memory = vconfig['vagrant_memory']
    p.cpus = vconfig['vagrant_cpus']
    p.update_guest_tools = true
  end

end

end end

Create local drush alias.

if vconfig['drush_create_alias'] && vconfig['beet_project'] == 'drupal' && File.directory?("#{Dir.home}/.drush")

alias_file = vconfig['drush_alias_file'] || "#{Dir.home}/.drush/"+hostname+".aliases.drushrc.php" alias_file = "#{project_root}/#{vconfig['drush_alias_file']}" if vconfig['drush_alias_file']

if ARGV[0] == "destroy" File.delete(alias_file) if File.exist?(alias_file) else require 'erb' class DrushAlias attr_accessor :hostname, :uri, :key, :root def template_binding binding end end

template = <<ALIAS

<?php

$aliases['<%= @hostname %>'] = array( 'uri' => '<%= @uri %>', 'remote-host' => '<%= @uri %>', 'remote-user' => 'vagrant', 'ssh-options' => '-i <%= @key %> -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no', 'root' => '<%= @root %>', ); ALIAS

alias_file = File.open(alias_file, "w+")
da = DrushAlias.new
da.hostname = vconfig['drush_alias_name'] || hostname
da.uri = hostname
da.key = "#{Dir.home}/.vagrant.d/insecure_private_key"
da.root = vconfig['beet_web'] ||= vconfig['beet_root'] ||= vconfig['beet_base']
alias_file << ERB.new(template).result(da.template_binding)
alias_file.close

end end

Load local Vagrantfile, if exists.

include_vagrantfile_root = "#{beet_root}/Vagrantfile.local" load include_vagrantfile_root if File.exist?(include_vagrantfile_root) include_vagrantfile_conf = "#{config_dir}/Vagrantfile.local" load include_vagrantfile_conf if File.exist?(include_vagrantfile_conf)

pendashteh commented 7 years ago

Thanks @leigit! Same here. Downgrading to 0.6.2 solved the issue for now.

thom8 commented 7 years ago

Was able to replicate the issue when the project's composer.json didn't contain any config.

This should fix it -- https://github.com/beetboxvm/beetbox/commit/6d855a6da37edde28a0f3a54e74789f36156b35c

klonos commented 7 years ago

Sorry for the late reply guys. Not able to test right now. Will give this a go tomorrow at work and report back.

roflcopterDorrie commented 7 years ago

Howdy, I had a similar problem as well, found that the line vendor_dir = ENV['COMPOSER_VENDOR_DIR'] ||= composer_conf['config']['vendor-dir'] ||= 'vendor' was causing the problems. I set it to vendor_dir = 'vendor' and this solved it for me. Obviously this is just a workaround, but might be useful for debugging.

thom8 commented 7 years ago

@roflcopterDorrie this should be fixed by -- https://github.com/beetboxvm/beetbox/commit/6d855a6da37edde28a0f3a54e74789f36156b35c

Can anyone confirm this?

thom8 commented 7 years ago

As mentioned this was fixed in commit referenced above, reopen if you believe this doesn't address this issue.