]> git.ipfire.org Git - people/ms/pakfire.git/blob - python/pakfire/distro.py
Update pakfire-daemon:
[people/ms/pakfire.git] / python / pakfire / distro.py
1 #!/usr/bin/python
2 ###############################################################################
3 # #
4 # Pakfire - The IPFire package management system #
5 # Copyright (C) 2011 Pakfire development team #
6 # #
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. #
11 # #
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. #
16 # #
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/>. #
19 # #
20 ###############################################################################
21
22 import os
23 import re
24
25 import logging
26 log = logging.getLogger("pakfire")
27
28 import system
29
30 class Distribution(object):
31 def __init__(self, data=None):
32 self._data = {}
33
34 if data:
35 self.update(data)
36 else:
37 # Read /etc/os-release if it does exist.
38 self.read_osrelease()
39
40 # Dump all data
41 self.dump()
42
43 def read_osrelease(self):
44 filename = "/etc/os-release"
45
46 if not os.path.exists(filename):
47 return
48
49 keymap = {
50 "NAME" : "name",
51 "PRETTY_NAME" : "pretty_name",
52 "VERSION_ID" : "release",
53 }
54
55 data = {}
56
57 f = open(filename)
58 for line in f.readlines():
59 m = re.match(r"^(.*)=(.*)$", line)
60 if m:
61 k, v = m.groups()
62
63 v = v.replace("\"", "")
64 v = v.strip()
65
66 try:
67 k = keymap[k]
68 except KeyError:
69 continue
70
71 data[k] = v
72 f.close()
73
74 self.update(data)
75
76 def dump(self):
77 log.debug("Distribution configuration:")
78
79 attrs = ("name", "release", "sname", "dist", "vendor", "contact",
80 "arch", "machine", "buildtarget", "source_dl",)
81
82 for attr in attrs:
83 log.debug(" %s : %s" % (attr, getattr(self, attr)))
84
85 def get_config(self):
86 lines = [
87 "[distro]",
88 "name = %s" % self.name,
89 "release = %s" % self.release,
90 "slogan = %s" % self.slogan,
91 "",
92 "vendor = %s" % self.vendor,
93 "contact = %s" % self.contact,
94 ]
95
96 return "\n".join(lines)
97
98 def update(self, config):
99 if not config:
100 return
101
102 # Exceptional handling for arch.
103 if config.has_key("arch"):
104 self.arch = config["arch"]
105 del config["arch"]
106
107 self._data.update(config)
108
109 @property
110 def name(self):
111 return self._data.get("name", "unknown")
112
113 @property
114 def pretty_name(self):
115 pretty_name = self._data.get("pretty_name", None)
116 if not pretty_name:
117 pretty_name = " ".join((self.name, self.release))
118
119 return pretty_name
120
121 @property
122 def release(self):
123 return self._data.get("release", "0")
124
125 @property
126 def sname(self):
127 return self.name.strip().lower()
128
129 @property
130 def slogan(self):
131 return self._data.get("slogan", "N/A")
132
133 @property
134 def vendor(self):
135 vendor = self._data.get("vendor")
136 if vendor is None:
137 vendor = "%s Project" % self.name
138
139 return vendor
140
141 @property
142 def contact(self):
143 return self._data.get("contact", "N/A")
144
145 def get_arch(self):
146 arch = self._data.get("arch", None) or system.system.arch
147
148 # We can not set up a build environment for noarch.
149 if arch == "noarch":
150 arch = system.system.arch
151
152 return arch
153
154 def set_arch(self, arch):
155 # XXX check if we are allowed to set this arch
156 if not arch:
157 return
158
159 self._data["arch"] = arch
160
161 arch = property(get_arch, set_arch)
162
163 @property
164 def platform(self):
165 """
166 Returns the "class" this architecture belongs to.
167 """
168 if self.arch.startswith("arm"):
169 return "arm"
170
171 if self.arch in ("i686", "x86_64"):
172 return "x86"
173
174 return "unknown"
175
176 @property
177 def dist(self):
178 return self.sname[:2] + self.release
179
180 @property
181 def machine(self):
182 vendor = self.vendor.split()[0]
183
184 s = "%s-%s-linux-gnu" % (self.arch, vendor.lower())
185
186 if self.arch.startswith("arm"):
187 s += "eabi"
188
189 return s
190
191 @property
192 def buildtarget(self):
193 # Cut off last segment of machine.
194 return self.machine.replace("-gnu", "")
195
196 @property
197 def source_dl(self):
198 return self._data.get("source_dl", None)
199
200 @property
201 def environ(self):
202 """
203 An attribute that adds some environment variables to the
204 chroot environment.
205 """
206 env = {
207 "DISTRO_NAME" : self.name,
208 "DISTRO_SNAME" : self.sname,
209 "DISTRO_RELEASE" : self.release,
210 "DISTRO_DISTTAG" : self.dist,
211 "DISTRO_ARCH" : self.arch,
212 "DISTRO_MACHINE" : self.machine,
213 "DISTRO_PLATFORM" : self.platform,
214 "DISTRO_BUILDTARGET" : self.buildtarget,
215 "DISTRO_VENDOR" : self.vendor,
216 "DISTRO_CONTACT" : self.contact,
217 "DISTRO_SLOGAN" : self.slogan,
218 }
219
220 return env
221
222 @property
223 def info(self):
224 info = {}
225
226 for k, v in self.environ.items():
227 info[k.lower()] = v
228
229 return info
230
231 @property
232 def personality(self):
233 """
234 Return the personality of the target system.
235
236 If host and target system are of the same architecture, we return
237 None to skip the setting of the personality in the build chroot.
238 """
239
240 if self.arch == system.system.native_arch:
241 return None
242
243 arch2personality = {
244 "x86_64" : "linux64",
245 "i686" : "linux32",
246 "i586" : "linux32",
247 "i486" : "linux32",
248 }
249
250 try:
251 personality = arch2personality[self.arch]
252 except KeyError:
253 personality = None
254
255 return personality