Running script automatically in vagrant - provisioning

How can I run a script automatically when vagrant is up? I used provision method. But in that method i need to point out some .sh file. I dont want to point to .sh file. I need to build the script within the Vagrantfile. Please help me to fix this issue.
I tried
Vagrant::Config.run do |config|
config.vm.provision :shell, :path => "test.sh
end
I want to append the scripts in test.sh into vagrant file directly.

You can use inline script in Vagrantfile, even Here Document which made complex shell scripts embedded in it possible.
Example:
$script = <<'EOF'
echo shell provisioning...
date -R > /etc/vagrant_provisioned_at
EOF
Vagrant.configure("2") do |config|
config.vm.provision :shell, :inline => $script
end
NOTE: single quoted LimitString is to escape special characters like or$`.
Check the Docs out => http://docs.vagrantup.com/v2/provisioning/shell.html

Related

Start Vagrant VM and start Node.js script by shell script

I installed StackEdit on Vagrant. I would like to start Vagrant and StackEdit by one click.
I created bash script:
#!/bin/bash
vagrant up
#ssh -p 2222 -i /d/stackedit/.vagrant/machines/default/virtualbox/private_key vagrant#127.0.0.1 -t '/home/vagrant/Code/start_server.sh'
start "C:\Program Files\Mozilla Firefox\firefox.exe" http://stackedit.app:5000
and start_server.sh in VM
if [ $(ps -e|grep node|wc -l) = "0" ] ; then
(export PORT=5000 && node Code/Project/public/stackedit/server.js) &
fi
sleep 5
exit 0
If I run start_server.sh via ssh manualy everything works, but when I try it with ssh in start script - now commented line - server doesn't run.
I tried copy this script to /ect/rc.local, but the result is same.
I tried add #reboot /home/vagrant/Code/start_server.sh to crontab -e too, but without success.
Can anyone help me?
My system is Windows 10. I use Git Bash.
you should put everything in your Vagrantfile
#Run provisioning
You can run your script from Vagrantfile using a shell provisioner
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "Code/start_server.sh"
end
check, you have some options by default it will run as root so you can change if you want to run your script as vagrant user
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "Code/start_server.sh", privileged: false
end
and also you can make sure you run your script everytime you boot the VM (by default it runs only once or when calling specifically the provision parameter)
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "Code/start_server.sh", run: "always"
end
#opening the website after the system is running
Vagrantfile is a ruby script so you can call any command from the file, but it will run the command immediately and in any occasion.
Then, if you want to run after the box is started, you can use the vagrant trigger and do something like
Vagrant.configure(2) do |config|
.....
config.trigger.after :up do |trigger|
trigger.run = {inline: 'system("open", "http://stackedit.app:5000"')
end
end

How to pass host environment variable to provisioning script

I have the following line in my Vagrantfile:
config.vm.provision :shell, path: "provisioning/myscript.sh"
I would like to toggle running that script based on an environment variable being set in the host (which may not be present). If the value is present and equals true I want the script skipped, otherwise it should run e.g.
if [ ENV[SKIP_MY_SCRIPT] != 'true' ]
config.vm.provision :shell, path: "provisioning/myscript.sh"
end
Or is there a better way (e.g. pass env into the script somehow)?
As Vagrantfile is mainly a ruby script, there's no bad to have conditional statement in the file.
To answer the specific question How to pass host environment variable to provisioning script (can help for other use cases) you can pass arguments like
username = `whoami`.chomp
config.vm.provision "shell", privileged: false, path: "provisioning/config-git.sh", args: "#{username}"
and in your script, you read as
#!/usr/bin/env bash
username=$1

Is it possible to send multiple commands to vagrant ssh via a shell script?

I'm on a Windows host using Git Bash to run the .sh files.
There are 4 components to my current project. To start up it on localhost, I have to:
webdriver-manager start since I'm the QA and need that running anyway
vagrant up in the project's parent folder, then close out that window (or just start the VM myself via VirtualBox UI)
vagrant ssh cd /vagrant cd "component's folder" docker-compose up x 4
grunt serve
Right now, I have a .sh file each for 1, 2, and 4, but I cannot find how to pass along multiple commands to vagrant ssh, especially since docker-compose up needs to be constantly running.
Is there a way to pass along those cds and the docker-compose?
I found the ssh documentation from vagrant which mentions something about needing to do fancy things to get it running background processes, but I have no idea what it's doing or how to implement that in a .sh file since the wording is so wishy-washy.
Also, I'm new to shell scripts in general, so if there's a smarter way to go about this to solve the issue, I'd appreciate it, too. These scripts aren't necessary, I just don't want to have to type it repeatedly every day when I'm running my tests locally.
From your Vagrantfile, have something like this
$script = <<SCRIPT
echo "running script in the VM"
cd /vagrant
cd "component's folder"
docker-compose up
cd "component's folder 2"
docker-compose up
# and add all other commands you would run from the VM
SCRIPT
Vagrant.configure(2) do |config|
....
config.vm.provision "shell", inline: $script
....
end
Note: this will run the commands as sudo (from your VM) if you want to run them as your vagrant user, just do
config.vm.provision "shell", inline: $script, privileged: "false"
If the commands needs to be invoked on vagrant up, you can provide provisioning script available on the host machine by:
config.vm.provision "shell", path: '/vagrant/scripts/provision.sh'
so Vagrant will then upload this script into the guest and execute it (using URL instead of path would also work),
Alternatively you may use inline shell syntax:
config.vm.provision "shell", inline: "echo Hello, World"
Or to run the script within VM, then try:
config.vm.provision "shell", inline: %Q(/usr/bin/env VAR=1 bash /vagrant/script.sh)
To run one-time off commands in VM, you may use vagrant ssh command for that, for example:
vagrant ssh -c "cd /vagrant && echo Hello, World"

Set VM's $PATH via Puppet config.yaml or Vagrantfile?

I would like to add an additional path to my VM's $PATH environment variable through use of my puppet config.yaml or Vagrant file (or some other VM external mechanism that I don't know).
Is this possible? If so, how?
In Vagrant you can easilly provision stuff with a shell script. So first, create a script (in the same folder than your Vagrantfile) that add additional path to $PATH. By exemple, create a file called bootstrap.sh with this content :
export PATH=$PATH:/foo/bar
# Or if you want it for all users :
echo 'PATH=$PATH:/foo/bar' >> /etc/profile
Then in your Vagrantfile, add this line to execute this script when the VM is booted :
config.vm.provision :shell, path: "bootstrap.sh"
This approach is partway there, but if for some reason you re-run provisioning on your Vagrant box, you'll end up with one of those lines in there for each time you run the provisioning. To avoid that:
grep -s -E "PATH=\$PATH:/foo/bar" /etc/profile || echo 'PATH=\$PATH:/foo/bar' >> /etc/profile
I don't know much about Chef, but Salt does a great job of creating a managed section in such files and then dealing with it on it's own. I'd be surprised if Chef doesn't do the same thing.

why doesn't vagrant provisioner modify ~/.bashrc?

How can I make the Vagrantfile append the contents of a file to the ~/.bashrc file ?
In my Vagrantfile, I am trying to append the contents of a file /vagrant/dev_env_config to the ~/.bashrc file.
When I run vagrant up it outputs the echo statement AND it outputs the expected contents of the ~/.bashrc file.... so I know it's reading the file dev_env_config and APPEARS to be appending it.
However, when I then run vagrant ssh and then cat ~/.bashrc the ~/.bashrc file is unmodified, it's the default ~/.bashrc file
In other words the mods to ~/.bashrc file are lost somewhere between when the vagrant provison runs and when I run vagrant ssh
# Vagrantfile
Vagrant.configure("2") do |config|
... various cmds to set box and network...
$install_user_vars = <<SCRIPT
sudo cat /vagrant/dev_env_config >> ~/.bashrc
echo "*** here is the .bashrc file:"
cat ~/.bashrc
SCRIPT
config.vm.provision "shell", inline: $install_user_vars
end
I think what's happening is the provisioning script is run as root (or sudo), so the "~" home location is actually /root rather than the default user home location /home/vagrant.
I can think of a couple ways to solve this:
First (and probably easiest) is to be explicit about the .bashrc path, like:
# Vagrantfile
Vagrant.configure("2") do |config|
... various cmds to set box and network...
$install_user_vars = <<SCRIPT
sudo cat /vagrant/dev_env_config >> /home/vagrant/.bashrc
echo "*** here is the .bashrc file:"
cat /home/vagrant/.bashrc
SCRIPT
config.vm.provision "shell", inline: $install_user_vars
end
The second option could be to run this part of the provisioning script as a non-privileged user. See the 'privileged' option on the Shell Scripts docs page.
A primitive solution is to set the path to .bashrc explicitly. As a rule default username of a SSH user (which will be used for vagrant ssh action) is vagrant so:
$install_user_vars = <<SCRIPT
sudo cat /vagrant/dev_env_config >> /home/vagrant/.bashrc
echo "*** here is the .bashrc file:"
cat /home/vagrant/.bashrc
SCRIPT
Also I'm not sure that it's a necessary to use a sudo command (in sudo cat ...). Probably you don't need it, but it depends on which user is used to run a provision script. I guess it's also vagrant.
So if it's really a vagrant you could leave the path to .bashrc unmodified (~/.bashrc), but have to remove sudo cat ... command and use simple cat ... instead. And it's a more clean solution in my opinion. Because actually we shouldn't use sudo (root) permissions without need.

Resources