]> git.ipfire.org Git - people/stevee/pakfire.git/blame - pakfire/base.py
Add search attributes to _pakfire.so module.
[people/stevee/pakfire.git] / pakfire / base.py
CommitLineData
47a4cb89
MT
1#!/usr/bin/python
2
7c8f2953
MT
3import logging
4import os
5import random
6import string
7
18edfe75 8import builder
53bb7960 9import config
7c8f2953
MT
10import distro
11import logger
53bb7960 12import repository
ae20b05f 13import packages
c605d735 14import satsolver
7c8f2953
MT
15import util
16
7c8f2953 17from constants import *
7c8f2953
MT
18from i18n import _
19
7c8f2953 20class Pakfire(object):
ae20b05f
MT
21 def __init__(self, builder=False, configs=[], enable_repos=None,
22 disable_repos=None, distro_config=None):
7c8f2953
MT
23 # Check if we are operating as the root user.
24 self.check_root_user()
25
3ad4bb5a
MT
26 config_type = None
27
7c8f2953
MT
28 # The path where we are operating in.
29 if builder:
3ad4bb5a 30 config_type = "builder"
7c8f2953
MT
31 self.builder = True
32 self.path = os.path.join(BUILD_ROOT, util.random_string())
33 else:
34 self.builder = False
35 self.path = "/"
36
37 # XXX check if we are actually running on an ipfire system.
38
39 # Read configuration file(s)
3ad4bb5a 40 self.config = config.Config(type=config_type)
7c8f2953
MT
41 for filename in configs:
42 self.config.read(filename)
43
44 # Setup the logger
45 logger.setup_logging(self.config)
46 self.config.dump()
47
48 # Get more information about the distribution we are running
49 # or building
53bb7960 50 self.distro = distro.Distribution(self, distro_config)
c605d735 51 self.pool = satsolver.Pool(self.distro.arch)
ae20b05f
MT
52 self.repos = repository.Repositories(self,
53 enable_repos=enable_repos, disable_repos=disable_repos)
7c8f2953 54
c605d735
MT
55 # Create the solver of this pakfire instance.
56 # XXX maybe we can only create it when we need it?
57 #self.solver = satsolver.Solver(self, self.pool)
58
59 def create_solver(self):
60 return satsolver.Solver(self, self.pool)
61
62 def create_request(self):
63 return satsolver.Request(self.pool)
7c8f2953
MT
64
65 def destroy(self):
66 if not self.path == "/":
67 util.rm(self.path)
68
69 @property
70 def supported_arches(self):
3ad4bb5a 71 return self.config.supported_arches
7c8f2953
MT
72
73 def check_root_user(self):
74 if not os.getuid() == 0 or not os.getgid() == 0:
75 raise Exception, "You must run pakfire as the root user."
76
77 def check_build_mode(self):
78 """
79 Check if we are running in build mode.
80 Otherwise, raise an exception.
81 """
82 if not self.builder:
83 raise BuildError, "Cannot build when not in build mode."
84
85 def check_host_arch(self, arch):
86 """
87 Check if we can build for arch.
88 """
7c8f2953
MT
89 # If no arch was given on the command line we build for our
90 # own arch which should always work.
91 if not arch:
92 return True
93
3ad4bb5a 94 if not self.config.host_supports_arch(arch):
7c8f2953
MT
95 raise BuildError, "Cannot build for the target architecture: %s" % arch
96
97 raise BuildError, arch
18edfe75
MT
98
99 def install(self, requires):
ae20b05f
MT
100 # Create a new request.
101 request = self.solver.create_request()
18edfe75 102 for req in requires:
ae20b05f 103 request.install(req)
18edfe75 104
ae20b05f
MT
105 # Do the solving.
106 t = self.solver.solve(request)
18edfe75 107
ae20b05f 108 if not t:
18edfe75
MT
109 return
110
c0fd807c
MT
111 # Ask if the user acknowledges the transaction.
112 if not t.cli_yesno():
113 return
114
115 # Run the transaction.
ae20b05f 116 t.run()
18edfe75 117
e0b99370
MT
118 def localinstall(self, files):
119 repo_name = "localinstall"
120
121 # Create a new repository that holds all packages we passed on
122 # the commandline.
123 repo = self.solver.pool.create_repo(repo_name)
124
125 # Open all passed files and try to open them.
126 for file in files:
127 pkg = packages.open(self, None, file)
128
129 if not isinstance(pkg, packages.BinaryPackage):
130 logging.warning("Skipping package which is a wrong format: %s" % file)
131 continue
132
133 # Add the package information to the solver.
134 self.solver.add_package(pkg, repo_name)
135
136 # Break if no packages were added at all.
137 if not repo.size():
138 logging.critical("There are no packages to install.")
139 return
140
141 # Create a new request which contains all solvabled from the CLI and
142 # try to solve it.
143 request = self.solver.create_request()
144 for solvable in repo:
e0b99370
MT
145 request.install(solvable)
146
147 t = self.solver.solve(request)
148
149 # If solving was not possible, we exit here.
150 if not t:
151 return
152
c0fd807c 153 # Ask the user if this is okay.
3ad4bb5a
MT
154 #if not t.cli_yesno():
155 # return
c0fd807c
MT
156
157 # If okay, run the transcation.
e0b99370
MT
158 t.run()
159
18edfe75 160 def update(self, pkgs):
0c1a80b8
MT
161 request = self.solver.create_request()
162
163 repo_installed = self.solver.get_repo("installed")
164 assert repo_installed
165
166 for solvable in repo_installed:
167 request.update(solvable)
168
169 t = self.solver.solve(request, update=True)
170
171 if not t:
172 return
173
c0fd807c
MT
174 # Ask the user if the transaction is okay.
175 if not t.cli_yesno():
176 return
0c1a80b8 177
c0fd807c 178 # Run the transaction.
0c1a80b8 179 t.run()
18edfe75 180
a39fd08b
MT
181 def remove(self, pkgs):
182 # Create a new request.
183 request = self.solver.create_request()
184 for pkg in pkgs:
185 request.remove(pkg)
186
187 # Solve the request.
188 t = self.solver.solve(request)
189
190 if not t:
191 return
192
c0fd807c
MT
193 # Ask the user if okay.
194 if not t.cli_yesno():
195 return
196
197 # Process the transaction.
a39fd08b
MT
198 t.run()
199
c1e7f927 200 def info(self, patterns):
18edfe75
MT
201 pkgs = []
202
203 for pattern in patterns:
204 pkgs += self.repos.get_by_glob(pattern)
205
206 return packages.PackageListing(pkgs)
207
208 def search(self, pattern):
209 # Do the search.
f1ab3110 210 pkgs = []
884cd2fb 211 for solv in self.pool.search(pattern, satsolver.SEARCH_STRING|satsolver.SEARCH_FILES):
f1ab3110 212 pkgs.append(packages.SolvPackage(self, solv))
18edfe75
MT
213
214 # Return the output as a package listing.
215 return packages.PackageListing(pkgs)
216
217 def groupinstall(self, group):
218 pkgs = self.grouplist(group)
219
220 self.install(pkgs)
221
222 def grouplist(self, group):
223 pkgs = self.repos.get_by_group(group)
224
225 pkgs = packages.PackageListing(pkgs)
226 pkgs.unique()
227
228 return [p.name for p in pkgs]
229
230 @staticmethod
dacaa18b 231 def build(pkg, resultdirs=None, shell=False, **kwargs):
18edfe75
MT
232 if not resultdirs:
233 resultdirs = []
234
235 b = builder.Builder(pkg, **kwargs)
236 p = b.pakfire
237
238 # Always include local repository.
239 resultdirs.append(p.repos.local_build.path)
240
241 try:
242 b.prepare()
243 b.extract()
244 b.build()
245 b.install_test()
246
247 # Copy-out all resultfiles
248 for resultdir in resultdirs:
249 if not resultdir:
250 continue
251
252 b.copy_result(resultdir)
253
254 except BuildError:
dacaa18b
MT
255 if shell:
256 b.shell()
257 else:
258 raise
18edfe75
MT
259
260 finally:
261 b.destroy()
262
263 @staticmethod
264 def shell(pkg, **kwargs):
265 b = builder.Builder(pkg, **kwargs)
266
267 try:
268 b.prepare()
269 b.extract()
270 b.shell()
271 finally:
272 b.destroy()
273
274 @staticmethod
50f96897
MT
275 def dist(pkgs, resultdirs=None, **pakfire_args):
276 # Create a builder with empty package.
277 b = builder.Builder(None, **pakfire_args)
18edfe75
MT
278 p = b.pakfire
279
280 if not resultdirs:
281 resultdirs = []
282
283 # Always include local repository
284 resultdirs.append(p.repos.local_build.path)
285
286 try:
287 b.prepare()
18edfe75 288
50f96897
MT
289 for pkg in pkgs:
290 b.pkg = pkg
18edfe75 291
50f96897 292 b.extract(build_deps=False)
18edfe75 293
50f96897
MT
294 # Run the actual dist.
295 b.dist()
296
297 # Copy-out all resultfiles
298 for resultdir in resultdirs:
299 if not resultdir:
300 continue
301
302 b.copy_result(resultdir)
303
304 # Cleanup the stuff that the package left.
305 b.cleanup()
18edfe75
MT
306 finally:
307 b.destroy()
308
309 def provides(self, patterns):
310 pkgs = []
311 for pattern in patterns:
c605d735 312 pkgs += self.repos.whatprovides(pattern)
18edfe75
MT
313
314 pkgs = packages.PackageListing(pkgs)
315 #pkgs.unique()
316
317 return pkgs
318
319 def requires(self, patterns):
320 pkgs = []
321 for pattern in patterns:
ae20b05f 322 pkgs += self.repos.get_by_requires(pattern)
18edfe75
MT
323
324 pkgs = packages.PackageListing(pkgs)
325 #pkgs.unique()
326
327 return pkgs
328
329 def repo_create(self, path, input_paths):
c605d735 330 repo = repository.RepositoryDir(
18edfe75
MT
331 self,
332 name="new",
333 description="New repository.",
334 path=path,
335 )
336
337 for input_path in input_paths:
c605d735 338 repo.collect_packages(input_path)
18edfe75
MT
339
340 repo.save()
341
342 def repo_list(self):
c605d735 343 return [r for r in self.repos]