1
2 """
3
4 @author: Fabio Erculiani <lxnay@sabayonlinux.org>
5 @contact: lxnay@sabayonlinux.org
6 @copyright: Fabio Erculiani
7 @license: GPL-2
8
9 B{Entropy Source Package Manager Plugins foundation classes}.
10 @todo: define SpmPlugin API
11
12 """
13
14 from entropy.const import etpConst
15 from entropy.core import Singleton
16 from entropy.misc import LogFile
19 """Base class for Source Package Manager plugins"""
20
21 BASE_PLUGIN_API_VERSION = 3
22
23
24
25 PLUGIN_API_VERSION = -1
26
27
28
29 SUPPORTED_MATCH_TYPES = []
30
31
32 PLUGIN_NAME = None
33
34
35
36
37
38 IS_DEFAULT = False
39
41 """
42 Source Package Manager Plugin singleton method.
43 This method must be reimplemented by subclasses.
44
45 @param output_interface: Entropy output interface
46 @type output_interface: entropy.output.TextInterface based instances
47 @raise NotImplementedError(): when method is not reimplemented
48 """
49 raise NotImplementedError()
50
51 @staticmethod
53 """
54 Return package groups available metadata (Spm categories are grouped
55 into macro categories called "groups").
56 """
57 raise NotImplementedError()
58
67
68 @staticmethod
70 """
71 Return a list of available and valid package build phases.
72 Default value is ["setup", "preinstall", "postinstall", "preremove",
73 "postremove"]
74
75 @return: list of available and valid package build phases
76 @rtype: list
77 """
78 return ["setup", "preinstall", "postinstall", "preremove",
79 "postremove", "configure"]
80
81 @staticmethod
83 """
84 Return a map of phases names between Entropy (as keys) and
85 Source Package Manager.
86
87 @return: map of package phases
88 @rtype: dict
89 """
90 raise NotImplementedError()
91
92 @staticmethod
94 """
95 Return a map composed by configuration file identifiers and their
96 path on disk. These configuration files are related to Source Package
97 Manager.
98
99 @return: configuration files map
100 @rtype: dict
101 """
102 raise NotImplementedError()
103
105 """
106 Return Source Package Manager cache directory path.
107
108 @keyword root: specify an alternative root directory "/"
109 @type root: string
110 @return: cache directory
111 @rtype: string
112 """
113 raise NotImplementedError()
114
128
130 """
131 Return ChangeLog content for given package.
132
133 @param package: package name
134 @type package: string
135 @return: changelog
136 @rtype: string or None
137 """
138 raise NotImplementedError()
139
141 """
142 Return build script path for given package looking through available
143 packages repositories.
144
145 @param package: package name
146 @type package: string
147 @return: build script path
148 @rtype: string
149 """
150 raise NotImplementedError()
151
153 """
154 Return build script path for given package looking into installed
155 packages repository.
156
157 @param package: package name
158 @type package: string
159 @keyword root: specify an alternative root directory "/"
160 @type root: string
161 @return: build script path
162 @rtype: string
163 """
164 raise NotImplementedError()
165
181
183 """
184 Return list of core (system) packages. Core packages are usually
185 consider vital for basic system operativity.
186
187 @return: list of system packages
188 @rtype: list
189 """
190 raise NotImplementedError()
191
193 """
194 Return list of package categories in available packages repositories.
195
196 @return: list of package categories
197 @rtype: list
198 """
199 raise NotImplementedError()
200
213
215 """
216 Return a list of packages affected by given security property argument.
217 Valid security_property values are: affected, new, all.
218
219 @param security_property: packages security property
220 @type security_property: string
221 @return: list of packages affected by given security property
222 @rtype: list
223 """
224 raise NotImplementedError()
225
237
239 """
240 Return Source Package Manager setting referenced by "key"
241
242 @param key: source package manager setting
243 @type key: string
244 @raise KeyError: if setting is not available
245 """
246 raise NotImplementedError()
247
249 """
250 Return path to file containing list (one per line) of packages
251 installed by user (in Portage world, this is the world file).
252
253 @keyword root: specify an alternative root directory "/"
254 @type root: string
255 @return: path to installed packages list file
256 @rtype: string
257 """
258 raise NotImplementedError()
259
261 """
262 Return a list of paths (either directories or files) whose are
263 protected from direct merge requiring user approval.
264
265 @return: list of protected paths
266 @rtype: list
267 """
268 raise NotImplementedError()
269
271 """
272 Return a list of unprotected paths (either directories or files) which
273 reside inside a protected path (see get_merge_protected_paths()).
274 """
275 raise NotImplementedError()
276
278 """
279 Return list of download mirror URLs for given mirror name
280
281 @param mirror_name: mirror name
282 @type mirror_name: string
283 @return: list of download URLs
284 @rtype: list
285 """
286 raise NotImplementedError()
287
294
296 """
297 Log message string to logfile.
298
299 @param message: message string to log
300 @type message: string
301 """
302 log = LogFile(
303 level = etpConst['spmloglevel'],
304 filename = etpConst['spmlogfile'],
305 header = "[spm]"
306 )
307 log.write(message)
308 log.flush()
309 log.close()
310
312 """
313 Match a package looking through available packages repositories using
314 the given match term argument (package) and match type (validity
315 defined by subclasses).
316
317 @param package: package string to match inside available repositories
318 @type package: string
319 @keyword match_type: match type
320 @type match_type: string
321 @return: matched package (atom) or None
322 @rtype: string or list or None
323 @raise KeyError: if match_type is not valid
324 """
325 raise NotImplementedError()
326
328 """
329 Match a package looking through installed packages repository using
330 the given match term argument (package).
331
332 @param package: package string to match inside installed packages
333 repository
334 @type package: string
335 @keyword match_all: return all the matching packages, not just the best
336 @type match_all: bool
337 @keyword root: specify an alternative root directory "/"
338 @type root: string
339 @return: matched package (atom) or None
340 @rtype: string or list or None
341 @raise KeyError: if match_type is not valid
342 """
343 raise NotImplementedError()
344
346 """
347 Generate a package tarball file for given package, from running system.
348 All the information is recomposed from system.
349
350 @param package: package name
351 @type package: string
352 @param file_save_path: exact path (including file name and extension)
353 where package file is saved
354 @type file_save_path: string
355 @return: None
356 @rtype: None
357 @raise entropy.exception.SPMError: if unable to satisfy the request
358 """
359 raise NotImplementedError()
360
372
374 """
375 WARNING: this is an Entropy Server functionality.
376 Enable compile options (also known as USE flags) for package.
377 Compile options are intended to be features that package can
378 expose to other packages or directly to user.
379
380 @param package: package name
381 @type package: string
382 @param options: list of compile options to enable
383 @type options: string
384 @return: enable status, True if enabled, False if not
385 @rtype: bool
386 """
387 raise NotImplementedError()
388
390 """
391 WARNING: this is an Entropy Server functionality.
392 Disable compile options (also known as USE flags) for package.
393 Compile options are intended to be features that package can
394 expose to other packages or directly to user.
395
396 @param package: package name
397 @type package: string
398 @param options: list of compile options to disable
399 @type options: string
400 @return: enable status, True if disabled, False if not
401 @rtype: bool
402 """
403 raise NotImplementedError()
404
406 """
407 WARNING: this is an Entropy Server functionality.
408 Return currently configured compile options (also known as USE flags)
409 for given package.
410 There can be different kinds of compile options so a dictionary should
411 be returned with compile options identifier as key and list of options
412 as value.
413 This method looks through available packages repositories.
414
415 @param package: package name
416 @type package: string
417 @return: compile options
418 @rtype: dict
419 """
420 raise NotImplementedError()
421
423 """
424
425 Return currently configured compile options (also known as USE flags)
426 for given package.
427 There can be different kinds of compile options so a dictionary should
428 be returned with compile options identifier as key and list of options
429 as value.
430 This method looks into installed packages repository.
431
432 @param package: package name
433 @type package: string
434 @keyword root: specify an alternative root directory "/"
435 @type root: string
436 @return: compile options
437 @rtype: dict
438 """
439 raise NotImplementedError()
440
441 - def get_installed_package_content(self, package, root = None):
442 """
443 Return list of files/directories owned by package.
444
445 @param package: package name
446 @type package: string
447 @keyword root: specify an alternative root directory "/"
448 @type root: string
449 @return: list of files/directories owned by package
450 @rtype: list
451 """
452 raise NotImplementedError()
453
454 - def get_packages(self, categories = None, filter_reinstalls = False):
455 """
456 Return list of packages found in available repositories.
457 Extra "filtering" arguments can be passed like "categories", which
458 will make this method returning only packages found in given category
459 list and "filter_reinstalls" which will actually filter out packages
460 already installed (with no updates nor downgrades available).
461
462 @keyword categories: list of package categories to look into
463 @type categories: iterable
464 @keyword filter_reinstalls: enable reinstall packages filter
465 @type filter_reinstalls: bool
466 @return: list of available packages found
467 @rtype: list
468 @todo: improve method, move filter_reinstalls to another function?
469 """
470 raise NotImplementedError()
471
472 - def compile_packages(self, packages, stdin = None, stdout = None,
473 stderr = None, environ = None, pid_write_func = None,
474 pretend = False, verbose = False, fetch_only = False,
475 build_only = False, no_dependencies = False,
476 ask = False, coloured_output = False, oneshot = False):
477 """
478 Compile given packages using given compile options. Extra compiler
479 options can be set via environmental variables (CFLAGS, LDFLAGS, etc).
480 By default, this function writes to stdout and can potentially interact
481 with user via stdin/stdout/stderr.
482 By default, when build_only=False, compiled packages are installed onto
483 the running system.
484
485 @param packages: list of Source Package Manager package names
486 @type packages: list
487 @keyword stdin: custom standard input
488 @type stdin: file object or valid file descriptor number
489 @keyword stdout: custom standard output
490 @type stdout: file object or valid file descriptor number
491 @keyword stderr: custom standard error
492 @type stderr: file object or valid file descriptor number
493 @keyword environ: dict
494 @type environ: map of environmental variables
495 @keyword pid_write_func: function to call with execution pid number
496 @type pid_write_func: callable function, signature func(int_pid_number)
497 @keyword pretend: just show what would be done
498 @type pretend: bool
499 @keyword verbose: execute compilation in verbose mode
500 @type verbose: bool
501 @keyword fetch_only: fetch source code only
502 @type fetch_only: bool
503 @keyword build_only: do not actually touch live system (don't install
504 compiled
505 @type build_only: bool
506 @keyword no_dependencies: ignore possible build time dependencies
507 @type no_dependencies: bool
508 @keyword ask: ask user via stdin before executing the required tasks
509 @type ask: bool
510 @keyword coloured_output: allow coloured output
511 @type coloured_output: bool
512 @keyword oneshot: when compiled packages are intended to not get
513 recorded into personal user compile preferences (if you are not
514 using a Portage-based SPM, just ignore this)
515 @type oneshot: bool
516 @return: execution status
517 @rtype: int
518 """
519 raise NotImplementedError()
520
521 - def remove_packages(self, packages, stdin = None, stdout = None,
522 stderr = None, environ = None, pid_write_func = None,
523 pretend = False, verbose = False, no_dependencies = False, ask = False,
524 coloured_output = False):
525 """
526 Compile given packages using given compile options. Extra compiler
527 options can be set via environmental variables (CFLAGS, LDFLAGS, etc).
528 By default, this function writes to stdout and can potentially interact
529 with user via stdin/stdout/stderr.
530 By default, when build_only=False, compiled packages are installed onto
531 the running system.
532
533 @param packages: list of Source Package Manager package names
534 @type packages: list
535 @keyword stdin: custom standard input
536 @type stdin: file object or valid file descriptor number
537 @keyword stdout: custom standard output
538 @type stdout: file object or valid file descriptor number
539 @keyword stderr: custom standard error
540 @type stderr: file object or valid file descriptor number
541 @keyword environ: dict
542 @type environ: map of environmental variables
543 @keyword pid_write_func: function to call with execution pid number
544 @type pid_write_func: callable function, signature func(int_pid_number)
545 @keyword pretend: just show what would be done
546 @type pretend: bool
547 @keyword verbose: execute compilation in verbose mode
548 @type verbose: bool
549 @keyword no_dependencies: ignore possible build time dependencies
550 @type no_dependencies: bool
551 @keyword ask: ask user via stdin before executing the required tasks
552 @type ask: bool
553 @keyword coloured_output: allow coloured output
554 @type coloured_output: bool
555 @return: execution status
556 @rtype: int
557 """
558 raise NotImplementedError()
559
560 - def print_build_environment_info(self, stdin = None, stdout = None,
561 stderr = None, environ = None, pid_write_func = None,
562 coloured_output = False):
563 """
564 Print build environment info to stdout.
565
566 @keyword stdin: custom standard input
567 @type stdin: file object or valid file descriptor number
568 @keyword stdout: custom standard output
569 @type stdout: file object or valid file descriptor number
570 @keyword stderr: custom standard error
571 @type stderr: file object or valid file descriptor number
572 @keyword environ: dict
573 @type environ: map of environmental variables
574 @keyword pid_write_func: function to call with execution pid number
575 @type pid_write_func: callable function, signature func(int_pid_number)
576 @keyword coloured_output: allow coloured output
577 @type coloured_output: bool
578 @return: execution status
579 @rtype: int
580 """
581 raise NotImplementedError()
582
584 """
585 Hook used by Entropy Client and Entropy Server to ask Source Package
586 Manager to update /etc/profile* and other environment settings around.
587 Since this is part of the Source Package Manager metaphor it must stay
588 in this class.
589
590 @keyword stdout: custom standard output
591 @type stdout: file object or valid file descriptor number
592 @keyword stderr: custom standard error
593 @type stderr: file object or valid file descriptor number
594 @return: execution status
595 @rtype: int
596 """
597 raise NotImplementedError()
598
600 """
601 Return list of packages found in installed packages repository.
602 Extra "filtering" arguments can be passed like "categories", which
603 will make this method returning only packages found in given category
604 list.
605
606 @keyword categories: list of package categories to look into
607 @type categories: iterable
608 @keyword root: specify an alternative root directory "/"
609 @type root: string
610 @return: list of installed packages found
611 @rtype: list
612 """
613 raise NotImplementedError()
614
616 """
617 Package sets are groups of packages meant to ease user installation and
618 removal of large amount of applications or libraries.
619 The difference between package groups is that sets can be referenced
620 anywhere inside Entropy, while the former is just a simple way to
621 group pacakge categories, usually too hard to understand (for eg.
622 "sys-apps" or "app-misc", where user has no clue about the meaning of
623 these).
624 Third party implementations of SPM can just return empty data if
625 this feature is not wanted or implementable.
626
627 @param builtin_sets: if True, also return SPM built-in package sets
628 @type builtin_sets: bool
629 @return: dictionary featuring set name as key, list (set) of package
630 dependencies as value
631 @rtype: dict
632 """
633 raise NotImplementedError()
634
636 """
637 Assign a new Unique Identifier to installed package and return it.
638
639 @param package: package name
640 @type package: string
641 @keyword root: specify an alternative root directory "/"
642 @type root: string
643 @return: assigned Unique Identifier
644 @rtype: int
645 """
646 raise NotImplementedError()
647
650 """
651 This is the bridge between Entropy package repository and its Source
652 Package Manager backend. Given an EntropyRepository instance and its
653 package identifier (which is available inside it). Return the package
654 Unique Identifier that is bound to it, if available, otherwise return
655 None. This function is used by EntropyRepository to regenerate
656 Entropy<->Spm package bindings.
657
658 @param entropy_repository: EntropyRepository instance
659 @param entropy_repository_package_id: EntropyRepository instance package
660 identifier
661 @type entropy_repository: EntropyRepository
662 @type entropy_repository_package_id: int
663 @return: bound Source Package Manager Unique Identifier
664 @rtype: int
665 @raise SPMError: in case of critical issues
666 """
667 raise NotImplementedError()
668
670 """
671 This function should be able to convert an Entropy package name (atom)
672 to a Source Package Manager one.
673
674 @param entropy_package_name: Entropy package name string
675 @type entropy_package_name: string
676 @return: Source Package Manager package name string
677 @rtype: string
678 """
679 raise NotImplementedError()
680
682 """
683 Return list of packages owning provided list of paths.
684 A dictionary is returned containing package name as key and list of
685 matched paths as value.
686
687 @param paths: list of paths to resolve
688 @type paths: list
689 @keyword exact_match: match paths exactly
690 @type exact_match: bool
691 @return: packages owning list of paths
692 @rtype: dict
693 """
694 raise NotImplementedError()
695
696 @staticmethod
698 """
699 Execute Source Package Manager based QA tests on Entropy package
700 files. This method can be used to test Entropy produced packages
701 to make sure that they are fine on this side too. It is called
702 by Entropy QA module (entropy.qa).
703
704 @param package_path: path to Entropy package
705 @type package_path: string
706 @return: tuple composed by error status and error message (if any).
707 Error status is an int with != 0 values if error occured.
708 @rtype: tuple
709 """
710 raise NotImplementedError()
711
725
726 - def package_names_update(self, entropy_repository, entropy_repository_id,
727 entropy_server, entropy_branch):
728 """
729 WARNING: this is an Entropy Server functionality.
730 Execute the synchronization (if needed) of Source Package Manager
731 package names with Entropy ones, stored inside the passed
732 EntropyRepository instance (entropy_repository) referenced by an unique
733 identifier (entropy_repository_id) for the given Entropy packages branch
734 (entropy_branch). This method must also take care of the Entropy package
735 names update file returned by Entropy server instance (entropy_server)
736 method "get_local_database_treeupdates_file".
737 If your Source Package Manager packages are subject to name changes, you
738 must implement this method to effectively keep Entropy aligned with it.
739
740 @param entropy_repository: EntropyRepository instance
741 @type entropy_repository: entropy.db.EntropyRepository
742 @param entropy_repository_id: Entropy Repository unique identifier
743 @type entropy_repository_id: string
744 @param entropy_server: Entropy Server instance
745 @type entropy_server: entropy.server.interfaces.Server instance
746 @param entropy_branch: Entropy branch string (may be handy to selectively
747 execute updates based on working branch)
748 @type entropy_branch: string (SystemSettings['repositories']['branch'])
749 """
750 raise NotImplementedError()
751
753 """
754 Execute Source Package Manager package phase (postinstall, preinstall,
755 preremove, postremove, etc).
756
757 @param package_metadata: Entropy package phase metadata
758 @type package_metadata: dict
759 @param phase_name: name of the phase to call, must be a valid phase
760 contained in package_phases() output.
761 @type phase_name: string
762 @return: phase script exit status
763 @rtype: int
764 @raise KeyError: if phase is not available
765 """
766 raise NotImplementedError()
767
769 """
770 Add package installed by Entropy to SPM database too.
771 "package_metadata" is a dictionary featuring the following (relevant)
772 keys:
773 ['accept_license', 'imagedir', 'xpakpath', 'slot', 'pkgdbpath',
774 'versiontag', 'version', 'xpakstatus', 'unpackdir', 'revision',
775 'category', 'repository', 'xpakdir', 'name', 'install_source',
776 ]
777
778 @param package_metadata: Entropy package metadata
779 @type package_metadata: dict
780 @return: SPM installed package UID or -1
781 @rtype: int
782 """
783 raise NotImplementedError()
784
786 """
787 Remove installed package from SPM database.
788 "package_metadata" is a dictionary featuring the following (relevant)
789 keys:
790 ['accept_license', 'imagedir', 'xpakpath', 'slot', 'pkgdbpath',
791 'versiontag', 'version', 'xpakstatus', 'unpackdir', 'revision',
792 'category', 'repository', 'xpakdir', 'name', 'install_source',
793 'removeatom'
794 ]
795
796 @param package_metadata: Entropy package metadata
797 @type package_metadata: dict
798 @return: execution status
799 @rtype: int
800 """
801 raise NotImplementedError()
802
803 @staticmethod
804 - def entropy_client_post_repository_update_hook(entropy_client,
805 entropy_repository_id):
806 """
807 This function is called by Entropy Client when updating Entropy
808 repositories. Place here all your Source Package Manager bullshit and,
809 remember to return an int form execution status.
810
811 @param entropy_client: Entropy Client interface instance
812 @type entropy_client: entropy.client.interfaces.Client.Client
813 @param entropy_repository_id: Entropy Repository unique identifier
814 @type: string
815 @return: execution status
816 @rtype: int
817 """
818 raise NotImplementedError()
819
820 @staticmethod
822 """
823 This function is called by Entropy Client during package metadata setup.
824 It is intended to be used to inject additional metadata (that would be
825 used afterwards in other entropy_install_* hooks) to entropy package
826 install metadata.
827 Note: for performance reasons, this is a static method !
828
829 @param entropy_client: Entropy Client interface instance
830 @type entropy_client: entropy.client.interfaces.Client.Client
831 @param package_metadata: Entropy package metadata
832 @type package_metadata: dict
833 @return: execution status
834 @rtype: int
835 """
836 raise NotImplementedError()
837
838
839 @staticmethod
841 """
842 This function is called by Entropy Client during package installation,
843 unpack phase. It is intended to be used to extract, if required,
844 Source Package Manager metadata from Entropy packages useful for
845 installing package into Source Package Manager plugin too.
846 For example, PortagePlugin uses this hook to extract xpak metadata
847 from entropy package files and setup Portage directories.
848 Note: for performance reasons, this is a static method !
849
850 @param entropy_client: Entropy Client interface instance
851 @type entropy_client: entropy.client.interfaces.Client.Client
852 @param package_metadata: Entropy package metadata
853 @type package_metadata: dict
854 @return: execution status
855 @rtype: int
856 """
857 raise NotImplementedError()
858