]>
git.ipfire.org Git - people/stevee/pakfire.git/blob - python/pakfire/cli.py
2 ###############################################################################
4 # Pakfire - The IPFire package management system #
5 # Copyright (C) 2011 Pakfire development team #
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. #
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. #
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/>. #
20 ###############################################################################
27 import pakfire
.api
as pakfire
37 from system
import system
38 from constants
import *
41 # Initialize a very simple logging that is removed when a Pakfire instance
43 logger
.setup_logging()
47 self
.parser
= argparse
.ArgumentParser(
48 description
= _("Pakfire command line interface."),
51 self
.parse_common_arguments()
53 self
.parser
.add_argument("--root", metavar
="PATH",
55 help=_("The path where pakfire should operate in."))
58 self
.sub_commands
= self
.parser
.add_subparsers()
60 self
.parse_command_install()
61 self
.parse_command_localinstall()
62 self
.parse_command_reinstall()
63 self
.parse_command_remove()
64 self
.parse_command_info()
65 self
.parse_command_search()
66 self
.parse_command_check_update()
67 self
.parse_command_update()
68 self
.parse_command_downgrade()
69 self
.parse_command_provides()
70 self
.parse_command_grouplist()
71 self
.parse_command_groupinstall()
72 self
.parse_command_repolist()
73 self
.parse_command_clean()
74 self
.parse_command_check()
75 self
.parse_command_resolvdep()
77 # Finally parse all arguments from the command line and save them.
78 self
.args
= self
.parser
.parse_args()
81 "install" : self
.handle_install
,
82 "localinstall" : self
.handle_localinstall
,
83 "reinstall" : self
.handle_reinstall
,
84 "remove" : self
.handle_remove
,
85 "check_update" : self
.handle_check_update
,
86 "update" : self
.handle_update
,
87 "downgrade" : self
.handle_downgrade
,
88 "info" : self
.handle_info
,
89 "search" : self
.handle_search
,
90 "provides" : self
.handle_provides
,
91 "grouplist" : self
.handle_grouplist
,
92 "groupinstall" : self
.handle_groupinstall
,
93 "repolist" : self
.handle_repolist
,
94 "clean_all" : self
.handle_clean_all
,
95 "check" : self
.handle_check
,
96 "resolvdep" : self
.handle_resolvdep
,
100 def pakfire_args(self
):
101 ret
= { "mode" : "normal" }
103 if hasattr(self
.args
, "root"):
104 ret
["path"] = self
.args
.root
106 if hasattr(self
.args
, "disable_repo"):
107 ret
["disable_repos"] = self
.args
.disable_repo
109 if hasattr(self
.args
, "enable_repo"):
110 ret
["enable_repos"] = self
.args
.enable_repo
112 if hasattr(self
.args
, "offline"):
113 ret
["offline"] = self
.args
.offline
117 def parse_common_arguments(self
, repo_manage_switches
=True, offline_switch
=True):
118 self
.parser
.add_argument("--version", action
="version",
119 version
="%(prog)s " + PAKFIRE_VERSION
)
121 self
.parser
.add_argument("-v", "--verbose", action
="store_true",
122 help=_("Enable verbose output."))
124 self
.parser
.add_argument("-c", "--config", nargs
="?",
125 help=_("Path to a configuration file to load."))
127 if repo_manage_switches
:
128 self
.parser
.add_argument("--disable-repo", nargs
="*", metavar
="REPO",
129 help=_("Disable a repository temporarily."))
131 self
.parser
.add_argument("--enabled-repo", nargs
="*", metavar
="REPO",
132 help=_("Enable a repository temporarily."))
135 self
.parser
.add_argument("--offline", action
="store_true",
136 help=_("Run pakfire in offline mode."))
138 def parse_command_install(self
):
139 # Implement the "install" command.
140 sub_install
= self
.sub_commands
.add_parser("install",
141 help=_("Install one or more packages to the system."))
142 sub_install
.add_argument("package", nargs
="+",
143 help=_("Give name of at least one package to install."))
144 sub_install
.add_argument("action", action
="store_const", const
="install")
146 def parse_command_localinstall(self
):
147 # Implement the "localinstall" command.
148 sub_install
= self
.sub_commands
.add_parser("localinstall",
149 help=_("Install one or more packages from the filesystem."))
150 sub_install
.add_argument("package", nargs
="+",
151 help=_("Give filename of at least one package."))
152 sub_install
.add_argument("action", action
="store_const", const
="localinstall")
154 def parse_command_reinstall(self
):
155 # Implement the "reinstall" command.
156 sub_install
= self
.sub_commands
.add_parser("reinstall",
157 help=_("Reinstall one or more packages."))
158 sub_install
.add_argument("package", nargs
="+",
159 help=_("Give name of at least one package to reinstall."))
160 sub_install
.add_argument("action", action
="store_const", const
="reinstall")
162 def parse_command_remove(self
):
163 # Implement the "remove" command.
164 sub_remove
= self
.sub_commands
.add_parser("remove",
165 help=_("Remove one or more packages from the system."))
166 sub_remove
.add_argument("package", nargs
="+",
167 help=_("Give name of at least one package to remove."))
168 sub_remove
.add_argument("action", action
="store_const", const
="remove")
171 def _parse_command_update(parser
):
172 parser
.add_argument("package", nargs
="*",
173 help=_("Give a name of a package to update or leave emtpy for all."))
174 parser
.add_argument("--exclude", "-x", nargs
="+",
175 help=_("Exclude package from update."))
176 parser
.add_argument("--allow-vendorchange", action
="store_true",
177 help=_("Allow changing the vendor of packages."))
178 parser
.add_argument("--allow-archchange", action
="store_true",
179 help=_("Allow changing the architecture of packages."))
181 def parse_command_update(self
):
182 # Implement the "update" command.
183 sub_update
= self
.sub_commands
.add_parser("update",
184 help=_("Update the whole system or one specific package."))
185 sub_update
.add_argument("action", action
="store_const", const
="update")
186 self
._parse
_command
_update
(sub_update
)
188 def parse_command_check_update(self
):
189 # Implement the "check-update" command.
190 sub_check_update
= self
.sub_commands
.add_parser("check-update",
191 help=_("Check, if there are any updates available."))
192 sub_check_update
.add_argument("action", action
="store_const", const
="check_update")
193 self
._parse
_command
_update
(sub_check_update
)
195 def parse_command_downgrade(self
):
196 # Implement the "downgrade" command.
197 sub_downgrade
= self
.sub_commands
.add_parser("downgrade",
198 help=_("Downgrade one or more packages."))
199 sub_downgrade
.add_argument("package", nargs
="*",
200 help=_("Give a name of a package to downgrade."))
201 sub_downgrade
.add_argument("--allow-vendorchange", action
="store_true",
202 help=_("Allow changing the vendor of packages."))
203 sub_downgrade
.add_argument("--allow-archchange", action
="store_true",
204 help=_("Allow changing the architecture of packages."))
205 sub_downgrade
.add_argument("action", action
="store_const", const
="downgrade")
207 def parse_command_info(self
):
208 # Implement the "info" command.
209 sub_info
= self
.sub_commands
.add_parser("info",
210 help=_("Print some information about the given package(s)."))
211 sub_info
.add_argument("package", nargs
="+",
212 help=_("Give at least the name of one package."))
213 sub_info
.add_argument("action", action
="store_const", const
="info")
215 def parse_command_search(self
):
216 # Implement the "search" command.
217 sub_search
= self
.sub_commands
.add_parser("search",
218 help=_("Search for a given pattern."))
219 sub_search
.add_argument("pattern",
220 help=_("A pattern to search for."))
221 sub_search
.add_argument("action", action
="store_const", const
="search")
223 def parse_command_provides(self
):
224 # Implement the "provides" command
225 sub_provides
= self
.sub_commands
.add_parser("provides",
226 help=_("Get a list of packages that provide a given file or feature."))
227 sub_provides
.add_argument("pattern", nargs
="+",
228 help=_("File or feature to search for."))
229 sub_provides
.add_argument("action", action
="store_const", const
="provides")
231 def parse_command_grouplist(self
):
232 # Implement the "grouplist" command
233 sub_grouplist
= self
.sub_commands
.add_parser("grouplist",
234 help=_("Get list of packages that belong to the given group."))
235 sub_grouplist
.add_argument("group", nargs
=1,
236 help=_("Group name to search for."))
237 sub_grouplist
.add_argument("action", action
="store_const", const
="grouplist")
239 def parse_command_groupinstall(self
):
240 # Implement the "grouplist" command
241 sub_groupinstall
= self
.sub_commands
.add_parser("groupinstall",
242 help=_("Install all packages that belong to the given group."))
243 sub_groupinstall
.add_argument("group", nargs
=1,
244 help=_("Group name."))
245 sub_groupinstall
.add_argument("action", action
="store_const", const
="groupinstall")
247 def parse_command_repolist(self
):
248 # Implement the "repolist" command
249 sub_repolist
= self
.sub_commands
.add_parser("repolist",
250 help=_("List all currently enabled repositories."))
251 sub_repolist
.add_argument("action", action
="store_const", const
="repolist")
253 def parse_command_clean(self
):
254 sub_clean
= self
.sub_commands
.add_parser("clean", help=_("Cleanup commands."))
256 sub_clean_commands
= sub_clean
.add_subparsers()
258 self
.parse_command_clean_all(sub_clean_commands
)
260 def parse_command_clean_all(self
, sub_commands
):
261 sub_create
= sub_commands
.add_parser("all",
262 help=_("Cleanup all temporary files."))
263 sub_create
.add_argument("action", action
="store_const", const
="clean_all")
265 def parse_command_check(self
):
266 # Implement the "check" command
267 sub_check
= self
.sub_commands
.add_parser("check",
268 help=_("Check the system for any errors."))
269 sub_check
.add_argument("action", action
="store_const", const
="check")
271 def parse_command_resolvdep(self
):
272 # Implement the "resolvdep" command.
273 sub_resolvdep
= self
.sub_commands
.add_parser("resolvdep",
274 help=_("Check the dependencies for a particular package."))
275 sub_resolvdep
.add_argument("package", nargs
="+",
276 help=_("Give name of at least one package to check."))
277 sub_resolvdep
.add_argument("action", action
="store_const", const
="resolvdep")
280 action
= self
.args
.action
283 func
= self
.action2func
[action
]
285 raise Exception, "Unhandled action: %s" % action
289 def handle_info(self
, long=False):
290 pkgs
= pakfire
.info(self
.args
.package
, **self
.pakfire_args
)
293 print pkg
.dump(long=long)
295 def handle_search(self
):
296 pkgs
= pakfire
.search(self
.args
.pattern
, **self
.pakfire_args
)
299 print pkg
.dump(short
=True)
301 def handle_update(self
, **args
):
302 args
.update(self
.pakfire_args
)
304 pakfire
.update(self
.args
.package
, excludes
=self
.args
.exclude
,
305 allow_vendorchange
=self
.args
.allow_vendorchange
,
306 allow_archchange
=self
.args
.allow_archchange
,
309 def handle_check_update(self
):
310 self
.handle_update(check
=True)
312 def handle_downgrade(self
, **args
):
313 args
.update(self
.pakfire_args
)
315 pakfire
.downgrade(self
.args
.package
,
316 allow_vendorchange
=self
.args
.allow_vendorchange
,
317 allow_archchange
=self
.args
.allow_archchange
,
320 def handle_install(self
):
321 pakfire
.install(self
.args
.package
, **self
.pakfire_args
)
323 def handle_localinstall(self
):
324 pakfire
.localinstall(self
.args
.package
, **self
.pakfire_args
)
326 def handle_reinstall(self
):
327 pakfire
.reinstall(self
.args
.package
, **self
.pakfire_args
)
329 def handle_remove(self
):
330 pakfire
.remove(self
.args
.package
, **self
.pakfire_args
)
332 def handle_provides(self
):
333 pkgs
= pakfire
.provides(self
.args
.pattern
, **self
.pakfire_args
)
338 def handle_grouplist(self
):
339 pkgs
= pakfire
.grouplist(self
.args
.group
[0], **self
.pakfire_args
)
344 def handle_groupinstall(self
):
345 pakfire
.groupinstall(self
.args
.group
[0], **self
.pakfire_args
)
347 def handle_repolist(self
):
348 repos
= pakfire
.repo_list(**self
.pakfire_args
)
350 FORMAT
= " %-20s %8s %12s %12s "
352 title
= FORMAT
% (_("Repository"), _("Enabled"), _("Priority"), _("Packages"))
354 print "=" * len(title
) # spacing line
357 # Skip the installed repository.
358 if repo
.name
== "installed":
361 print FORMAT
% (repo
.name
, repo
.enabled
, repo
.priority
, len(repo
))
363 def handle_clean_all(self
):
364 print _("Cleaning up everything...")
366 pakfire
.clean_all(**self
.pakfire_args
)
368 def handle_check(self
):
369 pakfire
.check(**self
.pakfire_args
)
371 def handle_resolvdep(self
):
372 pakfire
.resolvdep(self
.args
.package
, **self
.pakfire_args
)
375 class CliBuilder(Cli
):
377 # Check if we are already running in a pakfire container. In that
378 # case, we cannot start another pakfire-builder.
379 if os
.environ
.get("container", None) == "pakfire-builder":
380 raise PakfireContainerError
, _("You cannot run pakfire-builder in a pakfire chroot.")
382 self
.parser
= argparse
.ArgumentParser(
383 description
= _("Pakfire builder command line interface."),
386 self
.parse_common_arguments()
389 self
.sub_commands
= self
.parser
.add_subparsers()
391 self
.parse_command_build()
392 self
.parse_command_dist()
393 self
.parse_command_info()
394 self
.parse_command_search()
395 self
.parse_command_shell()
396 self
.parse_command_update()
397 self
.parse_command_provides()
398 self
.parse_command_grouplist()
399 self
.parse_command_repolist()
400 self
.parse_command_clean()
401 self
.parse_command_resolvdep()
402 self
.parse_command_cache()
404 # Finally parse all arguments from the command line and save them.
405 self
.args
= self
.parser
.parse_args()
408 "build" : self
.handle_build
,
409 "dist" : self
.handle_dist
,
410 "update" : self
.handle_update
,
411 "info" : self
.handle_info
,
412 "search" : self
.handle_search
,
413 "shell" : self
.handle_shell
,
414 "provides" : self
.handle_provides
,
415 "grouplist" : self
.handle_grouplist
,
416 "repolist" : self
.handle_repolist
,
417 "clean_all" : self
.handle_clean_all
,
418 "resolvdep" : self
.handle_resolvdep
,
419 "cache_create": self
.handle_cache_create
,
420 "cache_cleanup": self
.handle_cache_cleanup
,
424 def pakfire_args(self
):
425 ret
= { "mode" : "builder" }
427 if hasattr(self
.args
, "disable_repo"):
428 ret
["disable_repos"] = self
.args
.disable_repo
430 if hasattr(self
.args
, "enable_repo"):
431 ret
["enable_repos"] = self
.args
.enable_repo
433 if hasattr(self
.args
, "offline"):
434 ret
["offline"] = self
.args
.offline
438 def parse_command_update(self
):
439 # Implement the "update" command.
440 sub_update
= self
.sub_commands
.add_parser("update",
441 help=_("Update the package indexes."))
442 sub_update
.add_argument("action", action
="store_const", const
="update")
444 def parse_command_build(self
):
445 # Implement the "build" command.
446 sub_build
= self
.sub_commands
.add_parser("build",
447 help=_("Build one or more packages."))
448 sub_build
.add_argument("package", nargs
=1,
449 help=_("Give name of at least one package to build."))
450 sub_build
.add_argument("action", action
="store_const", const
="build")
452 sub_build
.add_argument("-a", "--arch",
453 help=_("Build the package for the given architecture."))
454 sub_build
.add_argument("--resultdir", nargs
="?",
455 help=_("Path were the output files should be copied to."))
456 sub_build
.add_argument("-m", "--mode", nargs
="?", default
="development",
457 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
458 sub_build
.add_argument("--after-shell", action
="store_true",
459 help=_("Run a shell after a successful build."))
461 def parse_command_shell(self
):
462 # Implement the "shell" command.
463 sub_shell
= self
.sub_commands
.add_parser("shell",
464 help=_("Go into a shell."))
465 sub_shell
.add_argument("package", nargs
="?",
466 help=_("Give name of a package."))
467 sub_shell
.add_argument("action", action
="store_const", const
="shell")
469 sub_shell
.add_argument("-a", "--arch",
470 help=_("Emulated architecture in the shell."))
471 sub_shell
.add_argument("-m", "--mode", nargs
="?", default
="development",
472 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
474 def parse_command_dist(self
):
475 # Implement the "dist" command.
476 sub_dist
= self
.sub_commands
.add_parser("dist",
477 help=_("Generate a source package."))
478 sub_dist
.add_argument("package", nargs
="+",
479 help=_("Give name(s) of a package(s)."))
480 sub_dist
.add_argument("action", action
="store_const", const
="dist")
482 sub_dist
.add_argument("--resultdir", nargs
="?",
483 help=_("Path were the output files should be copied to."))
486 def parse_command_cache(self
):
487 # Implement the "cache" command.
488 sub_cache
= self
.sub_commands
.add_parser("cache",
489 help=_("Create a build environment cache."))
491 # Implement subcommands.
492 sub_cache_commands
= sub_cache
.add_subparsers()
494 self
.parse_command_cache_create(sub_cache_commands
)
495 self
.parse_command_cache_cleanup(sub_cache_commands
)
497 def parse_command_cache_create(self
, sub_commands
):
498 sub_create
= sub_commands
.add_parser("create",
499 help=_("Create a new build environment cache."))
500 sub_create
.add_argument("action", action
="store_const", const
="cache_create")
502 def parse_command_cache_cleanup(self
, sub_commands
):
503 sub_cleanup
= sub_commands
.add_parser("cleanup",
504 help=_("Remove all cached build environments."))
505 sub_cleanup
.add_argument("action", action
="store_const", const
="cache_cleanup")
507 def handle_info(self
):
508 Cli
.handle_info(self
, long=True)
510 def handle_build(self
):
511 # Get the package descriptor from the command line options
512 pkg
= self
.args
.package
[0]
514 # Check, if we got a regular file
515 if os
.path
.exists(pkg
):
516 pkg
= os
.path
.abspath(pkg
)
519 raise FileNotFoundError
, pkg
521 # Create distribution configuration from command line.
523 "arch" : self
.args
.arch
,
526 pakfire
.build(pkg
, builder_mode
=self
.args
.mode
,
527 distro_config
=distro_config
, resultdirs
=[self
.args
.resultdir
,],
528 shell
=True, after_shell
=self
.args
.after_shell
, **self
.pakfire_args
)
530 def handle_shell(self
):
533 # Get the package descriptor from the command line options
534 if self
.args
.package
:
535 pkg
= self
.args
.package
537 # Check, if we got a regular file
538 if os
.path
.exists(pkg
):
539 pkg
= os
.path
.abspath(pkg
)
542 raise FileNotFoundError
, pkg
544 # Create distribution configuration from command line.
546 "arch" : self
.args
.arch
,
549 pakfire
.shell(pkg
, builder_mode
=self
.args
.mode
,
550 distro_config
=distro_config
, **self
.pakfire_args
)
552 def handle_dist(self
):
553 # Get the packages from the command line options
556 for pkg
in self
.args
.package
:
557 # Check, if we got a regular file
558 if os
.path
.exists(pkg
):
559 pkg
= os
.path
.abspath(pkg
)
563 raise FileNotFoundError
, pkg
565 pakfire
.dist(pkgs
, resultdirs
=[self
.args
.resultdir
,],
568 def handle_provides(self
):
569 pkgs
= pakfire
.provides(self
.args
.pattern
, **self
.pakfire_args
)
572 print pkg
.dump(long=True)
574 def handle_cache_create(self
):
575 pakfire
.cache_create(**self
.pakfire_args
)
577 def handle_cache_cleanup(self
):
578 for env
in os
.listdir(CACHE_ENVIRON_DIR
):
579 if not env
.endswith(".cache"):
582 print _("Removing environment cache file: %s..." % env
)
583 env
= os
.path
.join(CACHE_ENVIRON_DIR
, env
)
588 print _("Could not remove file: %s") % env
591 class CliServer(Cli
):
593 self
.parser
= argparse
.ArgumentParser(
594 description
= _("Pakfire server command line interface."),
597 self
.parse_common_arguments()
600 self
.sub_commands
= self
.parser
.add_subparsers()
602 self
.parse_command_build()
603 self
.parse_command_keepalive()
604 self
.parse_command_repoupdate()
605 self
.parse_command_repo()
606 self
.parse_command_info()
608 # Finally parse all arguments from the command line and save them.
609 self
.args
= self
.parser
.parse_args()
611 self
.server
= server
.Server(**self
.pakfire_args
)
614 "build" : self
.handle_build
,
615 "info" : self
.handle_info
,
616 "keepalive" : self
.handle_keepalive
,
617 "repoupdate" : self
.handle_repoupdate
,
618 "repo_create": self
.handle_repo_create
,
622 def pakfire_args(self
):
623 ret
= { "mode" : "server" }
625 if hasattr(self
.args
, "offline"):
626 ret
["offline"] = self
.args
.offline
630 def parse_command_build(self
):
631 # Implement the "build" command.
632 sub_build
= self
.sub_commands
.add_parser("build",
633 help=_("Send a scrach build job to the server."))
634 sub_build
.add_argument("package", nargs
=1,
635 help=_("Give name of at least one package to build."))
636 sub_build
.add_argument("--arch", "-a",
637 help=_("Limit build to only these architecture(s)."))
638 sub_build
.add_argument("action", action
="store_const", const
="build")
640 def parse_command_keepalive(self
):
641 # Implement the "keepalive" command.
642 sub_keepalive
= self
.sub_commands
.add_parser("keepalive",
643 help=_("Send a keepalive to the server."))
644 sub_keepalive
.add_argument("action", action
="store_const",
647 def parse_command_repoupdate(self
):
648 # Implement the "repoupdate" command.
649 sub_repoupdate
= self
.sub_commands
.add_parser("repoupdate",
650 help=_("Update all repositories."))
651 sub_repoupdate
.add_argument("action", action
="store_const",
654 def parse_command_repo(self
):
655 sub_repo
= self
.sub_commands
.add_parser("repo",
656 help=_("Repository management commands."))
658 sub_repo_commands
= sub_repo
.add_subparsers()
660 self
.parse_command_repo_create(sub_repo_commands
)
662 def parse_command_repo_create(self
, sub_commands
):
663 sub_create
= sub_commands
.add_parser("create",
664 help=_("Create a new repository index."))
665 sub_create
.add_argument("path", nargs
=1,
666 help=_("Path to the packages."))
667 sub_create
.add_argument("inputs", nargs
="+",
668 help=_("Path to input packages."))
669 sub_create
.add_argument("--key", "-k", nargs
="?",
670 help=_("Key to sign the repository with."))
671 sub_create
.add_argument("action", action
="store_const", const
="repo_create")
673 def parse_command_info(self
):
674 sub_info
= self
.sub_commands
.add_parser("info",
675 help=_("Dump some information about this machine."))
676 sub_info
.add_argument("action", action
="store_const", const
="info")
678 def handle_keepalive(self
):
679 self
.server
.update_info()
681 def handle_build(self
):
684 arches
= self
.args
.arch
.split()
686 (package
,) = self
.args
.package
688 self
.server
.create_scratch_build({})
691 # Temporary folter for source package.
692 tmpdir
= "/tmp/pakfire-%s" % util
.random_string()
697 pakfire
.dist(package
, resultdir
=[tmpdir
,])
699 for file in os
.listdir(tmpdir
):
700 file = os
.path
.join(tmpdir
, file)
705 if os
.path
.exists(tmpdir
):
708 def handle_repoupdate(self
):
709 self
.server
.update_repositories()
711 def handle_repo_create(self
):
712 path
= self
.args
.path
[0]
714 pakfire
.repo_create(path
, self
.args
.inputs
, key_id
=self
.args
.key
,
717 def handle_info(self
):
718 info
= self
.server
.info()
720 print "\n".join(info
)
723 class CliBuilderIntern(Cli
):
725 self
.parser
= argparse
.ArgumentParser(
726 description
= _("Pakfire builder command line interface."),
729 self
.parse_common_arguments()
732 self
.sub_commands
= self
.parser
.add_subparsers()
734 self
.parse_command_build()
736 # Finally parse all arguments from the command line and save them.
737 self
.args
= self
.parser
.parse_args()
740 "build" : self
.handle_build
,
743 def parse_command_build(self
):
744 # Implement the "build" command.
745 sub_build
= self
.sub_commands
.add_parser("build",
746 help=_("Build one or more packages."))
747 sub_build
.add_argument("package", nargs
=1,
748 help=_("Give name of at least one package to build."))
749 sub_build
.add_argument("action", action
="store_const", const
="build")
751 sub_build
.add_argument("-a", "--arch",
752 help=_("Build the package for the given architecture."))
753 sub_build
.add_argument("--resultdir", nargs
="?",
754 help=_("Path were the output files should be copied to."))
755 sub_build
.add_argument("-m", "--mode", nargs
="?", default
="development",
756 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
757 sub_build
.add_argument("--nodeps", action
="store_true",
758 help=_("Do not verify build dependencies."))
760 def handle_build(self
):
761 # Get the package descriptor from the command line options
762 pkg
= self
.args
.package
[0]
764 # Check, if we got a regular file
765 if os
.path
.exists(pkg
):
766 pkg
= os
.path
.abspath(pkg
)
768 raise FileNotFoundError
, pkg
770 # Create distribution configuration from command line.
772 "arch" : self
.args
.arch
,
775 pakfire
._build
(pkg
, builder_mode
=self
.args
.mode
,
776 distro_config
=distro_config
, resultdir
=self
.args
.resultdir
,)
779 class CliClient(Cli
):
781 self
.parser
= argparse
.ArgumentParser(
782 description
= _("Pakfire client command line interface."),
785 self
.parse_common_arguments(repo_manage_switches
=True, offline_switch
=True)
788 self
.sub_commands
= self
.parser
.add_subparsers()
790 self
.parse_command_build()
791 self
.parse_command_connection_check()
792 self
.parse_command_info()
794 # Finally parse all arguments from the command line and save them.
795 self
.args
= self
.parser
.parse_args()
798 "build" : self
.handle_build
,
799 "conn-check" : self
.handle_connection_check
,
800 "info" : self
.handle_info
,
803 # Read configuration for the pakfire client.
804 self
.conf
= conf
= config
.ConfigClient()
806 # Create connection to pakfire hub.
807 self
.client
= client
.PakfireUserClient(
808 conf
.get("client", "server"),
809 conf
.get("client", "username"),
810 conf
.get("client", "password"),
813 def parse_command_build(self
):
814 # Parse "build" command.
815 sub_build
= self
.sub_commands
.add_parser("build",
816 help=_("Build a package remotely."))
817 sub_build
.add_argument("package", nargs
=1,
818 help=_("Give name of a package to build."))
819 sub_build
.add_argument("action", action
="store_const", const
="build")
821 sub_build
.add_argument("-a", "--arch",
822 help=_("Build the package for the given architecture."))
824 def parse_command_info(self
):
825 # Implement the "info" command.
826 sub_info
= self
.sub_commands
.add_parser("info",
827 help=_("Print some information about this host."))
828 sub_info
.add_argument("action", action
="store_const", const
="info")
830 def parse_command_connection_check(self
):
831 # Implement the "conn-check" command.
832 sub_conn_check
= self
.sub_commands
.add_parser("conn-check",
833 help=_("Check the connection to the hub."))
834 sub_conn_check
.add_argument("action", action
="store_const", const
="conn-check")
836 def handle_build(self
):
837 (package
,) = self
.args
.package
839 # XXX just for now, we do only upload source pfm files.
840 assert os
.path
.exists(package
)
844 arches
= self
.args
.arch
.replace(",", " ")
848 # Create a new build on the server.
849 build
= self
.client
.build_create(package
, arches
=arches
)
851 # XXX Print the resulting build.
854 def handle_info(self
):
858 ret
.append(" PAKFIRE %s" % PAKFIRE_VERSION
)
860 ret
.append(" %-20s: %s" % (_("Hostname"), system
.hostname
))
861 ret
.append(" %-20s: %s" % (_("Pakfire hub"), self
.conf
.get("client", "server")))
862 if self
.conf
.get("client", "username") and self
.conf
.get("client", "password"):
863 ret
.append(" %-20s: %s" % \
864 (_("Username"), self
.conf
.get("client", "username")))
867 # Hardware information
868 ret
.append(" %s:" % _("Hardware information"))
869 ret
.append(" %-16s: %s" % (_("CPU model"), system
.cpu_model
))
870 ret
.append(" %-16s: %s" % (_("Memory"), util
.format_size(system
.memory
)))
872 ret
.append(" %-16s: %s" % (_("Native arch"), system
.native_arch
))
873 if not system
.arch
== system
.native_arch
:
874 ret
.append(" %-16s: %s" % (_("Default arch"), system
.arch
))
876 header
= _("Supported arches")
877 for arch
in system
.supported_arches
:
878 ret
.append(" %-16s: %s" % (header
, arch
))
885 def handle_connection_check(self
):
888 address
= self
.client
.get_my_address()
889 ret
.append(" %-20s: %s" % (_("Your IP address"), address
))
892 authenticated
= self
.client
.check_auth()
894 ret
.append(" %s" % _("You are authenticated to the build service:"))
896 user
= self
.client
.get_user_profile()
897 assert user
, "Could not fetch user infomation"
900 ("name", _("User name")),
901 ("realname", _("Real name")),
902 ("email", _("Email address")),
903 ("registered", _("Registered")),
906 for key
, desc
in keys
:
907 ret
.append(" %-18s: %s" % (desc
, user
.get(key
)))
910 ret
.append(_("You could not be authenticated to the build service."))
916 class CliDaemon(Cli
):
918 self
.parser
= argparse
.ArgumentParser(
919 description
= _("Pakfire daemon command line interface."),
922 self
.parse_common_arguments(repo_manage_switches
=True, offline_switch
=True)
924 # Finally parse all arguments from the command line and save them.
925 self
.args
= self
.parser
.parse_args()
929 Runs the pakfire daemon with provided settings.
931 # Read the configuration file for the daemon.
932 conf
= config
.ConfigDaemon()
934 # Create daemon instance.
935 d
= pakfire
.client
.PakfireDaemon(
936 server
= conf
.get("daemon", "server"),
937 hostname
= conf
.get("daemon", "hostname"),
938 secret
= conf
.get("daemon", "secret"),
944 # We cannot just kill the daemon, it needs a smooth shutdown.
945 except (SystemExit, KeyboardInterrupt):
951 self
.parser
= argparse
.ArgumentParser(
952 description
= _("Pakfire key command line interface."),
955 self
.parse_common_arguments(repo_manage_switches
=False,
959 self
.sub_commands
= self
.parser
.add_subparsers()
961 self
.parse_command_init()
962 self
.parse_command_generate()
963 self
.parse_command_import()
964 self
.parse_command_export()
965 self
.parse_command_delete()
966 self
.parse_command_list()
967 self
.parse_command_sign()
968 self
.parse_command_verify()
970 # Finally parse all arguments from the command line and save them.
971 self
.args
= self
.parser
.parse_args()
973 # Create a pakfire instance.
974 self
.pakfire
= pakfire
.Pakfire(**self
.pakfire_args
)
977 "init" : self
.handle_init
,
978 "generate" : self
.handle_generate
,
979 "import" : self
.handle_import
,
980 "export" : self
.handle_export
,
981 "delete" : self
.handle_delete
,
982 "list" : self
.handle_list
,
983 "sign" : self
.handle_sign
,
984 "verify" : self
.handle_verify
,
988 def pakfire_args(self
):
995 def parse_command_init(self
):
996 # Parse "init" command.
997 sub_init
= self
.sub_commands
.add_parser("init",
998 help=_("Initialize the local keyring."))
999 sub_init
.add_argument("action", action
="store_const", const
="init")
1001 def parse_command_generate(self
):
1002 # Parse "generate" command.
1003 sub_gen
= self
.sub_commands
.add_parser("generate",
1004 help=_("Import a key from file."))
1005 sub_gen
.add_argument("--realname", nargs
=1,
1006 help=_("The real name of the owner of this key."))
1007 sub_gen
.add_argument("--email", nargs
=1,
1008 help=_("The email address of the owner of this key."))
1009 sub_gen
.add_argument("action", action
="store_const", const
="generate")
1011 def parse_command_import(self
):
1012 # Parse "import" command.
1013 sub_import
= self
.sub_commands
.add_parser("import",
1014 help=_("Import a key from file."))
1015 sub_import
.add_argument("filename", nargs
=1,
1016 help=_("Filename of that key to import."))
1017 sub_import
.add_argument("action", action
="store_const", const
="import")
1019 def parse_command_export(self
):
1020 # Parse "export" command.
1021 sub_export
= self
.sub_commands
.add_parser("export",
1022 help=_("Export a key to a file."))
1023 sub_export
.add_argument("keyid", nargs
=1,
1024 help=_("The ID of the key to export."))
1025 sub_export
.add_argument("filename", nargs
=1,
1026 help=_("Write the key to this file."))
1027 sub_export
.add_argument("action", action
="store_const", const
="export")
1029 def parse_command_delete(self
):
1030 # Parse "delete" command.
1031 sub_del
= self
.sub_commands
.add_parser("delete",
1032 help=_("Delete a key from the local keyring."))
1033 sub_del
.add_argument("keyid", nargs
=1,
1034 help=_("The ID of the key to delete."))
1035 sub_del
.add_argument("action", action
="store_const", const
="delete")
1037 def parse_command_list(self
):
1038 # Parse "list" command.
1039 sub_list
= self
.sub_commands
.add_parser("list",
1040 help=_("List all imported keys."))
1041 sub_list
.add_argument("action", action
="store_const", const
="list")
1043 def parse_command_sign(self
):
1044 # Implement the "sign" command.
1045 sub_sign
= self
.sub_commands
.add_parser("sign",
1046 help=_("Sign one or more packages."))
1047 sub_sign
.add_argument("--key", "-k", nargs
=1,
1048 help=_("Key that is used sign the package(s)."))
1049 sub_sign
.add_argument("package", nargs
="+",
1050 help=_("Package(s) to sign."))
1051 sub_sign
.add_argument("action", action
="store_const", const
="sign")
1053 def parse_command_verify(self
):
1054 # Implement the "verify" command.
1055 sub_verify
= self
.sub_commands
.add_parser("verify",
1056 help=_("Verify one or more packages."))
1057 #sub_verify.add_argument("--key", "-k", nargs=1,
1058 # help=_("Key that is used verify the package(s)."))
1059 sub_verify
.add_argument("package", nargs
="+",
1060 help=_("Package(s) to verify."))
1061 sub_verify
.add_argument("action", action
="store_const", const
="verify")
1063 def handle_init(self
):
1064 # Initialize the keyring...
1065 pakfire
.key_init(**self
.pakfire_args
)
1067 def handle_generate(self
):
1068 realname
= self
.args
.realname
[0]
1069 email
= self
.args
.email
[0]
1071 print _("Generating the key may take a moment...")
1075 fpr
= pakfire
.key_generate(realname
, email
, **self
.pakfire_args
)
1077 # Dump all information about the new key.
1078 for line
in self
.dump_key(fpr
):
1081 def handle_import(self
):
1082 filename
= self
.args
.filename
[0]
1084 # Simply import the file.
1085 pakfire
.key_import(filename
, **self
.pakfire_args
)
1087 def handle_export(self
):
1088 keyid
= self
.args
.keyid
[0]
1089 filename
= self
.args
.filename
[0]
1091 pakfire
.key_export(keyid
, filename
, **self
.pakfire_args
)
1093 def handle_delete(self
):
1094 keyid
= self
.args
.keyid
[0]
1096 pakfire
.key_delete(keyid
, **self
.pakfire_args
)
1098 def handle_list(self
):
1099 lines
= pakfire
.key_list(**self
.pakfire_args
)
1104 def handle_sign(self
):
1105 # Get the files from the command line options
1108 for file in self
.args
.package
:
1109 # Check, if we got a regular file
1110 if os
.path
.exists(file):
1111 file = os
.path
.abspath(file)
1115 raise FileNotFoundError
, file
1117 key
= self
.args
.key
[0]
1121 pkg
= packages
.open(self
.pakfire
, None, file)
1123 print _("Signing %s...") % pkg
.friendly_name
1126 def handle_verify(self
):
1127 # Get the files from the command line options
1130 for file in self
.args
.package
:
1131 # Check, if we got a regular file
1132 if os
.path
.exists(file) and not os
.path
.isdir(file):
1133 file = os
.path
.abspath(file)
1138 pkg
= packages
.open(self
.pakfire
, None, file)
1140 print _("Verifying %s...") % pkg
.friendly_name
1144 key
= self
.pakfire
.keyring
.get_key(sig
.fpr
)
1146 subkey
= key
.subkeys
[0]
1148 print " %s %s" % (subkey
.fpr
[-16:], key
.uids
[0].uid
)
1150 print " %s" % _("This signature is valid.")
1153 print " %s <%s>" % (sig
.fpr
, _("Unknown key"))
1154 print " %s" % _("Could not check if this signature is valid.")
1156 created
= datetime
.datetime
.fromtimestamp(sig
.timestamp
)
1157 print " %s" % _("Created: %s") % created
1159 if sig
.exp_timestamp
:
1160 expires
= datetime
.datetime
.fromtimestamp(sig
.exp_timestamp
)
1161 print " %s" % _("Expires: %s") % expires