summaryrefslogtreecommitdiff
path: root/aptsources
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2015-07-05 22:06:22 +0300
committerIgor Pashev <pashev.igor@gmail.com>2015-07-05 22:06:22 +0300
commit622812485150fa7864910ee2f710d5aab2fa9e6d (patch)
treeb3bc4fd72bb80e74ba5a60d8b3d47e610dff012e /aptsources
parent798846ab8337471998b0a4d796d6d409453faa7d (diff)
parentfdd173dd444098ed533cbcd541a7f10f228bc47e (diff)
downloadpython-apt-622812485150fa7864910ee2f710d5aab2fa9e6d.tar.gz
Merge git://anonscm.debian.org/apt/python-apt
Conflicts: debian/changelog python/apt_pkgmodule.cc
Diffstat (limited to 'aptsources')
-rw-r--r--aptsources/__init__.py9
-rw-r--r--aptsources/distinfo.py15
-rw-r--r--aptsources/distro.py107
-rw-r--r--aptsources/sourceslist.py120
4 files changed, 153 insertions, 98 deletions
diff --git a/aptsources/__init__.py b/aptsources/__init__.py
index c02341c2..d711b4f3 100644
--- a/aptsources/__init__.py
+++ b/aptsources/__init__.py
@@ -1,4 +1,9 @@
+from __future__ import print_function
+
import apt_pkg
-# init the package system
-apt_pkg.init()
+
+# init the package system, but do not re-initialize config
+if "APT" not in apt_pkg.config:
+ apt_pkg.init_config()
+apt_pkg.init_system()
diff --git a/aptsources/distinfo.py b/aptsources/distinfo.py
index d80721e5..8fcbac96 100644
--- a/aptsources/distinfo.py
+++ b/aptsources/distinfo.py
@@ -33,6 +33,7 @@ import apt_pkg
from apt_pkg import gettext as _
+
class Template(object):
def __init__(self):
@@ -152,9 +153,7 @@ def split_url(url):
class DistInfo(object):
- def __init__(self,
- dist = None,
- base_dir = "/usr/share/python-apt/templates"):
+ def __init__(self, dist=None, base_dir="/usr/share/python-apt/templates"):
self.metarelease_uri = ''
self.templates = []
self.arch = apt_pkg.config.find("APT::Architecture")
@@ -196,7 +195,7 @@ class DistInfo(object):
self.metarelease_uri = value
elif field == 'Suite':
self.finish_template(template, component)
- component=None
+ component = None
template = Template()
template.name = value
template.distribution = dist
@@ -255,8 +254,8 @@ class DistInfo(object):
template.description = _(value)
elif field == 'Component':
if (component and not
- template.has_component(component.name)):
- template.components.append(component)
+ template.has_component(component.name)):
+ template.components.append(component)
component = Component(value)
elif field == 'CompDescription':
component.set_description(_(value))
@@ -265,8 +264,8 @@ class DistInfo(object):
elif field == 'ParentComponent':
component.set_parent_component(value)
self.finish_template(template, component)
- template=None
- component=None
+ template = None
+ component = None
def finish_template(self, template, component):
" finish the current tempalte "
diff --git a/aptsources/distro.py b/aptsources/distro.py
index e9facbfb..e11f113c 100644
--- a/aptsources/distro.py
+++ b/aptsources/distro.py
@@ -77,7 +77,7 @@ class Distribution(object):
# find the distro template
for template in self.sourceslist.matcher.templates:
if (self.is_codename(template.name) and
- template.distribution == self.id):
+ template.distribution == self.id):
#print "yeah! found a template for %s" % self.description
#print template.description, template.base_uri, \
# template.components
@@ -85,7 +85,7 @@ class Distribution(object):
break
if self.source_template is None:
raise NoDistroTemplateException(
- "Error: could not find a distribution template for %s/%s" %
+ "Error: could not find a distribution template for %s/%s" %
(self.id, self.codename))
# find main and child sources
@@ -95,41 +95,41 @@ class Distribution(object):
enabled_comps = []
#source_code = []
for source in self.sourceslist.list:
- if (source.invalid == False and
- self.is_codename(source.dist) and
- source.template and
- source.template.official == True and
- self.is_codename(source.template.name)):
+ if (not source.invalid and
+ self.is_codename(source.dist) and
+ source.template and
+ source.template.official and
+ self.is_codename(source.template.name)):
#print "yeah! found a distro repo: %s" % source.line
# cdroms need do be handled differently
if (source.uri.startswith("cdrom:") and
- source.disabled == False):
- self.cdrom_sources.append(source)
- cdrom_comps.extend(source.comps)
+ not source.disabled):
+ self.cdrom_sources.append(source)
+ cdrom_comps.extend(source.comps)
elif (source.uri.startswith("cdrom:") and
- source.disabled == True):
+ source.disabled):
self.cdrom_sources.append(source)
elif (source.type == self.binary_type and
- source.disabled == False):
+ not source.disabled):
self.main_sources.append(source)
comps.extend(source.comps)
media.append(source.uri)
elif (source.type == self.binary_type and
- source.disabled == True):
+ source.disabled):
self.disabled_sources.append(source)
- elif (source.type == self.source_type
- and source.disabled == False):
+ elif (source.type == self.source_type and
+ not source.disabled):
self.source_code_sources.append(source)
elif (source.type == self.source_type and
- source.disabled == True):
+ source.disabled):
self.disabled_sources.append(source)
- if (source.invalid == False and
- source.template in self.source_template.children):
- if (source.disabled == False
- and source.type == self.binary_type):
- self.child_sources.append(source)
- elif (source.disabled == False
- and source.type == self.source_type):
+ if (not source.invalid and
+ source.template in self.source_template.children):
+ if (not source.disabled
+ and source.type == self.binary_type):
+ self.child_sources.append(source)
+ elif (not source.disabled
+ and source.type == self.source_type):
self.source_code_sources.append(source)
else:
self.disabled_sources.append(source)
@@ -189,7 +189,7 @@ class Distribution(object):
z = locale.find(".")
if z == -1:
z = len(locale)
- country_code = locale[a+1:z].lower()
+ country_code = locale[a + 1:z].lower()
if mirror_template:
self.nearest_server = mirror_template % country_code
@@ -205,7 +205,7 @@ class Distribution(object):
i = server.find("://")
l = server.find(".archive.ubuntu.com")
if i != -1 and l != -1:
- country = server[i+len("://"):l]
+ country = server[i + len("://"):l]
if country in self.countries:
# TRANSLATORS: %s is a country
return _("Server for %s") % self.countries[country]
@@ -256,9 +256,9 @@ class Distribution(object):
for server in self.used_servers:
mirror_entry = [self._get_mirror_name(server), server, False]
if (compare_mirrors(server, self.nearest_server) or
- compare_mirrors(server, self.main_server)):
+ compare_mirrors(server, self.main_server)):
continue
- elif not mirror_entry in mirrors:
+ elif mirror_entry not in mirrors:
mirrors.append(mirror_entry)
return mirrors
@@ -280,10 +280,11 @@ class Distribution(object):
new_source = self.sourceslist.add(type, uri, dist, comps, comment)
# if source code is enabled add a deb-src line after the new
# source
- if self.get_source_code == True and type == self.binary_type:
- self.sourceslist.add(self.source_type, uri, dist, comps, comment,
- file=new_source.file,
- pos=self.sourceslist.list.index(new_source)+1)
+ if self.get_source_code and type == self.binary_type:
+ self.sourceslist.add(
+ self.source_type, uri, dist, comps, comment,
+ file=new_source.file,
+ pos=self.sourceslist.list.index(new_source) + 1)
def enable_component(self, comp):
"""
@@ -344,7 +345,7 @@ class Distribution(object):
# check if there is a main source at all
if len(self.main_sources) < 1:
# create a new main source
- self.add_source(comps=["%s"%comp])
+ self.add_source(comps=["%s" % comp])
else:
# add the comp to all main, child and source code sources
for source in sources:
@@ -354,10 +355,10 @@ class Distribution(object):
add_component_only_once(source, comps_per_sdist)
# check if there is a main source code source at all
- if self.get_source_code == True:
+ if self.get_source_code:
if len(self.source_code_sources) < 1:
# create a new main source
- self.add_source(type=self.source_type, comps=["%s"%comp])
+ self.add_source(type=self.source_type, comps=["%s" % comp])
else:
# add the comp to all main, child and source code sources
for source in self.source_code_sources:
@@ -404,7 +405,7 @@ class Distribution(object):
for source in self.child_sources:
# Do not change the forces server of a child source
if (source.template.base_uri is None or
- source.template.base_uri != source.uri):
+ source.template.base_uri != source.uri):
change_server_of_source(source, uri, seen_binary)
for source in self.source_code_sources:
change_server_of_source(source, uri, seen_source)
@@ -435,7 +436,7 @@ class DebianDistribution(Distribution):
i = server.find("://ftp.")
l = server.find(".debian.org")
if i != -1 and l != -1:
- country = server[i+len("://ftp."):l]
+ country = server[i + len("://ftp."):l]
if country in self.countries:
# TRANSLATORS: %s is a country
return _("Server for %s") % gettext.dgettext(
@@ -456,6 +457,13 @@ class UbuntuDistribution(Distribution):
self, mirror_template="http://%s.archive.ubuntu.com/ubuntu/")
+class UbuntuRTMDistribution(UbuntuDistribution):
+ ''' Class to support specific Ubuntu RTM features '''
+
+ def get_mirrors(self):
+ self.main_server = self.source_template.base_uri
+
+
def _lsb_release():
"""Call lsb_release --idrc and return a mapping."""
from subprocess import Popen, PIPE
@@ -474,6 +482,24 @@ def _lsb_release():
return result
+def _system_image_channel():
+ """Get the current channel from system-image-cli -i if possible."""
+ from subprocess import Popen, PIPE
+ import errno
+ try:
+ out = Popen(
+ ['system-image-cli', '-i'], stdout=PIPE,
+ universal_newlines=True).communicate()[0]
+ for l in out.splitlines():
+ if l.startswith('channel: '):
+ return l.split(': ', 1)[1]
+ except OSError as exc:
+ if exc.errno != errno.ENOENT:
+ logging.warning(
+ 'system-image-cli failed, using defaults: %s' % exc)
+ return None
+
+
def get_distro(id=None, codename=None, description=None, release=None):
"""
Check the currently used distribution and return the corresponding
@@ -489,8 +515,17 @@ def get_distro(id=None, codename=None, description=None, release=None):
codename = result['Codename']
description = result['Description']
release = result['Release']
+ if id == "Ubuntu":
+ channel = _system_image_channel()
+ if channel is not None and "ubuntu-rtm/" in channel:
+ id = "Ubuntu-RTM"
+ codename = channel.rsplit("/", 1)[1].split("-", 1)[0]
+ description = codename
+ release = codename
if id == "Ubuntu":
return UbuntuDistribution(id, codename, description, release)
+ if id == "Ubuntu-RTM":
+ return UbuntuRTMDistribution(id, codename, description, release)
elif id == "Debian":
return DebianDistribution(id, codename, description, release)
else:
diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py
index f5a86ecb..f4903523 100644
--- a/aptsources/sourceslist.py
+++ b/aptsources/sourceslist.py
@@ -23,7 +23,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
-from __future__ import absolute_import
+from __future__ import absolute_import, print_function
import glob
import logging
@@ -34,18 +34,20 @@ import time
import apt_pkg
from .distinfo import DistInfo
-from apt.deprecation import function_deprecated_by
#from apt_pkg import gettext as _
# some global helpers
+__all__ = ['is_mirror', 'SourceEntry', 'NullMatcher', 'SourcesList',
+ 'SourceEntryMatcher']
+
def is_mirror(master_uri, compare_uri):
- """ check if the given add_url is idential or a mirror of orig_uri
- e.g. master_uri = archive.ubuntu.com
- compare_uri = de.archive.ubuntu.com
- -> True
+ """ check if the given add_url is idential or a mirror of orig_uri e.g.:
+ master_uri = archive.ubuntu.com
+ compare_uri = de.archive.ubuntu.com
+ -> True
"""
# remove traling spaces and "/"
compare_uri = compare_uri.rstrip("/ ")
@@ -60,19 +62,24 @@ def is_mirror(master_uri, compare_uri):
compare_srv = compare_uri.split("//")[1]
master_srv = master_uri.split("//")[1]
#print "%s == %s " % (add_srv, orig_srv)
- except IndexError: # ok, somethings wrong here
+ except IndexError: # ok, somethings wrong here
#print "IndexError"
return False
# remove the leading "<country>." (if any) and see if that helps
if "." in compare_srv and \
- compare_srv[compare_srv.index(".")+1:] == master_srv:
+ compare_srv[compare_srv.index(".") + 1:] == master_srv:
#print "Mirror"
return True
return False
def uniq(s):
- """ simple and efficient way to return uniq list """
+ """ simple and efficient way to return uniq collection
+
+ This is not intended for use with a SourceList. It is provided
+ for internal use only. It does not have a leading underscore to
+ not break any old code that uses it; but it should not be used
+ in new code (and is not listed in __all__)."""
return list(set(s))
@@ -80,22 +87,22 @@ class SourceEntry(object):
""" single sources.list entry """
def __init__(self, line, file=None):
- self.invalid = False # is the source entry valid
- self.disabled = False # is it disabled ('#' in front)
- self.type = "" # what type (deb, deb-src)
- self.architectures = [] # architectures
- self.uri = "" # base-uri
- self.dist = "" # distribution (dapper, edgy, etc)
- self.comps = [] # list of available componetns
- # (may empty)
- self.comment = "" # (optional) comment
- self.line = line # the original sources.list line
+ self.invalid = False # is the source entry valid
+ self.disabled = False # is it disabled ('#' in front)
+ self.type = "" # what type (deb, deb-src)
+ self.architectures = [] # architectures
+ self.trusted = None # Trusted
+ self.uri = "" # base-uri
+ self.dist = "" # distribution (dapper, edgy, etc)
+ self.comps = [] # list of available componetns (may empty)
+ self.comment = "" # (optional) comment
+ self.line = line # the original sources.list line
if file is None:
file = apt_pkg.config.find_dir(
- "Dir::Etc")+apt_pkg.config.find("Dir::Etc::sourcelist")
- self.file = file # the file that the entry is located in
+ "Dir::Etc") + apt_pkg.config.find("Dir::Etc::sourcelist")
+ self.file = file # the file that the entry is located in
self.parse(line)
- self.template = None # type DistInfo.Suite
+ self.template = None # type DistInfo.Suite
self.children = []
def __eq__(self, other):
@@ -116,11 +123,17 @@ class SourceEntry(object):
p_found = False
space_found = False
for i in range(len(line)):
- if line[i] == "[" and not space_found:
- p_found=True
- tmp += line[i]
+ if line[i] == "[":
+ if space_found:
+ space_found = False
+ p_found = True
+ pieces.append(tmp)
+ tmp = line[i]
+ else:
+ p_found = True
+ tmp += line[i]
elif line[i] == "]":
- p_found=False
+ p_found = False
tmp += line[i]
elif space_found and not line[i].isspace():
# we skip one or more space
@@ -143,7 +156,7 @@ class SourceEntry(object):
line = self.line.strip()
#print line
# check if the source is enabled/disabled
- if line == "" or line == "#": # empty line
+ if line == "" or line == "#": # empty line
self.invalid = True
return
if line[0] == "#":
@@ -158,7 +171,7 @@ class SourceEntry(object):
# check for another "#" in the line (this is treated as a comment)
i = line.find("#")
if i > 0:
- self.comment = line[i+1:]
+ self.comment = line[i + 1:]
line = line[:i]
# source is ok, split it and see what we have
pieces = self.mysplit(line)
@@ -174,7 +187,7 @@ class SourceEntry(object):
return
if pieces[1].strip()[0] == "[":
- options = pieces.pop(1).strip("[]").split(";")
+ options = pieces.pop(1).strip("[]").split()
for option in options:
try:
key, value = option.split("=", 1)
@@ -183,9 +196,11 @@ class SourceEntry(object):
else:
if key == "arch":
self.architectures = value.split(",")
+ elif key == "trusted":
+ self.trusted = apt_pkg.string_to_bool(value)
else:
self.invalid = True
-
+
# URI
self.uri = pieces[1].strip()
if len(self.uri) < 1:
@@ -224,13 +239,18 @@ class SourceEntry(object):
line += self.type
- if self.architectures:
+ if self.architectures and self.trusted is not None:
+ line += " [arch=%s trusted=%s]" % (
+ ",".join(self.architectures), "yes" if self.trusted else "no")
+ elif self.trusted is not None:
+ line += " [trusted=%s]" % ("yes" if self.trusted else "no")
+ elif self.architectures:
line += " [arch=%s]" % ",".join(self.architectures)
line += " %s %s" % (self.uri, self.dist)
if len(self.comps) > 0:
line += " " + " ".join(self.comps)
if self.comment != "":
- line += " #"+self.comment
+ line += " #" + self.comment
line += "\n"
return line
@@ -280,10 +300,11 @@ class SourcesList(object):
def __find(self, *predicates, **attrs):
for source in self.list:
if (all(getattr(source, key) == attrs[key] for key in attrs) and
- all(predicate(source) for predicate in predicates)):
+ all(predicate(source) for predicate in predicates)):
yield source
- def add(self, type, uri, dist, orig_comps, comment="", pos=-1, file=None, architectures=[]):
+ def add(self, type, uri, dist, orig_comps, comment="", pos=-1, file=None,
+ architectures=[]):
"""
Add a new source to the sources.list.
The method will search for existing matching repos and will try to
@@ -295,8 +316,8 @@ class SourcesList(object):
# we can modify it later
comps = orig_comps[:]
sources = self.__find(lambda s: set(s.architectures) == architectures,
- disabled=False, invalid=False, type=type, uri=uri,
- dist=dist)
+ disabled=False, invalid=False, type=type,
+ uri=uri, dist=dist)
# check if we have this source already in the sources.list
for source in sources:
for new_comp in comps:
@@ -309,7 +330,6 @@ class SourcesList(object):
sources = self.__find(lambda s: set(s.architectures) == architectures,
invalid=False, type=type, uri=uri, dist=dist)
-
for source in sources:
# if there is a repo with the same (type, uri, dist) just add the
# components
@@ -343,17 +363,13 @@ class SourcesList(object):
def restore_backup(self, backup_ext):
" restore sources.list files based on the backup extension "
file = apt_pkg.config.find_file("Dir::Etc::sourcelist")
- if os.path.exists(file+backup_ext) and \
- os.path.exists(file):
- shutil.copy(file+backup_ext, file)
+ if os.path.exists(file + backup_ext) and os.path.exists(file):
+ shutil.copy(file + backup_ext, file)
# now sources.list.d
partsdir = apt_pkg.config.find_dir("Dir::Etc::sourceparts")
for file in glob.glob("%s/*.list" % partsdir):
- if os.path.exists(file+backup_ext):
- shutil.copy(file+backup_ext, file)
-
- if apt_pkg._COMPAT_0_7:
- restoreBackup = function_deprecated_by(restore_backup)
+ if os.path.exists(file + backup_ext):
+ shutil.copy(file + backup_ext, file)
def backup(self, backup_ext=None):
""" make a backup of the current source files, if no backup extension
@@ -362,8 +378,8 @@ class SourcesList(object):
if backup_ext is None:
backup_ext = time.strftime("%y%m%d.%H%M")
for source in self.list:
- if not source.file in already_backuped \
- and os.path.exists(source.file):
+ if (source.file not in already_backuped
+ and os.path.exists(source.file)):
shutil.copy(source.file, "%s%s" % (source.file, backup_ext))
return backup_ext
@@ -450,15 +466,15 @@ class SourceEntryMatcher(object):
found = False
for template in self.templates:
if (re.search(template.match_uri, source.uri) and
- re.match(template.match_name, source.dist) and
- # deb is a valid fallback for deb-src (if that is not
- # definied, see #760035
- (source.type == template.type or template.type == "deb")):
+ re.match(template.match_name, source.dist) and
+ # deb is a valid fallback for deb-src (if that is not
+ # definied, see #760035
+ (source.type == template.type or template.type == "deb")):
found = True
source.template = template
break
elif (template.is_mirror(source.uri) and
- re.match(template.match_name, source.dist)):
+ re.match(template.match_name, source.dist)):
found = True
source.template = template
break