Merge lp:~laney/ubuntu-archive-publishing/updates into lp:ubuntu-archive-publishing

Proposed by Iain Lane
Status: Needs review
Proposed branch: lp:~laney/ubuntu-archive-publishing/updates
Merge into: lp:ubuntu-archive-publishing
Prerequisite: lp:~laney/ubuntu-archive-publishing/more-options
Diff against target: 205 lines (+65/-23)
2 files modified
lib/scripts/generate_extra_overrides.py (+21/-9)
tests/test_generate_extra_overrides.py (+44/-14)
To merge this branch: bzr merge lp:~laney/ubuntu-archive-publishing/updates
Reviewer Review Type Date Requested Status
Colin Watson Pending
Ubuntu Package Archive Administrators Pending
Review via email: mp+402698@code.launchpad.net

Description of the change

Run for -updates. I'm not really sure of all the consequences here, maybe consider this as a basis for discussion initially.

To post a comment you must log in.
Revision history for this message
Dimitri John Ledkov (xnox) wrote :

I support this change. How to best test this?

Unmerged revisions

116. By Iain Lane

generate_extra_overrides: Germinate for stable releases too

Currently we only generate for the release pocket of -devel releases.
This means that Task headers don't get updated for SRUs meaning that,
for example, it's not easily possible to add new packages to the live
seed (other seeds are OK because they get pulled in by Depends of the
metapackage).

Germinate for -updates, and for stable releases. When generating
overrides for stable releases, write overrides to -updates.

This is not a full solution. The immutable nature of release pockets
means that some things can't work properly, for example

  - dependencies of the new package which aren't in -updates won't get
    Task entries
  - *dropping* things from seeds can't work properly, at least not
    without care from consuming code to have -updates dominate release;
    a simple grep-dctrl will not do

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/scripts/generate_extra_overrides.py'
--- lib/scripts/generate_extra_overrides.py 2021-05-13 12:49:01 +0000
+++ lib/scripts/generate_extra_overrides.py 2021-05-13 12:49:01 +0000
@@ -82,7 +82,12 @@
82 return [82 return [
83 series for series in distribution.series83 series for series in distribution.series
84 if series.status in (84 if series.status in (
85 "Experimental", "Active Development", "Pre-release Freeze")]85 "Current Stable Release",
86 "Supported",
87 "Experimental",
88 "Active Development",
89 "Pre-release Freeze"
90 )]
8691
8792
88class GenerateExtraOverrides(ScriptBase):93class GenerateExtraOverrides(ScriptBase):
@@ -346,8 +351,8 @@
346 if "build-essential" in structure.names and primary_flavour:351 if "build-essential" in structure.names and primary_flavour:
347 write_overrides("build-essential", "Build-Essential", "yes")352 write_overrides("build-essential", "Build-Essential", "yes")
348353
349 def germinateArch(self, series_name, components, arch, flavours,354 def germinateArch(self, series_name, series_is_stable, components, arch,
350 structures):355 flavours, structures):
351 """Germinate seeds on all flavours for a single architecture."""356 """Germinate seeds on all flavours for a single architecture."""
352 # Buffer log output for each architecture so that it appears357 # Buffer log output for each architecture so that it appears
353 # sequential.358 # sequential.
@@ -358,8 +363,11 @@
358 germinator = Germinator(arch)363 germinator = Germinator(arch)
359364
360 # Read archive metadata.365 # Read archive metadata.
366 series = [series_name]
367 if series_is_stable:
368 series += [series_name + "-updates"]
361 archive = TagFile(369 archive = TagFile(
362 series_name, components, arch, "file://%s" % self.archiveroot,370 series, components, arch, "file://%s" % self.archiveroot,
363 cleanup=True)371 cleanup=True)
364 germinator.parse_archive(archive)372 germinator.parse_archive(archive)
365373
@@ -405,8 +413,12 @@
405 if os.path.basename(output) not in seed_outputs:413 if os.path.basename(output) not in seed_outputs:
406 os.remove(output)414 os.remove(output)
407415
408 def generateExtraOverrides(self, series_name, components, architectures,416 def generateExtraOverrides(self, series, components, architectures,
409 flavours, seed_bases=None):417 flavours, seed_bases=None):
418 series_name = series.name
419 series_is_stable = series.status in ("Current Stable Release",
420 "Supported")
421 suffix = series_name + "-updates" if series_is_stable else series_name
410 structures = self.makeSeedStructures(422 structures = self.makeSeedStructures(
411 series_name, flavours, seed_bases=seed_bases)423 series_name, flavours, seed_bases=seed_bases)
412424
@@ -420,7 +432,8 @@
420 if pid == 0: # child432 if pid == 0: # child
421 os._exit(self.germinateArchChild(433 os._exit(self.germinateArchChild(
422 close_in_child, wfd,434 close_in_child, wfd,
423 series_name, components, arch, flavours, structures))435 series_name, series_is_stable, components, arch,
436 flavours, structures))
424 else: # parent437 else: # parent
425 os.close(wfd)438 os.close(wfd)
426 reader = os.fdopen(rfd, "rb")439 reader = os.fdopen(rfd, "rb")
@@ -429,7 +442,7 @@
429 seed_outputs = set()442 seed_outputs = set()
430 override_path = os.path.join(443 override_path = os.path.join(
431 self.options.misc_root,444 self.options.misc_root,
432 "more-extra.override.%s.main" % series_name)445 "more-extra.override.%s.main" % suffix)
433 with AtomicFile(override_path) as override_file:446 with AtomicFile(override_path) as override_file:
434 for pid, reader in procs:447 for pid, reader in procs:
435 log_records, overrides, arch_seed_outputs = pickle.load(448 log_records, overrides, arch_seed_outputs = pickle.load(
@@ -447,7 +460,6 @@
447 self.setUp()460 self.setUp()
448461
449 for series in self.series:462 for series in self.series:
450 series_name = series.name
451 components = self.getComponents(series)463 components = self.getComponents(series)
452 if not self.options.architectures:464 if not self.options.architectures:
453 architectures = sorted(465 architectures = sorted(
@@ -456,7 +468,7 @@
456 architectures = self.options.architectures468 architectures = self.options.architectures
457469
458 self.generateExtraOverrides(470 self.generateExtraOverrides(
459 series_name, components, architectures, self.args,471 series, components, architectures, self.args,
460 seed_bases=seed_bases)472 seed_bases=seed_bases)
461473
462 # Add a marker line so that other code can tell from the log file474 # Add a marker line so that other code can tell from the log file
463475
=== modified file 'tests/test_generate_extra_overrides.py'
--- tests/test_generate_extra_overrides.py 2021-05-13 12:49:01 +0000
+++ tests/test_generate_extra_overrides.py 2021-05-13 12:49:01 +0000
@@ -311,23 +311,39 @@
311 sources_path = os.path.join(311 sources_path = os.path.join(
312 script.archiveroot, "dists", distroseries.name, component,312 script.archiveroot, "dists", distroseries.name, component,
313 "source", "Sources.gz")313 "source", "Sources.gz")
314 sources_path_updates = os.path.join(
315 script.archiveroot, "dists",
316 distroseries.name + "-updates", component,
317 "source", "Sources.gz")
314 ensure_directory_exists(os.path.dirname(sources_path))318 ensure_directory_exists(os.path.dirname(sources_path))
319 ensure_directory_exists(os.path.dirname(sources_path_updates))
315 sources_index = gzip.GzipFile(sources_path, "wb")320 sources_index = gzip.GzipFile(sources_path, "wb")
316 for spp in distroseries.test_sources[component]:321 for spp in distroseries.test_sources[component]:
317 stanza = spp.getIndexStanza().encode("utf-8") + "\n\n"322 stanza = spp.getIndexStanza().encode("utf-8") + "\n\n"
318 sources_index.write(stanza)323 sources_index.write(stanza)
319 sources_index.close()324 sources_index.close()
325 sources_index_updates = gzip.GzipFile(sources_path_updates,
326 "wb")
327 sources_index_updates.close()
320328
321 for arch in distroseries.architectures:329 for arch in distroseries.architectures:
322 packages_path = os.path.join(330 packages_path = os.path.join(
323 script.archiveroot, "dists", distroseries.name, component,331 script.archiveroot, "dists", distroseries.name, component,
324 "binary-%s" % arch.architecture_tag, "Packages.gz")332 "binary-%s" % arch.architecture_tag, "Packages.gz")
333 packages_path_updates = os.path.join(
334 script.archiveroot, "dists",
335 distroseries.name + "-updates", component,
336 "binary-%s" % arch.architecture_tag, "Packages.gz")
325 ensure_directory_exists(os.path.dirname(packages_path))337 ensure_directory_exists(os.path.dirname(packages_path))
338 ensure_directory_exists(os.path.dirname(packages_path_updates))
326 packages_index = gzip.GzipFile(packages_path, "wb")339 packages_index = gzip.GzipFile(packages_path, "wb")
327 for bpp in arch.test_binaries[component]:340 for bpp in arch.test_binaries[component]:
328 stanza = bpp.getIndexStanza().encode("utf-8") + "\n\n"341 stanza = bpp.getIndexStanza().encode("utf-8") + "\n\n"
329 packages_index.write(stanza)342 packages_index.write(stanza)
330 packages_index.close()343 packages_index.close()
344 packages_index_updates = gzip.GzipFile(packages_path_updates,
345 "wb")
346 packages_index_updates.close()
331347
332 def composeSeedPath(self, flavour, series_name, seed_name):348 def composeSeedPath(self, flavour, series_name, seed_name):
333 return os.path.join(349 return os.path.join(
@@ -405,24 +421,17 @@
405 self.setUpDistroAndScript()421 self.setUpDistroAndScript()
406 self.assertEqual(self.distro, self.script.distribution)422 self.assertEqual(self.distro, self.script.distribution)
407423
408 def test_prefers_development_distro_series(self):424 def test_uses_all_series(self):
409 # The script prefers a DEVELOPMENT series for the named425 # The script operates on DEVELOPMENT and CURRENT series.
410 # distribution over CURRENT and SUPPORTED series.
411 self.setUpDistroAndScript(426 self.setUpDistroAndScript(
412 ["Supported", "Current Stable Release", "Active Development"])427 ["Supported", "Current Stable Release", "Active Development"])
413 self.assertEqual([self.distroseries[2]], self.script.series)428 self.assertEqual(self.distroseries, self.script.series)
414429
415 def test_permits_frozen_distro_series(self):430 def test_permits_frozen_distro_series(self):
416 # If there is no DEVELOPMENT series, a FROZEN one will do.431 # FROZEN series are included
417 self.setUpDistroAndScript(432 self.setUpDistroAndScript(
418 ["Supported", "Current Stable Release", "Pre-release Freeze"])433 ["Supported", "Current Stable Release", "Pre-release Freeze"])
419 self.assertEqual([self.distroseries[2]], self.script.series)434 self.assertEqual(self.distroseries, self.script.series)
420
421 def test_requires_development_frozen_distro_series(self):
422 # If there is no DEVELOPMENT or FROZEN series, the script fails.
423 self.setUpDistroAndScript(
424 ["Supported", "Current Stable Release"], run_setup=False)
425 self.assertRaises(ScriptFailure, self.script.processOptions)
426435
427 def test_multiple_development_frozen_distro_series(self):436 def test_multiple_development_frozen_distro_series(self):
428 # If there are multiple DEVELOPMENT or FROZEN series, they are all437 # If there are multiple DEVELOPMENT or FROZEN series, they are all
@@ -457,6 +466,24 @@
457 self.distroseries[0].name, arch),466 self.distroseries[0].name, arch),
458 output)467 output)
459468
469 def test_stable_compose_output_path_in_miscroot(self):
470 # Output files are written to the correct locations under
471 # misc_root when running for a stable release.
472 flavour = factory.getUniqueString()
473 self.setUpDistroAndScript(
474 ["Current Stable Release"], extra_args=[flavour])
475 self.setUpComponent()
476 self.distroseries[0].makeDistroArchSeries()
477 self.makeIndexFiles(self.script, self.distroseries[0])
478 seed = factory.getUniqueString()
479 self.makeSeedStructure(flavour, self.distroseries[0].name, [seed])
480 self.makeSeed(flavour, self.distroseries[0].name, seed, [])
481
482 self.script.process(seed_bases=["file://%s" % self.seeddir])
483 self.assertTrue(os.path.exists(os.path.join(
484 self.script.options.misc_root,
485 "more-extra.override.%s-updates.main" % self.distroseries[0].name)))
486
460 def test_make_seed_structures_missing_seeds(self):487 def test_make_seed_structures_missing_seeds(self):
461 # makeSeedStructures ignores missing seeds.488 # makeSeedStructures ignores missing seeds.
462 self.setUpDistroAndScript()489 self.setUpDistroAndScript()
@@ -497,9 +524,12 @@
497 distroseries.name, flavours,524 distroseries.name, flavours,
498 seed_bases=["file://%s" % self.seeddir])525 seed_bases=["file://%s" % self.seeddir])
499526
527 series_is_stable = distroseries.status in ("Current Stable Release",
528 "Supported")
529
500 _, overrides, _ = script.germinateArch(530 _, overrides, _ = script.germinateArch(
501 distroseries.name, script.getComponents(distroseries), arch,531 distroseries.name, series_is_stable,
502 flavours, structures)532 script.getComponents(distroseries), arch, flavours, structures)
503 return overrides.splitlines()533 return overrides.splitlines()
504534
505 def test_germinate_output(self):535 def test_germinate_output(self):

Subscribers

People subscribed via source and target branches