Comment 3 for bug 1964115

Revision history for this message
Michael Weiss (primeos-work) wrote :

The problem persists with Ubuntu 22.04 LTS (tested with one of the final RCs: https://iso.qa.ubuntu.com/qatracker/milestones/432/builds/247146/downloads).

I did some analysis and the issue seems to be the "$MIRROR/$RELEASE" part of the custom template.

The relevant source code part (the generate_sources_list function in curtin/commands/apt_config.py):
```
   333 def generate_sources_list(cfg, release, mirrors, target=None, arch=None):
   334 """ generate_sources_list
   335 create a source.list file based on a custom or default template
   336 by replacing mirrors and release in the template
   337 """
   338 aptsrc = "/etc/apt/sources.list"
   339
   340 tmpl = cfg.get('sources_list', None)
   341 from_file = False
   342 if tmpl is None:
   343 LOG.info("No custom template provided, fall back to modify"
   344 "mirrors in %s on the target system", aptsrc)
   345 tmpl = util.load_file(paths.target_path(target, aptsrc))
   346 from_file = True
   347
   348 entries = [SourceEntry(line) for line in tmpl.splitlines(True)]
   349 if from_file:
   350 # when loading from an existing file, we also replace default
   351 # URIs with configured mirrors
   352 entries = update_default_mirrors(entries, mirrors, target, arch)
   353
   354 entries = update_mirrors(entries, mirrors)
   355 entries = update_dist(entries, release)
```

After SourceEntry from python-apt ("from aptsources.sourceslist import SourceEntry") parses the custom template (s. apt.sources_list above), the data ("entries") looks as follows:
```
{'invalid': False, 'disabled': False, 'type': 'deb', 'architectures': [], 'trusted': None, 'uri': '$MIRROR/$RELEASE', 'dist': '$RELEASE', 'comps': ['main', 'restricted'], 'comment': '', 'line': 'deb $MIRROR/$RELEASE $RELEASE main restricted\n', 'file': '/etc/apt/sources.list', 'template': None, 'children': []}
{'invalid': False, 'disabled': False, 'type': 'deb', 'architectures': [], 'trusted': None, 'uri': '$MIRROR/$RELEASE-updates', 'dist': '$RELEASE-updates', 'comps': ['main', 'restricted'], 'comment': '', 'line': 'deb $MIRROR/$RELEASE-updates $RELEASE-updates main restricted\n', 'file': '/etc/apt/sources.list', 'template': None, 'children': []}
{'invalid': False, 'disabled': False, 'type': 'deb', 'architectures': [], 'trusted': None, 'uri': '$MIRROR/$RELEASE-security', 'dist': '$RELEASE-security', 'comps': ['main', 'restricted'], 'comment': '', 'line': 'deb $MIRROR/$RELEASE-security $RELEASE-security main restricted\n', 'file': '/etc/apt/sources.list', 'template': None, 'children': []}
{'invalid': True, 'disabled': False, 'type': '', 'architectures': [], 'trusted': None, 'uri': '', 'dist': '', 'comps': [], 'comment': '', 'line': '\n', 'file': '/etc/apt/sources.list', 'template': None, 'children': []}
{'invalid': False, 'disabled': False, 'type': 'deb', 'architectures': [], 'trusted': None, 'uri': '$MIRROR/$RELEASE', 'dist': '$RELEASE', 'comps': ['universe'], 'comment': '', 'line': 'deb $MIRROR/$RELEASE $RELEASE universe\n', 'file': '/etc/apt/sources.list', 'template': None, 'children': []}
{'invalid': False, 'disabled': False, 'type': 'deb', 'architectures': [], 'trusted': None, 'uri': '$MIRROR/$RELEASE-updates', 'dist': '$RELEASE-updates', 'comps': ['universe'], 'comment': '', 'line': 'deb $MIRROR/$RELEASE-updates $RELEASE-updates universe\n', 'file': '/etc/apt/sources.list', 'template': None, 'children': []}
{'invalid': False, 'disabled': False, 'type': 'deb', 'architectures': [], 'trusted': None, 'uri': '$MIRROR/$RELEASE-security', 'dist': '$RELEASE-security', 'comps': ['universe'], 'comment': '', 'line': 'deb $MIRROR/$RELEASE-security $RELEASE-security universe\n', 'file': '/etc/apt/sources.list', 'template': None, 'children': []}
```

The problem here is that $RELEASE appears in the "uri" attribute, e.g.: "'uri': '$MIRROR/$RELEASE'".

This causes the update_mirrors function (curtin/commands/apt_config.py) to fail:
```
   251 def update_mirrors(entries, mirrors):
   252 """perform template replacement of mirror placeholders with configured
   253 values"""
   254 for entry in entries:
   255 entry.uri = util.render_string(entry.uri, mirrors)
   256 return entries
```

The "mirrors" parameter has the following value: "{'PRIMARY': 'http://ubuntu.company.tld', 'SECURITY': 'http://ubuntu.company.tld', 'MIRROR': 'http://ubuntu.company.tld'}"

Therefore, it fails with "KeyError: 'RELEASE'".

The $RELEASE key is normally handled by the update_dist function but it only operates on entry.dist and not entry.uri.

The easiest (but not necessarily most elegant) solution would probably be to put the "RELEASE" key in the "mirrors" dictionary as well.