Vagrant/Virtualbox Vm Provisioning: Rbenv Installs Successfully But Subsequent Uses in Script Fail

Vagrant/VirtualBox VM provisioning: rbenv installs successfully but subsequent uses in script fail

I had a similar problem because I was trying to install rbenv and the vagrant provisioning was giving me the error:

==> default: /tmp/vagrant-shell: line 10: rbenv: command not found

First of all, it is very important to understand that vagrant provisioning script is running in sudo mode.
So, when in the script we refer to ~/ path, we are referring to /root/ path and not to /home/vagrant/ path.
The problem is that I was installing rbenv for the root user and after trying to call rbenv command from a vagrant user and, of course, it didn't work!

So, what I did is specify the vagrant to run the provisioner NOT in sudo user, adding privileged: false:

config.vm.provision :shell, privileged: false, inline: $script

Then in my script I considered everything as being called from the vagrant user.
Here @Casper answer helped me a lot, because it works only specifying:
sudo -H -u vagrant bash -i -c '......'

Since you just updated .bashrc with a new path and other settings, you
will want to run "sudo bash" with the -i option. This will force bash
to simulate an interactive login shell, and therefore read .bashrc and
load the correct path for rbenv.

Below is my final Vagrantfile.

# -*- mode: ruby -*-
# vi: set ft=ruby :

$script = <<SCRIPT
sudo apt-get -y update
sudo apt-get -y install curl git-core python-software-properties ruby-dev libpq-dev build-essential nginx libsqlite3-0 libsqlite3-dev libxml2 libxml2-dev libxslt1-dev nodejs postgresql postgresql-contrib imagemagick

git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc

git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
sudo -H -u vagrant bash -i -c 'rbenv install 2.1.3'
sudo -H -u vagrant bash -i -c 'rbenv rehash'
sudo -H -u vagrant bash -i -c 'rbenv global 2.1.3'
sudo -H -u vagrant bash -i -c 'gem install bundler --no-ri --no-rdoc'
sudo -H -u vagrant bash -i -c 'rbenv rehash'
sudo -u postgres createdb --locale en_US.utf8 --encoding UTF8 --template template0 development
echo "ALTER USER postgres WITH PASSWORD \'develop\';" | sudo -u postgres psql
SCRIPT

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "hashicorp/precise64"
config.vm.network "forwarded_port", guest: 3000, host: 3000

# config.vm.provider :virtualbox do |vb|
# vb.customize ["modifyvm", :id, "--memory", "1024"]
# end

config.vm.provision :shell, privileged: false, inline: $script
end

Hope it will be helpful to someone else.

Vagrant provisioning - installing ruby version on rbenv fails

OK so after some digging I found this info on official ruby-build github page

So since I wanted to use provisioning and didn't want users to install anything by them own I added to Berksfile this cookbook:

cookbook 'libffi-dev', git: 'https://github.com/zchee/libffi-dev-cookbook'

abd to Vagrantfile this line:

chef.add_recipe "libffi-dev"

right after line with apt.

The whole project is here if anyone would like to play with it.

Error To Upload File Via Vagrant on Linux to Virtual Machine Windows Server

I followed vahdet guidance: I read github.com/hashicorp/vagrant/issues/7435 and did some workarounds:

  1. replace file provision destination "/tmp" by "C:\tmp"
  2. I upload the "PHP_ZEND.zip" file to a NEXUS server then downloaded to the VM by a powershell script provisioned by the vagrant script.

I did the second point because the VM was forced to shutdown and auto-destroy when the script was running the provision for the zip file.

That solved the problem.

Vagrant starts but cannot connect until I do a 'force provision'

Might just be my own setup - but I noticed nginx was restarting so have to restart this each time

Shell provisioning in a multi-machine vagrantfile

You need to replace:

kitcore.provision 

by

kitcore.vm.provision

Do the same for the vm called agent.

Vagrant Provisioning Error

I managed to resolve the problem.

The issue was related to the DNS cache which was populated with the DNS table of the VPN software I was running on my Macbook.

I rebooted my Macbook and the issue was resolved immediately as the DNS cache was reset.

I looked up online later and found that a hard reset such as rebooting the laptop was not necessary, although it is the standard practice followed by most when troubleshooting such issues in the presence of a VPN software.

One can also do a soft reset by flushing the DNS. There is a good tutorial as how one can do this on Windows, Mac or Linux on Wikihow

execute commands as user after Vagrant provisioning

You should be able to do this using the Vagrant Shell provisioner, e.g.

Vagrant.configure("2") do |config|
$script = <<-SCRIPT
rbenv install 2.0.0-p353
rbenv global 2.0.0-p353
gem update --system
yes | gem update
gem install rdoc
gem install rails pg
SCRIPT

config.vm.provision "shell", inline: $script, privileged: false
end

The key is to specify privileged: false so that it will use the default user and not root.

Vagrant machine wont run SED correctly - How to escape backslashes in Vagrant shell scripts

The issue turns out to be more complex than you would think. The problem is that you have three stages of string interpolation going on here. Each stage needs strings and backslashes escaped properly in order for the final sed command to be correct:

  1. Ruby does string interpolation on the heredoc <<-SHELL string.
  2. The shell under which the script is executed does its own interpolation.
  3. Sed does its own interpolation on the regular expression you provide.

Let's work backwards starting from stage 3, so that we know what the end requirements are before we begin with the other stages.

Stage 3 - Sed

We know that sed requires the backslash to be escaped in its regular expression. So the sed command needs the following string s/\\/ /.

The question then becomes: how do we feed exactly that string to sed?

Stage 2 - The Shell

We KNOW we have to feed two backslashes to sed. Let's run some test in the shell and see how it escapes backslashes:

$ echo "\\"
\

Aha. It turns out the shell (bash) interpolates backslashes inside double quotes. What about single quotes?

$ echo '\\'
\\

Well that's useful. It means we can use single quotes to prevent backslash interpolation in Bash.

Let's test it:

$ echo '\\' | sed -E 's/\\/X/'
X\

It seems to work. Note that if you want to replace all backslashes, you need to use the g modifier:

$ echo '\\' | sed -E 's/\\/X/g'
XX

Ok. It seems we have gathered all the puzzle pieces for moving to stage 1.

Stage 1 - Ruby

In Ruby the heredoc <<-SHELL operator does its own string interpolation. Therefore backslashes need to be escaped.

Let's test it in irb:

> puts <<-SHELL
sed -E 's/\\\\/ /' ...
SHELL

sed -E 's/\\/ /' ...

Looks good!

What we learned so far:

  1. Ruby heredoc <<-SHELL requires backslashes to be escaped.
  2. The shell (Bash or sh), requires backslashes to be escaped, unless single quotes are used.
  3. Sed needs two backslashes.

Now we can assemble our script properly:

node.vm.provision :shell, privileged: false, inline: <<-SHELL
...
sed -i -E 's/\\\\/ /' /vagrant/control_join_file#{i + 12}.sh
...
SHELL


Related Topics



Leave a reply



Submit