1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
import os
import layman
import Bcfg2.Server.Plugin
class LaymanSource(Bcfg2.Server.Plugin.Debuggable):
basegroups = ['portage', 'gentoo', 'emerge']
ptype = 'layman'
cclass = 'Portage'
def __init__(self, basepath, xsource):
Bcfg2.Server.Plugin.Debuggable.__init__(self)
self.basepath = basepath
self.xsource = xsource
self.url = xsource.get('url', 'http://www.gentoo.org/proj/en/overlays/repositories.xml')
self.name = xsource.get('name', '')
self.priority = xsource.get('priority', 0)
self.cachefile = None
self.gpgkeys = []
self.recommended = False
self.essentialpkgs = set()
self.arches = [item.text for item in xsource.findall('Arch')]
self.url_map = [dict(version=None, component=None, arch=arch,
url=self.url, baseurl=self.url) for arch in self.arches]
#: A list of the the names of packages that are blacklisted
#: from this source
self.blacklist = [item.text for item in xsource.findall('Blacklist')]
#: A list of the the names of packages that are whitelisted in
#: this source
self.whitelist = [item.text for item in xsource.findall('Whitelist')]
# configure layman
base = os.path.join(basepath, 'layman')
storage = os.path.join(base, 'overlays')
config = layman.config.OptionConfig(options = {
'storage': os.path.join(base, 'overlays'),
'cache': os.path.join(base, 'cache'),
'installed': os.path.join(base, 'installed.xml'),
'local_list': os.path.join(base, 'overlays.xml'),
'overlays': [self.url]
})
self.api = layman.LaymanAPI(config)
# path
self.dir = os.path.join(storage, self.name)
# build the set of conditions to see if this source applies to
# a given set of metadata
self.conditions = []
self.groups = [] # provided for some limited backwards compat
for el in xsource.iterancestors():
if el.tag == "Group":
if el.get("negate", "false").lower() == "true":
self.conditions.append(lambda m, el=el:
el.get("name") not in m.groups)
else:
self.groups.append(el.get("name"))
self.conditions.append(lambda m, el=el:
el.get("name") in m.groups)
elif el.tag == "Client":
if el.get("negate", "false").lower() == "true":
self.conditions.append(lambda m, el=el:
el.get("name") != m.hostname)
else:
self.conditions.append(lambda m, el=el:
el.get("name") == m.hostname)
def get_repo_name(self, url_map):
return self.name
def save_state(self):
pass
def load_state(self):
pass
def filter_unknown(self, unknown):
filtered = set([u for u in unknown if u.startswith('choice')])
unknown.difference_update(filtered)
def get_urls(self):
return self.url
urls = property(get_urls)
def setup_data(self, force_update=False):
self.api.fetch_remote_list()
if not self.api.is_repo(self.name):
self.logger.error("Packages: Layman overlay '%s' not"
" found" % self.name)
return False
if not self.api.is_installed(self.name):
self.logger.info("Packages: Adding layman overlay '%s'" %
self.name)
if not self.api.add_repos(self.name):
self.logger.error("Packages: Failed adding layman"
" overlay '%s'" % self.name)
return False
if force_update:
if not self.api.sync(self.name):
self.logger.error("Packages: Failed syncing layman"
" overlay '%s'" % self.name)
return False
return True
def applies(self, metadata):
""" Return true if this source applies to the given client,
i.e., the client is in all necessary groups.
:param metadata: The client metadata to check to see if this
source applies
:type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata
:returns: bool
"""
# check arch groups
if not self.arch_groups_match(metadata):
return False
# check Group/Client tags from sources.xml
for condition in self.conditions:
if not condition(metadata):
return False
return True
def arch_groups_match(self, metadata):
""" Returns True if the client is in an arch group that
matches the arch of this source.
:returns: bool
"""
for arch in self.arches:
if arch in metadata.groups:
return True
return False
|