Skip to content

Instantly share code, notes, and snippets.

@carlos-jenkins
Last active May 4, 2016 18:07
Show Gist options
  • Save carlos-jenkins/92183b70b96a1613e24c41c61d4193b2 to your computer and use it in GitHub Desktop.
Save carlos-jenkins/92183b70b96a1613e24c41c61d4193b2 to your computer and use it in GitHub Desktop.
Python script that allows to run commands in the host from inside a Vagrant container using SSH
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from os import getcwd
from json import loads
from sys import argv, stdout
from shlex import split as shsplit
from os.path import expanduser, isfile, relpath, join
from subprocess import check_output, CalledProcessError, Popen, PIPE
def main():
# Determine arguments
arguments = ' '.join(argv[1:])
if not arguments:
print(
'ERROR: No command given'
)
exit(1)
# Read host information
infofile = expanduser('~/.hostinfo.json')
if not isfile(infofile):
print(
'ERROR: Host info file not found: {}'.format(infofile)
)
exit(1)
with open(infofile) as fd:
hostinfo = loads(fd.read())
user = hostinfo.get('user')
root = hostinfo.get('root')
if user is None or root is None:
print(
'ERROR: Missing data in host info file: {}'.format(infofile)
)
exit(1)
# Determine host ip
try:
cmd_ip = 'ip route | awk \'/default/ { print $3 }\''
host = check_output(
cmd_ip, shell=True
).decode('utf-8').strip()
except CalledProcessError:
print('ERROR: Unable to determine host IP address')
exit(1)
# Determine repository root
try:
cmd_git = 'git rev-parse --show-toplevel'
repo_root = check_output(
shsplit(cmd_git)
).decode('utf-8').strip()
except CalledProcessError:
print('ERROR: Unable to determine git root directory')
exit(1)
# Determine relative path from repository root
subdir = relpath(getcwd(), repo_root)
chdir = 'cd {} && '.format(join(root, subdir))
# Execute command
cmd = 'ssh -A -t {user}@{host} "{chdir}{arguments}"'.format(**locals())
print('=> Executing:')
print(cmd)
process = Popen(shsplit(cmd), stdout=PIPE, stderr=PIPE)
while True:
out = process.stdout.read(1)
if out != b'':
stdout.buffer.write(out)
stdout.flush()
elif process.poll() is not None:
break
exit(process.poll())
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment