add motd generator script
[freebsd-maintainer-scripts/.git] / poudriere-runner.py
1 #!/usr/bin/env python3
2
3 """
4 sbz poudriere runner
5 """
6
7 import argparse
8 import configparser
9 import os
10 import shlex
11 import subprocess
12 import sys
13
14 LOCALBASE="/usr/local"
15 PORTSDIR="/usr/ports" or os.environ['PORTSDIR']
16
17 default_conf="""
18 [default]
19 debug=False
20 disk_path=%s/zfsfs
21 jails=10i386,10amd64,93amd64,93i386
22 jails_disabled=84i386,84amd64
23 mdconfig_cmd=mdconfig -f
24 cpuset=True
25 cpuset_cmd=cpuset -c -l 0-3
26
27 [84i386]
28 name=84i386
29 arch=i386
30 version=8.4-RELEASE
31
32 [84amd64]
33 name=84amd64
34 arch=amd64
35 version=8.4-RELEASE
36
37 [93i386]
38 name=93i386
39 arch=i386
40 version=9.3-RELEASE
41
42 [93amd64]
43 name=93amd64
44 arch=amd64
45 version=9.3-RELEASE
46
47 [10i386]
48 name=10i386
49 arch=i386
50 version=10.3-RELEASE
51
52 [10amd64]
53 name=10amd64
54 arch=amd64
55 version=10.3-RELEASE
56 """ % LOCALBASE
57
58 class Prunner(object):
59     def __init__(self):
60         loadDisk()
61         self._jails = loadJails()
62         self._port_trees = []
63         self.is_setup = True
64         if not self.is_setup:
65             self.setUp()
66
67     def setUp(self, **params):
68         if debug:
69             print("setup...")
70         #TODO: test if exists to avoid recreating jails
71         params['host'] = 'FREEBSD_HOST=ftp.fr.freebsd.org'
72         for jail in self._jails:
73             cmd = "poudriere jail -c -j {0} -a {1} -v {2} {3}".format(
74                 jail['name'],
75                 jail['arch'],
76                 jail['version'],
77                 params['host'])
78             if debug:
79                 print("exec: {0}".format(cmd))
80             sudo(cmd)
81
82     def tearDown(self):
83         #TODO: kill jail (stop them)
84         for jail in self._jails:
85             cmd = "poudriere jail -k -j {0}".format(jail['name'])
86             if debug:
87                 print("exec: {0}".format(cmd))
88             sudo(cmd)
89
90     @property
91     def jails(self):
92        return self._jails
93
94     @property
95     def port_trees(self):
96        return self._port_trees
97
98     def testPort(self, origin, port_tree="portsdir"):
99         for jail in self._jails:
100             if debug:
101                 print("testport o: {0}: j: {1}".format(origin, jail['name']))
102             cmd = "poudriere testport -o {0} -j {1} -p {2} -n".format(
103                     origin,
104                     jail['name'], port_tree)
105             out, err = sudo(cmd)
106             if debug:
107                 print("j: {0}, out: {1}, err: {2}".format(jail['name'], out,
108                     err))
109
110     def testAll(self):
111         for o in self.sbzports():
112             self.test_port(o)
113
114     def bulk(self, jail):
115         raise NotImplemented("not available yet")
116
117     def sbzPorts(self):
118         #TODO: don't rely on sbzports file
119         ports = open('{0}/sbzports'.format(os.path.expanduser('~%s' %
120             os.environ['USER'])), 'r').read().strip().split('\n')
121         return ports
122
123     def __del__(self):
124         if debug:
125             print("teardown()...")
126         if hasattr(self, 'is_setup') and self.is_setup:
127             self.tearDown()
128
129 def run(command, use_sudo=False):
130     cpuset_cmd = cfg.get('default', 'cpuset_cmd')
131     use_cpuset = cfg.get('default', 'cpuset')
132     if use_cpuset:
133         command = "%s %s" % (cpuset_cmd, command)
134
135     command = "sudo %s" % command if use_sudo else command
136     p = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
137     stdout, stderr = p.communicate()
138     p.wait()
139     return stdout.strip(), stderr
140
141 def sudo(command):
142     return run(command, use_sudo=True)
143
144 def loadDisk():
145     mdconfig_cmd = cfg.get('default', 'mdconfig_cmd')
146     disk_path = cfg.get('default', 'disk_path')
147     if not os.path.exists('/dev/md0'):
148         out, err = sudo("{0} {1}".format(mdconfig_cmd, disk_path))
149         if err is not None:
150             print("Error: {0}".format(out))
151             sys.exit(1)
152     return True
153
154 def loadJails():
155     jails = []
156     existing_jails = cfg.get('default', 'jails').split(',')
157     try:
158         existing_jails.remove(cfg.get('default', 'jails_disabled'))
159     except:
160         pass
161
162     for jail in existing_jails:
163         name = cfg.get(jail, 'name')
164         arch = cfg.get(jail, 'arch')
165         version = cfg.get(jail, 'version')
166         jails.append({'name': name, 'arch': arch, 'version': version})
167
168     return jails
169
170 def isValidOrigin(origin):
171     abspath = "{0}/{1}".format(PORTSDIR, origin)
172     return os.path.isdir(abspath)
173
174 def main():
175     global cfg, debug
176     cfg = configparser.ConfigParser()
177     cfg.read_string(default_conf)
178     debug = cfg.get('default', 'debug')
179     if debug:
180         print(cfg.get('default', 'disk_path'))
181
182     runner = Prunner()
183     if len(sys.argv) == 1:
184         cwd = os.getcwd()
185         origin = "{0}/{1}".format(cwd.split('/')[-2], cwd.split('/')[-1])
186     else:
187         origin = sys.argv[1]
188
189     if isValidOrigin(origin):
190         runner.testPort(origin)
191     #runner.testAll()
192
193 if __name__ == '__main__':
194     main()