24
24
from __future__ import print_function
25
25
from __future__ import unicode_literals
26
26
27
+ import argparse
28
+
27
29
import libdnf .transaction
28
30
29
31
from dnf .comps import CompsQuery
32
34
from dnf .module .metadata_loader import ModuleMetadataLoader
33
35
from dnf .module .repo_module_dict import RepoModuleDict
34
36
from dnf .module .repo_module_version import RepoModuleVersion
35
- from dnf .util import first
37
+ from dnf .util import _parse_specs
36
38
from dnf .db .history import SwdbInterface
37
39
from dnf .yum import misc
38
40
from functools import reduce
@@ -113,6 +115,7 @@ def __init__(self, conf=None):
113
115
self ._allow_erasing = False
114
116
self ._repo_set_imported_gpg_keys = set ()
115
117
self .repo_module_dict = RepoModuleDict (self )
118
+ self .output = None
116
119
117
120
def __enter__ (self ):
118
121
return self
@@ -577,6 +580,8 @@ def reset(self, sack=False, repos=False, goal=False):
577
580
self ._goal = None
578
581
if self ._sack is not None :
579
582
self ._goal = dnf .goal .Goal (self ._sack )
583
+ if self ._module_persistor is not None :
584
+ self ._module_persistor .reset ()
580
585
self .history .close ()
581
586
self ._comps_trans = dnf .comps .TransactionBunch ()
582
587
self ._transaction = None
@@ -1581,13 +1586,13 @@ def reason_fn(pkgname):
1581
1586
1582
1587
return dnf .comps .Solver (self .history , self ._comps , reason_fn )
1583
1588
1584
- def environment_install (self , env_id , types , exclude = None , strict = True ):
1589
+ def environment_install (self , env_id , types , exclude = None , strict = True , exclude_groups = None ):
1585
1590
assert dnf .util .is_string_type (env_id )
1586
1591
solver = self ._build_comps_solver ()
1587
1592
types = self ._translate_comps_pkg_types (types )
1588
1593
trans = dnf .comps .install_or_skip (solver ._environment_install ,
1589
1594
env_id , types , exclude or set (),
1590
- strict )
1595
+ strict , exclude_groups )
1591
1596
if not trans :
1592
1597
return 0
1593
1598
return self ._add_comps_trans (trans )
@@ -1643,7 +1648,7 @@ def _pattern_to_pkgname(pattern):
1643
1648
grp_id , trans .install )
1644
1649
return self ._add_comps_trans (trans )
1645
1650
1646
- def env_group_install (self , patterns , types , strict = True ):
1651
+ def env_group_install (self , patterns , types , strict = True , exclude = None , exclude_groups = None ):
1647
1652
q = CompsQuery (self .comps , self .history ,
1648
1653
CompsQuery .ENVIRONMENTS | CompsQuery .GROUPS ,
1649
1654
CompsQuery .AVAILABLE | CompsQuery .INSTALLED )
@@ -1657,9 +1662,10 @@ def env_group_install(self, patterns, types, strict=True):
1657
1662
done = False
1658
1663
continue
1659
1664
for group_id in res .groups :
1660
- cnt += self .group_install (group_id , types , strict = strict )
1665
+ cnt += self .group_install (group_id , types , exclude = exclude , strict = strict )
1661
1666
for env_id in res .environments :
1662
- cnt += self .environment_install (env_id , types , strict = strict )
1667
+ cnt += self .environment_install (env_id , types , exclude = exclude , strict = strict ,
1668
+ exclude_groups = exclude_groups )
1663
1669
if not done and strict :
1664
1670
raise dnf .exceptions .Error (_ ('Nothing to do.' ))
1665
1671
return cnt
@@ -1754,6 +1760,10 @@ def _install_multiarch(self, query, reponame=None, strict=True):
1754
1760
self ._goal .install (select = sltr , optional = (not strict ))
1755
1761
return len (available )
1756
1762
1763
+ def enable_module (self , specs , save_immediately = False ):
1764
+ for spec in specs :
1765
+ self .repo_module_dict .enable (spec , save_immediately )
1766
+
1757
1767
def install_module (self , specs , strict = True ):
1758
1768
"""
1759
1769
Install module based on provided specs
@@ -1763,6 +1773,97 @@ def install_module(self, specs, strict=True):
1763
1773
"""
1764
1774
return self .repo_module_dict .install (specs , strict )
1765
1775
1776
+ def _categorize_specs (self , install , exclude ):
1777
+ """
1778
+ Categorize :param install and :param exclude list into two groups each (packages and groups)
1779
+
1780
+ :param install: list of specs, whether packages ('foo') or groups/modules ('@bar')
1781
+ :param exclude: list of specs, whether packages ('foo') or groups/modules ('@bar')
1782
+ :return: categorized install and exclude specs (stored in argparse.Namespace class)
1783
+
1784
+ To access packages use: specs.pkg_specs,
1785
+ to access groups use: specs.grp_specs
1786
+ """
1787
+ install_specs = argparse .Namespace ()
1788
+ exclude_specs = argparse .Namespace ()
1789
+ _parse_specs (install_specs , install )
1790
+ _parse_specs (exclude_specs , exclude )
1791
+
1792
+ return install_specs , exclude_specs
1793
+
1794
+ def _exclude_package_specs (self , exclude_specs ):
1795
+ glob_excludes = [exclude for exclude in exclude_specs .pkg_specs
1796
+ if dnf .util .is_glob_pattern (exclude )]
1797
+ excludes = [exclude for exclude in exclude_specs .pkg_specs
1798
+ if exclude not in glob_excludes ]
1799
+
1800
+ exclude_query = self .sack .query ().filter (name = excludes )
1801
+ glob_exclude_query = self .sack .query ().filter (name__glob = glob_excludes )
1802
+
1803
+ self .sack .add_excludes (exclude_query )
1804
+ self .sack .add_excludes (glob_exclude_query )
1805
+
1806
+ def _exclude_groups (self , group_specs ):
1807
+ group_excludes = []
1808
+
1809
+ for group_spec in group_specs :
1810
+ if '/' in group_spec :
1811
+ split = group_spec .split ('/' )
1812
+ group_spec = split [0 ]
1813
+
1814
+ environment = self .comps .environment_by_pattern (group_spec )
1815
+ if environment :
1816
+ for group in environment .groups_iter ():
1817
+ for pkg in group .packages_iter ():
1818
+ group_excludes .append (pkg .name )
1819
+ else :
1820
+ group = self .comps .group_by_pattern (group_spec )
1821
+ if not group :
1822
+ continue
1823
+
1824
+ for pkg in group .packages_iter ():
1825
+ group_excludes .append (pkg .name )
1826
+
1827
+ exclude_query = self .sack .query ().filter (name = group_excludes )
1828
+ self .sack .add_excludes (exclude_query )
1829
+
1830
+ def _install_groups (self , group_specs , excludes , skipped , strict = True ):
1831
+ for group_spec in group_specs :
1832
+ try :
1833
+ types = self .conf .group_package_types
1834
+
1835
+ if '/' in group_spec :
1836
+ split = group_spec .split ('/' )
1837
+ group_spec = split [0 ]
1838
+ types = split [1 ].split (',' )
1839
+
1840
+ self .env_group_install ([group_spec ], types , strict , excludes .pkg_specs ,
1841
+ excludes .grp_specs )
1842
+ except dnf .exceptions .Error :
1843
+ skipped .append ("@" + group_spec )
1844
+
1845
+ def install_specs (self , install , exclude = None , reponame = None , strict = True , forms = None ):
1846
+ if exclude is None :
1847
+ exclude = []
1848
+
1849
+ skipped = []
1850
+ install_specs , exclude_specs = self ._categorize_specs (install , exclude )
1851
+
1852
+ self ._exclude_package_specs (exclude_specs )
1853
+ for spec in install_specs .pkg_specs :
1854
+ try :
1855
+ self .install (spec , reponame = reponame , strict = strict , forms = forms )
1856
+ except dnf .exceptions .Error :
1857
+ skipped .append (spec )
1858
+
1859
+ groups = self .install_module (install_specs .grp_specs , strict )
1860
+
1861
+ self .read_comps (arch_filter = True )
1862
+ self ._exclude_groups (exclude_specs .grp_specs )
1863
+ self ._install_groups (groups , exclude_specs , skipped , strict )
1864
+
1865
+ return skipped
1866
+
1766
1867
def install (self , pkg_spec , reponame = None , strict = True , forms = None ):
1767
1868
# :api
1768
1869
"""Mark package(s) given by pkg_spec and reponame for installation."""
0 commit comments