Introduce precooked project
[deliverable/lttng-ivc.git] / lttng_ivc / utils / ProjectFactory.py
CommitLineData
de9b991b
JR
1import os
2import logging
3import yaml
fe7b987e 4import pickle
de9b991b
JR
5
6import lttng_ivc.utils.project as Project
fe7b987e 7import lttng_ivc.settings as Settings
de9b991b
JR
8
9
10_logger = logging.getLogger('project.factory')
de9b991b
JR
11_project_constructor = {
12 'babeltrace': Project.Babeltrace,
13 'lttng-modules': Project.Lttng_modules,
14 'lttng-tools': Project.Lttng_tools,
15 'lttng-ust': Project.Lttng_ust,
16}
17
fe7b987e
JR
18__projects_cache = {}
19
de9b991b 20_markers = None
fe7b987e
JR
21with open(Settings.run_configuration_file, 'r') as stream:
22 # This is voluntary static across calls, no need to perform this
de9b991b
JR
23 # every time.
24 _markers = yaml.load(stream)
25
26
fe7b987e 27def get_fresh(label, tmpdir):
de9b991b
JR
28 if label not in _markers:
29 # TODO: specialized exception, handle it caller-side so the caller
30 # can decide to skip or fail test.
31 raise Exception('Label is no present')
32 marker = _markers[label]
33 constructor = _project_constructor[marker['project']]
34 path = marker['path']
35 sha1 = marker['sha1']
36 return constructor(label, path, sha1, tmpdir)
fe7b987e
JR
37
38
39def _validate_pickle(pickle, label):
40 _logger.warn("Checking validate for {} {}".format(pickle,
41 label))
42 if pickle.label != label:
43 _logger.warn("Label {} and {} are not the same".format(pickle.label,
44 label))
45 return False
46 if pickle.sha1 != _markers[label]['sha1']:
47 _logger.warn("Sha1 {} and {} are not the same".format(pickle.sha1,
48 _markers[label]['sha1']))
49 return False
50
51 deps = _markers[label]['deps']
52 if len(deps) != len(pickle.dependencies):
53 _logger.warn("Len {} and {} are not the same".format(len(deps),
54 len(pickle.dependencies)))
55 return False
56 for dep in deps:
57 if dep not in pickle.dependencies:
58 _logger.warn("Dep {} is not in {}".format(dep,
59 pickle.dependencies))
60 return False
61 else:
62 _logger.debug("Calling validate {} {}".format(pickle.dependencies[dep],
63 dep))
64 valid = _validate_pickle(pickle.dependencies[dep], dep)
65 if not valid:
66 return False
67 return True
68
69
70def get_precook(label):
71 """
72 Retrieve a precooked immutable projects from a cache if present
73 otherwise the project is built, installed and cached for future access.
74 """
75 if label not in _markers:
76 # TODO: specialized exception, handle it caller-side so the caller
77 # can decide to skip or fail test.
78 raise Exception('Label is no present')
79 marker = _markers[label]
80 constructor = _project_constructor[marker['project']]
81 path = marker['path']
82 sha1 = marker['sha1']
83 deps = marker['deps']
84
85 # Cache path for the label
86 cache_path = os.path.join(Settings.projects_cache_folder, label)
87 pickle_path = os.path.join(cache_path, label+".pickle")
88
89 # Check if Pickle Rick is present and valid. If so return it asap.
90 if os.path.exists(pickle_path):
91 with open(pickle_path, 'rb') as pickle_file:
92 pickled = pickle.load(pickle_file)
93 if _validate_pickle(pickled, label):
94 return pickled
95 else:
96 pickled.cleanup()
97 _logger.warn("Pickle for {} is invalid. Rebuilding".format(label))
98
99 project = constructor(label, path, sha1, cache_path)
100
101 for dep in deps:
102 obj_dep = get_precook(dep)
103 project.dependencies[dep] = obj_dep
104
105 project.autobuild()
106 project._immutable = True
107 with open(pickle_path, 'wb') as pickle_file:
108 pickle.dump(project, pickle_file)
109
110 return project
This page took 0.027491 seconds and 5 git commands to generate.