Skip to content

Instantly share code, notes, and snippets.

@pmoranga
Forked from blech75/README.md
Created September 13, 2017 09:10
Show Gist options
  • Save pmoranga/e4cf399fd41dbe798707a29e795c833a to your computer and use it in GitHub Desktop.
Save pmoranga/e4cf399fd41dbe798707a29e795c833a to your computer and use it in GitHub Desktop.
vagrant_local_status - bash function to display name and status of vagrant machine (for use in PS1)

Vagrant Status in Your Shell Prompt

vagrant_local_status is a Bash function that returns the name and status the relevant Vagrant machine for the current directory.

The primary use case is in your PS1 environment variable, so the status of your current project's Vagrant machine is always visible at every shell prompt. Here's an example of my Bash prompt in a test project dir:

[01:29 PM]-[1506]-[justin@justin]-[~/projects/test]-[dev u= bb/dev @d59dc2d]-[vagrant:poweroff]
$

(vagrant:poweroff is the output of vagrant_local_status)

vagrant_local_status utilizes vagrant-global-status, a tool written in Go that replaces the slow execution of vagrant global-status. (This super-fast exection is what makes inclusion in the shell prompt reasonable.)

Installation

  • Download the vagrant-global-status binary and place it somewhere in your $PATH so vagrant_local_status can find it. (I prefer ~/bin for tools like this.)
  • Place the entire vagrant_local_status function definition into whichever startup file you use (.bash_profile, .profile, etc.).
  • Start a new shell (or source your startup file) and you'll then be able to run vagrant_local_status.

Usage

Called eithout any arguments, vagrant_local_status operates on the current directory. A single argument (the path to check) can be optionally passed (ex: vagrant_local_status ~/path/to/dir).

If a Vagrant machine is found for the current/passed directory or its parents, a simple status is output (vm_name:vm_status). If no Vagrant machine is defined for the directory, an empty string will be returned. If an invalid directory is passed or anything else goes wrong, an empty string will be returned.

Note: Multi-Machine Vagrant configs are not currently accounted for.

Configuring Your Prompt (PS1)

A complete example utilizing PROMPT_COMMAND can be found in my composite_ps1 function.

# outputs name and status of vagrant machine if passed path is child of a
# vagrant project
function vagrant_local_status() {
# https://github.com/monochromegane/vagrant-global-status
local VGS="vagrant-global-status"
# note: a fully resolved path (no symlinks) is required because the path that
# vagrant-global-status outputs also resolves symlinks.
local TARGET_PATH=""
# this function accepts a single (optional) argument, the path to check
# against vagrant-global-status.
if [ $# -lt 1 ]; then
# resolve symlinks of current dir
TARGET_PATH="`pwd -P`"
# check to see if the passed dir exists
elif [[ $# -eq 1 && -d $1 ]]; then
# resolve symlinks of passed dir
TARGET_PATH="$( cd $1 ; pwd -P )"
else
return 1
fi
# return immediately if we can't find the tool in $PATH
if [ "`which $VGS`" = "" ]; then
return 1
fi
# capture output of vagrant-global-status. we'll need to process it a few
# more times later.
local VAGRANT_STATUS="`$VGS`"
# extract dir paths (5th col)
local ALL_VM_PATHS=$(echo "$VAGRANT_STATUS" | awk '{ print $5 }')
# holds the path to the VM (a parent of TARGET_PATH)
local MATCHED_VM_PATH=""
# attempt to match one one of the paths with TARGET_PATH
for p in $ALL_VM_PATHS; do
# test if TARGET_PATH is a child dir of a candidate path by attempting to
# remove candidate path from begnning of TARGET_PATH, (re-)combining with
# candiate path, and checking to see if it's identical to TARGET_PATH.
if [ "${p}${TARGET_PATH##$p}" = "$TARGET_PATH" ]; then
MATCHED_VM_PATH=$p
break
fi
done
# bail if we didn't match anything
if [ "$MATCHED_VM_PATH" = "" ]; then
# this is still considered a success
return 0
fi
# holds entire status line(s). we'll process it later
local MATCHED_VM=$(echo "$VAGRANT_STATUS" | grep $MATCHED_VM_PATH)
# count the number of VMs we've matched, stripping out leading spaces from
# wc output
local NUM_VMS=$(echo $MATCHED_VM | wc -l | sed -e 's/ //g')
# FIXME: no multi-machine vagrant right now.
# https://docs.vagrantup.com/v2/multi-machine/
if [ "${NUM_VMS}" = "1" ]; then
# for the line that matches, get extract the desired status info
local VM_NAME="$(echo $MATCHED_VM | awk '{ print $2}')"
local VM_STATUS="$(echo $MATCHED_VM | awk '{ print $4}')"
# FIXME: make output more succinct. need to account for all status values
# (poweroff|running|saved|...)
echo ${VM_NAME}:${VM_STATUS}
fi
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment