forked from alisw/alibuild
-
Notifications
You must be signed in to change notification settings - Fork 0
/
aliDoctor
executable file
·195 lines (179 loc) · 8.37 KB
/
aliDoctor
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#!/usr/bin/env python
import argparse
import os, re
from os.path import exists, abspath, expanduser
from glob import glob
import yaml
try:
from commands import getstatusoutput
except ImportError:
from subprocess import getstatusoutput
import logging
from alibuild_helpers.log import debug, error, banner, info, success, warning
from alibuild_helpers.log import logger_handler, logger, LogFormatter, ProgressPrint
from alibuild_helpers.utilities import getPackageList, format, detectArch, parseDefaults, readDefaults
from alibuild_helpers.utilities import dockerStatusOutput
import subprocess
def execute(command):
popen = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
lines_iterator = iter(popen.stdout.readline, "")
txt = ""
for line in lines_iterator:
if not line: break
txt += line.decode('utf-8', "ignore") # yield line
txt += popen.communicate()[0].decode('utf-8', 'ignore')
return (popen.returncode, txt)
def prunePaths(workDir):
for x in ["PATH", "LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH"]:
if not x in os.environ:
continue
workDirEscaped = re.escape("%s" % workDir) + "[^:]*:?"
os.environ[x] = re.sub(workDirEscaped, "", os.environ[x])
def checkPreferSystem(spec, cmd, homebrew_replacement, dockerImage):
if cmd == "false":
debug("Package %s can only be managed via alibuild." % spec["package"])
return (1, "")
cmd = homebrew_replacement + cmd
err, out = dockerStatusOutput(cmd, dockerImage=dockerImage, executor=execute)
if not err:
success("Package %s will be picked up from the system." % spec["package"])
for x in out.split("\n"):
debug(spec["package"] + ": " + x)
return (err, "")
warning(format("Package %(p)s cannot be picked up from the system and will be built by aliBuild.\n"
"This is due to the fact the following script fails:\n\n"
"%(cmd)s\n\n"
"with the following output:\n\n"
"%(error)s\n",
p=spec["package"],
cmd=cmd,
error="\n".join(["%s: %s" % (spec["package"],x) for x in out.split("\n")])))
return (err, "")
def checkRequirements(spec, cmd, homebrew_replacement, dockerImage):
if cmd == "false":
debug("Package %s is not a system requirement." % spec["package"])
return (0, "")
cmd = homebrew_replacement + cmd
err, out = dockerStatusOutput(cmd, dockerImage=dockerImage, executor=execute)
if not err:
success("Required package %s will be picked up from the system." % spec["package"])
debug(cmd)
for x in out.split("\n"):
debug(spec["package"] + ": " + x)
return (0, "")
error(format("Package %(p)s is a system requirement and cannot be found.\n"
"This is due to the fact that the following script fails:\n\n"
"%(cmd)s\n"
"with the following output:\n\n"
"%(error)s\n"
"%(help)s\n",
p=spec["package"],
cmd=cmd,
error="\n".join(["%s: %s" % (spec["package"],x) for x in out.split("\n")]),
help=spec.get("system_requirement_missing")))
return (err, "")
def systemInfo():
_,out = getstatusoutput("env")
debug("Environment:\n"+out)
_,out = getstatusoutput("uname -a")
debug("uname -a: "+out)
_,out = getstatusoutput("mount")
debug("Mounts:\n"+out)
_,out = getstatusoutput("df")
debug("Disk free:\n"+out)
for f in ["/etc/lsb-release", "/etc/redhat-release", "/etc/os-release"]:
err,out = getstatusoutput("cat "+f)
if not err:
debug(f+":\n"+out)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-a", "--architecture", help="force architecture",
dest="architecture", default=detectArch())
parser.add_argument("-c", "--config", help="path to alidist",
dest="configDir", default="alidist")
parser.add_argument("-w", "--work-dir", help="path to work dir",
dest="workDir", default="workDir")
parser.add_argument("-d", "--debug", help="Show also successful tests.",
dest="debug", action="store_true", default=False)
parser.add_argument("--defaults", default="release",
dest="defaults", help="Specify default to use")
parser.add_argument("--disable", dest="disable", default=[],
metavar="PACKAGE", action="append",
help="Do not build PACKAGE and all its (unique) dependencies.")
parser.add_argument("--always-prefer-system", dest="preferSystem", default=False,
action="store_true", help="Always use system packages when compatible")
parser.add_argument("--no-system", dest="noSystem", default=False,
action="store_true", help="Never use system packages")
parser.add_argument("packages", nargs="+", help="Package to test",
default=[])
parser.add_argument("--docker", dest="docker", action="store_true", default=False)
parser.add_argument("--docker-image", dest="dockerImage",
help="Image to use in case you build with docker (implies --docker-image)")
args = parser.parse_args()
if not exists(args.configDir):
parser.error("Wrong path to alidist specified: %s" % args.configDir)
prunePaths(abspath(args.workDir))
if exists(expanduser("~/.rootlogon.C")):
warning("You have a ~/.rootlogon.C notice that this might"
" interphere with your environment in hidden ways.\n"
"Please review it an make sure you are not force loading any library"
" which might interphere with the rest of the setup.")
# Decide if we can use homebrew. If not, we replace it with "true" so
# that we do not get spurious messages on linux
homebrew_replacement = ""
err, output = getstatusoutput("which brew")
if err:
homebrew_replacement = "brew() { true; }; "
dockerImage = args.dockerImage if "dockerImage" in args else ""
if args.docker and not dockerImage:
dockerImage = "alisw/%s-builder" % args.architecture.split("_")[0]
logger.setLevel(logging.BANNER)
if args.debug:
logger.setLevel(logging.DEBUG)
specs = {}
packages = []
exitcode = 0
for p in args.packages:
path = "%s/%s.sh" % (args.configDir, p.lower())
if not exists(path):
error("Cannot find recipe %s for package %s." % (path, p))
exitcode = 1
continue
packages.append(p)
systemInfo()
specs = {}
def unreachable():
assert(False)
defaultsReader = lambda : readDefaults(args.configDir, args.defaults, parser.error)
(err, overrides, taps) = parseDefaults(args.disable, defaultsReader, info)
if err:
error(err)
exit(1)
(fromSystem, own, failed) = getPackageList(packages=packages,
specs=specs,
configDir=args.configDir,
preferSystem=args.preferSystem,
noSystem=args.noSystem,
architecture=args.architecture,
disable=args.disable,
defaults=args.defaults,
dieOnError=lambda x, y : unreachable,
performPreferCheck=lambda pkg, cmd : checkPreferSystem(pkg, cmd, homebrew_replacement, dockerImage),
performRequirementCheck=lambda pkg, cmd : checkRequirements(pkg, cmd, homebrew_replacement, dockerImage),
overrides=overrides,
taps=taps,
log=info)
if fromSystem:
banner("The following packages will be picked up from the system:\n\n- " +
"\n- ".join(fromSystem) +
"\n\nIf this is not you want, you have to uninstall / unload them.")
if own:
banner("The following packages will be build by aliBuild because they couldn't be picked up from the system:\n\n- " +
"\n- ".join(own) +
"\n\nThis is not a real issue, but it might take longer the first time you invoke aliBuild.")
if failed:
banner("The following packages are system dependencies and could not be found:\n\n- "+
"\n- ".join(failed)
)
exitcode = 1
exit(exitcode)