]> git.ipfire.org Git - people/stevee/pakfire.git/blame - python/pakfire/cli.py
Fix enable/disable repository options.
[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):
36b328f2 451 ret = {}
f9a012a8 452
98733451
MT
453 if hasattr(self.args, "offline") and self.args.offline:
454 ret["downloader"] = {
455 "offline" : self.args.offline,
456 }
6a509182 457
4f08c65d
MT
458 if hasattr(self.args, "distro"):
459 ret["distro_name"] = self.args.distro
460
f9a012a8 461 return ret
7c8f2953 462
4f08c65d
MT
463 def parse_common_arguments(self, *args, **kwargs):
464 Cli.parse_common_arguments(self, *args, **kwargs)
465
466 self.parser.add_argument("--distro", nargs="?",
467 help=_("Choose the distribution configuration to use for build"))
468
47a4cb89
MT
469 def parse_command_update(self):
470 # Implement the "update" command.
471 sub_update = self.sub_commands.add_parser("update",
472 help=_("Update the package indexes."))
473 sub_update.add_argument("action", action="store_const", const="update")
474
475 def parse_command_build(self):
476 # Implement the "build" command.
477 sub_build = self.sub_commands.add_parser("build",
478 help=_("Build one or more packages."))
479 sub_build.add_argument("package", nargs=1,
480 help=_("Give name of at least one package to build."))
481 sub_build.add_argument("action", action="store_const", const="build")
482
483 sub_build.add_argument("-a", "--arch",
484 help=_("Build the package for the given architecture."))
485 sub_build.add_argument("--resultdir", nargs="?",
486 help=_("Path were the output files should be copied to."))
f22069bb
MT
487 sub_build.add_argument("-m", "--mode", nargs="?", default="development",
488 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
1710ccec
MT
489 sub_build.add_argument("--after-shell", action="store_true",
490 help=_("Run a shell after a successful build."))
4fffe3c4
MT
491 sub_build.add_argument("--no-install-test", action="store_true",
492 help=_("Do not perform the install test."))
47a4cb89
MT
493
494 def parse_command_shell(self):
495 # Implement the "shell" command.
496 sub_shell = self.sub_commands.add_parser("shell",
497 help=_("Go into a shell."))
042266f3 498 sub_shell.add_argument("package", nargs="?",
47a4cb89
MT
499 help=_("Give name of a package."))
500 sub_shell.add_argument("action", action="store_const", const="shell")
501
502 sub_shell.add_argument("-a", "--arch",
503 help=_("Emulated architecture in the shell."))
6ee3d6b9
MT
504 sub_shell.add_argument("-m", "--mode", nargs="?", default="development",
505 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
47a4cb89
MT
506
507 def parse_command_dist(self):
508 # Implement the "dist" command.
509 sub_dist = self.sub_commands.add_parser("dist",
510 help=_("Generate a source package."))
e412b8dc
MT
511 sub_dist.add_argument("package", nargs="+",
512 help=_("Give name(s) of a package(s)."))
47a4cb89
MT
513 sub_dist.add_argument("action", action="store_const", const="dist")
514
515 sub_dist.add_argument("--resultdir", nargs="?",
516 help=_("Path were the output files should be copied to."))
517
9afa5620
MT
518 def handle_info(self):
519 Cli.handle_info(self, long=True)
520
47a4cb89 521 def handle_build(self):
47a4cb89
MT
522 # Get the package descriptor from the command line options
523 pkg = self.args.package[0]
524
525 # Check, if we got a regular file
526 if os.path.exists(pkg):
527 pkg = os.path.abspath(pkg)
528
47a4cb89 529 else:
7c8f2953 530 raise FileNotFoundError, pkg
47a4cb89 531
4fffe3c4
MT
532 # Check whether to enable the install test.
533 install_test = not self.args.no_install_test
534
36b328f2
MT
535 if self.args.mode == "release":
536 release_build = True
537 else:
538 release_build = False
539
685cb819 540 p = self.create_pakfire(arch=self.args.arch)
36b328f2
MT
541 p.build(pkg,
542 install_test=install_test,
543 resultdirs=[self.args.resultdir,],
544 shell=True,
545 after_shell=self.args.after_shell,
546 release_build=release_build,
547 )
47a4cb89
MT
548
549 def handle_shell(self):
042266f3
MT
550 pkg = None
551
47a4cb89 552 # Get the package descriptor from the command line options
042266f3 553 if self.args.package:
ad1b844f 554 pkg = self.args.package
47a4cb89 555
7c8f2953
MT
556 # Check, if we got a regular file
557 if os.path.exists(pkg):
558 pkg = os.path.abspath(pkg)
47a4cb89 559
7c8f2953
MT
560 else:
561 raise FileNotFoundError, pkg
47a4cb89 562
36b328f2
MT
563 if self.args.mode == "release":
564 release_build = True
565 else:
566 release_build = False
567
685cb819 568 p = self.create_pakfire(arch=self.args.arch)
36b328f2 569 p.shell(pkg, release_build=release_build)
47a4cb89
MT
570
571 def handle_dist(self):
e412b8dc
MT
572 # Get the packages from the command line options
573 pkgs = []
47a4cb89 574
e412b8dc
MT
575 for pkg in self.args.package:
576 # Check, if we got a regular file
577 if os.path.exists(pkg):
578 pkg = os.path.abspath(pkg)
7c8f2953 579 pkgs.append(pkg)
47a4cb89 580
e412b8dc 581 else:
7c8f2953
MT
582 raise FileNotFoundError, pkg
583
7d40ac70
MT
584 # Put packages to where the user said or our
585 # current working directory.
586 resultdir = self.args.resultdir or os.getcwd()
587
685cb819 588 p = self.create_pakfire()
7d40ac70 589 for pkg in pkgs:
36b328f2 590 p.dist(pkg, resultdir=resultdir)
47a4cb89 591
c605d735 592 def handle_provides(self):
36b328f2 593 Cli.handle_provides(long=True)
c605d735 594
47a4cb89 595
3ad4bb5a 596class CliServer(Cli):
36b328f2
MT
597 pakfire = base.PakfireServer
598
677ff42a
MT
599 def __init__(self):
600 self.parser = argparse.ArgumentParser(
3ad4bb5a 601 description = _("Pakfire server command line interface."),
677ff42a
MT
602 )
603
604 self.parse_common_arguments()
605
606 # Add sub-commands.
607 self.sub_commands = self.parser.add_subparsers()
608
a52f536c 609 self.parse_command_build()
677ff42a 610 self.parse_command_keepalive()
8276111d 611 self.parse_command_repoupdate()
df9c4f62 612 self.parse_command_repo()
aad6f600 613 self.parse_command_info()
677ff42a
MT
614
615 # Finally parse all arguments from the command line and save them.
616 self.args = self.parser.parse_args()
617
269c59f3 618 self.server = server.Server(**self.pakfire_args)
677ff42a
MT
619
620 self.action2func = {
8276111d 621 "build" : self.handle_build,
aad6f600 622 "info" : self.handle_info,
8276111d
MT
623 "keepalive" : self.handle_keepalive,
624 "repoupdate" : self.handle_repoupdate,
df9c4f62 625 "repo_create": self.handle_repo_create,
677ff42a
MT
626 }
627
6557ff4c
MT
628 @property
629 def pakfire_args(self):
36b328f2 630 ret = {}
6557ff4c 631
98733451
MT
632 if hasattr(self.args, "offline") and self.args.offline:
633 ret["downloader"] = {
634 "offline" : self.args.offline,
635 }
6a509182 636
6557ff4c
MT
637 return ret
638
a52f536c
MT
639 def parse_command_build(self):
640 # Implement the "build" command.
c62d93f1
MT
641 sub_build = self.sub_commands.add_parser("build",
642 help=_("Send a scrach build job to the server."))
643 sub_build.add_argument("package", nargs=1,
644 help=_("Give name of at least one package to build."))
645 sub_build.add_argument("--arch", "-a",
646 help=_("Limit build to only these architecture(s)."))
647 sub_build.add_argument("action", action="store_const", const="build")
a52f536c 648
677ff42a
MT
649 def parse_command_keepalive(self):
650 # Implement the "keepalive" command.
651 sub_keepalive = self.sub_commands.add_parser("keepalive",
652 help=_("Send a keepalive to the server."))
653 sub_keepalive.add_argument("action", action="store_const",
654 const="keepalive")
655
8276111d
MT
656 def parse_command_repoupdate(self):
657 # Implement the "repoupdate" command.
658 sub_repoupdate = self.sub_commands.add_parser("repoupdate",
659 help=_("Update all repositories."))
660 sub_repoupdate.add_argument("action", action="store_const",
661 const="repoupdate")
662
df9c4f62
MT
663 def parse_command_repo(self):
664 sub_repo = self.sub_commands.add_parser("repo",
665 help=_("Repository management commands."))
666
667 sub_repo_commands = sub_repo.add_subparsers()
668
669 self.parse_command_repo_create(sub_repo_commands)
670
671 def parse_command_repo_create(self, sub_commands):
672 sub_create = sub_commands.add_parser("create",
673 help=_("Create a new repository index."))
68c0e769
MT
674 sub_create.add_argument("path", nargs=1,
675 help=_("Path to the packages."))
676 sub_create.add_argument("inputs", nargs="+",
677 help=_("Path to input packages."))
678 sub_create.add_argument("--key", "-k", nargs="?",
679 help=_("Key to sign the repository with."))
df9c4f62
MT
680 sub_create.add_argument("action", action="store_const", const="repo_create")
681
aad6f600
MT
682 def parse_command_info(self):
683 sub_info = self.sub_commands.add_parser("info",
684 help=_("Dump some information about this machine."))
685 sub_info.add_argument("action", action="store_const", const="info")
686
677ff42a 687 def handle_keepalive(self):
3ad4bb5a 688 self.server.update_info()
9613a111 689
a52f536c 690 def handle_build(self):
c62d93f1
MT
691 # Arch.
692 if self.args.arch:
693 arches = self.args.arch.split()
694
695 (package,) = self.args.package
696
697 self.server.create_scratch_build({})
698 return
699
700 # Temporary folter for source package.
701 tmpdir = "/tmp/pakfire-%s" % util.random_string()
702
703 try:
704 os.makedirs(tmpdir)
705
706 pakfire.dist(package, resultdir=[tmpdir,])
707
708 for file in os.listdir(tmpdir):
709 file = os.path.join(tmpdir, file)
710
711 print file
712
713 finally:
714 if os.path.exists(tmpdir):
715 util.rm(tmpdir)
8276111d
MT
716
717 def handle_repoupdate(self):
718 self.server.update_repositories()
df9c4f62
MT
719
720 def handle_repo_create(self):
721 path = self.args.path[0]
722
36b328f2
MT
723 p = self.pakfire(**self.pakfire_args)
724 p.repo_create(path, self.args.inputs, key_id=self.args.key)
c07a3ca7 725
aad6f600
MT
726 def handle_info(self):
727 info = self.server.info()
728
729 print "\n".join(info)
730
c07a3ca7 731
9b875540 732class CliBuilderIntern(Cli):
c07a3ca7
MT
733 def __init__(self):
734 self.parser = argparse.ArgumentParser(
735 description = _("Pakfire builder command line interface."),
736 )
737
738 self.parse_common_arguments()
739
740 # Add sub-commands.
741 self.sub_commands = self.parser.add_subparsers()
742
743 self.parse_command_build()
744
745 # Finally parse all arguments from the command line and save them.
746 self.args = self.parser.parse_args()
747
748 self.action2func = {
749 "build" : self.handle_build,
750 }
751
752 def parse_command_build(self):
753 # Implement the "build" command.
754 sub_build = self.sub_commands.add_parser("build",
755 help=_("Build one or more packages."))
756 sub_build.add_argument("package", nargs=1,
757 help=_("Give name of at least one package to build."))
758 sub_build.add_argument("action", action="store_const", const="build")
759
760 sub_build.add_argument("-a", "--arch",
761 help=_("Build the package for the given architecture."))
762 sub_build.add_argument("--resultdir", nargs="?",
763 help=_("Path were the output files should be copied to."))
764 sub_build.add_argument("-m", "--mode", nargs="?", default="development",
765 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
766 sub_build.add_argument("--nodeps", action="store_true",
767 help=_("Do not verify build dependencies."))
47230b23
MT
768 sub_build.add_argument("--prepare", action="store_true",
769 help=_("Only run the prepare stage."))
c07a3ca7
MT
770
771 def handle_build(self):
772 # Get the package descriptor from the command line options
773 pkg = self.args.package[0]
774
775 # Check, if we got a regular file
776 if os.path.exists(pkg):
777 pkg = os.path.abspath(pkg)
778 else:
779 raise FileNotFoundError, pkg
780
013eb9f2
MT
781 # Create pakfire instance.
782 c = config.ConfigBuilder()
783 p = base.Pakfire(arch = self.args.arch, config = c)
854d8ccf 784
013eb9f2 785 # Disable all repositories.
8fe602a7 786 if self.args.nodeps:
013eb9f2
MT
787 p.repos.disable_repo("*")
788
789 # Limit stages that are to be run.
790 if self.args.prepare:
791 stages = ["prepare"]
8fe602a7 792 else:
013eb9f2 793 stages = None
4fffe3c4 794
013eb9f2 795 p.build(pkg, resultdir=self.args.resultdir, stages=stages)
c62d93f1
MT
796
797
798class CliClient(Cli):
799 def __init__(self):
800 self.parser = argparse.ArgumentParser(
801 description = _("Pakfire client command line interface."),
802 )
803
804 self.parse_common_arguments(repo_manage_switches=True, offline_switch=True)
805
806 # Add sub-commands.
807 self.sub_commands = self.parser.add_subparsers()
808
809 self.parse_command_build()
810 self.parse_command_connection_check()
811 self.parse_command_info()
25a98632
MT
812 self.parse_command_jobs()
813 self.parse_command_builds()
37ff3f8f 814 self.parse_command_test()
c62d93f1
MT
815
816 # Finally parse all arguments from the command line and save them.
817 self.args = self.parser.parse_args()
818
819 self.action2func = {
820 "build" : self.handle_build,
821 "conn-check" : self.handle_connection_check,
822 "info" : self.handle_info,
25a98632
MT
823 "jobs_show" : self.handle_jobs_show,
824 "jobs_active" : self.handle_jobs_active,
825 "jobs_latest" : self.handle_jobs_latest,
826 "builds_show" : self.handle_builds_show,
37ff3f8f 827 "test" : self.handle_test,
c62d93f1
MT
828 }
829
830 # Read configuration for the pakfire client.
831 self.conf = conf = config.ConfigClient()
832
833 # Create connection to pakfire hub.
834 self.client = client.PakfireUserClient(
835 conf.get("client", "server"),
836 conf.get("client", "username"),
837 conf.get("client", "password"),
838 )
839
840 def parse_command_build(self):
841 # Parse "build" command.
842 sub_build = self.sub_commands.add_parser("build",
843 help=_("Build a package remotely."))
844 sub_build.add_argument("package", nargs=1,
845 help=_("Give name of a package to build."))
846 sub_build.add_argument("action", action="store_const", const="build")
847
848 sub_build.add_argument("-a", "--arch",
849 help=_("Build the package for the given architecture."))
850
851 def parse_command_info(self):
852 # Implement the "info" command.
853 sub_info = self.sub_commands.add_parser("info",
854 help=_("Print some information about this host."))
855 sub_info.add_argument("action", action="store_const", const="info")
856
857 def parse_command_connection_check(self):
858 # Implement the "conn-check" command.
859 sub_conn_check = self.sub_commands.add_parser("conn-check",
860 help=_("Check the connection to the hub."))
861 sub_conn_check.add_argument("action", action="store_const", const="conn-check")
862
25a98632
MT
863 def parse_command_jobs(self):
864 sub_jobs = self.sub_commands.add_parser("jobs",
865 help=_("Show information about build jobs."))
866
867 sub_jobs_commands = sub_jobs.add_subparsers()
868
869 self.parse_command_jobs_active(sub_jobs_commands)
870 self.parse_command_jobs_latest(sub_jobs_commands)
871 self.parse_command_jobs_show(sub_jobs_commands)
872
873 def parse_command_jobs_active(self, sub_commands):
874 sub_active = sub_commands.add_parser("active",
875 help=_("Show a list of all active jobs."))
876 sub_active.add_argument("action", action="store_const", const="jobs_active")
877
878 def parse_command_jobs_latest(self, sub_commands):
879 sub_latest = sub_commands.add_parser("latest",
880 help=_("Show a list of all recently finished of failed build jobs."))
881 sub_latest.add_argument("action", action="store_const", const="jobs_latest")
882
883 def parse_command_jobs_show(self, sub_commands):
884 sub_show = sub_commands.add_parser("show",
885 help=_("Show details about given build job."))
886 sub_show.add_argument("job_id", nargs=1, help=_("The ID of the build job."))
887 sub_show.add_argument("action", action="store_const", const="jobs_show")
888
889 def parse_command_builds(self):
890 sub_builds = self.sub_commands.add_parser("builds",
891 help=_("Show information about builds."))
892
893 sub_builds_commands = sub_builds.add_subparsers()
894
895 self.parse_command_builds_show(sub_builds_commands)
896
897 def parse_command_builds_show(self, sub_commands):
898 sub_show = sub_commands.add_parser("show",
899 help=_("Show details about the given build."))
900 sub_show.add_argument("build_id", nargs=1, help=_("The ID of the build."))
901 sub_show.add_argument("action", action="store_const", const="builds_show")
902
37ff3f8f
MT
903 def parse_command_test(self):
904 sub_test = self.sub_commands.add_parser("test",
905 help=_("Test the connection to the hub."))
906 sub_test.add_argument("error_code", nargs=1, help=_("Error code to test."))
907 sub_test.add_argument("action", action="store_const", const="test")
908
c62d93f1
MT
909 def handle_build(self):
910 (package,) = self.args.package
911
912 # XXX just for now, we do only upload source pfm files.
913 assert os.path.exists(package)
914
b913e798
MT
915 # Create a temporary directory.
916 temp_dir = tempfile.mkdtemp()
917
918 try:
919 if package.endswith(".%s" % MAKEFILE_EXTENSION):
36b328f2 920 pakfire_args = {}
b913e798
MT
921
922 # Create a source package from the makefile.
36b328f2
MT
923 p = self.pakfire(**self.pakfire_args)
924 package = p.dist(package, temp_dir)
b913e798
MT
925
926 elif package.endswith(".%s" % PACKAGE_EXTENSION):
927 pass
c62d93f1 928
b913e798
MT
929 else:
930 raise Exception, "Unknown filetype: %s" % package
931
932 # Format arches.
933 if self.args.arch:
934 arches = self.args.arch.replace(",", " ")
935 else:
936 arches = None
c62d93f1 937
b913e798
MT
938 # Create a new build on the server.
939 build = self.client.build_create(package, arches=arches)
940
941 # XXX Print the resulting build.
942 print build
943
944 finally:
945 # Cleanup the temporary directory and all files.
946 if os.path.exists(temp_dir):
947 shutil.rmtree(temp_dir, ignore_errors=True)
c62d93f1
MT
948
949 def handle_info(self):
950 ret = []
951
952 ret.append("")
953 ret.append(" PAKFIRE %s" % PAKFIRE_VERSION)
954 ret.append("")
955 ret.append(" %-20s: %s" % (_("Hostname"), system.hostname))
956 ret.append(" %-20s: %s" % (_("Pakfire hub"), self.conf.get("client", "server")))
957 if self.conf.get("client", "username") and self.conf.get("client", "password"):
958 ret.append(" %-20s: %s" % \
959 (_("Username"), self.conf.get("client", "username")))
960 ret.append("")
961
962 # Hardware information
963 ret.append(" %s:" % _("Hardware information"))
964 ret.append(" %-16s: %s" % (_("CPU model"), system.cpu_model))
965 ret.append(" %-16s: %s" % (_("Memory"), util.format_size(system.memory)))
cae35096 966 ret.append(" %-16s: %s" % (_("Parallelism"), system.parallelism))
c62d93f1 967 ret.append("")
790a44cc
MT
968 ret.append(" %-16s: %s" % (_("Native arch"), system.native_arch))
969 if not system.arch == system.native_arch:
970 ret.append(" %-16s: %s" % (_("Default arch"), system.arch))
c62d93f1
MT
971
972 header = _("Supported arches")
973 for arch in system.supported_arches:
974 ret.append(" %-16s: %s" % (header, arch))
975 header = ""
976 ret.append("")
977
978 for line in ret:
979 print line
980
981 def handle_connection_check(self):
982 ret = []
983
984 address = self.client.get_my_address()
985 ret.append(" %-20s: %s" % (_("Your IP address"), address))
986 ret.append("")
987
988 authenticated = self.client.check_auth()
989 if authenticated:
990 ret.append(" %s" % _("You are authenticated to the build service:"))
991
992 user = self.client.get_user_profile()
993 assert user, "Could not fetch user infomation"
994
995 keys = [
996 ("name", _("User name")),
997 ("realname", _("Real name")),
998 ("email", _("Email address")),
999 ("registered", _("Registered")),
1000 ]
1001
1002 for key, desc in keys:
1003 ret.append(" %-18s: %s" % (desc, user.get(key)))
1004
1005 else:
1006 ret.append(_("You could not be authenticated to the build service."))
1007
1008 for line in ret:
1009 print line
1010
25a98632
MT
1011 def _print_jobs(self, jobs, heading=None):
1012 if heading:
1013 print "%s:" % heading
1014 print
1015
1016 for job in jobs:
1017 line = " [%(type)8s] %(name)-30s: %(state)s"
1018
1019 print line % job
1020
1021 print # Empty line at the end.
1022
1023 def handle_jobs_active(self):
1024 jobs = self.client.get_active_jobs()
1025
1026 if not jobs:
1027 print _("No ongoing jobs found.")
1028 return
1029
1030 self._print_jobs(jobs, _("Active build jobs"))
1031
1032 def handle_jobs_latest(self):
1033 jobs = self.client.get_latest_jobs()
1034
1035 if not jobs:
1036 print _("No jobs found.")
1037 return
1038
1039 self._print_jobs(jobs, _("Recently processed build jobs"))
1040
1041 def handle_builds_show(self):
1042 (build_id,) = self.args.build_id
1043
1044 build = self.client.get_build(build_id)
1045 if not build:
1046 print _("A build with ID %s could not be found.") % build_id
1047 return
1048
1049 print _("Build: %(name)s") % build
1050
1051 fmt = "%-14s: %s"
1052 lines = [
1053 fmt % (_("State"), build["state"]),
1054 fmt % (_("Priority"), build["priority"]),
1055 ]
1056
1057 lines.append("%s:" % _("Jobs"))
1058 for job in build["jobs"]:
1059 lines.append(" * [%(uuid)s] %(name)-30s: %(state)s" % job)
1060
1061 for line in lines:
1062 print " ", line
1063 print
1064
1065 def handle_jobs_show(self):
1066 (job_id,) = self.args.job_id
1067
1068 job = self.client.get_job(job_id)
1069 if not job:
1070 print _("A job with ID %s could not be found.") % job_id
1071 return
1072
1073 builder = None
1074 if job["builder_id"]:
1075 builder = self.client.get_builder(job["builder_id"])
1076
1077 print _("Job: %(name)s") % job
1078
1079 fmt = "%-14s: %s"
1080 lines = [
1081 fmt % (_("State"), job["state"]),
1082 fmt % (_("Arch"), job["arch"]),
1083 ]
1084
1085 if builder:
1086 lines += [
1087 fmt % (_("Build host"), builder["name"]),
1088 "",
1089 ]
1090
1091 lines += [
1092 fmt % (_("Time created"), job["time_created"]),
1093 fmt % (_("Time started"), job["time_started"]),
1094 fmt % (_("Time finished"), job["time_finished"]),
1095 fmt % (_("Duration"), job["duration"]),
1096 ]
1097
1098 if job["packages"]:
1099 lines += ["", "%s:" % _("Packages")]
1100
1101 for pkg in job["packages"]:
1102 pkg_lines = [
1103 "* %(friendly_name)s" % pkg,
1104 " %(uuid)s" % pkg,
1105 "",
1106 ]
1107
1108 lines += [" %s" % line for line in pkg_lines]
1109
1110 for line in lines:
1111 print " ", line
1112 print # New line.
1113
37ff3f8f
MT
1114 def handle_test(self):
1115 error_code = self.args.error_code[0]
1116
1117 try:
1118 error_code = int(error_code)
1119 except ValueError:
1120 error_code = 0
1121
1122 if error_code < 100 or error_code > 999:
1123 raise Error, _("Invalid error code given.")
1124
1125 res = self.client.test_code(error_code)
1126 print _("Reponse from the server: %s") % res
1127
c62d93f1
MT
1128
1129class CliDaemon(Cli):
1130 def __init__(self):
1131 self.parser = argparse.ArgumentParser(
1132 description = _("Pakfire daemon command line interface."),
1133 )
1134
1135 self.parse_common_arguments(repo_manage_switches=True, offline_switch=True)
1136
1137 # Finally parse all arguments from the command line and save them.
1138 self.args = self.parser.parse_args()
1139
1140 def run(self):
1141 """
1142 Runs the pakfire daemon with provided settings.
1143 """
1144 # Read the configuration file for the daemon.
1145 conf = config.ConfigDaemon()
1146
1147 # Create daemon instance.
2dbaea05 1148 d = pakfire.client.PakfireDaemon()
c62d93f1
MT
1149 try:
1150 d.run()
1151
1152 # We cannot just kill the daemon, it needs a smooth shutdown.
1153 except (SystemExit, KeyboardInterrupt):
1154 d.shutdown()
68c0e769
MT
1155
1156
1157class CliKey(Cli):
1158 def __init__(self):
1159 self.parser = argparse.ArgumentParser(
1160 description = _("Pakfire key command line interface."),
1161 )
1162
1163 self.parse_common_arguments(repo_manage_switches=False,
1164 offline_switch=True)
1165
1166 # Add sub-commands.
1167 self.sub_commands = self.parser.add_subparsers()
1168
68c0e769
MT
1169 self.parse_command_generate()
1170 self.parse_command_import()
1171 self.parse_command_export()
eaf999ef 1172 self.parse_command_delete()
68c0e769
MT
1173 self.parse_command_list()
1174 self.parse_command_sign()
1175 self.parse_command_verify()
1176
1177 # Finally parse all arguments from the command line and save them.
1178 self.args = self.parser.parse_args()
1179
68c0e769 1180 self.action2func = {
68c0e769
MT
1181 "generate" : self.handle_generate,
1182 "import" : self.handle_import,
1183 "export" : self.handle_export,
eaf999ef 1184 "delete" : self.handle_delete,
68c0e769
MT
1185 "list" : self.handle_list,
1186 "sign" : self.handle_sign,
1187 "verify" : self.handle_verify,
1188 }
1189
1190 @property
1191 def pakfire_args(self):
36b328f2 1192 return {}
68c0e769 1193
68c0e769
MT
1194 def parse_command_generate(self):
1195 # Parse "generate" command.
1196 sub_gen = self.sub_commands.add_parser("generate",
1197 help=_("Import a key from file."))
1198 sub_gen.add_argument("--realname", nargs=1,
1199 help=_("The real name of the owner of this key."))
1200 sub_gen.add_argument("--email", nargs=1,
1201 help=_("The email address of the owner of this key."))
1202 sub_gen.add_argument("action", action="store_const", const="generate")
1203
1204 def parse_command_import(self):
1205 # Parse "import" command.
1206 sub_import = self.sub_commands.add_parser("import",
1207 help=_("Import a key from file."))
1208 sub_import.add_argument("filename", nargs=1,
1209 help=_("Filename of that key to import."))
1210 sub_import.add_argument("action", action="store_const", const="import")
1211
1212 def parse_command_export(self):
1213 # Parse "export" command.
1214 sub_export = self.sub_commands.add_parser("export",
1215 help=_("Export a key to a file."))
1216 sub_export.add_argument("keyid", nargs=1,
1217 help=_("The ID of the key to export."))
1218 sub_export.add_argument("filename", nargs=1,
1219 help=_("Write the key to this file."))
a78770d3
MT
1220 sub_export.add_argument("--secret", action="store_true",
1221 help=_("Export the secret key, too."))
68c0e769
MT
1222 sub_export.add_argument("action", action="store_const", const="export")
1223
eaf999ef
MT
1224 def parse_command_delete(self):
1225 # Parse "delete" command.
1226 sub_del = self.sub_commands.add_parser("delete",
1227 help=_("Delete a key from the local keyring."))
1228 sub_del.add_argument("keyid", nargs=1,
1229 help=_("The ID of the key to delete."))
1230 sub_del.add_argument("action", action="store_const", const="delete")
1231
68c0e769
MT
1232 def parse_command_list(self):
1233 # Parse "list" command.
1234 sub_list = self.sub_commands.add_parser("list",
1235 help=_("List all imported keys."))
1236 sub_list.add_argument("action", action="store_const", const="list")
1237
1238 def parse_command_sign(self):
1239 # Implement the "sign" command.
1240 sub_sign = self.sub_commands.add_parser("sign",
1241 help=_("Sign one or more packages."))
1242 sub_sign.add_argument("--key", "-k", nargs=1,
1243 help=_("Key that is used sign the package(s)."))
1244 sub_sign.add_argument("package", nargs="+",
1245 help=_("Package(s) to sign."))
1246 sub_sign.add_argument("action", action="store_const", const="sign")
1247
1248 def parse_command_verify(self):
1249 # Implement the "verify" command.
1250 sub_verify = self.sub_commands.add_parser("verify",
1251 help=_("Verify one or more packages."))
1252 #sub_verify.add_argument("--key", "-k", nargs=1,
1253 # help=_("Key that is used verify the package(s)."))
1254 sub_verify.add_argument("package", nargs="+",
1255 help=_("Package(s) to verify."))
1256 sub_verify.add_argument("action", action="store_const", const="verify")
1257
68c0e769
MT
1258 def handle_generate(self):
1259 realname = self.args.realname[0]
1260 email = self.args.email[0]
1261
1262 print _("Generating the key may take a moment...")
1263 print
1264
1265 # Generate the key.
36b328f2
MT
1266 p = self.pakfire(**self.pakfire_args)
1267 p.key_generate(realname, email)
68c0e769
MT
1268
1269 def handle_import(self):
1270 filename = self.args.filename[0]
1271
1272 # Simply import the file.
36b328f2
MT
1273 p = self.pakfire(**self.pakfire_args)
1274 p.key_import(filename)
68c0e769
MT
1275
1276 def handle_export(self):
1277 keyid = self.args.keyid[0]
1278 filename = self.args.filename[0]
a78770d3 1279 secret = self.args.secret
68c0e769 1280
36b328f2
MT
1281 p = self.pakfire(**self.pakfire_args)
1282 p.key_export(keyid, filename, secret=secret)
68c0e769 1283
eaf999ef
MT
1284 def handle_delete(self):
1285 keyid = self.args.keyid[0]
1286
36b328f2
MT
1287 p = self.pakfire(**self.pakfire_args)
1288 p.key_delete(keyid)
eaf999ef 1289
68c0e769 1290 def handle_list(self):
36b328f2
MT
1291 p = self.pakfire(**self.pakfire_args)
1292 for line in p.key_list():
68c0e769
MT
1293 print line
1294
1295 def handle_sign(self):
1296 # Get the files from the command line options
1297 files = []
1298
1299 for file in self.args.package:
1300 # Check, if we got a regular file
1301 if os.path.exists(file):
1302 file = os.path.abspath(file)
1303 files.append(file)
1304
1305 else:
1306 raise FileNotFoundError, file
1307
1308 key = self.args.key[0]
1309
36b328f2
MT
1310 # Create pakfire instance.
1311 p = self.pakfire(**self.pakfire_args)
1312
68c0e769
MT
1313 for file in files:
1314 # Open the package.
36b328f2 1315 pkg = packages.open(p, None, file)
68c0e769
MT
1316
1317 print _("Signing %s...") % pkg.friendly_name
1318 pkg.sign(key)
1319
1320 def handle_verify(self):
1321 # Get the files from the command line options
1322 files = []
1323
1324 for file in self.args.package:
1325 # Check, if we got a regular file
1326 if os.path.exists(file) and not os.path.isdir(file):
1327 file = os.path.abspath(file)
1328 files.append(file)
1329
36b328f2
MT
1330 # Create pakfire instance.
1331 p = self.pakfire(**self.pakfire_args)
1332
68c0e769
MT
1333 for file in files:
1334 # Open the package.
36b328f2 1335 pkg = packages.open(p, None, file)
68c0e769
MT
1336
1337 print _("Verifying %s...") % pkg.friendly_name
1338 sigs = pkg.verify()
1339
1340 for sig in sigs:
1341 key = self.pakfire.keyring.get_key(sig.fpr)
1342 if key:
1343 subkey = key.subkeys[0]
1344
1345 print " %s %s" % (subkey.fpr[-16:], key.uids[0].uid)
1346 if sig.validity:
1347 print " %s" % _("This signature is valid.")
1348
1349 else:
1350 print " %s <%s>" % (sig.fpr, _("Unknown key"))
1351 print " %s" % _("Could not check if this signature is valid.")
1352
1353 created = datetime.datetime.fromtimestamp(sig.timestamp)
1354 print " %s" % _("Created: %s") % created
1355
1356 if sig.exp_timestamp:
1357 expires = datetime.datetime.fromtimestamp(sig.exp_timestamp)
1358 print " %s" % _("Expires: %s") % expires
1359
1360 print # Empty line