how to check if vagrant machine is running through the shell - shell

I am new to Vagrant and almost new to Linux. I am practicing to learn about vagrant and so I have a vagrantfile which starts 3 machines, the first machine executes a shell script as provision method but, some the last 2 commands need to be executed just when the other 2 machines are up, so it will need to skip these commands and go back to then when the other 2 machines are up... I have gone through Vagrant documentation and I have not been able to find if this is possible to do. Is there any way to do this?

Maybe is there a more "robust" solution, but im using:
vagrant status | grep "is running"

Related

Are Vagrant shell provisioner scripts idempotent or OTO?

I want to write a Vagrantfile and accompanying shell script so that the script runs/executes only the very 1st time a user executes a vagrant up for that VM. That's because this shell script will install all sorts of system services that should only happen one time.
According to the shell provisioner docs, it looks like I might be able to do something like:
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "init-services.sh"
end
However, from the docs I can't tell if init-services.sh will be executed every time a user does a vagrant up (in which case I need to write it carefully so as to be idempotent), or whether it truly only executes the script one time, when the box is first being provisioned.
And, if it does only execute the script one time, then how does Vagrant handle updates to the script (if we want to, say, add a new service to the machine)?
However, from the docs I can't tell if init-services.sh will be executed every time a user does a vagrant up (in which case I need to write it carefully so as to be idempotent), or whether it truly only executes the script one time, when the box is first being provisioned.
yes the script will be executed only at the first time the machine is spinned up during the vagrant up. There is an option is you want to run it everytime (even though its not something you want in this case)
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "init-services.sh", :run => 'always'
end
And, if it does only execute the script one time, then how does Vagrant handle updates to the script (if we want to, say, add a new service to the machine)?
There are 2 commands you can use for this:
A specific call to vagrant provision will still force the script to run wether the machine has already been initialized or not.
Calling vagrant up --provision when spining an existing VM will run the provisioning script
on this point though vagrant will not check what are the update in your script, it will just run the whole script again; if you need to run just a specific update you will need to manage this yourself in your script file.
You can read a bit more about how the provisioning work in the doc

How to pass a script to a Windows 8 Vagrant box from the Mac command line?

I'm running a Windows 8.1 guest on a Mac OSX 10.11 host, via Vagrant. I want to pass in a script to this guest via command-line. If the guest were Unix-based, I could just do vagrant ssh -c "$THE_SCRIPT" my-unix-box and call it a day. When I try for the Windows guest, I'm told that the command bash does not exist.
However, I can vagrant ssh into the Windows guest without specifying a command just fine. The resulting shell is cmd, not PowerShell or Bash or similar.
How can I execute a script on a guest Windows Vagrant box (from an OS X host) by passing it in on the command line? Vagrantfile configuration, guest software to install, or similar. I'm not picky about which shell ultimately runs my script.
It turns out you can pass the script to vagrant with double-dash separation, like so:
WINDOWS_THINGS="..."
vagrant ssh windowsBox -- "$WINDOWS_THINGS"
In my case, this will run the contents of WINDOWS_THINGS as a cmd script. I guess the interpreter used depends on the underlying box, but whatever the case this solved my problem. Someone on IRC suggested this to me, and unfortunately I don't remember their name. But, if you're reading this, thank you!

Vagrant: How can you run scripts on the host via commands in the guest shell?

It's possible to open ports, network files, and there are plug-ins that allow for running guest or host [shell] commands during Vagrant's Provisioning process.
What I'd like to do is be able to (perhaps through a bash alias) run a command in the Vagrant guest/VM, and have this execute a command on the host, ideally with a variable being passed on the command line.
Example: In my host I run the Atom editor (same applies to TextMate, whatever). If I want to work on a shared file in the VM, I have to manually open that file from over in the host, either by opening it directly in the editor, or running the 'atom filename' shell command.
I want parity, so while inside the VM, I can run 'atom filename', and this will pass the filename to the 'atom $1' script outside of the VM, in the host, and open it in my host editor (Atom).
Note: We use Salt for Vagrant Provisioning, and NFS for mounting, for what it's worth. And of course, ssh with key.
Bonus question: Making this work with .gitconfig as its merge conflict editor (should just work, if the former is possible, right?).
This is a very interesting use case that I haven't heard before. There isn't a native method of handling this in Vagrant, but this functionality was added to Packer in the form of a local shell provisioner. You could open a GitHub issue on the Vagrant project and propose the same feature. Double check the current list of issues, though, because it's possible someone has beaten you to it.
In the meantime, though, you do have a workaround if you're determined to do this...
Create an ssh key pair on your host.
Use Salt to add the private key in /home/vagrant/.ssh on the box.
Use a shell provisioner to run remote ssh commands on the host from the guest.
These commands would take the form of...
ssh username#192.168.0.1 "ls -l ~"
In my experience, the 192.168.0.1 IP always points back to the host, but your mileage may vary. I'm not a networking expert by any means.
I hope this works for you and I think a local shell provisioner for Vagrant would be a reasonable feature.

How to tell if I am inside a Vagrant host?

Whats a bulletproof way to determine if I am running inside a vagrant machine?
Guest OS is Debian Linux, though if there are indicators per-os that would be great to have documented as well.
AFAIK, there isn't a way outside of your own customizations. One idea that comes to mind is to touch a file that you then reference from your apps. Add something like config.vm.provision "shell", inline: "touch /etc/is_vagrant_vm" to the bottom of your Vagrantfile and base your conditionals around the existence of that file.
Provisioning a file that you can check the existence of seems like the most reliable way to handle this.
Another option if you don't want to write files to the box would be to check for the existence of the vagrant user itself:
grep -q '^vagrant:' /etc/passwd && echo 'Vagrant environment: true'
This is not foolproof as others have indicated, and it is possible (although uncommon) to have a vagrant box that uses a different user to connect as.
Checking the user's existence also would not work reliably if you have machines in your environment with a user account called vagrant that are not actually vagrant boxes, but that would also be fairly uncommon.
I don't know if there is any bulletproof way for this, but one thing I often do is to config my vagrant environment's shell UI to be different from the shell UI of my host machine. This way I can tell the difference at first glance. It also helps if you want to distinguish among multiple vagrant environments.
To customize the shell UI, oh-my-zsh will come in handy.
Assuming you don't run a vagrant instance in your vagrant instance:
if which vagrant > /dev/null 2>&1; then
echo "This is most likely the host"
fi
You can use facter
facter | grep vagrant
This is how I was able to answer the question with a very small chunk of bash. The -e flag checks if the file exists. Change provision to a file path that makes sense for your build.
#!/usr/bin/env bash
user=$USER
provision=/vagrant/Vagrantfile
if [ -e $provision ]
then
echo "Vagrantfile found..."
echo "Setting $user to vagrant..."
user=vagrant
fi
# Example usage
cd /home/$user
Tested on "centos/7"
In vagrant your are in control of which IP you are running against, so you could change it to for example 192.168.0.10
Then:
curl localhost:8080/health => in local e.g spring-boot
curl 192.168.0.10:8080/health => in vagrant
NOTE: /health assumes spring-boot but you could also use your own implementation of a /health endpoint as well

Chef knife winRM interactive mode hangs in Jenkins

I've been stuck on this issue for the past 3 or 4 days. I am trying to run the attached command in a Windows batch file in Jenkins. This causes it to hang and it doesn't accept any further inputs:
knife winrm ec2-xx-xx-xx-xx.compute-1.amazonaws.com interactive -m -x Administrator -P xxxxxxxx
This works fine if run manually on a Windows machine, but I think the ruby.exe that is being opened is starting to cause Jenkins some problems.
Has anyone ever used knife winRM's interactive mode in such a way before? I'm at my wits end here and I really need this to work. Thank you for any help you could provide.
Have you tried running it as "call knife" instead of just "knife"? If, inside a batch file, you run another batch file (knife.bat, for example) without "call", the initial batch file run is terminated. There's a good explanation here: http://www.robvanderwoude.com/call.php

Resources