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