]>
git.ipfire.org Git - people/ms/pakfire.git/blob - pakfire/base.py
17 from constants
import *
20 class Pakfire(object):
22 (">=", satsolver
.REL_GE
,),
23 ("<=", satsolver
.REL_LE
,),
24 ("=" , satsolver
.REL_EQ
,),
25 ("<" , satsolver
.REL_LT
,),
26 (">" , satsolver
.REL_GT
,),
29 def __init__(self
, mode
, path
="/", configs
=[],
30 enable_repos
=None, disable_repos
=None,
34 assert mode
in ("normal", "builder", "repo", "server", "master")
37 # Check if we are operating as the root user.
38 self
.check_root_user()
40 # The path where we are operating in.
43 # Configure the instance of Pakfire we just started.
45 self
.path
= os
.path
.join(BUILD_ROOT
, util
.random_string())
47 elif mode
== "normal":
48 # check if we are actually running on an ipfire system.
49 self
.check_is_ipfire()
51 # Read configuration file(s)
52 self
.config
= config
.Config(type=mode
)
53 for filename
in configs
:
54 self
.config
.read(filename
)
57 logger
.setup_logging(self
.config
)
60 # Get more information about the distribution we are running
62 self
.distro
= distro
.Distribution(self
, distro_config
)
63 self
.pool
= satsolver
.Pool(self
.distro
.arch
)
64 self
.repos
= repository
.Repositories(self
,
65 enable_repos
=enable_repos
, disable_repos
=disable_repos
)
67 def create_solver(self
):
68 return satsolver
.Solver(self
, self
.pool
)
70 def create_request(self
):
71 return satsolver
.Request(self
.pool
)
73 def create_relation(self
, s
):
77 return satsolver
.Relation(self
.pool
, s
)
79 for pattern
, type in self
.RELATIONS
:
83 name
, version
= s
.split(pattern
, 1)
85 return satsolver
.Relation(self
.pool
, name
, version
, type)
87 return satsolver
.Relation(self
.pool
, s
)
90 if not self
.path
== "/":
94 def supported_arches(self
):
95 return self
.config
.supported_arches
97 def check_root_user(self
):
98 if not os
.getuid() == 0 or not os
.getgid() == 0:
99 raise Exception, "You must run pakfire as the root user."
101 def check_build_mode(self
):
103 Check if we are running in build mode.
104 Otherwise, raise an exception.
106 if not self
.mode
== "builder":
107 raise BuildError
, "Cannot build when not in build mode."
109 def check_host_arch(self
, arch
):
111 Check if we can build for arch.
113 # If no arch was given on the command line we build for our
114 # own arch which should always work.
118 if not self
.config
.host_supports_arch(arch
):
119 raise BuildError
, "Cannot build for the target architecture: %s" % arch
121 raise BuildError
, arch
123 def check_is_ipfire(self
):
124 ret
= os
.path
.exists("/etc/ipfire-release")
127 raise NotAnIPFireSystemError
, "You can run pakfire only on an IPFire system"
131 # XXX just backwards compatibility
132 return self
.mode
== "builder"
134 def install(self
, requires
):
135 # Create a new request.
136 request
= self
.create_request()
141 solver
= self
.create_solver()
142 t
= solver
.solve(request
)
147 # Ask if the user acknowledges the transaction.
148 if not t
.cli_yesno():
151 # Run the transaction.
154 def localinstall(self
, files
):
155 repo_name
= "localinstall"
157 # Create a new repository that holds all packages we passed on
159 repo
= self
.solver
.pool
.create_repo(repo_name
)
161 # Open all passed files and try to open them.
163 pkg
= packages
.open(self
, None, file)
165 if not isinstance(pkg
, packages
.BinaryPackage
):
166 logging
.warning("Skipping package which is a wrong format: %s" % file)
169 # Add the package information to the solver.
170 self
.solver
.add_package(pkg
, repo_name
)
172 # Break if no packages were added at all.
174 logging
.critical("There are no packages to install.")
177 # Create a new request which contains all solvabled from the CLI and
179 request
= self
.solver
.create_request()
180 for solvable
in repo
:
181 request
.install(solvable
)
183 solver
= self
.create_solver()
184 t
= solver
.solve(request
)
186 # If solving was not possible, we exit here.
190 # Ask the user if this is okay.
191 #if not t.cli_yesno():
194 # If okay, run the transcation.
197 def update(self
, pkgs
):
198 request
= self
.create_request()
200 # If there are given any packets on the command line, we will
201 # only update them. Otherwise, we update the whole system.
209 solver
= self
.create_solver()
210 t
= solver
.solve(request
, update
=update
)
215 # Ask the user if the transaction is okay.
216 if not t
.cli_yesno():
219 # Run the transaction.
222 def remove(self
, pkgs
):
223 # Create a new request.
224 request
= self
.create_request()
229 solver
= self
.create_solver()
230 t
= solver
.solve(request
, uninstall
=True)
235 # Ask the user if okay.
236 if not t
.cli_yesno():
239 # Process the transaction.
242 def info(self
, patterns
):
245 # For all patterns we run a single search which returns us a bunch
246 # of solvables which are transformed into Package objects.
247 for pattern
in patterns
:
248 solvs
= self
.pool
.search(pattern
, satsolver
.SEARCH_GLOB
, "solvable:name")
251 pkgs
.append(packages
.SolvPackage(self
, solv
))
253 return packages
.PackageListing(pkgs
)
255 def search(self
, pattern
):
258 for solv
in self
.pool
.search(pattern
, satsolver
.SEARCH_STRING|satsolver
.SEARCH_FILES
):
259 pkgs
.append(packages
.SolvPackage(self
, solv
))
261 # Return the output as a package listing.
262 return packages
.PackageListing(pkgs
)
264 def groupinstall(self
, group
):
265 pkgs
= self
.grouplist(group
)
269 def grouplist(self
, group
):
272 for solv
in self
.pool
.search(group
, satsolver
.SEARCH_SUBSTRING
, "solvable:group"):
273 pkg
= packages
.SolvPackage(self
, solv
)
275 if group
in pkg
.groups
and not pkg
.name
in pkgs
:
276 pkgs
.append(pkg
.name
)
281 def build(pkg
, resultdirs
=None, shell
=False, **kwargs
):
285 b
= builder
.Builder(pkg
, **kwargs
)
288 # Always include local repository.
289 resultdirs
.append(p
.repos
.local_build
.path
)
297 # Copy-out all resultfiles
298 for resultdir
in resultdirs
:
302 b
.copy_result(resultdir
)
314 def shell(pkg
, **kwargs
):
315 b
= builder
.Builder(pkg
, **kwargs
)
325 def dist(pkgs
, resultdirs
=None, **pakfire_args
):
326 # Create a builder with empty package.
327 b
= builder
.Builder(None, **pakfire_args
)
333 # Always include local repository
334 resultdirs
.append(p
.repos
.local_build
.path
)
342 b
.extract(build_deps
=False)
344 # Run the actual dist.
347 # Copy-out all resultfiles
348 for resultdir
in resultdirs
:
352 b
.copy_result(resultdir
)
354 # Cleanup the stuff that the package left.
359 def provides(self
, patterns
):
361 for pattern
in patterns
:
362 pkgs
+= self
.repos
.whatprovides(pattern
)
364 pkgs
= packages
.PackageListing(pkgs
)
369 def requires(self
, patterns
):
371 for pattern
in patterns
:
372 pkgs
+= self
.repos
.get_by_requires(pattern
)
374 pkgs
= packages
.PackageListing(pkgs
)
379 def repo_create(self
, path
, input_paths
):
380 repo
= repository
.RepositoryDir(
383 description
="New repository.",
387 for input_path
in input_paths
:
388 repo
.collect_packages(input_path
)
393 return [r
for r
in self
.repos
]
396 logging
.debug("Cleaning up everything...")
398 # Clean up repository caches.