Refactor automirror

Summary:
 * Updated automirror.conf
   * Removed useless configs
   * Added URL for the country code

 * Refactored main.py
   * Added dictionary with the subdomains of some countries
   * Simplified logic
   * Removed premature optimizations
   * Renamed variables and methods

Test Plan: Compare this version with the previous version. The behaviour is expected to be the same.

Reviewers: tsimonq2, wxl

Differential Revision: https://phab.lubuntu.me/D49
This commit is contained in:
apt-ghetto 2019-01-12 15:29:24 -06:00 committed by Simon Quigley
parent 25c5f3c7e4
commit 2ea0f7f12d
2 changed files with 61 additions and 68 deletions

View File

@ -4,19 +4,11 @@
# This assumes that your mirror URLs are under XX.baseURL # This assumes that your mirror URLs are under XX.baseURL
baseUrl: archive.ubuntu.com baseUrl: archive.ubuntu.com
# Package manager backend to use. Currently only supports apt. # URL used for IP address lookup
backend: apt geoIpUrl: https://ipapi.co/json
# Distribution that this is based off of. # Distribution that this is based off of.
# This is so we can make safe assumptions for the contents of # This is so we can make safe assumptions for the contents of
# sources.list-like files. # sources.list-like files.
distribution: Ubuntu distribution: Ubuntu
# URL for a JSON file which looks something like the following:
# {
# "GB": "gb"
# "US": "us"
# }
#
# This would then allow for a URL like us.baseURL
mirrorList: https://mirrorlist.lubuntu.me/list.json

View File

@ -16,7 +16,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import json import json
import subprocess
import libcalamares import libcalamares
from time import strftime from time import strftime
import urllib.request import urllib.request
@ -83,43 +82,51 @@ deb URL/ubuntu/ CODENAME-backports main restricted universe multiverse
# deb http://archive.canonical.com/ubuntu CODENAME partner # deb http://archive.canonical.com/ubuntu CODENAME partner
# deb-src http://archive.canonical.com/ubuntu CODENAME partner""" # deb-src http://archive.canonical.com/ubuntu CODENAME partner"""
SUBDOMAINS_BY_COUNTRY_CODE = {"US": "us.",
"AU": "au.",
"SE": "no.",
"NO": "no.",
"NZ": "nz.",
"NL": "nl.",
"KR": "kr.",
"DE": "de.",
"GE": "ge.",
"PF": "pf.",
"CZ": "cz.",
"HR": "hr."}
def getcountry():
# This URI hardcoded for now, but should eventually be put into the config def getcountrycode():
geoipurl = "https://ipapi.co/json" """
try: Return the two-letter country code or an empty string.
with urllib.request.urlopen(geoipurl, timeout=75) as url:
localedata = json.loads(url.read().decode()) Tries to determine the country code based on the public IP address,
except HTTPError as error: if the device is connected to the Internet. Otherwise it returns
logging.error("Data of %s not retrieved because %s - URL: %s", an empty string.
name, error, url) """
except URLError as error: if libcalamares.globalstorage.value("hasInternet"):
if isinstance(error.reason, socket.timeout): geoipurl = libcalamares.job.configuration["geoIpUrl"]
logging.error("Socket timed out - URL %s", url) try:
with urllib.request.urlopen(geoipurl, timeout=75) as url:
localedata = json.loads(url.read().decode())
except HTTPError as error:
logging.error("Data of %s not retrieved because %s - URL: %s",
name, error, url)
except URLError as error:
if isinstance(error.reason, socket.timeout):
logging.error("Socket timed out - URL %s", url)
else:
logging.error("Non-timeout protocol error.")
else: else:
logging.error("Non-timeout protocol error.") logging.info("Country successfully determined.")
return localedata["country"]
else: else:
print("Country successfully determined.") return ""
return localedata["country"]
def getmirror(country): def get_subdomain_by_country(countrycode):
mirrorlisturl = libcalamares.job.configuration["mirrorList"] if countrycode in SUBDOMAINS_BY_COUNTRY_CODE.keys():
try: return SUBDOMAINS_BY_COUNTRY_CODE[countrycode]
with urllib.request.urlopen(mirrorlisturl, timeout=75) as url:
mirrors = json.loads(url.read().decode())
except HTTPError as error:
logging.error("Data of %s not retrieved because %s - URL: %s",
name, error, url)
except URLError as error:
if isinstance(error.reason, socket.timeout):
logging.error("Socket timed out - URL %s", url)
else:
logging.error("Non-timeout protocol error.")
else:
print("Mirror successfully determined.")
if country in mirrors.keys():
return mirrors[country] + "."
else: else:
return "" return ""
@ -128,34 +135,28 @@ def getcodename():
return get_distro_information()["CODENAME"] return get_distro_information()["CODENAME"]
def changesources(prefix): def changesources(subdomain):
root = libcalamares.globalstorage.value("rootMountPoint")
url = prefix + libcalamares.job.configuration["baseUrl"]
if not url.startswith("http://") and not url.startswith("https://"):
url = "http://" + url
if libcalamares.job.configuration["backend"] == "apt":
distro = libcalamares.job.configuration["distribution"] distro = libcalamares.job.configuration["distribution"]
if "ubuntu" in distro.lower(): url = "http://{}{}".format(subdomain,
global sources libcalamares.job.configuration["baseUrl"])
sources = sources.replace("DISTRIBUTION", distro)
sources = sources.replace("CODENAME", getcodename())
sources = sources.replace("URL", url)
sources = sources.replace("DATE", strftime("%Y-%m-%d"))
with open(root + "/etc/apt/sources.list", "r+") as sourcesfile: global sources
sourcesfile.seek(0) sources = sources.replace("DISTRIBUTION", distro)
sourcesfile.write(sources) sources = sources.replace("CODENAME", getcodename())
sourcesfile.truncate() sources = sources.replace("URL", url)
sources = sources.replace("DATE", strftime("%Y-%m-%d"))
filepath = libcalamares.globalstorage.value("rootMountPoint")
filepath += "/etc/apt/sources.list"
with open(filepath, "r+") as sourcesfile:
sourcesfile.seek(0)
sourcesfile.write(sources)
sourcesfile.truncate()
def run(): def run():
"""Autoselect a mirror from a list.""" """Autoselect a mirror and create the sources.list file."""
if libcalamares.globalstorage.value("hasInternet"): countrycode = getcountrycode()
country = getcountry() subdomain = get_subdomain_by_country(countrycode)
prefix = getmirror(country)
else:
prefix = ""
changesources(prefix) changesources(subdomain)