]> git.ipfire.org Git - people/stevee/pakfire.git/blame - python/pakfire/cli.py
Update translation.
[people/stevee/pakfire.git] / python / pakfire / cli.py
CommitLineData
47a4cb89 1#!/usr/bin/python
b792d887
MT
2###############################################################################
3# #
4# Pakfire - The IPFire package management system #
5# Copyright (C) 2011 Pakfire development team #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
47a4cb89
MT
21
22import argparse
68c0e769 23import datetime
936f6b37 24import os
b913e798 25import shutil
47a4cb89 26import sys
b913e798 27import tempfile
47a4cb89 28
36b328f2 29import base
c62d93f1
MT
30import client
31import config
60845a36 32import logger
47a4cb89 33import packages
fa6d335b 34import repository
677ff42a 35import server
36b328f2 36import transaction
e9c20259 37import util
47a4cb89 38
c62d93f1 39from system import system
47a4cb89
MT
40from constants import *
41from i18n import _
42
60845a36
MT
43# Initialize a very simple logging that is removed when a Pakfire instance
44# is started.
45logger.setup_logging()
46
47a4cb89 47class Cli(object):
36b328f2
MT
48 pakfire = base.Pakfire
49
47a4cb89
MT
50 def __init__(self):
51 self.parser = argparse.ArgumentParser(
52 description = _("Pakfire command line interface."),
53 )
54
55 self.parse_common_arguments()
56
2ba449f0 57 self.parser.add_argument("--root", metavar="PATH",
d2e26956 58 default="/",
47a4cb89
MT
59 help=_("The path where pakfire should operate in."))
60
61 # Add sub-commands.
62 self.sub_commands = self.parser.add_subparsers()
63
64 self.parse_command_install()
0ca71090 65 self.parse_command_reinstall()
a39fd08b 66 self.parse_command_remove()
47a4cb89
MT
67 self.parse_command_info()
68 self.parse_command_search()
e38914be 69 self.parse_command_check_update()
47a4cb89 70 self.parse_command_update()
67d1ddbd 71 self.parse_command_downgrade()
fa6d335b 72 self.parse_command_provides()
c1962d40 73 self.parse_command_grouplist()
ce2764c1 74 self.parse_command_groupinstall()
67bc4528 75 self.parse_command_repolist()
31267a64 76 self.parse_command_clean()
35d89fd7 77 self.parse_command_check()
b25a3d84 78 self.parse_command_resolvdep()
47a4cb89
MT
79
80 # Finally parse all arguments from the command line and save them.
81 self.args = self.parser.parse_args()
82
47a4cb89 83 self.action2func = {
5e87fa4f 84 "install" : self.handle_install,
0ca71090 85 "reinstall" : self.handle_reinstall,
a39fd08b 86 "remove" : self.handle_remove,
e38914be 87 "check_update" : self.handle_check_update,
5e87fa4f 88 "update" : self.handle_update,
67d1ddbd 89 "downgrade" : self.handle_downgrade,
5e87fa4f
MT
90 "info" : self.handle_info,
91 "search" : self.handle_search,
fa6d335b 92 "provides" : self.handle_provides,
c1962d40 93 "grouplist" : self.handle_grouplist,
ce2764c1 94 "groupinstall" : self.handle_groupinstall,
67bc4528 95 "repolist" : self.handle_repolist,
31267a64 96 "clean_all" : self.handle_clean_all,
35d89fd7 97 "check" : self.handle_check,
b25a3d84 98 "resolvdep" : self.handle_resolvdep,
47a4cb89
MT
99 }
100
7c8f2953
MT
101 @property
102 def pakfire_args(self):
36b328f2 103 ret = {}
6557ff4c 104
2ba449f0
MT
105 if hasattr(self.args, "root"):
106 ret["path"] = self.args.root
f9a012a8 107
98733451
MT
108 if hasattr(self.args, "offline") and self.args.offline:
109 ret["downloader"] = {
110 "offline" : self.args.offline,
111 }
6a509182 112
854d8ccf
MT
113 if hasattr(self.args, "config"):
114 ret["configs"] = self.args.config
115 else:
116 ret["configs"] = None
117
f9a012a8 118 return ret
7c8f2953 119
685cb819
MT
120 def create_pakfire(self, cls=None, **kwargs):
121 if cls is None:
122 cls = self.pakfire
123
124 args = self.pakfire_args
125 args.update(kwargs)
126
127 p = cls(**args)
128
129 # Disable repositories.
130 for repo in self.args.disable_repo:
131 p.repos.disable_repo(repo)
132
133 # Enable repositories.
134 for repo in self.args.enable_repo:
135 p.repos.enable_repo(repo)
136
137 return p
138
139 def parse_common_arguments(self, offline_switch=True):
50381f5c
MT
140 self.parser.add_argument("--version", action="version",
141 version="%(prog)s " + PAKFIRE_VERSION)
142
47a4cb89
MT
143 self.parser.add_argument("-v", "--verbose", action="store_true",
144 help=_("Enable verbose output."))
145
146 self.parser.add_argument("-c", "--config", nargs="?",
147 help=_("Path to a configuration file to load."))
148
685cb819
MT
149 self.parser.add_argument("--disable-repo", nargs="*", metavar="REPO",
150 help=_("Disable a repository temporarily."), default=[])
f781b1ab 151
685cb819
MT
152 self.parser.add_argument("--enable-repo", nargs="*", metavar="REPO",
153 help=_("Enable a repository temporarily."), default=[])
f9a012a8 154
c62d93f1
MT
155 if offline_switch:
156 self.parser.add_argument("--offline", action="store_true",
157 help=_("Run pakfire in offline mode."))
6a509182 158
47a4cb89
MT
159 def parse_command_install(self):
160 # Implement the "install" command.
161 sub_install = self.sub_commands.add_parser("install",
162 help=_("Install one or more packages to the system."))
163 sub_install.add_argument("package", nargs="+",
164 help=_("Give name of at least one package to install."))
a60f0f7d
MT
165 sub_install.add_argument("--without-recommends", action="store_true",
166 help=_("Don't install recommended packages."))
47a4cb89
MT
167 sub_install.add_argument("action", action="store_const", const="install")
168
0ca71090
MT
169 def parse_command_reinstall(self):
170 # Implement the "reinstall" command.
171 sub_install = self.sub_commands.add_parser("reinstall",
172 help=_("Reinstall one or more packages."))
173 sub_install.add_argument("package", nargs="+",
174 help=_("Give name of at least one package to reinstall."))
175 sub_install.add_argument("action", action="store_const", const="reinstall")
176
a39fd08b
MT
177 def parse_command_remove(self):
178 # Implement the "remove" command.
179 sub_remove = self.sub_commands.add_parser("remove",
180 help=_("Remove one or more packages from the system."))
181 sub_remove.add_argument("package", nargs="+",
182 help=_("Give name of at least one package to remove."))
183 sub_remove.add_argument("action", action="store_const", const="remove")
184
05fb1da0
MT
185 @staticmethod
186 def _parse_command_update(parser):
187 parser.add_argument("package", nargs="*",
188 help=_("Give a name of a package to update or leave emtpy for all."))
189 parser.add_argument("--exclude", "-x", nargs="+",
190 help=_("Exclude package from update."))
191 parser.add_argument("--allow-vendorchange", action="store_true",
192 help=_("Allow changing the vendor of packages."))
193 parser.add_argument("--allow-archchange", action="store_true",
194 help=_("Allow changing the architecture of packages."))
195
47a4cb89
MT
196 def parse_command_update(self):
197 # Implement the "update" command.
198 sub_update = self.sub_commands.add_parser("update",
199 help=_("Update the whole system or one specific package."))
47a4cb89 200 sub_update.add_argument("action", action="store_const", const="update")
05fb1da0 201 self._parse_command_update(sub_update)
47a4cb89 202
e38914be
MT
203 def parse_command_check_update(self):
204 # Implement the "check-update" command.
205 sub_check_update = self.sub_commands.add_parser("check-update",
206 help=_("Check, if there are any updates available."))
e38914be 207 sub_check_update.add_argument("action", action="store_const", const="check_update")
05fb1da0 208 self._parse_command_update(sub_check_update)
e38914be 209
67d1ddbd
MT
210 def parse_command_downgrade(self):
211 # Implement the "downgrade" command.
212 sub_downgrade = self.sub_commands.add_parser("downgrade",
213 help=_("Downgrade one or more packages."))
214 sub_downgrade.add_argument("package", nargs="*",
215 help=_("Give a name of a package to downgrade."))
216 sub_downgrade.add_argument("--allow-vendorchange", action="store_true",
217 help=_("Allow changing the vendor of packages."))
218 sub_downgrade.add_argument("--allow-archchange", action="store_true",
219 help=_("Allow changing the architecture of packages."))
220 sub_downgrade.add_argument("action", action="store_const", const="downgrade")
221
47a4cb89
MT
222 def parse_command_info(self):
223 # Implement the "info" command.
224 sub_info = self.sub_commands.add_parser("info",
225 help=_("Print some information about the given package(s)."))
226 sub_info.add_argument("package", nargs="+",
227 help=_("Give at least the name of one package."))
228 sub_info.add_argument("action", action="store_const", const="info")
229
230 def parse_command_search(self):
231 # Implement the "search" command.
232 sub_search = self.sub_commands.add_parser("search",
233 help=_("Search for a given pattern."))
234 sub_search.add_argument("pattern",
235 help=_("A pattern to search for."))
236 sub_search.add_argument("action", action="store_const", const="search")
237
fa6d335b
MT
238 def parse_command_provides(self):
239 # Implement the "provides" command
240 sub_provides = self.sub_commands.add_parser("provides",
241 help=_("Get a list of packages that provide a given file or feature."))
242 sub_provides.add_argument("pattern", nargs="+",
243 help=_("File or feature to search for."))
244 sub_provides.add_argument("action", action="store_const", const="provides")
245
c1962d40
MT
246 def parse_command_grouplist(self):
247 # Implement the "grouplist" command
248 sub_grouplist = self.sub_commands.add_parser("grouplist",
249 help=_("Get list of packages that belong to the given group."))
250 sub_grouplist.add_argument("group", nargs=1,
251 help=_("Group name to search for."))
252 sub_grouplist.add_argument("action", action="store_const", const="grouplist")
253
ce2764c1
MT
254 def parse_command_groupinstall(self):
255 # Implement the "grouplist" command
256 sub_groupinstall = self.sub_commands.add_parser("groupinstall",
257 help=_("Install all packages that belong to the given group."))
258 sub_groupinstall.add_argument("group", nargs=1,
259 help=_("Group name."))
260 sub_groupinstall.add_argument("action", action="store_const", const="groupinstall")
261
67bc4528
MT
262 def parse_command_repolist(self):
263 # Implement the "repolist" command
264 sub_repolist = self.sub_commands.add_parser("repolist",
265 help=_("List all currently enabled repositories."))
266 sub_repolist.add_argument("action", action="store_const", const="repolist")
ce2764c1 267
31267a64
MT
268 def parse_command_clean(self):
269 sub_clean = self.sub_commands.add_parser("clean", help=_("Cleanup commands."))
270
271 sub_clean_commands = sub_clean.add_subparsers()
272
273 self.parse_command_clean_all(sub_clean_commands)
274
275 def parse_command_clean_all(self, sub_commands):
276 sub_create = sub_commands.add_parser("all",
277 help=_("Cleanup all temporary files."))
278 sub_create.add_argument("action", action="store_const", const="clean_all")
279
35d89fd7
MT
280 def parse_command_check(self):
281 # Implement the "check" command
282 sub_check = self.sub_commands.add_parser("check",
283 help=_("Check the system for any errors."))
284 sub_check.add_argument("action", action="store_const", const="check")
285
b25a3d84
MT
286 def parse_command_resolvdep(self):
287 # Implement the "resolvdep" command.
288 sub_resolvdep = self.sub_commands.add_parser("resolvdep",
289 help=_("Check the dependencies for a particular package."))
c901e1f8 290 sub_resolvdep.add_argument("package", nargs=1,
b25a3d84
MT
291 help=_("Give name of at least one package to check."))
292 sub_resolvdep.add_argument("action", action="store_const", const="resolvdep")
293
47a4cb89
MT
294 def run(self):
295 action = self.args.action
296
47a4cb89
MT
297 try:
298 func = self.action2func[action]
299 except KeyError:
c62d93f1 300 raise Exception, "Unhandled action: %s" % action
47a4cb89
MT
301
302 return func()
303
9afa5620 304 def handle_info(self, long=False):
685cb819 305 p = self.create_pakfire()
47a4cb89 306
36b328f2 307 for pkg in p.info(self.args.package):
7c8f2953 308 print pkg.dump(long=long)
47a4cb89
MT
309
310 def handle_search(self):
685cb819 311 p = self.create_pakfire()
47a4cb89 312
36b328f2 313 for pkg in p.search(self.args.pattern):
47a4cb89
MT
314 print pkg.dump(short=True)
315
05fb1da0 316 def handle_update(self, **args):
685cb819 317 p = self.create_pakfire()
36b328f2
MT
318 p.update(
319 self.args.package,
320 excludes=self.args.exclude,
05fb1da0
MT
321 allow_vendorchange=self.args.allow_vendorchange,
322 allow_archchange=self.args.allow_archchange,
36b328f2
MT
323 **args
324 )
47a4cb89 325
e38914be 326 def handle_check_update(self):
05fb1da0 327 self.handle_update(check=True)
e38914be 328
67d1ddbd 329 def handle_downgrade(self, **args):
685cb819 330 p = self.create_pakfire()
36b328f2
MT
331 p.downgrade(
332 self.args.package,
67d1ddbd
MT
333 allow_vendorchange=self.args.allow_vendorchange,
334 allow_archchange=self.args.allow_archchange,
36b328f2
MT
335 **args
336 )
67d1ddbd 337
e0b99370 338 def handle_install(self):
685cb819 339 p = self.create_pakfire()
36b328f2 340 p.install(self.args.package, ignore_recommended=self.args.without_recommends)
5e87fa4f 341
0ca71090 342 def handle_reinstall(self):
685cb819 343 p = self.create_pakfire()
36b328f2 344 p.reinstall(self.args.package)
0ca71090 345
a39fd08b 346 def handle_remove(self):
685cb819 347 p = self.create_pakfire()
36b328f2 348 p.remove(self.args.package)
a39fd08b 349
36b328f2 350 def handle_provides(self, long=False):
685cb819 351 p = self.create_pakfire()
fa6d335b 352
36b328f2
MT
353 for pkg in p.provides(self.args.pattern):
354 print pkg.dump(long=long)
fa6d335b 355
c1962d40 356 def handle_grouplist(self):
685cb819 357 p = self.create_pakfire()
c1962d40 358
36b328f2 359 for pkg in p.grouplist(self.args.group[0]):
c1962d40
MT
360 print " * %s" % pkg
361
ce2764c1 362 def handle_groupinstall(self):
685cb819 363 p = self.create_pakfire()
36b328f2 364 p.groupinstall(self.args.group[0])
ce2764c1 365
67bc4528 366 def handle_repolist(self):
685cb819
MT
367 p = self.create_pakfire()
368
369 # Get a list of all repositories.
569b3054 370 repos = p.repo_list()
67bc4528 371
c605d735 372 FORMAT = " %-20s %8s %12s %12s "
c605d735 373 title = FORMAT % (_("Repository"), _("Enabled"), _("Priority"), _("Packages"))
67bc4528
MT
374 print title
375 print "=" * len(title) # spacing line
376
569b3054 377 for repo in repos:
c605d735 378 print FORMAT % (repo.name, repo.enabled, repo.priority, len(repo))
67bc4528 379
31267a64
MT
380 def handle_clean_all(self):
381 print _("Cleaning up everything...")
382
685cb819 383 p = self.create_pakfire()
36b328f2 384 p.clean_all()
31267a64 385
35d89fd7 386 def handle_check(self):
685cb819 387 p = self.create_pakfire()
36b328f2 388 p.check()
35d89fd7 389
b25a3d84 390 def handle_resolvdep(self):
685cb819 391 p = self.create_pakfire()
c901e1f8 392
36b328f2 393 (pkg,) = self.args.package
c901e1f8 394
569b3054 395 solver = p.resolvdep(pkg)
c901e1f8 396 assert solver.status
36b328f2
MT
397
398 t = transaction.Transaction.from_solver(p, solver)
399 t.dump()
b25a3d84 400
47a4cb89
MT
401
402class CliBuilder(Cli):
36b328f2
MT
403 pakfire = base.PakfireBuilder
404
47a4cb89 405 def __init__(self):
936f6b37
MT
406 # Check if we are already running in a pakfire container. In that
407 # case, we cannot start another pakfire-builder.
408 if os.environ.get("container", None) == "pakfire-builder":
409 raise PakfireContainerError, _("You cannot run pakfire-builder in a pakfire chroot.")
410
47a4cb89
MT
411 self.parser = argparse.ArgumentParser(
412 description = _("Pakfire builder command line interface."),
413 )
414
415 self.parse_common_arguments()
416
417 # Add sub-commands.
418 self.sub_commands = self.parser.add_subparsers()
419
420 self.parse_command_build()
421 self.parse_command_dist()
422 self.parse_command_info()
423 self.parse_command_search()
424 self.parse_command_shell()
425 self.parse_command_update()
4fbd4216 426 self.parse_command_provides()
2c84aceb 427 self.parse_command_grouplist()
67bc4528 428 self.parse_command_repolist()
31267a64 429 self.parse_command_clean()
b25a3d84 430 self.parse_command_resolvdep()
47a4cb89
MT
431
432 # Finally parse all arguments from the command line and save them.
433 self.args = self.parser.parse_args()
434
47a4cb89 435 self.action2func = {
fa6d335b
MT
436 "build" : self.handle_build,
437 "dist" : self.handle_dist,
438 "update" : self.handle_update,
439 "info" : self.handle_info,
440 "search" : self.handle_search,
441 "shell" : self.handle_shell,
4fbd4216 442 "provides" : self.handle_provides,
2c84aceb 443 "grouplist" : self.handle_grouplist,
67bc4528 444 "repolist" : self.handle_repolist,
31267a64 445 "clean_all" : self.handle_clean_all,
b25a3d84 446 "resolvdep" : self.handle_resolvdep,
47a4cb89
MT
447 }
448
7c8f2953
MT
449 @property
450 def pakfire_args(self):
91f20fe4
MT
451 ret = {
452 "arch" : self.args.arch,
453 }
f9a012a8 454
98733451
MT
455 if hasattr(self.args, "offline") and self.args.offline:
456 ret["downloader"] = {
457 "offline" : self.args.offline,
458 }
6a509182 459
4f08c65d
MT
460 if hasattr(self.args, "distro"):
461 ret["distro_name"] = self.args.distro
462
f9a012a8 463 return ret
7c8f2953 464
4f08c65d
MT
465 def parse_common_arguments(self, *args, **kwargs):
466 Cli.parse_common_arguments(self, *args, **kwargs)
467
468 self.parser.add_argument("--distro", nargs="?",
469 help=_("Choose the distribution configuration to use for build"))
470
91f20fe4
MT
471 self.parser.add_argument("--arch", "-a", nargs="?",
472 help=_("Run pakfire for the given architecture."))
473
47a4cb89
MT
474 def parse_command_update(self):
475 # Implement the "update" command.
476 sub_update = self.sub_commands.add_parser("update",
477 help=_("Update the package indexes."))
478 sub_update.add_argument("action", action="store_const", const="update")
479
480 def parse_command_build(self):
481 # Implement the "build" command.
482 sub_build = self.sub_commands.add_parser("build",
483 help=_("Build one or more packages."))
484 sub_build.add_argument("package", nargs=1,
485 help=_("Give name of at least one package to build."))
486 sub_build.add_argument("action", action="store_const", const="build")
487
47a4cb89
MT
488 sub_build.add_argument("--resultdir", nargs="?",
489 help=_("Path were the output files should be copied to."))
f22069bb
MT
490 sub_build.add_argument("-m", "--mode", nargs="?", default="development",
491 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
1710ccec
MT
492 sub_build.add_argument("--after-shell", action="store_true",
493 help=_("Run a shell after a successful build."))
4fffe3c4
MT
494 sub_build.add_argument("--no-install-test", action="store_true",
495 help=_("Do not perform the install test."))
47a4cb89
MT
496
497 def parse_command_shell(self):
498 # Implement the "shell" command.
499 sub_shell = self.sub_commands.add_parser("shell",
500 help=_("Go into a shell."))
042266f3 501 sub_shell.add_argument("package", nargs="?",
47a4cb89
MT
502 help=_("Give name of a package."))
503 sub_shell.add_argument("action", action="store_const", const="shell")
504
6ee3d6b9
MT
505 sub_shell.add_argument("-m", "--mode", nargs="?", default="development",
506 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
47a4cb89
MT
507
508 def parse_command_dist(self):
509 # Implement the "dist" command.
510 sub_dist = self.sub_commands.add_parser("dist",
511 help=_("Generate a source package."))
e412b8dc
MT
512 sub_dist.add_argument("package", nargs="+",
513 help=_("Give name(s) of a package(s)."))
47a4cb89
MT
514 sub_dist.add_argument("action", action="store_const", const="dist")
515
516 sub_dist.add_argument("--resultdir", nargs="?",
517 help=_("Path were the output files should be copied to."))
518
9afa5620
MT
519 def handle_info(self):
520 Cli.handle_info(self, long=True)
521
47a4cb89 522 def handle_build(self):
47a4cb89
MT
523 # Get the package descriptor from the command line options
524 pkg = self.args.package[0]
525
526 # Check, if we got a regular file
527 if os.path.exists(pkg):
528 pkg = os.path.abspath(pkg)
529
47a4cb89 530 else:
7c8f2953 531 raise FileNotFoundError, pkg
47a4cb89 532
4fffe3c4
MT
533 # Check whether to enable the install test.
534 install_test = not self.args.no_install_test
535
36b328f2
MT
536 if self.args.mode == "release":
537 release_build = True
538 else:
539 release_build = False
540
91f20fe4 541 p = self.create_pakfire()
36b328f2
MT
542 p.build(pkg,
543 install_test=install_test,
544 resultdirs=[self.args.resultdir,],
545 shell=True,
546 after_shell=self.args.after_shell,
547 release_build=release_build,
548 )
47a4cb89
MT
549
550 def handle_shell(self):
042266f3
MT
551 pkg = None
552
47a4cb89 553 # Get the package descriptor from the command line options
042266f3 554 if self.args.package:
ad1b844f 555 pkg = self.args.package
47a4cb89 556
7c8f2953
MT
557 # Check, if we got a regular file
558 if os.path.exists(pkg):
559 pkg = os.path.abspath(pkg)
47a4cb89 560
7c8f2953
MT
561 else:
562 raise FileNotFoundError, pkg
47a4cb89 563
36b328f2
MT
564 if self.args.mode == "release":
565 release_build = True
566 else:
567 release_build = False
568
91f20fe4 569 p = self.create_pakfire()
36b328f2 570 p.shell(pkg, release_build=release_build)
47a4cb89
MT
571
572 def handle_dist(self):
e412b8dc
MT
573 # Get the packages from the command line options
574 pkgs = []
47a4cb89 575
e412b8dc
MT
576 for pkg in self.args.package:
577 # Check, if we got a regular file
578 if os.path.exists(pkg):
579 pkg = os.path.abspath(pkg)
7c8f2953 580 pkgs.append(pkg)
47a4cb89 581
e412b8dc 582 else:
7c8f2953
MT
583 raise FileNotFoundError, pkg
584
7d40ac70
MT
585 # Put packages to where the user said or our
586 # current working directory.
587 resultdir = self.args.resultdir or os.getcwd()
588
685cb819 589 p = self.create_pakfire()
7d40ac70 590 for pkg in pkgs:
36b328f2 591 p.dist(pkg, resultdir=resultdir)
47a4cb89 592
c605d735 593 def handle_provides(self):
e313dac1 594 Cli.handle_provides(self, long=True)
c605d735 595
47a4cb89 596
3ad4bb5a 597class CliServer(Cli):
36b328f2
MT
598 pakfire = base.PakfireServer
599
677ff42a
MT
600 def __init__(self):
601 self.parser = argparse.ArgumentParser(
3ad4bb5a 602 description = _("Pakfire server command line interface."),
677ff42a
MT
603 )
604
605 self.parse_common_arguments()
606
607 # Add sub-commands.
608 self.sub_commands = self.parser.add_subparsers()
609
a52f536c 610 self.parse_command_build()
677ff42a 611 self.parse_command_keepalive()
8276111d 612 self.parse_command_repoupdate()
df9c4f62 613 self.parse_command_repo()
aad6f600 614 self.parse_command_info()
677ff42a
MT
615
616 # Finally parse all arguments from the command line and save them.
617 self.args = self.parser.parse_args()
618
269c59f3 619 self.server = server.Server(**self.pakfire_args)
677ff42a
MT
620
621 self.action2func = {
8276111d 622 "build" : self.handle_build,
aad6f600 623 "info" : self.handle_info,
8276111d
MT
624 "keepalive" : self.handle_keepalive,
625 "repoupdate" : self.handle_repoupdate,
df9c4f62 626 "repo_create": self.handle_repo_create,
677ff42a
MT
627 }
628
6557ff4c
MT
629 @property
630 def pakfire_args(self):
36b328f2 631 ret = {}
6557ff4c 632
98733451
MT
633 if hasattr(self.args, "offline") and self.args.offline:
634 ret["downloader"] = {
635 "offline" : self.args.offline,
636 }
6a509182 637
6557ff4c
MT
638 return ret
639
a52f536c
MT
640 def parse_command_build(self):
641 # Implement the "build" command.
c62d93f1
MT
642 sub_build = self.sub_commands.add_parser("build",
643 help=_("Send a scrach build job to the server."))
644 sub_build.add_argument("package", nargs=1,
645 help=_("Give name of at least one package to build."))
646 sub_build.add_argument("--arch", "-a",
647 help=_("Limit build to only these architecture(s)."))
648 sub_build.add_argument("action", action="store_const", const="build")
a52f536c 649
677ff42a
MT
650 def parse_command_keepalive(self):
651 # Implement the "keepalive" command.
652 sub_keepalive = self.sub_commands.add_parser("keepalive",
653 help=_("Send a keepalive to the server."))
654 sub_keepalive.add_argument("action", action="store_const",
655 const="keepalive")
656
8276111d
MT
657 def parse_command_repoupdate(self):
658 # Implement the "repoupdate" command.
659 sub_repoupdate = self.sub_commands.add_parser("repoupdate",
660 help=_("Update all repositories."))
661 sub_repoupdate.add_argument("action", action="store_const",
662 const="repoupdate")
663
df9c4f62
MT
664 def parse_command_repo(self):
665 sub_repo = self.sub_commands.add_parser("repo",
666 help=_("Repository management commands."))
667
668 sub_repo_commands = sub_repo.add_subparsers()
669
670 self.parse_command_repo_create(sub_repo_commands)
671
672 def parse_command_repo_create(self, sub_commands):
673 sub_create = sub_commands.add_parser("create",
674 help=_("Create a new repository index."))
68c0e769
MT
675 sub_create.add_argument("path", nargs=1,
676 help=_("Path to the packages."))
677 sub_create.add_argument("inputs", nargs="+",
678 help=_("Path to input packages."))
679 sub_create.add_argument("--key", "-k", nargs="?",
680 help=_("Key to sign the repository with."))
df9c4f62
MT
681 sub_create.add_argument("action", action="store_const", const="repo_create")
682
aad6f600
MT
683 def parse_command_info(self):
684 sub_info = self.sub_commands.add_parser("info",
685 help=_("Dump some information about this machine."))
686 sub_info.add_argument("action", action="store_const", const="info")
687
677ff42a 688 def handle_keepalive(self):
3ad4bb5a 689 self.server.update_info()
9613a111 690
a52f536c 691 def handle_build(self):
c62d93f1
MT
692 # Arch.
693 if self.args.arch:
694 arches = self.args.arch.split()
695
696 (package,) = self.args.package
697
698 self.server.create_scratch_build({})
699 return
700
701 # Temporary folter for source package.
702 tmpdir = "/tmp/pakfire-%s" % util.random_string()
703
704 try:
705 os.makedirs(tmpdir)
706
707 pakfire.dist(package, resultdir=[tmpdir,])
708
709 for file in os.listdir(tmpdir):
710 file = os.path.join(tmpdir, file)
711
712 print file
713
714 finally:
715 if os.path.exists(tmpdir):
716 util.rm(tmpdir)
8276111d
MT
717
718 def handle_repoupdate(self):
719 self.server.update_repositories()
df9c4f62
MT
720
721 def handle_repo_create(self):
722 path = self.args.path[0]
723
36b328f2
MT
724 p = self.pakfire(**self.pakfire_args)
725 p.repo_create(path, self.args.inputs, key_id=self.args.key)
c07a3ca7 726
aad6f600
MT
727 def handle_info(self):
728 info = self.server.info()
729
730 print "\n".join(info)
731
c07a3ca7 732
9b875540 733class CliBuilderIntern(Cli):
c07a3ca7
MT
734 def __init__(self):
735 self.parser = argparse.ArgumentParser(
736 description = _("Pakfire builder command line interface."),
737 )
738
739 self.parse_common_arguments()
740
741 # Add sub-commands.
742 self.sub_commands = self.parser.add_subparsers()
743
744 self.parse_command_build()
745
746 # Finally parse all arguments from the command line and save them.
747 self.args = self.parser.parse_args()
748
749 self.action2func = {
750 "build" : self.handle_build,
751 }
752
753 def parse_command_build(self):
754 # Implement the "build" command.
755 sub_build = self.sub_commands.add_parser("build",
756 help=_("Build one or more packages."))
757 sub_build.add_argument("package", nargs=1,
758 help=_("Give name of at least one package to build."))
759 sub_build.add_argument("action", action="store_const", const="build")
760
761 sub_build.add_argument("-a", "--arch",
762 help=_("Build the package for the given architecture."))
763 sub_build.add_argument("--resultdir", nargs="?",
764 help=_("Path were the output files should be copied to."))
765 sub_build.add_argument("-m", "--mode", nargs="?", default="development",
766 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
767 sub_build.add_argument("--nodeps", action="store_true",
768 help=_("Do not verify build dependencies."))
47230b23
MT
769 sub_build.add_argument("--prepare", action="store_true",
770 help=_("Only run the prepare stage."))
c07a3ca7
MT
771
772 def handle_build(self):
773 # Get the package descriptor from the command line options
774 pkg = self.args.package[0]
775
776 # Check, if we got a regular file
777 if os.path.exists(pkg):
778 pkg = os.path.abspath(pkg)
779 else:
780 raise FileNotFoundError, pkg
781
013eb9f2
MT
782 # Create pakfire instance.
783 c = config.ConfigBuilder()
784 p = base.Pakfire(arch = self.args.arch, config = c)
854d8ccf 785
013eb9f2 786 # Disable all repositories.
8fe602a7 787 if self.args.nodeps:
013eb9f2
MT
788 p.repos.disable_repo("*")
789
790 # Limit stages that are to be run.
791 if self.args.prepare:
792 stages = ["prepare"]
8fe602a7 793 else:
013eb9f2 794 stages = None
4fffe3c4 795
013eb9f2 796 p.build(pkg, resultdir=self.args.resultdir, stages=stages)
c62d93f1
MT
797
798
799class CliClient(Cli):
800 def __init__(self):
801 self.parser = argparse.ArgumentParser(
802 description = _("Pakfire client command line interface."),
803 )
804
805 self.parse_common_arguments(repo_manage_switches=True, offline_switch=True)
806
807 # Add sub-commands.
808 self.sub_commands = self.parser.add_subparsers()
809
810 self.parse_command_build()
811 self.parse_command_connection_check()
812 self.parse_command_info()
25a98632
MT
813 self.parse_command_jobs()
814 self.parse_command_builds()
37ff3f8f 815 self.parse_command_test()
c62d93f1
MT
816
817 # Finally parse all arguments from the command line and save them.
818 self.args = self.parser.parse_args()
819
820 self.action2func = {
821 "build" : self.handle_build,
822 "conn-check" : self.handle_connection_check,
823 "info" : self.handle_info,
25a98632
MT
824 "jobs_show" : self.handle_jobs_show,
825 "jobs_active" : self.handle_jobs_active,
826 "jobs_latest" : self.handle_jobs_latest,
827 "builds_show" : self.handle_builds_show,
37ff3f8f 828 "test" : self.handle_test,
c62d93f1
MT
829 }
830
831 # Read configuration for the pakfire client.
832 self.conf = conf = config.ConfigClient()
833
834 # Create connection to pakfire hub.
835 self.client = client.PakfireUserClient(
836 conf.get("client", "server"),
837 conf.get("client", "username"),
838 conf.get("client", "password"),
839 )
840
841 def parse_command_build(self):
842 # Parse "build" command.
843 sub_build = self.sub_commands.add_parser("build",
844 help=_("Build a package remotely."))
845 sub_build.add_argument("package", nargs=1,
846 help=_("Give name of a package to build."))
847 sub_build.add_argument("action", action="store_const", const="build")
848
849 sub_build.add_argument("-a", "--arch",
850 help=_("Build the package for the given architecture."))
851
852 def parse_command_info(self):
853 # Implement the "info" command.
854 sub_info = self.sub_commands.add_parser("info",
855 help=_("Print some information about this host."))
856 sub_info.add_argument("action", action="store_const", const="info")
857
858 def parse_command_connection_check(self):
859 # Implement the "conn-check" command.
860 sub_conn_check = self.sub_commands.add_parser("conn-check",
861 help=_("Check the connection to the hub."))
862 sub_conn_check.add_argument("action", action="store_const", const="conn-check")
863
25a98632
MT
864 def parse_command_jobs(self):
865 sub_jobs = self.sub_commands.add_parser("jobs",
866 help=_("Show information about build jobs."))
867
868 sub_jobs_commands = sub_jobs.add_subparsers()
869
870 self.parse_command_jobs_active(sub_jobs_commands)
871 self.parse_command_jobs_latest(sub_jobs_commands)
872 self.parse_command_jobs_show(sub_jobs_commands)
873
874 def parse_command_jobs_active(self, sub_commands):
875 sub_active = sub_commands.add_parser("active",
876 help=_("Show a list of all active jobs."))
877 sub_active.add_argument("action", action="store_const", const="jobs_active")
878
879 def parse_command_jobs_latest(self, sub_commands):
880 sub_latest = sub_commands.add_parser("latest",
881 help=_("Show a list of all recently finished of failed build jobs."))
882 sub_latest.add_argument("action", action="store_const", const="jobs_latest")
883
884 def parse_command_jobs_show(self, sub_commands):
885 sub_show = sub_commands.add_parser("show",
886 help=_("Show details about given build job."))
887 sub_show.add_argument("job_id", nargs=1, help=_("The ID of the build job."))
888 sub_show.add_argument("action", action="store_const", const="jobs_show")
889
890 def parse_command_builds(self):
891 sub_builds = self.sub_commands.add_parser("builds",
892 help=_("Show information about builds."))
893
894 sub_builds_commands = sub_builds.add_subparsers()
895
896 self.parse_command_builds_show(sub_builds_commands)
897
898 def parse_command_builds_show(self, sub_commands):
899 sub_show = sub_commands.add_parser("show",
900 help=_("Show details about the given build."))
901 sub_show.add_argument("build_id", nargs=1, help=_("The ID of the build."))
902 sub_show.add_argument("action", action="store_const", const="builds_show")
903
37ff3f8f
MT
904 def parse_command_test(self):
905 sub_test = self.sub_commands.add_parser("test",
906 help=_("Test the connection to the hub."))
907 sub_test.add_argument("error_code", nargs=1, help=_("Error code to test."))
908 sub_test.add_argument("action", action="store_const", const="test")
909
c62d93f1
MT
910 def handle_build(self):
911 (package,) = self.args.package
912
913 # XXX just for now, we do only upload source pfm files.
914 assert os.path.exists(package)
915
b913e798
MT
916 # Create a temporary directory.
917 temp_dir = tempfile.mkdtemp()
918
919 try:
920 if package.endswith(".%s" % MAKEFILE_EXTENSION):
36b328f2 921 pakfire_args = {}
b913e798
MT
922
923 # Create a source package from the makefile.
36b328f2
MT
924 p = self.pakfire(**self.pakfire_args)
925 package = p.dist(package, temp_dir)
b913e798
MT
926
927 elif package.endswith(".%s" % PACKAGE_EXTENSION):
928 pass
c62d93f1 929
b913e798
MT
930 else:
931 raise Exception, "Unknown filetype: %s" % package
932
933 # Format arches.
934 if self.args.arch:
935 arches = self.args.arch.replace(",", " ")
936 else:
937 arches = None
c62d93f1 938
b913e798
MT
939 # Create a new build on the server.
940 build = self.client.build_create(package, arches=arches)
941
942 # XXX Print the resulting build.
943 print build
944
945 finally:
946 # Cleanup the temporary directory and all files.
947 if os.path.exists(temp_dir):
948 shutil.rmtree(temp_dir, ignore_errors=True)
c62d93f1
MT
949
950 def handle_info(self):
951 ret = []
952
953 ret.append("")
954 ret.append(" PAKFIRE %s" % PAKFIRE_VERSION)
955 ret.append("")
956 ret.append(" %-20s: %s" % (_("Hostname"), system.hostname))
957 ret.append(" %-20s: %s" % (_("Pakfire hub"), self.conf.get("client", "server")))
958 if self.conf.get("client", "username") and self.conf.get("client", "password"):
959 ret.append(" %-20s: %s" % \
960 (_("Username"), self.conf.get("client", "username")))
961 ret.append("")
962
963 # Hardware information
964 ret.append(" %s:" % _("Hardware information"))
965 ret.append(" %-16s: %s" % (_("CPU model"), system.cpu_model))
966 ret.append(" %-16s: %s" % (_("Memory"), util.format_size(system.memory)))
cae35096 967 ret.append(" %-16s: %s" % (_("Parallelism"), system.parallelism))
c62d93f1 968 ret.append("")
790a44cc
MT
969 ret.append(" %-16s: %s" % (_("Native arch"), system.native_arch))
970 if not system.arch == system.native_arch:
971 ret.append(" %-16s: %s" % (_("Default arch"), system.arch))
c62d93f1
MT
972
973 header = _("Supported arches")
974 for arch in system.supported_arches:
975 ret.append(" %-16s: %s" % (header, arch))
976 header = ""
977 ret.append("")
978
979 for line in ret:
980 print line
981
982 def handle_connection_check(self):
983 ret = []
984
985 address = self.client.get_my_address()
986 ret.append(" %-20s: %s" % (_("Your IP address"), address))
987 ret.append("")
988
989 authenticated = self.client.check_auth()
990 if authenticated:
991 ret.append(" %s" % _("You are authenticated to the build service:"))
992
993 user = self.client.get_user_profile()
994 assert user, "Could not fetch user infomation"
995
996 keys = [
997 ("name", _("User name")),
998 ("realname", _("Real name")),
999 ("email", _("Email address")),
1000 ("registered", _("Registered")),
1001 ]
1002
1003 for key, desc in keys:
1004 ret.append(" %-18s: %s" % (desc, user.get(key)))
1005
1006 else:
1007 ret.append(_("You could not be authenticated to the build service."))
1008
1009 for line in ret:
1010 print line
1011
25a98632
MT
1012 def _print_jobs(self, jobs, heading=None):
1013 if heading:
1014 print "%s:" % heading
1015 print
1016
1017 for job in jobs:
1018 line = " [%(type)8s] %(name)-30s: %(state)s"
1019
1020 print line % job
1021
1022 print # Empty line at the end.
1023
1024 def handle_jobs_active(self):
1025 jobs = self.client.get_active_jobs()
1026
1027 if not jobs:
1028 print _("No ongoing jobs found.")
1029 return
1030
1031 self._print_jobs(jobs, _("Active build jobs"))
1032
1033 def handle_jobs_latest(self):
1034 jobs = self.client.get_latest_jobs()
1035
1036 if not jobs:
1037 print _("No jobs found.")
1038 return
1039
1040 self._print_jobs(jobs, _("Recently processed build jobs"))
1041
1042 def handle_builds_show(self):
1043 (build_id,) = self.args.build_id
1044
1045 build = self.client.get_build(build_id)
1046 if not build:
1047 print _("A build with ID %s could not be found.") % build_id
1048 return
1049
1050 print _("Build: %(name)s") % build
1051
1052 fmt = "%-14s: %s"
1053 lines = [
1054 fmt % (_("State"), build["state"]),
1055 fmt % (_("Priority"), build["priority"]),
1056 ]
1057
1058 lines.append("%s:" % _("Jobs"))
1059 for job in build["jobs"]:
1060 lines.append(" * [%(uuid)s] %(name)-30s: %(state)s" % job)
1061
1062 for line in lines:
1063 print " ", line
1064 print
1065
1066 def handle_jobs_show(self):
1067 (job_id,) = self.args.job_id
1068
1069 job = self.client.get_job(job_id)
1070 if not job:
1071 print _("A job with ID %s could not be found.") % job_id
1072 return
1073
1074 builder = None
1075 if job["builder_id"]:
1076 builder = self.client.get_builder(job["builder_id"])
1077
1078 print _("Job: %(name)s") % job
1079
1080 fmt = "%-14s: %s"
1081 lines = [
1082 fmt % (_("State"), job["state"]),
1083 fmt % (_("Arch"), job["arch"]),
1084 ]
1085
1086 if builder:
1087 lines += [
1088 fmt % (_("Build host"), builder["name"]),
1089 "",
1090 ]
1091
1092 lines += [
1093 fmt % (_("Time created"), job["time_created"]),
1094 fmt % (_("Time started"), job["time_started"]),
1095 fmt % (_("Time finished"), job["time_finished"]),
1096 fmt % (_("Duration"), job["duration"]),
1097 ]
1098
1099 if job["packages"]:
1100 lines += ["", "%s:" % _("Packages")]
1101
1102 for pkg in job["packages"]:
1103 pkg_lines = [
1104 "* %(friendly_name)s" % pkg,
1105 " %(uuid)s" % pkg,
1106 "",
1107 ]
1108
1109 lines += [" %s" % line for line in pkg_lines]
1110
1111 for line in lines:
1112 print " ", line
1113 print # New line.
1114
37ff3f8f
MT
1115 def handle_test(self):
1116 error_code = self.args.error_code[0]
1117
1118 try:
1119 error_code = int(error_code)
1120 except ValueError:
1121 error_code = 0
1122
1123 if error_code < 100 or error_code > 999:
1124 raise Error, _("Invalid error code given.")
1125
1126 res = self.client.test_code(error_code)
1127 print _("Reponse from the server: %s") % res
1128
c62d93f1
MT
1129
1130class CliDaemon(Cli):
1131 def __init__(self):
1132 self.parser = argparse.ArgumentParser(
1133 description = _("Pakfire daemon command line interface."),
1134 )
1135
1136 self.parse_common_arguments(repo_manage_switches=True, offline_switch=True)
1137
1138 # Finally parse all arguments from the command line and save them.
1139 self.args = self.parser.parse_args()
1140
1141 def run(self):
1142 """
1143 Runs the pakfire daemon with provided settings.
1144 """
1145 # Read the configuration file for the daemon.
1146 conf = config.ConfigDaemon()
1147
1148 # Create daemon instance.
2dbaea05 1149 d = pakfire.client.PakfireDaemon()
c62d93f1
MT
1150 try:
1151 d.run()
1152
1153 # We cannot just kill the daemon, it needs a smooth shutdown.
1154 except (SystemExit, KeyboardInterrupt):
1155 d.shutdown()
68c0e769
MT
1156
1157
1158class CliKey(Cli):
1159 def __init__(self):
1160 self.parser = argparse.ArgumentParser(
1161 description = _("Pakfire key command line interface."),
1162 )
1163
1164 self.parse_common_arguments(repo_manage_switches=False,
1165 offline_switch=True)
1166
1167 # Add sub-commands.
1168 self.sub_commands = self.parser.add_subparsers()
1169
68c0e769
MT
1170 self.parse_command_generate()
1171 self.parse_command_import()
1172 self.parse_command_export()
eaf999ef 1173 self.parse_command_delete()
68c0e769
MT
1174 self.parse_command_list()
1175 self.parse_command_sign()
1176 self.parse_command_verify()
1177
1178 # Finally parse all arguments from the command line and save them.
1179 self.args = self.parser.parse_args()
1180
68c0e769 1181 self.action2func = {
68c0e769
MT
1182 "generate" : self.handle_generate,
1183 "import" : self.handle_import,
1184 "export" : self.handle_export,
eaf999ef 1185 "delete" : self.handle_delete,
68c0e769
MT
1186 "list" : self.handle_list,
1187 "sign" : self.handle_sign,
1188 "verify" : self.handle_verify,
1189 }
1190
1191 @property
1192 def pakfire_args(self):
36b328f2 1193 return {}
68c0e769 1194
68c0e769
MT
1195 def parse_command_generate(self):
1196 # Parse "generate" command.
1197 sub_gen = self.sub_commands.add_parser("generate",
1198 help=_("Import a key from file."))
1199 sub_gen.add_argument("--realname", nargs=1,
1200 help=_("The real name of the owner of this key."))
1201 sub_gen.add_argument("--email", nargs=1,
1202 help=_("The email address of the owner of this key."))
1203 sub_gen.add_argument("action", action="store_const", const="generate")
1204
1205 def parse_command_import(self):
1206 # Parse "import" command.
1207 sub_import = self.sub_commands.add_parser("import",
1208 help=_("Import a key from file."))
1209 sub_import.add_argument("filename", nargs=1,
1210 help=_("Filename of that key to import."))
1211 sub_import.add_argument("action", action="store_const", const="import")
1212
1213 def parse_command_export(self):
1214 # Parse "export" command.
1215 sub_export = self.sub_commands.add_parser("export",
1216 help=_("Export a key to a file."))
1217 sub_export.add_argument("keyid", nargs=1,
1218 help=_("The ID of the key to export."))
1219 sub_export.add_argument("filename", nargs=1,
1220 help=_("Write the key to this file."))
a78770d3
MT
1221 sub_export.add_argument("--secret", action="store_true",
1222 help=_("Export the secret key, too."))
68c0e769
MT
1223 sub_export.add_argument("action", action="store_const", const="export")
1224
eaf999ef
MT
1225 def parse_command_delete(self):
1226 # Parse "delete" command.
1227 sub_del = self.sub_commands.add_parser("delete",
1228 help=_("Delete a key from the local keyring."))
1229 sub_del.add_argument("keyid", nargs=1,
1230 help=_("The ID of the key to delete."))
1231 sub_del.add_argument("action", action="store_const", const="delete")
1232
68c0e769
MT
1233 def parse_command_list(self):
1234 # Parse "list" command.
1235 sub_list = self.sub_commands.add_parser("list",
1236 help=_("List all imported keys."))
1237 sub_list.add_argument("action", action="store_const", const="list")
1238
1239 def parse_command_sign(self):
1240 # Implement the "sign" command.
1241 sub_sign = self.sub_commands.add_parser("sign",
1242 help=_("Sign one or more packages."))
1243 sub_sign.add_argument("--key", "-k", nargs=1,
1244 help=_("Key that is used sign the package(s)."))
1245 sub_sign.add_argument("package", nargs="+",
1246 help=_("Package(s) to sign."))
1247 sub_sign.add_argument("action", action="store_const", const="sign")
1248
1249 def parse_command_verify(self):
1250 # Implement the "verify" command.
1251 sub_verify = self.sub_commands.add_parser("verify",
1252 help=_("Verify one or more packages."))
1253 #sub_verify.add_argument("--key", "-k", nargs=1,
1254 # help=_("Key that is used verify the package(s)."))
1255 sub_verify.add_argument("package", nargs="+",
1256 help=_("Package(s) to verify."))
1257 sub_verify.add_argument("action", action="store_const", const="verify")
1258
68c0e769
MT
1259 def handle_generate(self):
1260 realname = self.args.realname[0]
1261 email = self.args.email[0]
1262
1263 print _("Generating the key may take a moment...")
1264 print
1265
1266 # Generate the key.
36b328f2
MT
1267 p = self.pakfire(**self.pakfire_args)
1268 p.key_generate(realname, email)
68c0e769
MT
1269
1270 def handle_import(self):
1271 filename = self.args.filename[0]
1272
1273 # Simply import the file.
36b328f2
MT
1274 p = self.pakfire(**self.pakfire_args)
1275 p.key_import(filename)
68c0e769
MT
1276
1277 def handle_export(self):
1278 keyid = self.args.keyid[0]
1279 filename = self.args.filename[0]
a78770d3 1280 secret = self.args.secret
68c0e769 1281
36b328f2
MT
1282 p = self.pakfire(**self.pakfire_args)
1283 p.key_export(keyid, filename, secret=secret)
68c0e769 1284
eaf999ef
MT
1285 def handle_delete(self):
1286 keyid = self.args.keyid[0]
1287
36b328f2
MT
1288 p = self.pakfire(**self.pakfire_args)
1289 p.key_delete(keyid)
eaf999ef 1290
68c0e769 1291 def handle_list(self):
36b328f2
MT
1292 p = self.pakfire(**self.pakfire_args)
1293 for line in p.key_list():
68c0e769
MT
1294 print line
1295
1296 def handle_sign(self):
1297 # Get the files from the command line options
1298 files = []
1299
1300 for file in self.args.package:
1301 # Check, if we got a regular file
1302 if os.path.exists(file):
1303 file = os.path.abspath(file)
1304 files.append(file)
1305
1306 else:
1307 raise FileNotFoundError, file
1308
1309 key = self.args.key[0]
1310
36b328f2
MT
1311 # Create pakfire instance.
1312 p = self.pakfire(**self.pakfire_args)
1313
68c0e769
MT
1314 for file in files:
1315 # Open the package.
36b328f2 1316 pkg = packages.open(p, None, file)
68c0e769
MT
1317
1318 print _("Signing %s...") % pkg.friendly_name
1319 pkg.sign(key)
1320
1321 def handle_verify(self):
1322 # Get the files from the command line options
1323 files = []
1324
1325 for file in self.args.package:
1326 # Check, if we got a regular file
1327 if os.path.exists(file) and not os.path.isdir(file):
1328 file = os.path.abspath(file)
1329 files.append(file)
1330
36b328f2
MT
1331 # Create pakfire instance.
1332 p = self.pakfire(**self.pakfire_args)
1333
68c0e769
MT
1334 for file in files:
1335 # Open the package.
36b328f2 1336 pkg = packages.open(p, None, file)
68c0e769
MT
1337
1338 print _("Verifying %s...") % pkg.friendly_name
1339 sigs = pkg.verify()
1340
1341 for sig in sigs:
1342 key = self.pakfire.keyring.get_key(sig.fpr)
1343 if key:
1344 subkey = key.subkeys[0]
1345
1346 print " %s %s" % (subkey.fpr[-16:], key.uids[0].uid)
1347 if sig.validity:
1348 print " %s" % _("This signature is valid.")
1349
1350 else:
1351 print " %s <%s>" % (sig.fpr, _("Unknown key"))
1352 print " %s" % _("Could not check if this signature is valid.")
1353
1354 created = datetime.datetime.fromtimestamp(sig.timestamp)
1355 print " %s" % _("Created: %s") % created
1356
1357 if sig.exp_timestamp:
1358 expires = datetime.datetime.fromtimestamp(sig.exp_timestamp)
1359 print " %s" % _("Expires: %s") % expires
1360
1361 print # Empty line