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