189
195
def manifest_file_allowed(self, path):
190
196
"""Return true if a given file is allowed in the manifest."""
191
197
if (path.endswith(".iso") or path.endswith(".img") or
192
path.endswith(".img.gz") or path.endswith(".tar.gz") or
193
path.endswith(".tar.xz")):
198
path.endswith(".img.gz") or path.endswith(".img.xz") or
199
path.endswith(".tar.gz") or path.endswith(".tar.xz")):
195
201
if stat.S_ISREG(os.stat(path).st_mode):
379
385
return "preinstalled-headless"
380
386
elif self.project == "ubuntu-server":
381
387
return "preinstalled-server"
382
elif self.project == "ubuntu-touch":
388
elif self.project in ("ubuntu-touch", "ubuntu-touch-custom"):
383
389
return "preinstalled-touch"
384
elif self.project == "ubuntu-pd":
385
return "preinstalled-pd"
386
390
elif self.project == "ubuntu-core":
387
391
return "preinstalled-core"
388
392
elif self.project == "ubuntu-desktop-next":
441
447
if publish_type.startswith("preinstalled-"):
442
448
return "daily-preinstalled"
443
449
elif publish_type in (
444
"desktop", "live", "mid", "moblin-remix", "netbook"):
450
"desktop", "live", "mid", "moblin-remix", "netbook",
451
"live-core", "live-server"):
445
452
return "daily-live"
446
453
elif publish_type == "base" and self.project == "xubuntu-base":
447
454
return "daily-live"
448
455
elif publish_type == "dvd":
450
457
elif publish_type in (
451
"addon", "alternate", "core", "install", "jeos", "server"):
458
"addon", "alternate", "base", "install", "jeos", "server"):
476
483
return ["http://releases.ubuntu.com/include/kubuntu.css"]
477
484
if self.project == "kubuntu-plasma5":
478
485
return ["http://releases.ubuntu.com/include/kubuntu-plasma5.css"]
486
if self.project in ("lubuntu", "lubuntu-next"):
487
return ["http://cdimage.ubuntu.com/include/lubuntu/style.css"]
480
489
return ["http://releases.ubuntu.com/include/style.css"]
958
970
sentences.append(
959
971
"However, you may still test it using a larger USB drive or a "
960
972
"virtual machine.")
973
elif (self.project in ("ubuntu-gnome",
976
"ubuntu-budgie") and series >= "xenial"):
978
"Warning: This image is oversized (which is a bug) and will "
979
"not fit onto a 2GB USB stick.")
981
"However, you may still test it using a DVD, a larger USB "
982
"drive, or a virtual machine.")
961
983
elif (self.project in usb_projects or
962
984
(self.project == "xubuntu" and series >= "raring") or
963
(self.project == "ubuntu-gnome" and series >= "saucy")):
985
(self.project == "ubuntu-gnome" and series >= "saucy" and
986
series << "xenial")):
964
987
sentences.append(
965
988
"Warning: This image is oversized (which is a bug) and will "
966
989
"not fit onto a 1GB USB stick.")
1003
1026
return "contents of desktop part of live filesystem"
1004
1027
elif extension == "manifest-remove":
1005
1028
return "packages to remove from live filesystem on installation"
1029
elif extension == "manifest-minimal-remove":
1030
return "packages to remove from live filesystem on " + \
1031
" installation when performing a minimal install"
1006
1032
elif extension == "template":
1007
1033
return "%s template" % Link("http://atterer.org/jigdo", "jigdo")
1008
1034
elif extension.endswith(".zsync"):
1087
1113
prefix_type = "%s-%s" % (prefix, publish_type)
1088
1114
for entry in os.listdir(directory):
1089
if entry == ("%s.img" % prefix_type):
1115
if entry in ("%s.img" % prefix_type, "%s.img.xz" % prefix_type):
1090
1116
images.append(entry)
1091
1117
elif publish_type == "wubi" and entry.endswith(".tar.xz"):
1092
1118
# Wubi images are just "ARCH.tar.xz", with no prefix.
1132
1159
"preinstalled-mobile", "preinstalled-active",
1133
1160
"preinstalled-headless", "preinstalled-server",
1134
1161
"preinstalled-touch", "preinstalled-core", "wubi",
1135
"preinstalled-desktop-next",
1162
"preinstalled-desktop-next", "live-core",
1139
1166
"amd64", "amd64+mac",
1141
"armel+dove", "armel+imx51", "armel+omap", "armel+omap4",
1168
"armel", "armel+dove", "armel+imx51", "armel+omap", "armel+omap4",
1142
1169
"armel+ac100", "armel+mx5",
1143
"armhf+omap", "armhf+omap4", "armhf+ac100", "armhf+mx5",
1144
"armhf+nexus7", "armhf", "armel", "arm64",
1170
"armhf", "armhf+omap", "armhf+omap4", "armhf+ac100", "armhf+mx5",
1171
"armhf+nexus7", "armhf+raspi2",
1184
1212
"href='http://fonts.googleapis.com/css?family=Ubuntu' "
1185
1213
"rel='stylesheet' type='text/css'>", file=header)
1187
"<link rel=\"icon\" type=\"image/png\" "
1188
"href=\"http://www.kubuntu.org/themes/kubuntu10.04/"
1189
"favicon.ico\">", file=header)
1190
1214
if self.project == "kubuntu-plasma5":
1197
1221
"<link rel=\"icon\" type=\"image/png\" "
1198
1222
"href=\"http://www.kubuntu.org/themes/kubuntu10.04/"
1199
1223
"favicon.ico\">", file=header)
1224
if self.project in ("lubuntu", "lubuntu-next"):
1226
"<link rel=\"icon\" type=\"image/png\" "
1227
"href=\"http://cdimage.ubuntu.com/include/lubuntu/"
1228
"favicon.png\" />", file=header)
1229
header_href = 'https://lubuntu.me/'
1231
header_href = 'http://www.ubuntu.com/'
1200
1233
print(dedent("""\
1202
1235
<body><div id="pageWrapper">
1204
<div id="header"><a href="http://www.ubuntu.com/"></a></div>
1237
<div id="header"><a href="%s"></a></div>
1208
1241
<div id="main">
1209
""") % heading, file=header)
1242
""") % (header_href, heading), file=header)
1211
1244
mirrors_url = "http://www.ubuntu.com/getubuntu/downloadmirrors"
1212
1245
reldir = os.path.realpath(directory)
1274
1307
arches = all_arches
1276
1309
for image_format in (
1277
"iso", "img", "img.gz", "img.tar.gz", "tar.gz",
1278
"tar.xz", "custom.tar.gz",
1310
"iso", "img", "img.gz", "img.xz", "img.tar.gz",
1311
"tar.gz", "tar.xz", "custom.tar.gz",
1281
if image_format == "img":
1314
if image_format == "img" or image_format == "img.xz":
1282
1315
path = os.path.join(
1390
1423
htaccess_extensions = (
1391
1424
"img.gz.torrent", "img.gz.zsync", "img.gz",
1392
"img.tar.gz", "img.torrent", "img.zsync",
1393
"img", "iso.torrent", "iso.zsync", "iso",
1394
"jigdo", "list", "manifest",
1395
"manifest-desktop", "manifest-remove",
1425
"img.xz", "img.tar.gz", "img.torrent",
1426
"img.zsync", "img", "iso.torrent",
1427
"iso.zsync", "iso", "jigdo", "list",
1428
"manifest", "manifest-desktop",
1430
"manifest-minimal-remove",
1396
1431
"template", "tar.gz", "tar.gz.zsync",
1397
1432
"bootimg", "tar.xz", "custom.tar.gz",
1575
1610
for icon, patterns in (
1576
1611
("folder.png", "^^DIRECTORY^^"),
1577
1612
("iso.png", ".iso"),
1578
("img.png", ".img .tar.gz .tar.xz"),
1613
("img.png", ".img .img.xz .tar.gz .tar.xz"),
1579
1614
("jigdo.png", ".jigdo .template"),
1581
1616
".list .manifest .html .zsync "
1591
1626
for extension in (
1592
1627
"img.gz.torrent", "img.gz", "img.torrent", "img",
1593
1628
"iso.torrent", "iso", "jigdo", "list", "manifest",
1594
"manifest-desktop", "manifest-remove", "template",
1629
"manifest-desktop", "manifest-remove",
1630
"manifest-minimal-remove", "template",
1596
1632
mimetype = self.mimetypestr(extension)
1597
1633
if (mimetype and
1600
1636
"AddType %s .%s" % (mimetype, extension),
1603
def make_metalink(self, directory, version):
1639
def make_metalink(self, directory, version, dry_run=False):
1604
1640
"""Create and publish metalink files."""
1605
1641
osextras.unlink_force(os.path.join(directory, "MD5SUMS-metalink"))
1606
1642
osextras.unlink_force(os.path.join(directory, "MD5SUMS-metalink.gpg"))
1612
1648
metalink_builder, self.tree.directory, version, reldir,
1613
1649
self.tree.site_name,
1616
if subprocess.call(command) == 0:
1617
metalink_checksum_directory(self.config, directory)
1619
except OSError as e:
1620
if e.errno != errno.ENOENT:
1652
logger.info(" ".join(shell_quote(arg) for arg in command))
1655
if subprocess.call(command) == 0:
1656
metalink_checksum_directory(self.config, directory)
1658
except OSError as e:
1659
if e.errno != errno.ENOENT:
1623
# Metalink creation failed. Remove any stale .metalink files.
1624
for name in os.listdir(directory):
1625
if name.endswith(".metalink"):
1626
osextras.unlink_force(os.path.join(directory, name))
1663
# Metalink creation failed. Remove any stale .metalink files.
1664
for name in os.listdir(directory):
1665
if name.endswith(".metalink"):
1666
osextras.unlink_force(os.path.join(directory, name))
1629
1669
class DailyTree(Tree):
1696
1736
def image_type_dir(self):
1737
if (self.config.project == "ubuntu-core" and
1738
self.image_type == 'daily-live'):
1739
channel = self.config.get("CHANNEL", "edge")
1740
return os.path.join(self.config.core_series, channel)
1697
1741
image_type_dir = self.image_type.replace("_", "/")
1698
1742
if (self.config.distribution != "ubuntu" or
1699
1743
not self.config["DIST"].is_latest):
1719
1763
elif self.project in (
1720
1764
"kubuntu", "kubuntu-active", "kubuntu-plasma5",
1766
if self.config["DIST"] >= "xenial":
1767
# Per https://lists.ubuntu.com/archives/
1768
# ... ubuntu-release/2016-May/003749.html
1769
return 2 * 1000 * 1000 * 1000
1722
1770
# 1.2GB arbitrary limit, set jriddell 2014-08-21
1723
1771
return (1024 * 1024 * 1024) + (1024 * 1024 * 200)
1724
elif (self.project == "ubuntu" and self.publish_type != "dvd" and
1772
elif (self.project in ("ubuntu", "ubuntukylin") and
1773
self.publish_type != "dvd" and
1725
1774
self.config["DIST"] >= "quantal"):
1726
1775
# Ubuntu quantal onward has a succession of arbitrary limits.
1727
1776
if self.config["DIST"] == "quantal":
1733
1782
return 835000000
1734
1783
elif self.config["DIST"] == "saucy":
1735
1784
return 950000000
1785
elif self.config["DIST"] in ("trusty", "utopic", "vivid", "wily"):
1786
return 1.2 * 1000 * 1000 * 1000
1737
return 1024 * 1024 * 1024
1788
# next relevant size limit is a 2GB (not 2GiB) USB stick
1789
return 2 * 1000 * 1000 * 1000
1738
1790
elif self.project == "ubuntu-gnome" and self.config["DIST"] >= "saucy":
1791
# Per https://lists.ubuntu.com/archives/
1792
# ... ubuntu-release/2016-May/003740.html
1793
if self.config["DIST"] >= "xenial":
1794
return 2 * 1000 * 1000 * 1000
1739
1795
# Requested by darkxst in #ubuntu-release on 2013/06/28 03:29 UTC
1740
1796
return 1024 * 1024 * 1024
1797
elif (self.project in ("ubuntu-budgie", "mythbuntu") and
1798
self.config["DIST"] >= "xenial"):
1799
# mythbuntu project has disbanded per
1800
# https://bugs.launchpad.net/bugs/1639445, xenial images were
1801
# oversized; executive decision by vorlon to raise the limit
1802
# and suppress the warnings
1803
return 2 * 1000 * 1000 * 1000
1804
elif self.project == "xubuntu" and self.config["DIST"] >= "xenial":
1805
# http://irclogs.ubuntu.com/2016/03/09/
1806
# %23ubuntu-release.html#t12:11
1741
1808
elif self.project == "xubuntu" and self.config["DIST"] >= "raring":
1742
1809
# http://irclogs.ubuntu.com/2013/02/11/%23xubuntu-devel.html#t21:48
1743
1810
return 1024 * 1024 * 1024
1744
1811
elif self.project == "ubuntu-mate":
1745
return 1024 * 1024 * 1024
1812
if self.config["DIST"] >= "xenial":
1813
# https://lists.ubuntu.com/archives/ubuntu-release/2016-May/003744.html
1814
return 2 * 1000 * 1000 * 1000
1815
return 1024 * 1024 * 1024
1816
elif (self.project in ("lubuntu", "lubuntu-next") and
1817
self.config["DIST"] >= "artful"):
1818
# https://irclogs.ubuntu.com/2017/07/27/%23ubuntu-release.html#t23:05
1819
return int(1.5 * 1000 * 1000 * 1000)
1820
elif self.project == "lubuntu" and self.config["DIST"] >= "trusty":
1822
# https://irclogs.ubuntu.com/2016/10/01/%23ubuntu-release.html#t19:06
1823
return 1024 * 1024 * 1024
1824
elif self.project == "ubuntu-server":
1825
if self.config["DIST"] == "xenial":
1826
return 1024 * 1024 * 1024
1827
elif self.config["DIST"] >= "zesty" and arch == "ppc64el":
1828
return 1024 * 1024 * 1024
1747
1832
if self.publish_type == "dvd":
1748
1833
# http://en.wikipedia.org/wiki/DVD_plus_RW
1800
1885
elif output.startswith("x86 boot sector"):
1802
elif output.startswith("gzip compressed data"):
1887
elif output.startswith(("gzip compressed data", "XZ compressed data")):
1888
if output.startswith("gzip compressed data"):
1889
compressed_extension = "gz"
1890
if output.startswith("XZ compressed data"):
1891
compressed_extension = "xz"
1803
1892
with open("%s.type" % source_prefix) as compressed_type:
1804
1893
real_output = compressed_type.readline().rstrip("\n")
1805
1894
if real_output.startswith("ISO 9660 CD-ROM filesystem data "):
1895
return "iso.%s" % compressed_extension
1807
1896
elif real_output.startswith("x86 boot sector"):
1897
return "img.%s" % compressed_extension
1809
1898
elif real_output.startswith("tar archive"):
1899
return "tar.%s" % compressed_extension
1812
1901
logger.warning(
1813
"Unknown compressed file type '%s'; assuming .img.gz" %
1902
"Unknown compressed file type '%s'; assuming .img.%s" %
1903
(real_output, compressed_extension))
1904
return "img.%s" % compressed_extension
1817
1906
logger.warning("Unknown file type '%s'; assuming .iso" % output)
1847
1936
def publish_binary(self, publish_type, arch, date):
1848
1937
in_prefix = "%s-%s-%s" % (self.config.series, publish_type, arch)
1849
out_prefix = "%s-%s-%s" % (self.config.series, publish_type, arch)
1938
if publish_type == "live-core":
1939
out_prefix = "ubuntu-core-%s-%s" % (self.config.core_series, arch)
1941
out_prefix = "%s-%s-%s" % (self.config.series, publish_type, arch)
1850
1942
source_dir = self.image_output(arch)
1851
1943
source_prefix = os.path.join(source_dir, in_prefix)
1852
1944
target_dir = os.path.join(self.publish_base, date)
1949
2041
"%s.%s.device.tar.gz" % (source_prefix, devarch),
1950
2042
"%s.%s.device.tar.gz" % (target_prefix, devarch))
2045
if os.path.exists("%s.os.snap" % source_prefix):
2046
logger.info("Publishing %s os snap package ..." % arch)
2048
"%s.os.snap" % source_prefix,
2049
"%s.os.snap" % target_prefix)
2051
# kernel snap packages
2052
if os.path.exists("%s.kernel.snap" % source_prefix):
2053
logger.info("Publishing %s kernel snap package ..." % arch)
2055
"%s.kernel.snap" % source_prefix,
2056
"%s.kernel.snap" % target_prefix)
2058
for devarch in ("dragonboard", "raspi2"):
2059
if os.path.exists("%s.%s.kernel.snap" % (source_prefix,
2061
logger.info("Publishing %s %s kernel snap package ..." %
2064
"%s.%s.kernel.snap" % (source_prefix, devarch),
2065
"%s.%s.kernel.snap" % (target_prefix, devarch))
2067
# snappy model assertions
2068
if os.path.exists("%s.model-assertion" % source_prefix):
2069
logger.info("Publishing %s model assertion ..." % arch)
2071
"%s.model-assertion" % source_prefix,
2072
"%s.model-assertion" % target_prefix)
1952
2074
# zsync metafiles
1953
2075
if osextras.find_on_path("zsyncmake"):
1954
2076
logger.info("Making %s zsync metafile ..." % arch)
2004
2126
"%s.manifest-remove" % source_prefix,
2005
2127
"%s.manifest-remove" % target_prefix)
2128
if os.path.exists("%s.manifest-minimal-remove" % source_prefix):
2130
"%s.manifest-minimal-remove" % source_prefix,
2131
"%s.manifest-minimal-remove" % target_prefix)
2006
2132
elif os.path.exists("%s.manifest-desktop" % source_prefix):
2008
2134
"%s.manifest-desktop" % source_prefix,
2118
2244
if (entry.startswith("%s-" % self.config.series) or
2119
2245
(self.config.subproject == "wubi" and
2120
entry.endswith(".tar.xz"))):
2246
entry.endswith(".tar.xz")) or
2247
(self.config.project == "ubuntu-core" and
2248
self.image_type == "daily-live" and
2249
entry.endswith(".img.xz"))):
2121
2250
images.add(entry)
2153
2282
for arch in arches:
2154
2283
if image_base.endswith("-%s" % arch):
2156
elif (self.config.project in ("ubuntu-touch", "ubuntu-pd") and
2285
elif (self.config.project in ("ubuntu-touch",
2286
"ubuntu-touch-custom") and
2157
2287
arch == "armhf" and
2158
2288
("-armel+" in image_base or "-armhf+" in image_base)):
2160
elif (self.config.project in ("ubuntu-touch", "ubuntu-pd") and
2290
elif (self.config.project in ("ubuntu-touch",
2291
"ubuntu-touch-custom") and
2161
2292
arch == "i386" and "-i386+" in image_base):
2294
elif (self.config.project in ("ubuntu-touch",
2295
"ubuntu-touch-custom") and
2296
arch == "arm64" and "-arm64+" in image_base):
2163
2298
elif self.config.subproject == "wubi" and image_base == arch:
2922
3056
"uec", "server-uec", "core", "wubi",
3059
elif publish_type.startswith("preinstalled") and os.path.exists(path):
2925
3061
elif publish_type == "dvd" and os.path.exists(path):
2926
3062
# DVDs are allowed to not have .manifest files, but may have
2927
3063
# them depending on configuration.
2979
3115
return os.path.join(
2980
3116
torrent_dir, "%s%s%s" % (base_plain, sep, ext))
2982
for ext in "iso", "img", "img.gz", "tar.gz", "img.tar.gz", "tar.xz":
3118
for ext in ("iso", "img", "img.gz", "img.xz", "tar.gz", "img.tar.gz",
2983
3120
if os.path.exists(daily(ext)):
2988
3125
# Copy, to make sure we have a canonical version of this.
2989
artifacts = ["iso", "list", "img", "img.gz", "tar.gz", "img.tar.gz",
2990
"tar.xz", "bootimg", "custom.tar.gz", "device.tar.gz",
2991
"azure.device.tar.gz"]
3126
artifacts = ["iso", "list", "img", "img.gz", "img.xz", "tar.gz",
3127
"img.tar.gz", "tar.xz", "bootimg", "custom.tar.gz",
3128
"device.tar.gz", "azure.device.tar.gz"]
2992
3129
for ext in artifacts:
2993
3130
if not os.path.exists(daily(ext)):
3053
3190
if self.want_full:
3054
3191
self.copy(daily("manifest"), full("manifest"))
3056
for ext in "iso", "img", "img.gz", "tar.gz":
3193
for ext in "iso", "img", "img.gz", "img.xz", "tar.gz":
3057
3194
zsyncext = "%s.zsync" % ext
3058
3195
if not os.path.exists(daily(zsyncext)):
3108
3245
if source == "ubuntu-server/daily":
3109
3246
source = os.path.join(
3110
3247
"ubuntu-server", series.full_name, "daily")
3248
elif source == "ubuntu-server/daily-preinstalled":
3249
source = os.path.join(
3250
"ubuntu-server", series.full_name, "daily-preinstalled")
3112
3252
source = os.path.join(series.full_name, source)
3136
3276
if publish_type not in ("netbook", "mid", "src"):
3137
3277
for arch in arches:
3139
for ext in "iso", "img", "img.gz", "img.tar.gz", "tar.gz":
3279
for ext in ("iso", "img", "img.gz", "img.xz", "img.tar.gz",
3140
3281
paths.append(os.path.join(
3142
3283
"%s-%s-%s.%s" % (series, publish_type, arch, ext)))
3264
3406
self.full_version, self.status)
3266
3408
metalink_target_dir = target_dir
3267
self.make_metalink(metalink_target_dir, self.version)
3410
metalink_target_dir, self.version, dry_run=self.dry_run)
3269
3412
if self.want_dist or self.want_pool:
3270
3413
if self.dry_run: