]>
git.ipfire.org Git - 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 ###############################################################################
28 import pakfire
.api
as pakfire
38 from system
import system
39 from constants
import *
42 # Initialize a very simple logging that is removed when a Pakfire instance
44 logger
.setup_logging()
48 self
.parser
= argparse
.ArgumentParser(
49 description
= _("Pakfire command line interface."),
52 self
.parse_common_arguments()
54 self
.parser
.add_argument("--root", metavar
="PATH",
56 help=_("The path where pakfire should operate in."))
59 self
.sub_commands
= self
.parser
.add_subparsers()
61 self
.parse_command_install()
62 self
.parse_command_localinstall()
63 self
.parse_command_reinstall()
64 self
.parse_command_remove()
65 self
.parse_command_info()
66 self
.parse_command_search()
67 self
.parse_command_check_update()
68 self
.parse_command_update()
69 self
.parse_command_downgrade()
70 self
.parse_command_provides()
71 self
.parse_command_grouplist()
72 self
.parse_command_groupinstall()
73 self
.parse_command_repolist()
74 self
.parse_command_clean()
75 self
.parse_command_check()
76 self
.parse_command_resolvdep()
78 # Finally parse all arguments from the command line and save them.
79 self
.args
= self
.parser
.parse_args()
82 "install" : self
.handle_install
,
83 "localinstall" : self
.handle_localinstall
,
84 "reinstall" : self
.handle_reinstall
,
85 "remove" : self
.handle_remove
,
86 "check_update" : self
.handle_check_update
,
87 "update" : self
.handle_update
,
88 "downgrade" : self
.handle_downgrade
,
89 "info" : self
.handle_info
,
90 "search" : self
.handle_search
,
91 "provides" : self
.handle_provides
,
92 "grouplist" : self
.handle_grouplist
,
93 "groupinstall" : self
.handle_groupinstall
,
94 "repolist" : self
.handle_repolist
,
95 "clean_all" : self
.handle_clean_all
,
96 "check" : self
.handle_check
,
97 "resolvdep" : self
.handle_resolvdep
,
101 def pakfire_args(self
):
102 ret
= { "mode" : "normal" }
104 if hasattr(self
.args
, "root"):
105 ret
["path"] = self
.args
.root
107 if hasattr(self
.args
, "disable_repo"):
108 ret
["disable_repos"] = self
.args
.disable_repo
110 if hasattr(self
.args
, "enable_repo"):
111 ret
["enable_repos"] = self
.args
.enable_repo
113 if hasattr(self
.args
, "offline"):
114 ret
["offline"] = self
.args
.offline
118 def parse_common_arguments(self
, repo_manage_switches
=True, offline_switch
=True):
119 self
.parser
.add_argument("--version", action
="version",
120 version
="%(prog)s " + PAKFIRE_VERSION
)
122 self
.parser
.add_argument("-v", "--verbose", action
="store_true",
123 help=_("Enable verbose output."))
125 self
.parser
.add_argument("-c", "--config", nargs
="?",
126 help=_("Path to a configuration file to load."))
128 if repo_manage_switches
:
129 self
.parser
.add_argument("--disable-repo", nargs
="*", metavar
="REPO",
130 help=_("Disable a repository temporarily."))
132 self
.parser
.add_argument("--enabled-repo", nargs
="*", metavar
="REPO",
133 help=_("Enable a repository temporarily."))
136 self
.parser
.add_argument("--offline", action
="store_true",
137 help=_("Run pakfire in offline mode."))
139 def parse_command_install(self
):
140 # Implement the "install" command.
141 sub_install
= self
.sub_commands
.add_parser("install",
142 help=_("Install one or more packages to the system."))
143 sub_install
.add_argument("package", nargs
="+",
144 help=_("Give name of at least one package to install."))
145 sub_install
.add_argument("action", action
="store_const", const
="install")
147 def parse_command_localinstall(self
):
148 # Implement the "localinstall" command.
149 sub_install
= self
.sub_commands
.add_parser("localinstall",
150 help=_("Install one or more packages from the filesystem."))
151 sub_install
.add_argument("package", nargs
="+",
152 help=_("Give filename of at least one package."))
153 sub_install
.add_argument("action", action
="store_const", const
="localinstall")
155 def parse_command_reinstall(self
):
156 # Implement the "reinstall" command.
157 sub_install
= self
.sub_commands
.add_parser("reinstall",
158 help=_("Reinstall one or more packages."))
159 sub_install
.add_argument("package", nargs
="+",
160 help=_("Give name of at least one package to reinstall."))
161 sub_install
.add_argument("action", action
="store_const", const
="reinstall")
163 def parse_command_remove(self
):
164 # Implement the "remove" command.
165 sub_remove
= self
.sub_commands
.add_parser("remove",
166 help=_("Remove one or more packages from the system."))
167 sub_remove
.add_argument("package", nargs
="+",
168 help=_("Give name of at least one package to remove."))
169 sub_remove
.add_argument("action", action
="store_const", const
="remove")
172 def _parse_command_update(parser
):
173 parser
.add_argument("package", nargs
="*",
174 help=_("Give a name of a package to update or leave emtpy for all."))
175 parser
.add_argument("--exclude", "-x", nargs
="+",
176 help=_("Exclude package from update."))
177 parser
.add_argument("--allow-vendorchange", action
="store_true",
178 help=_("Allow changing the vendor of packages."))
179 parser
.add_argument("--allow-archchange", action
="store_true",
180 help=_("Allow changing the architecture of packages."))
182 def parse_command_update(self
):
183 # Implement the "update" command.
184 sub_update
= self
.sub_commands
.add_parser("update",
185 help=_("Update the whole system or one specific package."))
186 sub_update
.add_argument("action", action
="store_const", const
="update")
187 self
._parse
_command
_update
(sub_update
)
189 def parse_command_check_update(self
):
190 # Implement the "check-update" command.
191 sub_check_update
= self
.sub_commands
.add_parser("check-update",
192 help=_("Check, if there are any updates available."))
193 sub_check_update
.add_argument("action", action
="store_const", const
="check_update")
194 self
._parse
_command
_update
(sub_check_update
)
196 def parse_command_downgrade(self
):
197 # Implement the "downgrade" command.
198 sub_downgrade
= self
.sub_commands
.add_parser("downgrade",
199 help=_("Downgrade one or more packages."))
200 sub_downgrade
.add_argument("package", nargs
="*",
201 help=_("Give a name of a package to downgrade."))
202 sub_downgrade
.add_argument("--allow-vendorchange", action
="store_true",
203 help=_("Allow changing the vendor of packages."))
204 sub_downgrade
.add_argument("--allow-archchange", action
="store_true",
205 help=_("Allow changing the architecture of packages."))
206 sub_downgrade
.add_argument("action", action
="store_const", const
="downgrade")
208 def parse_command_info(self
):
209 # Implement the "info" command.
210 sub_info
= self
.sub_commands
.add_parser("info",
211 help=_("Print some information about the given package(s)."))
212 sub_info
.add_argument("package", nargs
="+",
213 help=_("Give at least the name of one package."))
214 sub_info
.add_argument("action", action
="store_const", const
="info")
216 def parse_command_search(self
):
217 # Implement the "search" command.
218 sub_search
= self
.sub_commands
.add_parser("search",
219 help=_("Search for a given pattern."))
220 sub_search
.add_argument("pattern",
221 help=_("A pattern to search for."))
222 sub_search
.add_argument("action", action
="store_const", const
="search")
224 def parse_command_provides(self
):
225 # Implement the "provides" command
226 sub_provides
= self
.sub_commands
.add_parser("provides",
227 help=_("Get a list of packages that provide a given file or feature."))
228 sub_provides
.add_argument("pattern", nargs
="+",
229 help=_("File or feature to search for."))
230 sub_provides
.add_argument("action", action
="store_const", const
="provides")
232 def parse_command_grouplist(self
):
233 # Implement the "grouplist" command
234 sub_grouplist
= self
.sub_commands
.add_parser("grouplist",
235 help=_("Get list of packages that belong to the given group."))
236 sub_grouplist
.add_argument("group", nargs
=1,
237 help=_("Group name to search for."))
238 sub_grouplist
.add_argument("action", action
="store_const", const
="grouplist")
240 def parse_command_groupinstall(self
):
241 # Implement the "grouplist" command
242 sub_groupinstall
= self
.sub_commands
.add_parser("groupinstall",
243 help=_("Install all packages that belong to the given group."))
244 sub_groupinstall
.add_argument("group", nargs
=1,
245 help=_("Group name."))
246 sub_groupinstall
.add_argument("action", action
="store_const", const
="groupinstall")
248 def parse_command_repolist(self
):
249 # Implement the "repolist" command
250 sub_repolist
= self
.sub_commands
.add_parser("repolist",
251 help=_("List all currently enabled repositories."))
252 sub_repolist
.add_argument("action", action
="store_const", const
="repolist")
254 def parse_command_clean(self
):
255 sub_clean
= self
.sub_commands
.add_parser("clean", help=_("Cleanup commands."))
257 sub_clean_commands
= sub_clean
.add_subparsers()
259 self
.parse_command_clean_all(sub_clean_commands
)
261 def parse_command_clean_all(self
, sub_commands
):
262 sub_create
= sub_commands
.add_parser("all",
263 help=_("Cleanup all temporary files."))
264 sub_create
.add_argument("action", action
="store_const", const
="clean_all")
266 def parse_command_check(self
):
267 # Implement the "check" command
268 sub_check
= self
.sub_commands
.add_parser("check",
269 help=_("Check the system for any errors."))
270 sub_check
.add_argument("action", action
="store_const", const
="check")
272 def parse_command_resolvdep(self
):
273 # Implement the "resolvdep" command.
274 sub_resolvdep
= self
.sub_commands
.add_parser("resolvdep",
275 help=_("Check the dependencies for a particular package."))
276 sub_resolvdep
.add_argument("package", nargs
="+",
277 help=_("Give name of at least one package to check."))
278 sub_resolvdep
.add_argument("action", action
="store_const", const
="resolvdep")
281 action
= self
.args
.action
284 func
= self
.action2func
[action
]
286 raise Exception, "Unhandled action: %s" % action
290 def handle_info(self
, long=False):
291 pkgs
= pakfire
.info(self
.args
.package
, **self
.pakfire_args
)
294 print pkg
.dump(long=long)
296 def handle_search(self
):
297 pkgs
= pakfire
.search(self
.args
.pattern
, **self
.pakfire_args
)
300 print pkg
.dump(short
=True)
302 def handle_update(self
, **args
):
303 args
.update(self
.pakfire_args
)
305 pakfire
.update(self
.args
.package
, excludes
=self
.args
.exclude
,
306 allow_vendorchange
=self
.args
.allow_vendorchange
,
307 allow_archchange
=self
.args
.allow_archchange
,
310 def handle_check_update(self
):
311 self
.handle_update(check
=True)
313 def handle_downgrade(self
, **args
):
314 args
.update(self
.pakfire_args
)
316 pakfire
.downgrade(self
.args
.package
,
317 allow_vendorchange
=self
.args
.allow_vendorchange
,
318 allow_archchange
=self
.args
.allow_archchange
,
321 def handle_install(self
):
322 pakfire
.install(self
.args
.package
, **self
.pakfire_args
)
324 def handle_localinstall(self
):
325 pakfire
.localinstall(self
.args
.package
, **self
.pakfire_args
)
327 def handle_reinstall(self
):
328 pakfire
.reinstall(self
.args
.package
, **self
.pakfire_args
)
330 def handle_remove(self
):
331 pakfire
.remove(self
.args
.package
, **self
.pakfire_args
)
333 def handle_provides(self
):
334 pkgs
= pakfire
.provides(self
.args
.pattern
, **self
.pakfire_args
)
339 def handle_grouplist(self
):
340 pkgs
= pakfire
.grouplist(self
.args
.group
[0], **self
.pakfire_args
)
345 def handle_groupinstall(self
):
346 pakfire
.groupinstall(self
.args
.group
[0], **self
.pakfire_args
)
348 def handle_repolist(self
):
349 repos
= pakfire
.repo_list(**self
.pakfire_args
)
351 FORMAT
= " %-20s %8s %12s %12s "
353 title
= FORMAT
% (_("Repository"), _("Enabled"), _("Priority"), _("Packages"))
355 print "=" * len(title
) # spacing line
358 # Skip the installed repository.
359 if repo
.name
== "installed":
362 print FORMAT
% (repo
.name
, repo
.enabled
, repo
.priority
, len(repo
))
364 def handle_clean_all(self
):
365 print _("Cleaning up everything...")
367 pakfire
.clean_all(**self
.pakfire_args
)
369 def handle_check(self
):
370 pakfire
.check(**self
.pakfire_args
)
372 def handle_resolvdep(self
):
373 pakfire
.resolvdep(self
.args
.package
, **self
.pakfire_args
)
376 class CliBuilder(Cli
):
378 # Check if we are already running in a pakfire container. In that
379 # case, we cannot start another pakfire-builder.
380 if os
.environ
.get("container", None) == "pakfire-builder":
381 raise PakfireContainerError
, _("You cannot run pakfire-builder in a pakfire chroot.")
383 self
.parser
= argparse
.ArgumentParser(
384 description
= _("Pakfire builder command line interface."),
387 self
.parse_common_arguments()
390 self
.sub_commands
= self
.parser
.add_subparsers()
392 self
.parse_command_build()
393 self
.parse_command_dist()
394 self
.parse_command_info()
395 self
.parse_command_search()
396 self
.parse_command_shell()
397 self
.parse_command_update()
398 self
.parse_command_provides()
399 self
.parse_command_grouplist()
400 self
.parse_command_repolist()
401 self
.parse_command_clean()
402 self
.parse_command_resolvdep()
403 self
.parse_command_cache()
405 # Finally parse all arguments from the command line and save them.
406 self
.args
= self
.parser
.parse_args()
409 "build" : self
.handle_build
,
410 "dist" : self
.handle_dist
,
411 "update" : self
.handle_update
,
412 "info" : self
.handle_info
,
413 "search" : self
.handle_search
,
414 "shell" : self
.handle_shell
,
415 "provides" : self
.handle_provides
,
416 "grouplist" : self
.handle_grouplist
,
417 "repolist" : self
.handle_repolist
,
418 "clean_all" : self
.handle_clean_all
,
419 "resolvdep" : self
.handle_resolvdep
,
420 "cache_create": self
.handle_cache_create
,
421 "cache_cleanup": self
.handle_cache_cleanup
,
425 def pakfire_args(self
):
426 ret
= { "mode" : "builder" }
428 if hasattr(self
.args
, "disable_repo"):
429 ret
["disable_repos"] = self
.args
.disable_repo
431 if hasattr(self
.args
, "enable_repo"):
432 ret
["enable_repos"] = self
.args
.enable_repo
434 if hasattr(self
.args
, "offline"):
435 ret
["offline"] = self
.args
.offline
439 def parse_command_update(self
):
440 # Implement the "update" command.
441 sub_update
= self
.sub_commands
.add_parser("update",
442 help=_("Update the package indexes."))
443 sub_update
.add_argument("action", action
="store_const", const
="update")
445 def parse_command_build(self
):
446 # Implement the "build" command.
447 sub_build
= self
.sub_commands
.add_parser("build",
448 help=_("Build one or more packages."))
449 sub_build
.add_argument("package", nargs
=1,
450 help=_("Give name of at least one package to build."))
451 sub_build
.add_argument("action", action
="store_const", const
="build")
453 sub_build
.add_argument("-a", "--arch",
454 help=_("Build the package for the given architecture."))
455 sub_build
.add_argument("--resultdir", nargs
="?",
456 help=_("Path were the output files should be copied to."))
457 sub_build
.add_argument("-m", "--mode", nargs
="?", default
="development",
458 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
459 sub_build
.add_argument("--after-shell", action
="store_true",
460 help=_("Run a shell after a successful build."))
462 def parse_command_shell(self
):
463 # Implement the "shell" command.
464 sub_shell
= self
.sub_commands
.add_parser("shell",
465 help=_("Go into a shell."))
466 sub_shell
.add_argument("package", nargs
="?",
467 help=_("Give name of a package."))
468 sub_shell
.add_argument("action", action
="store_const", const
="shell")
470 sub_shell
.add_argument("-a", "--arch",
471 help=_("Emulated architecture in the shell."))
472 sub_shell
.add_argument("-m", "--mode", nargs
="?", default
="development",
473 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
475 def parse_command_dist(self
):
476 # Implement the "dist" command.
477 sub_dist
= self
.sub_commands
.add_parser("dist",
478 help=_("Generate a source package."))
479 sub_dist
.add_argument("package", nargs
="+",
480 help=_("Give name(s) of a package(s)."))
481 sub_dist
.add_argument("action", action
="store_const", const
="dist")
483 sub_dist
.add_argument("--resultdir", nargs
="?",
484 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 pakfire
.build(pkg
, builder_mode
=self
.args
.mode
,
522 arch
=self
.args
.arch
, resultdirs
=[self
.args
.resultdir
,],
523 shell
=True, after_shell
=self
.args
.after_shell
, **self
.pakfire_args
)
525 def handle_shell(self
):
528 # Get the package descriptor from the command line options
529 if self
.args
.package
:
530 pkg
= self
.args
.package
532 # Check, if we got a regular file
533 if os
.path
.exists(pkg
):
534 pkg
= os
.path
.abspath(pkg
)
537 raise FileNotFoundError
, pkg
539 pakfire
.shell(pkg
, builder_mode
=self
.args
.mode
,
540 arch
=self
.args
.arch
, **self
.pakfire_args
)
542 def handle_dist(self
):
543 # Get the packages from the command line options
546 for pkg
in self
.args
.package
:
547 # Check, if we got a regular file
548 if os
.path
.exists(pkg
):
549 pkg
= os
.path
.abspath(pkg
)
553 raise FileNotFoundError
, pkg
555 # Put packages to where the user said or our
556 # current working directory.
557 resultdir
= self
.args
.resultdir
or os
.getcwd()
559 # Change the default pakfire configuration, because
560 # packaging source packages can be done in server mode.
561 pakfire_args
= self
.pakfire_args
562 pakfire_args
["mode"] = "server"
565 pakfire
.dist(pkg
, resultdir
=resultdir
, **pakfire_args
)
567 def handle_provides(self
):
568 pkgs
= pakfire
.provides(self
.args
.pattern
, **self
.pakfire_args
)
571 print pkg
.dump(long=True)
573 def handle_cache_create(self
):
574 pakfire
.cache_create(**self
.pakfire_args
)
576 def handle_cache_cleanup(self
):
577 for env
in os
.listdir(CACHE_ENVIRON_DIR
):
578 if not env
.endswith(".cache"):
581 print _("Removing environment cache file: %s..." % env
)
582 env
= os
.path
.join(CACHE_ENVIRON_DIR
, env
)
587 print _("Could not remove file: %s") % env
590 class CliServer(Cli
):
592 self
.parser
= argparse
.ArgumentParser(
593 description
= _("Pakfire server command line interface."),
596 self
.parse_common_arguments()
599 self
.sub_commands
= self
.parser
.add_subparsers()
601 self
.parse_command_build()
602 self
.parse_command_keepalive()
603 self
.parse_command_repoupdate()
604 self
.parse_command_repo()
605 self
.parse_command_info()
607 # Finally parse all arguments from the command line and save them.
608 self
.args
= self
.parser
.parse_args()
610 self
.server
= server
.Server(**self
.pakfire_args
)
613 "build" : self
.handle_build
,
614 "info" : self
.handle_info
,
615 "keepalive" : self
.handle_keepalive
,
616 "repoupdate" : self
.handle_repoupdate
,
617 "repo_create": self
.handle_repo_create
,
621 def pakfire_args(self
):
622 ret
= { "mode" : "server" }
624 if hasattr(self
.args
, "offline"):
625 ret
["offline"] = self
.args
.offline
629 def parse_command_build(self
):
630 # Implement the "build" command.
631 sub_build
= self
.sub_commands
.add_parser("build",
632 help=_("Send a scrach build job to the server."))
633 sub_build
.add_argument("package", nargs
=1,
634 help=_("Give name of at least one package to build."))
635 sub_build
.add_argument("--arch", "-a",
636 help=_("Limit build to only these architecture(s)."))
637 sub_build
.add_argument("action", action
="store_const", const
="build")
639 def parse_command_keepalive(self
):
640 # Implement the "keepalive" command.
641 sub_keepalive
= self
.sub_commands
.add_parser("keepalive",
642 help=_("Send a keepalive to the server."))
643 sub_keepalive
.add_argument("action", action
="store_const",
646 def parse_command_repoupdate(self
):
647 # Implement the "repoupdate" command.
648 sub_repoupdate
= self
.sub_commands
.add_parser("repoupdate",
649 help=_("Update all repositories."))
650 sub_repoupdate
.add_argument("action", action
="store_const",
653 def parse_command_repo(self
):
654 sub_repo
= self
.sub_commands
.add_parser("repo",
655 help=_("Repository management commands."))
657 sub_repo_commands
= sub_repo
.add_subparsers()
659 self
.parse_command_repo_create(sub_repo_commands
)
661 def parse_command_repo_create(self
, sub_commands
):
662 sub_create
= sub_commands
.add_parser("create",
663 help=_("Create a new repository index."))
664 sub_create
.add_argument("path", nargs
=1, help=_("Path to the packages."))
665 sub_create
.add_argument("inputs", nargs
="+", help=_("Path to input packages."))
666 sub_create
.add_argument("action", action
="store_const", const
="repo_create")
668 def parse_command_info(self
):
669 sub_info
= self
.sub_commands
.add_parser("info",
670 help=_("Dump some information about this machine."))
671 sub_info
.add_argument("action", action
="store_const", const
="info")
673 def handle_keepalive(self
):
674 self
.server
.update_info()
676 def handle_build(self
):
679 arches
= self
.args
.arch
.split()
681 (package
,) = self
.args
.package
683 self
.server
.create_scratch_build({})
686 # Temporary folter for source package.
687 tmpdir
= "/tmp/pakfire-%s" % util
.random_string()
692 pakfire
.dist(package
, resultdir
=[tmpdir
,])
694 for file in os
.listdir(tmpdir
):
695 file = os
.path
.join(tmpdir
, file)
700 if os
.path
.exists(tmpdir
):
703 def handle_repoupdate(self
):
704 self
.server
.update_repositories()
706 def handle_repo_create(self
):
707 path
= self
.args
.path
[0]
709 pakfire
.repo_create(path
, self
.args
.inputs
, **self
.pakfire_args
)
711 def handle_info(self
):
712 info
= self
.server
.info()
714 print "\n".join(info
)
717 class CliBuilderIntern(Cli
):
719 self
.parser
= argparse
.ArgumentParser(
720 description
= _("Pakfire builder command line interface."),
723 self
.parse_common_arguments()
726 self
.sub_commands
= self
.parser
.add_subparsers()
728 self
.parse_command_build()
730 # Finally parse all arguments from the command line and save them.
731 self
.args
= self
.parser
.parse_args()
734 "build" : self
.handle_build
,
737 def parse_command_build(self
):
738 # Implement the "build" command.
739 sub_build
= self
.sub_commands
.add_parser("build",
740 help=_("Build one or more packages."))
741 sub_build
.add_argument("package", nargs
=1,
742 help=_("Give name of at least one package to build."))
743 sub_build
.add_argument("action", action
="store_const", const
="build")
745 sub_build
.add_argument("-a", "--arch",
746 help=_("Build the package for the given architecture."))
747 sub_build
.add_argument("--resultdir", nargs
="?",
748 help=_("Path were the output files should be copied to."))
749 sub_build
.add_argument("-m", "--mode", nargs
="?", default
="development",
750 help=_("Mode to run in. Is either 'release' or 'development' (default)."))
751 sub_build
.add_argument("--nodeps", action
="store_true",
752 help=_("Do not verify build dependencies."))
754 def handle_build(self
):
755 # Get the package descriptor from the command line options
756 pkg
= self
.args
.package
[0]
758 # Check, if we got a regular file
759 if os
.path
.exists(pkg
):
760 pkg
= os
.path
.abspath(pkg
)
762 raise FileNotFoundError
, pkg
764 pakfire
._build
(pkg
, builder_mode
=self
.args
.mode
,
765 arch
=self
.args
.arch
, resultdir
=self
.args
.resultdir
,)
768 class CliClient(Cli
):
770 self
.parser
= argparse
.ArgumentParser(
771 description
= _("Pakfire client command line interface."),
774 self
.parse_common_arguments(repo_manage_switches
=True, offline_switch
=True)
777 self
.sub_commands
= self
.parser
.add_subparsers()
779 self
.parse_command_build()
780 self
.parse_command_connection_check()
781 self
.parse_command_info()
783 # Finally parse all arguments from the command line and save them.
784 self
.args
= self
.parser
.parse_args()
787 "build" : self
.handle_build
,
788 "conn-check" : self
.handle_connection_check
,
789 "info" : self
.handle_info
,
792 # Read configuration for the pakfire client.
793 self
.conf
= conf
= config
.ConfigClient()
795 # Create connection to pakfire hub.
796 self
.client
= client
.PakfireUserClient(
797 conf
.get("client", "server"),
798 conf
.get("client", "username"),
799 conf
.get("client", "password"),
802 def parse_command_build(self
):
803 # Parse "build" command.
804 sub_build
= self
.sub_commands
.add_parser("build",
805 help=_("Build a package remotely."))
806 sub_build
.add_argument("package", nargs
=1,
807 help=_("Give name of a package to build."))
808 sub_build
.add_argument("action", action
="store_const", const
="build")
810 sub_build
.add_argument("-a", "--arch",
811 help=_("Build the package for the given architecture."))
813 def parse_command_info(self
):
814 # Implement the "info" command.
815 sub_info
= self
.sub_commands
.add_parser("info",
816 help=_("Print some information about this host."))
817 sub_info
.add_argument("action", action
="store_const", const
="info")
819 def parse_command_connection_check(self
):
820 # Implement the "conn-check" command.
821 sub_conn_check
= self
.sub_commands
.add_parser("conn-check",
822 help=_("Check the connection to the hub."))
823 sub_conn_check
.add_argument("action", action
="store_const", const
="conn-check")
825 def handle_build(self
):
826 (package
,) = self
.args
.package
828 # XXX just for now, we do only upload source pfm files.
829 assert os
.path
.exists(package
)
831 # Create a temporary directory.
832 temp_dir
= tempfile
.mkdtemp()
835 if package
.endswith(".%s" % MAKEFILE_EXTENSION
):
836 pakfire_args
= { "mode" : "server" }
838 # Create a source package from the makefile.
839 package
= pakfire
.dist(package
, temp_dir
, **pakfire_args
)
841 elif package
.endswith(".%s" % PACKAGE_EXTENSION
):
845 raise Exception, "Unknown filetype: %s" % package
849 arches
= self
.args
.arch
.replace(",", " ")
853 # Create a new build on the server.
854 build
= self
.client
.build_create(package
, arches
=arches
)
856 # XXX Print the resulting build.
860 # Cleanup the temporary directory and all files.
861 if os
.path
.exists(temp_dir
):
862 shutil
.rmtree(temp_dir
, ignore_errors
=True)
864 def handle_info(self
):
868 ret
.append(" PAKFIRE %s" % PAKFIRE_VERSION
)
870 ret
.append(" %-20s: %s" % (_("Hostname"), system
.hostname
))
871 ret
.append(" %-20s: %s" % (_("Pakfire hub"), self
.conf
.get("client", "server")))
872 if self
.conf
.get("client", "username") and self
.conf
.get("client", "password"):
873 ret
.append(" %-20s: %s" % \
874 (_("Username"), self
.conf
.get("client", "username")))
877 # Hardware information
878 ret
.append(" %s:" % _("Hardware information"))
879 ret
.append(" %-16s: %s" % (_("CPU model"), system
.cpu_model
))
880 ret
.append(" %-16s: %s" % (_("Memory"), util
.format_size(system
.memory
)))
882 ret
.append(" %-16s: %s" % (_("Native arch"), system
.native_arch
))
883 if not system
.arch
== system
.native_arch
:
884 ret
.append(" %-16s: %s" % (_("Default arch"), system
.arch
))
886 header
= _("Supported arches")
887 for arch
in system
.supported_arches
:
888 ret
.append(" %-16s: %s" % (header
, arch
))
895 def handle_connection_check(self
):
898 address
= self
.client
.get_my_address()
899 ret
.append(" %-20s: %s" % (_("Your IP address"), address
))
902 authenticated
= self
.client
.check_auth()
904 ret
.append(" %s" % _("You are authenticated to the build service:"))
906 user
= self
.client
.get_user_profile()
907 assert user
, "Could not fetch user infomation"
910 ("name", _("User name")),
911 ("realname", _("Real name")),
912 ("email", _("Email address")),
913 ("registered", _("Registered")),
916 for key
, desc
in keys
:
917 ret
.append(" %-18s: %s" % (desc
, user
.get(key
)))
920 ret
.append(_("You could not be authenticated to the build service."))
926 class CliDaemon(Cli
):
928 self
.parser
= argparse
.ArgumentParser(
929 description
= _("Pakfire daemon command line interface."),
932 self
.parse_common_arguments(repo_manage_switches
=True, offline_switch
=True)
934 # Finally parse all arguments from the command line and save them.
935 self
.args
= self
.parser
.parse_args()
939 Runs the pakfire daemon with provided settings.
941 # Read the configuration file for the daemon.
942 conf
= config
.ConfigDaemon()
944 # Create daemon instance.
945 d
= pakfire
.client
.PakfireDaemon(
946 server
= conf
.get("daemon", "server"),
947 hostname
= conf
.get("daemon", "hostname"),
948 secret
= conf
.get("daemon", "secret"),
954 # We cannot just kill the daemon, it needs a smooth shutdown.
955 except (SystemExit, KeyboardInterrupt):