]> git.ipfire.org Git - pakfire.git/blob - pakfire/__init__.py
Add an automatic install test to see if we could install the built packages.
[pakfire.git] / pakfire / __init__.py
1 #!/usr/bin/python
2
3 import logging
4 import os
5 import random
6 import string
7
8 import builder
9 import config
10 import depsolve
11 import distro
12 import logger
13 import packages
14 import plugins
15 import repository
16 import transaction
17
18 from constants import *
19 from errors import BuildError, PakfireError
20 from i18n import _
21
22 __version__ = PAKFIRE_VERSION
23
24
25 class Pakfire(object):
26 def __init__(self, path="/", builder=False, configs=[],
27 disable_repos=None):
28 # Check if we are operating as the root user.
29 self.check_root_user()
30
31 # The path where we are operating in
32 self.path = path
33
34 # Save if we are in the builder mode
35 self.builder = builder
36
37 if self.builder:
38 rnd = random.sample(string.lowercase + string.digits, 12)
39 self.path = os.path.join(BUILD_ROOT, "".join(rnd))
40
41 self.debug = False
42
43 # Read configuration file(s)
44 self.config = config.Config(pakfire=self)
45 for filename in configs:
46 self.config.read(filename)
47
48 # Setup the logger
49 logger.setup_logging(self.config)
50 self.config.dump()
51
52 # Load plugins
53 self.plugins = plugins.Plugins(pakfire=self)
54
55 # Get more information about the distribution we are running
56 # or building
57 self.distro = distro.Distribution(pakfire=self)
58
59 # Load all repositories
60 self.repos = repository.Repositories(pakfire=self)
61
62 # Run plugins that implement an initialization method.
63 self.plugins.run("init")
64
65 # Disable repositories if passed on command line
66 if disable_repos:
67 for repo in disable_repos:
68 self.repos.disable_repo(repo)
69
70 # Check if there is at least one enabled repository.
71 if len(self.repos) < 2:
72 raise PakfireError, "No repositories were configured."
73
74 # Update all indexes of the repositories (not force) so that we will
75 # always work with valid data.
76 self.repos.update()
77
78 def check_root_user(self):
79 if not os.getuid() == 0 or not os.getgid() == 0:
80 raise Exception, "You must run pakfire as the root user."
81
82 def check_build_mode(self):
83 """
84 Check if we are running in build mode.
85 Otherwise, raise an exception.
86 """
87 if not self.builder:
88 raise BuildError, "Cannot build when not in build mode."
89
90 def check_host_arch(self, arch):
91 """
92 Check if we can build for arch.
93 """
94
95 # If no arch was given on the command line we build for our
96 # own arch which should always work.
97 if not arch:
98 return True
99
100 if not self.distro.host_supports_arch(arch):
101 raise BuildError, "Cannot build for the target architecture: %s" % arch
102
103 raise BuildError, arch
104
105 def build(self, pkg, arch=None, resultdirs=None):
106 self.check_build_mode()
107 self.check_host_arch(arch)
108
109 if not resultdirs:
110 resultdirs = []
111
112 # Always include local repository
113 resultdirs.append(self.repos.local_build.path)
114
115 b = builder.Builder(pakfire=self, pkg=pkg)
116
117 try:
118 b.prepare()
119 b.extract()
120 b.build()
121 b.install_test()
122
123 # Copy-out all resultfiles
124 for resultdir in resultdirs:
125 if not resultdir:
126 continue
127
128 b.copy_result(resultdir)
129
130 except BuildError:
131 b.shell()
132
133 finally:
134 b.destroy()
135
136 def shell(self, pkg, arch=None):
137 self.check_build_mode()
138 self.check_host_arch(arch)
139
140 b = builder.Builder(pakfire=self, pkg=pkg)
141
142 try:
143 b.prepare()
144 b.extract()
145 b.shell()
146 finally:
147 b.destroy()
148
149 def dist(self, pkgs, resultdirs=None):
150 self.check_build_mode()
151
152 # Select first package out of pkgs.
153 pkg = pkgs[0]
154
155 b = builder.Builder(pakfire=self, pkg=pkg)
156 try:
157 b.prepare()
158 b.extract(build_deps=False)
159 except:
160 # If there is any exception, we destroy our stuff and raise it.
161 b.destroy()
162 raise
163
164 if not resultdirs:
165 resultdirs = []
166
167 # Always include local repository
168 resultdirs.append(self.repos.local_build.path)
169
170 try:
171 for pkg in pkgs:
172 # Change package of the builder to current one.
173 b.pkg = pkg
174 b.extract(build_deps=False)
175
176 # Run the actual dist.
177 b.dist()
178
179 # Copy-out all resultfiles
180 for resultdir in resultdirs:
181 if not resultdir:
182 continue
183
184 b.copy_result(resultdir)
185
186 # Cleanup all the stuff from pkg.
187 b.cleanup()
188 finally:
189 b.destroy()
190
191 def install(self, requires):
192 ds = depsolve.DependencySet(pakfire=self)
193
194 for req in requires:
195 if isinstance(req, packages.BinaryPackage):
196 ds.add_package(req)
197 else:
198 ds.add_requires(req)
199
200 ds.resolve()
201 ds.dump()
202
203 ret = cli.ask_user(_("Is this okay?"))
204 if not ret:
205 return
206
207 ts = transaction.Transaction(self, ds)
208 ts.run()
209
210 def update(self, pkgs):
211 ds = depsolve.DependencySet(pakfire=self)
212
213 for pkg in ds.packages:
214 # Skip unwanted packages (passed on command line)
215 if pkgs and not pkg.name in pkgs:
216 continue
217
218 updates = self.repos.get_by_name(pkg.name)
219 updates = packages.PackageListing(updates)
220
221 latest = updates.get_most_recent()
222
223 # If the current package is already the latest
224 # we skip it.
225 if latest == pkg:
226 continue
227
228 # Otherwise we want to update the package.
229 ds.add_package(latest)
230
231 ds.resolve()
232 ds.dump()
233
234 ret = cli.ask_user(_("Is this okay?"))
235 if not ret:
236 return
237
238 ts = transaction.Transaction(self, ds)
239 ts.run()
240
241 def provides(self, patterns):
242 pkgs = []
243
244 for pattern in patterns:
245 requires = depsolve.Requires(None, pattern)
246 pkgs += self.repos.get_by_provides(requires)
247
248 pkgs = packages.PackageListing(pkgs)
249 #pkgs.unique()
250
251 return pkgs
252
253 def repo_create(self, path, input_paths):
254 repo = repository.LocalRepository(
255 self,
256 name="new",
257 description="New repository.",
258 path=path,
259 )
260
261 for input_path in input_paths:
262 repo._collect_packages(input_path)
263
264 repo.save()