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
|
#!/usr/bin/env python
import sys
import os
import base64
import re
import pipes
import optparse
SLAVE_TYPE_FILE = "/var/run/build-tools/slave-type"
SLAVE_TYPE_RESTRICTED = "restricted builds"
# sf-safe build config is written to this file
BUILD_CONFIG_FILE = "/var/run/build-tools/build-config"
class BuildConfigMismatchException(Exception):
pass
def shell_unquote(s):
# Primitive implementation, but we didn't really advertize
# support for shell quoting, and I never saw it used
if len(s) < 2:
return s
if s[0] == '"' and s[-1] == '"':
return s[1:-1]
if s[0] == "'" and s[-1] == "'":
return s[1:-1]
return s
def get_slave_type():
slave_type = ""
try:
f = open(SLAVE_TYPE_FILE)
slave_type = f.read().rstrip()
f.close()
except:
pass
return slave_type
def validate_config(config, slave_type):
"""Validate various constraints on the config params and overall
environment."""
full_job_name = os.environ.get("JOB_NAME")
owner, job_subname = full_job_name.split("_", 1)
# Deduce parameter "categories" which we can directly match
# against each other
if SLAVE_TYPE_RESTRICTED in slave_type:
slave_type_cat = "restricted"
else:
slave_type_cat = "normal"
if owner.endswith("-restricted"):
owner_cat = "restricted"
else:
owner_cat = "normal"
if config.get("BUILD_TYPE", "build-android") in ["build-android-private",
"build-android-restricted",
"build-android-toolchain-linaro-restricted",
"build-android-testsuite-restricted"]:
build_type_cat = "restricted"
else:
build_type_cat = "normal"
# Now, process few most expected mismatches in adhoc way,
# to provide better error messages
if slave_type_cat == "restricted" and owner_cat != "restricted":
raise BuildConfigMismatchException("Only jobs owned by ~linaro-android-*-restricted may run on this build slave type")
if owner_cat == "restricted" and build_type_cat != "restricted":
raise BuildConfigMismatchException("Jobs owned by ~linaro-android-*-restricted must use BUILD_TYPE=build-android-*-restricted")
# Finally, generic mismatch detection
if slave_type_cat != owner_cat or slave_type_cat != build_type_cat:
raise BuildConfigMismatchException("Incompatible slave type, job owner and build type")
def convert_config_to_shell(config_text, out_filename):
config = {}
out = open(out_filename, "w")
for l in config_text.split("\n"):
l = l.strip()
if not l or l[0] == "#":
continue
if not re.match(r"[A-Za-z][A-Za-z0-9_]*=", l):
print "Invalid build config syntax: " + l
sys.exit(1)
var, val = l.split("=", 1)
val = shell_unquote(val)
config[var] = val
out.write("%s=%s\n" % (var, pipes.quote(val)))
out.close()
return config
def main(config_in, is_base64):
if is_base64:
config_in = base64.b64decode(config_in)
config = convert_config_to_shell(config_in, BUILD_CONFIG_FILE)
try:
validate_config(config, get_slave_type())
except BuildConfigMismatchException, e:
print str(e)
sys.exit(1)
if __name__ == "__main__":
optparser = optparse.OptionParser(usage="%prog")
optparser.add_option("--base64", action="store_true", help="Process only jobs matching regex pattern")
options, args = optparser.parse_args(sys.argv[1:])
if len(args) != 1:
optparser.error("Wrong number of arguments")
main(args[0], options.base64)
|