Skip to content

Commit

Permalink
Support for Elementary OS (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
xolox committed Apr 17, 2020
1 parent 5a75488 commit 594a660
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 18 deletions.
10 changes: 5 additions & 5 deletions apt_mirror_updater/__init__.py
@@ -1,7 +1,7 @@
# Automated, robust apt-get mirror selection for Debian and Ubuntu.
#
# Author: Peter Odding <peter@peterodding.com>
# Last Change: April 17, 2020
# Last Change: April 18, 2020
# URL: https://apt-mirror-updater.readthedocs.io

"""
Expand Down Expand Up @@ -154,8 +154,8 @@ def backend(self):
:raises: :exc:`~exceptions.EnvironmentError` when no matching backend
module is available.
"""
logger.debug("Checking whether %s platform is supported ..", self.distributor_id.capitalize())
module_path = "%s.backends.%s" % (__name__, self.distributor_id)
logger.debug("Checking if '%s' module can be imported ..", module_path)
try:
__import__(module_path)
except ImportError:
Expand Down Expand Up @@ -522,7 +522,7 @@ def create_chroot(self, directory, arch=None):
if arch:
debootstrap_command.append('--arch=%s' % arch)
debootstrap_command.append('--keyring=%s' % self.release.keyring_file)
debootstrap_command.append(self.distribution_codename)
debootstrap_command.append(self.release.upstream_series)
debootstrap_command.append(directory)
debootstrap_command.append(self.best_mirror)
self.context.execute(*debootstrap_command, sudo=True)
Expand Down Expand Up @@ -865,9 +865,9 @@ def release_gpg_url(self):
:attr:`~AptMirrorUpdater.distribution_codename` property of the
:attr:`updater` object.
"""
if self.updater and self.updater.distribution_codename:
if self.updater and self.updater.release.upstream_series:
return '%s/dists/%s/Release.gpg' % (
self.mirror_url, self.updater.distribution_codename,
self.mirror_url, self.updater.release.upstream_series,
)

@mutable_property
Expand Down
117 changes: 117 additions & 0 deletions apt_mirror_updater/backends/elementary.py
@@ -0,0 +1,117 @@
# Automated, robust apt-get mirror selection for Debian and Ubuntu.
#
# Author: Peter Odding <peter@peterodding.com>
# Last Change: April 16, 2020
# URL: https://apt-mirror-updater.readthedocs.io

"""
Support for `Elementary OS`_ package archive mirror selection.
Elementary OS is based on Ubuntu LTS releases and as such this module is a very
thin wrapper for the :mod:`apt_mirror_updater.backends.ubuntu` module.
.. _Elementary OS: https://en.wikipedia.org/wiki/Elementary_OS
"""

# Standard library modules.
import datetime
import decimal

# Modules included in our package.
from apt_mirror_updater.backends import ubuntu
from apt_mirror_updater.releases import Release

# Public identifiers that require documentation.
__all__ = (
'KNOWN_RELEASES',
'OLD_RELEASES_URL',
'SECURITY_URL',
'discover_mirrors',
'generate_sources_list',
)

OLD_RELEASES_URL = ubuntu.OLD_RELEASES_URL
"""Alias for :attr:`apt_mirror_updater.backends.ubuntu.OLD_RELEASES_URL`."""

SECURITY_URL = ubuntu.SECURITY_URL
"""Alias for :attr:`apt_mirror_updater.backends.ubuntu.SECURITY_URL`."""

discover_mirrors = ubuntu.discover_mirrors
"""Alias for :func:`apt_mirror_updater.backends.ubuntu.discover_mirrors`."""

generate_sources_list = ubuntu.generate_sources_list
"""Alias for :func:`apt_mirror_updater.backends.ubuntu.generate_sources_list`."""

KNOWN_RELEASES = [
Release(
codename='Jupiter',
created_date=datetime.date(2011, 3, 31),
distributor_id='elementary',
upstream_distributor_id='ubuntu',
upstream_series='maverick',
upstream_version=decimal.Decimal('10.10'),
is_lts=False,
series='jupiter',
version=decimal.Decimal('0.1'),
),
Release(
codename='Luna',
created_date=datetime.date(2013, 8, 10),
distributor_id='elementary',
upstream_distributor_id='ubuntu',
upstream_series='precise',
upstream_version=decimal.Decimal('12.04'),
is_lts=False,
series='luna',
version=decimal.Decimal('0.2'),
),
Release(
codename='Freya',
created_date=datetime.date(2015, 4, 11),
distributor_id='elementary',
upstream_distributor_id='ubuntu',
upstream_series='trusty',
upstream_version=decimal.Decimal('14.04'),
is_lts=False,
series='freya',
version=decimal.Decimal('0.3'),
),
Release(
codename='Loki',
created_date=datetime.date(2016, 9, 9),
distributor_id='elementary',
upstream_distributor_id='ubuntu',
upstream_series='xenial',
upstream_version=decimal.Decimal('16.04'),
is_lts=False,
series='loki',
version=decimal.Decimal('0.4'),
),
Release(
codename='Juno',
created_date=datetime.date(2018, 10, 16),
distributor_id='elementary',
upstream_distributor_id='ubuntu',
upstream_series='bionic',
upstream_version=decimal.Decimal('18.04'),
is_lts=False,
series='juno',
version=decimal.Decimal('5.0'),
),
Release(
codename='Hera',
created_date=datetime.date(2019, 12, 3),
distributor_id='elementary',
upstream_distributor_id='ubuntu',
upstream_series='bionic',
upstream_version=decimal.Decimal('18.04'),
is_lts=False,
series='hera',
version=decimal.Decimal('5.1'),
),
]
"""
List of :class:`.Release` objects corresponding to known elementary OS
releases based on the summary table on the following web page:
https://en.wikipedia.org/wiki/Elementary_OS#Summary_table
"""
57 changes: 44 additions & 13 deletions apt_mirror_updater/releases.py
@@ -1,7 +1,7 @@
# Easy to use metadata on Debian and Ubuntu releases.
#
# Author: Peter Odding <peter@peterodding.com>
# Last Change: April 16, 2020
# Last Change: April 18, 2020
# URL: https://apt-mirror-updater.readthedocs.io

"""
Expand Down Expand Up @@ -123,18 +123,20 @@ def coerce_release(value):
@cached
def discover_releases():
"""
Discover known Debian and Ubuntu releases.
Discover known Debian, Elementary OS and Ubuntu releases.
:returns: A list of discovered :class:`Release` objects sorted by
:attr:`~Release.distributor_id` and :attr:`~Release.version`.
The first time this function is called it will try to parse the CSV files
in ``/usr/share/distro-info`` using :func:`parse_csv_file()` and merge any
releases it finds with the releases embedded into the source code of this
module. The result is cached and returned each time the function is called.
It's not a problem if the ``/usr/share/distro-info`` directory doesn't
exist or doesn't contain any ``*.csv`` files (it won't cause a warning or
error). Of course in this case only the embedded releases will be returned.
module and the releases defined by
:data:`apt_mirror_updater.backends.elementary.KNOWN_RELEASES`. The result
is cached and returned each time the function is called. It's not a problem
if the ``/usr/share/distro-info`` directory doesn't exist or doesn't
contain any ``*.csv`` files (it won't cause a warning or error). Of course
in this case only the embedded releases will be returned.
"""
# Discover the known releases on the first call to discover_releases().
# First we check the CSV files on the system where apt-mirror-updater
Expand All @@ -144,10 +146,14 @@ def discover_releases():
for filename in glob.glob(os.path.join(DISTRO_INFO_DIRECTORY, '*.csv')):
for release in parse_csv_file(filename):
result.add(release)
# Add the releases bundled with apt-mirror-updater to the result
# without causing duplicate entries (due to the use of a set and key
# Add the Debian and Ubuntu releases bundled with apt-mirror-updater to the
# result without causing duplicate entries (due to the use of a set and key
# properties).
result.update(BUNDLED_RELEASES)
# Add the Elementary OS releases bundled with apt-mirror-updater.
# We import the known releases here to avoid circular imports.
from apt_mirror_updater.backends import elementary
result.update(elementary.KNOWN_RELEASES)
# Sort the releases by distributor ID and version / series.
return sorted(result, key=lambda r: (r.distributor_id, r.version or 0, r.series))

Expand Down Expand Up @@ -240,7 +246,7 @@ def ubuntu_keyring_updated():

class Release(PropertyManager):

"""Data class for metadata on Debian and Ubuntu releases."""
"""Data class for metadata on Debian, Elementary OS and Ubuntu releases."""

@key_property
def codename(self):
Expand All @@ -252,7 +258,7 @@ def created_date(self):

@key_property
def distributor_id(self):
"""The name of the distributor (a string like ``debian`` or ``ubuntu``)."""
"""The name of the distributor (one of the strings ``debian``, ``elementary`` or ``ubuntu``)."""

@writable_property
def eol_date(self):
Expand Down Expand Up @@ -283,6 +289,21 @@ def release_date(self):
def series(self):
"""The short version of :attr:`codename` (a string)."""

@writable_property
def upstream_distributor_id(self):
"""The upstream distributor ID (a string, defaults to :attr:`distributor_id`)."""
return self.distributor_id

@writable_property
def upstream_series(self):
"""The upstream series (a string, defaults to :attr:`series`)."""
return self.series

@writable_property
def upstream_version(self):
"""The upstream version (a string, defaults to :attr:`version`)."""
return self.version

@writable_property
def version(self):
"""
Expand All @@ -304,12 +325,12 @@ def keyring_file(self):
filename = None
reason = None
logger.debug("Selecting keyring file for %s ..", self)
if self.distributor_id == 'debian':
if self.upstream_distributor_id == 'debian':
filename = DEBIAN_KEYRING_CURRENT
reason = "only known keyring"
elif self.distributor_id == 'ubuntu':
elif self.upstream_distributor_id == 'ubuntu':
if ubuntu_keyring_updated():
if self.version > decimal.Decimal('12.04'):
if self.upstream_version > decimal.Decimal('12.04'):
filename = UBUNTU_KEYRING_CURRENT
reason = "new keyring package / new release"
else:
Expand Down Expand Up @@ -337,6 +358,8 @@ def __str__(self):
if self.version:
label.append(str(self.version))
label.append("(%s)" % self.series)
if self.upstream_distributor_id and self.upstream_version:
label.extend(("based on", self.upstream_distributor_id.title(), str(self.upstream_version)))
return " ".join(label)


Expand All @@ -349,9 +372,17 @@ def __str__(self):
# indent = " " * 4
# cog.out("\nBUNDLED_RELEASES = [\n")
# for release in discover_releases():
# if release.distributor_id == 'elementary':
# # Don't duplicate the Elementary OS releases.
# continue
# cog.out(indent + "Release(\n")
# for name in release.find_properties(cached=False):
# value = getattr(release, name)
# if ((name == 'upstream_distributor_id' and value == release.distributor_id) or
# (name == 'upstream_series' and value == release.series) or
# (name == 'upstream_version' and value == release.version)):
# # Skip redundant values.
# continue
# if value is not None:
# if isinstance(value, decimal.Decimal):
# # It seems weirdly inconsistency to me that this is needed
Expand Down
6 changes: 6 additions & 0 deletions docs/api.rst
Expand Up @@ -19,6 +19,12 @@ the `apt-mirror-updater` package. The following modules are available:
.. automodule:: apt_mirror_updater.backends.debian
:members:

:mod:`apt_mirror_updater.backends.elementary`
---------------------------------------------

.. automodule:: apt_mirror_updater.backends.elementary
:members:

:mod:`apt_mirror_updater.backends.ubuntu`
-----------------------------------------

Expand Down

0 comments on commit 594a660

Please sign in to comment.