-
Notifications
You must be signed in to change notification settings - Fork 0
/
releaseToProd.py
executable file
·103 lines (83 loc) · 3.12 KB
/
releaseToProd.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python
"""releaseToProd
Push staging environment to production via rsync.
Usage:
releaseToProd.py [options]
Options:
-h --help Show this screen.
-c --config YAML config file specifying source and target paths for code push
-d --dry Does not actually push code; Just show the files that would be pushed.
--version Show version.
"""
from docopt import docopt
from yaml import load as parseYAML
from subprocess import call
from os import getcwd
import os.path
import re
import sys
OPTS = docopt(__doc__, version='releaseToProd 1.0')
RSYNC = '/usr/bin/rsync'
SSH = '/usr/bin/ssh'
DEFAULT_CONFIG = os.getcwd() + '/config.yaml'
def chkOptions():
if OPTS['--config'] == None:
OPTS['--config'] = DEFAULT_CONFIG
try:
OPTS['config'] = parseYAML(open(OPTS['--config'], 'r').read())
except IOError as e:
if e.strerror == 'No such file or directory':
print "{0}: {1}".format(e.strerror, DEFAULT_CONFIG)
else:
print "I/O error({0}): {1}".format(e.errno, e.strerror)
sys.exit()
def pushCode():
for configKey in OPTS['config']:
rsync_opts = '-avz --delete -e "ssh -oStrictHostKeyChecking=no"'
if OPTS['--dry']:
rsync_opts += ' --dry-run'
p = re.compile('(.*?)\s+((.*?)@)?(.*?):(/.*)$')
(src, ignore, tUser, tHost, tPath) = p.match(configKey).groups()
if not tHost:
print >>sys.stderr, 'No target host specified for code push; skipping.'
#
# Add exclude options
#
if OPTS['config'][configKey] != None and 'excludeFiles' in OPTS['config'][configKey]:
if OPTS['config'][configKey]['excludeFiles']:
excludeStr = ""
for excludeFile in OPTS['config'][configKey]['excludeFiles']:
excludeStr += " --exclude '{}'".format(excludeFile)
rsync_opts += excludeStr
cmd = RSYNC + " {} {} ".format(rsync_opts, src)
if tUser:
cmd += tUser + '@'
if tHost:
cmd += tHost + ':'
if tPath:
cmd += tPath
if OPTS['--dry']:
print "CMD: {}\n".format(cmd)
try:
retcode = call(cmd, shell=True)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
except OSError as e:
print >>sys.stderr, "Execution failed:", e
#
# Handle Post Processes
#
if OPTS['config'][configKey] != None and 'postProcess' in OPTS['config'][configKey]:
if OPTS['config'][configKey]['postProcess']:
for postProcess in OPTS['config'][configKey]['postProcess']:
print "Running commmand: {}\n".format(postProcess)
if not OPTS['--dry']:
try:
retcode = call(postProcess, shell=True)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
except OSError as e:
print >>sys.stderr, "Execution failed:", e
if __name__ == '__main__':
chkOptions()
pushCode()