-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdeploy
executable file
·165 lines (132 loc) · 4.37 KB
/
deploy
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/usr/bin/python
"""
Dirty tool to deploy config scripts.
We use this in conjunction with a git repo where every machine has its branch
"""
from argparse import ArgumentParser
from csv import reader
from os import X_OK, access, environ, makedirs, symlink, unlink
from os.path import dirname, expanduser, exists, islink, join, realpath
from shutil import rmtree
import sys
import logging
SRC = realpath(dirname(sys.argv[0]))
DST = expanduser("~")
def delconf(filename):
"""
deletes anything you ask
"""
if islink(filename):
unlink(filename)
else:
rmtree(filename)
class Deployer(object):
"""
This will deploy (or not) your config files
"""
def __init__(self, syspath, src, dst):
"""
The constructor wants:
syslog: the environment PATH variable
src: the dir where we pull files
dst: the base installation dir (likely home)
"""
self.syspath = syspath.split(':')
self.src = src
self.dst = dst
def has_exe(self, exename):
"""
If this name in the PATH?
Is the file executable?
"""
for directory in self.syspath:
searched = join(directory, exename)
if exists(searched) and access(searched, X_OK):
return True
return False
def deploy(self, exename, confsrc, confdst):
"""
unlinks previous install, which is rude.
installs new conf
exename: the exe that must exist if you want config files installation
confsrc: the place
"""
logger = logging.getLogger('%s>%s' % (exename, confsrc))
logger.debug("Processing exe: %s\tsrc: %s\tdst: %s" %
(exename, confsrc, confdst))
if not self.has_exe(exename):
logger.info('[NOT INSTALLED] (skipping)')
return
logger.info('[INSTALLED] (installing conf)')
confsrc = join(self.src, confsrc)
confdst = join(self.dst, confdst)
#wipe
if exists(confdst):
logger.debug('Removing %s' % confdst)
delconf(confdst)
#prepare if dirs don't exist
basedir = dirname(confdst)
if not exists(basedir):
logger.debug("Creating %s" % basedir)
makedirs(basedir)
#install
symlink(realpath(confsrc), confdst)
logger.debug('\t Copy done')
def parse_args():
"""
returns parsed argv
"""
parser = ArgumentParser(
description='deploys your config files the dirty way')
parser.add_argument('--sourcedir', '-s', default=SRC,
help="Conf files repository, must hold a 'conf.list' file, "
"defaults to %s" % SRC)
parser.add_argument('--destdir', '-d', default=DST,
help="Where to install, defaults to %s" % DST)
parser.add_argument('--verbose', '-v', action='store_true',
help="be verbose")
return parser.parse_args()
def read_conflist(filename):
"""
reads supplied file and yields a list of records
"""
with open(filename, 'r') as conffd:
csvreader = reader(conffd)
for index, row in enumerate(csvreader):
if not row:
continue
if row[0].startswith('#'):
continue
if len(row) != 3:
raise ValueError("Row %d has incorrect formatting: %s" %
(index + 1, ','.join(row)))
yield row
def deploy(syspath, src, dst, records):
"""
Function that does the job
"""
deployer = Deployer(syspath, src, dst)
for exename, confsrc, confdst in records:
deployer.deploy(exename, confsrc, confdst)
def main():
"""
Main function, ran when the module is executed
"""
parsed = parse_args()
level = logging.DEBUG if parsed.verbose else logging.INFO
logging.basicConfig(format="[%(name)-27s] %(message)s", level=level)
syspath = environ.get('PATH')
if not syspath:
logging.error('Needs PATH environment variable to seek exe')
sys.exit(2)
src = parsed.sourcedir
dst = parsed.destdir
conflist = realpath(join(src, 'conf.list'))
logarg = {'conflist': conflist}
if not exists(conflist):
logging.error('%(conflist)s: file not found', logarg)
sys.exit(2)
logging.debug('Reading %s', logarg)
deploy(syspath, src, dst, read_conflist(conflist))
if __name__ == '__main__':
main()