Skip to content

Instantly share code, notes, and snippets.

@raypendergraph
Last active September 27, 2019 20:52
Show Gist options
  • Save raypendergraph/08e50ff48d32beb039789c3afe291305 to your computer and use it in GitHub Desktop.
Save raypendergraph/08e50ff48d32beb039789c3afe291305 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
from __future__ import print_function
import json
import subprocess
import multiprocessing
import sys
import os
import signal
import threading
'''
This script will build and run all the configured Go services. Each service is defined by a definition (directly below) which fully describe
the location and naming conventions of the service. By default the script assumes that all the services are checked out into one parent
directory and with the default name from the Git repo. This script (by default) should run in that parent directory.
**Remember** - The ports here should line up with the dev proxy configuration.
Optional json keys:
'dir' - (defaults to relative name)if you put this key in the definition with the full path of the service root then that will be used
'exe' - (defaults to name) if the executable name produced by go build is not the same as the directory, this corrects that.
'env_file' - (defaults to dev.env) An env file for service env variables.
'''
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def service_dir(svc):
return svc['dir'] if 'dir' in svc else os.path.join(os.getcwd(), svc['name'])
def read_env(env_file):
# By default each process gets a copy of the callers env, values can be added
# or overridden by providing an 'env_file' key in the service definition.
env = dict(os.environ)
if not os.path.isfile(env_file):
return env
print('Reading env file: {}'.format(env_file))
with open(env_file, 'r') as f:
lines = f.readlines()
for l in lines:
sl = l.strip()
if sl.startswith('#'):
continue
parts = sl.split('=', 1)
if len(parts) != 2:
print('Ignoring badly formatted line {}'.format(sl))
continue
k, v = parts
print(' {}={}'.format(k, v))
env[k.strip()]=v.strip()
return env
def create_svc_target(svc, notify):
def run_svc():
command = [
'./{}'.format(svc.get('exe', svc['name'])),
'-{grpc_arg}'.format(**svc),
'{grpc_port}'.format(**svc),
'-{http_arg}'.format(**svc),
'{http_port}'.format(**svc)]
svc_path=service_dir(svc)
env_file=os.path.join(svc_path, svc.get('env_file', 'dev.env'))
env = read_env(env_file)
print('Starting {} in {}'.format(' '.join(command), svc_path))
subprocess.call(command, cwd=svc_path, stderr=sys.stderr.fileno(), stdout=sys.stdout.fileno(), env=env)
return run_svc
if __name__ == '__main__':
with open('svc_config.json', 'r') as f:
config = json.load(f)
active_services = [s for s in config['services'] if s['launch'] == True]
for service in active_services:
svc_path = service_dir(service)
print('Building service {}...'.format(service['name']))
try:
subprocess.check_call(['go', 'build'], stderr=sys.stderr.fileno(), stdout=sys.stdout.fileno(), cwd=svc_path)
except:
eprint('The {} service failed to build.'.format(s['name']))
exit(-1)
svc_processes = []
def notify_terminated(signal, frame):
print('Stopping services...')
return
signal.signal(signal.SIGINT, notify_terminated)
for service in active_services:
p = multiprocessing.Process(target=create_svc_target(service, notify_terminated), name=service['name'])
p.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment