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