22
22
__metaclass__ = type
24
from collections import defaultdict, namedtuple
24
from collections import Iterable, defaultdict
30
from cdimage import osextras
33
33
class UnknownSeries(Exception):
37
BaseSeries = namedtuple("BaseSeries", ["name", "version", "displayname"])
41
class Series(BaseSeries):
42
def __init__(self, *args, **kwargs):
40
class Series(Iterable):
41
def __init__(self, name, version, displayname, distribution="ubuntu",
44
self.version = version
45
self.displayname = displayname
46
self.distribution = distribution
48
for key, value in kwargs.items():
49
setattr(self, key, value)
46
52
def find_by_name(self, name):
54
distribution, name = name.split("/", 1)
56
distribution = "ubuntu"
47
57
for series in all_series:
48
if series.name == name:
58
if series.distribution == distribution and series.name == name:
51
raise ValueError("No series named %s" % name)
61
raise ValueError("No series named %s/%s" % (distribution, name))
54
64
def find_by_version(self, version):
66
distribution, version = version.split("/", 1)
68
distribution = "ubuntu"
55
69
for series in all_series:
56
if series.version == version:
70
if (series.distribution == distribution and
71
series.version == version):
59
raise ValueError("No series with version %s" % version)
75
"No series with version %s/%s" % (distribution, version))
78
def latest(self, distribution="ubuntu"):
79
for series in reversed(all_series):
80
if series.distribution == distribution:
82
raise ValueError("No series with distribution %s" % distribution)
89
if self.distribution == "ubuntu":
92
return "%s/%s" % (self.distribution, self.name)
97
yield self.displayname
70
101
if self._index is None:
99
133
def __gt__(self, other):
100
134
return self._compare(other, operator.gt)
136
def displayversion(self, project):
137
version = getattr(self, "pointversion", self.version)
138
if (project in getattr(self, "lts_projects", []) or
139
getattr(self, "all_lts_projects", False)):
103
144
# TODO: This should probably come from a configuration file.
104
145
all_series.extend([
105
146
Series("warty", "4.10", "Warty Warthog"),
106
147
Series("hoary", "5.04", "Hoary Hedgehog"),
107
148
Series("breezy", "5.10", "Breezy Badger"),
108
Series("dapper", "6.06", "Dapper Drake"),
150
"dapper", "6.06", "Dapper Drake",
151
pointversion="6.06.2",
152
lts_projects=["ubuntu", "kubuntu", "edubuntu", "ubuntu-server"]),
109
153
Series("edgy", "6.10", "Edgy Eft"),
110
154
Series("feisty", "7.04", "Feisty Fawn"),
111
155
Series("gutsy", "7.10", "Gutsy Gibbon"),
112
Series("hardy", "8.04", "Hardy Heron"),
157
"hardy", "8.04", "Hardy Heron",
158
pointversion="8.04.4", lts_projects=["ubuntu", "ubuntu-server"]),
113
159
Series("intrepid", "8.10", "Intrepid Ibex"),
114
160
Series("jaunty", "9.04", "Jaunty Jackalope"),
115
161
Series("karmic", "9.10", "Karmic Koala"),
116
Series("lucid", "10.04", "Lucid Lynx"),
163
"lucid", "10.04", "Lucid Lynx",
164
pointversion="10.04.4",
165
lts_projects=["ubuntu", "kubuntu", "ubuntu-server"]),
117
166
Series("maverick", "10.10", "Maverick Meerkat"),
118
167
Series("natty", "11.04", "Natty Narwhal"),
119
168
Series("oneiric", "11.10", "Oneiric Ocelot"),
120
Series("precise", "12.04", "Precise Pangolin"),
170
"precise", "12.04", "Precise Pangolin",
171
pointversion="12.04.5",
173
"ubuntu", "kubuntu", "ubuntu-server", "edubuntu", "xubuntu",
174
"mythbuntu", "ubuntustudio",
121
176
Series("quantal", "12.10", "Quantal Quetzal"),
122
177
Series("raring", "13.04", "Raring Ringtail"),
178
Series("saucy", "13.10", "Saucy Salamander"),
180
"trusty", "14.04", "Trusty Tahr",
181
pointversion="14.04.2",
182
all_lts_projects=True),
183
Series("utopic", "14.10", "Utopic Unicorn"),
184
Series("vivid", "15.04", "Vivid Vervet"),
185
Series("wily", "15.10", "Wily Werewolf"),
187
Series("14.09", "14.09", "RTM 14.09", distribution="ubuntu-rtm"),
189
"14.09-factory", "14.09.1", "RTM 14.09-factory",
190
distribution="ubuntu-rtm"),
193
all_touch_targets = []
197
def __init__(self, subarch, android_arch, ubuntu_arch):
198
self.subarch = subarch
199
self.android_arch = android_arch
200
self.ubuntu_arch = ubuntu_arch
203
def list_android_arches(self):
204
return list(set([touch.android_arch for touch in all_touch_targets]))
207
def list_ubuntu_arches(self):
208
return list(set([touch.ubuntu_arch for touch in all_touch_targets]))
211
def list_targets_by_ubuntu_arch(self, arch):
212
return [target for target in all_touch_targets
213
if target.ubuntu_arch == arch]
216
# TODO: This should probably come from a configuration file.
217
all_touch_targets.extend([
218
Touch("mako", "armel", "armhf"),
219
Touch("manta", "armel", "armhf"),
220
Touch("generic", "armel", "armhf"),
221
Touch("generic_x86", "i386", "i386"),
222
Touch("flo", "armel", "armhf"),
126
225
_whitelisted_keys = (
140
238
"TRIGGER_MIRRORS",
141
239
"TRIGGER_MIRRORS_ASYNC",
165
267
self.read(config_path)
169
if "IMAGE_TYPE" in kwargs:
170
if "ARCHES" not in os.environ:
171
self.set_default_arches()
172
if "CPUARCHES" not in os.environ:
173
self.set_default_cpuarches()
175
def _read_nullsep_output(self, command):
176
raw = subprocess.Popen(
177
command, stdout=subprocess.PIPE,
178
universal_newlines=True).communicate()[0]
180
for line in raw.split("\0"):
182
key, value = line.split("=", 1)
188
def _shell_escape(self, arg):
189
if re.match(r"^[a-zA-Z0-9+,./:=@_-]+$", arg):
192
return "'%s'" % arg.replace("'", "'\\''")
194
271
def read(self, config_path=None):
196
if config_path is not None:
197
commands.append(". %s" % self._shell_escape(config_path))
198
commands.append("cat /proc/self/environ")
199
for key in _whitelisted_keys:
201
"test -z \"${KEY+x}\" || printf '%s\\0' \"KEY=$KEY\"".replace(
203
env = self._read_nullsep_output(["sh", "-c", "; ".join(commands)])
204
for key, value in env.items():
272
for key, value in osextras.read_shell_config(
273
config_path, _whitelisted_keys):
205
274
if key.startswith("CDIMAGE_") or key in _whitelisted_keys:
206
275
super(Config, self).__setitem__(key, value)