Merge lp:~sil2100/ubuntu-archive-tools/migration-assistant-minor-clean into lp:ubuntu-archive-tools

Proposed by Łukasz Zemczak
Status: Merged
Merged at revision: 1163
Proposed branch: lp:~sil2100/ubuntu-archive-tools/migration-assistant-minor-clean
Merge into: lp:ubuntu-archive-tools
Diff against target: 371 lines (+104/-100)
1 file modified
migration-assistant.py (+104/-100)
To merge this branch: bzr merge lp:~sil2100/ubuntu-archive-tools/migration-assistant-minor-clean
Reviewer Review Type Date Requested Status
Łukasz Zemczak Approve
Review via email: mp+341119@code.launchpad.net

Commit message

Refactor the migration-assistant script slightly, with indent changes and removing some of the global variables that should have been local.

Description of the change

Refactor the migration-assistant script slightly, with indent changes and removing some of the global variables that should have been local.

To post a comment you must log in.
1172. By Łukasz Zemczak

Fix some brokenness caused by the cleanup.

Revision history for this message
Łukasz Zemczak (sil2100) wrote :

+1 by Matt.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'migration-assistant.py'
--- migration-assistant.py 2018-03-08 10:28:01 +0000
+++ migration-assistant.py 2018-03-08 11:12:37 +0000
@@ -38,23 +38,13 @@
38import logging38import logging
3939
40from enum import Enum40from enum import Enum
41
42from urllib.request import FancyURLopener41from urllib.request import FancyURLopener
43
44from launchpadlib.launchpad import Launchpad42from launchpadlib.launchpad import Launchpad
4543
46DEBIAN_CURRENT_SERIES = 'sid'44DEBIAN_CURRENT_SERIES = 'sid'
47ARCHIVE_PAGES = 'https://people.canonical.com/~ubuntu-archive/'45ARCHIVE_PAGES = 'https://people.canonical.com/~ubuntu-archive/'
48MAX_CACHE_AGE = 14400 # excuses cache should not be older than 4 hours46MAX_CACHE_AGE = 14400 # excuses cache should not be older than 4 hours
4947
50lp_cachedir = os.path.expanduser(os.path.join("~", ".launchpadlib/cache"))
51lp = Launchpad.login_anonymously(
52 'what-next', 'production', lp_cachedir, version='devel')
53
54ubuntu = lp.distributions["ubuntu"]
55archive = ubuntu.main_archive
56series = ubuntu.current_series
57
58excuses = {}48excuses = {}
5949
60level = 050level = 0
@@ -137,7 +127,7 @@
137 return None127 return None
138128
139129
140def find_excuses(src, level, seen):130def find_excuses(lp, src, level, seen):
141 if src in seen:131 if src in seen:
142 return132 return
143133
@@ -145,7 +135,7 @@
145 item_name = item.get('item-name')135 item_name = item.get('item-name')
146136
147 if item_name == src:137 if item_name == src:
148 process(item, level, seen)138 process(lp, item, level, seen)
149139
150140
151def get_pkg_archive_path(package):141def get_pkg_archive_path(package):
@@ -181,12 +171,12 @@
181 return None171 return None
182172
183173
184def package_in_distro(package, distro='ubuntu', proposed=False):174def package_in_distro(package, distro='ubuntu', distroseries='bionic',
175 proposed=False):
185 assistant = StatusAdapter(assistant_logger, {'depth': 0})176 assistant = StatusAdapter(assistant_logger, {'depth': 0})
186177
187 # TODO: This operation is pretty costly, do caching?178 # TODO: This operation is pretty costly, do caching?
188179
189 distroseries = series.name
190 if distro == 'debian':180 if distro == 'debian':
191 distroseries = DEBIAN_CURRENT_SERIES181 distroseries = DEBIAN_CURRENT_SERIES
192 if proposed:182 if proposed:
@@ -204,7 +194,7 @@
204 if " {} ".format(package) not in line:194 if " {} ".format(package) not in line:
205 continue195 continue
206 package_line = line.split(' | ')196 package_line = line.split(' | ')
207 197
208 series_component = package_line[2].split('/')198 series_component = package_line[2].split('/')
209 component = 'main'199 component = 'main'
210 if len(series_component) > 1:200 if len(series_component) > 1:
@@ -226,7 +216,7 @@
226 return {}216 return {}
227217
228218
229def process_lp_build_results(source, level, uploads, failed):219def process_lp_build_results(source, archive, series, level, uploads, failed):
230 assistant = StatusAdapter(assistant_logger, {'depth': level + 1})220 assistant = StatusAdapter(assistant_logger, {'depth': level + 1})
231221
232 source_name = source.get('source')222 source_name = source.get('source')
@@ -270,11 +260,12 @@
270 }260 }
271261
272262
273def process_unsatisfiable_depends(source, level, seen):263def process_unsatisfiable_depends(source, series, level, seen):
274 assistant = StatusAdapter(assistant_logger, {'depth': level + 1})264 assistant = StatusAdapter(assistant_logger, {'depth': level + 1})
275265
276 affected_sources = {}266 affected_sources = {}
277 unsatisfiable = {}267 unsatisfiable = {}
268 distroseries = series.name
278269
279 depends = source.get('dependencies').get('unsatisfiable-dependencies')270 depends = source.get('dependencies').get('unsatisfiable-dependencies')
280 for arch, signatures in depends.items():271 for arch, signatures in depends.items():
@@ -287,12 +278,15 @@
287 pkg = get_source_package(binary_name)278 pkg = get_source_package(binary_name)
288 affected_sources[arch].add(pkg)279 affected_sources[arch].add(pkg)
289 except Exception:280 except Exception:
290 # FIXME: we might be dealing with a new package in proposed here,281 # FIXME: we might be dealing with a new package in proposed
291 # but using the binary name instead of the source name.282 # here, but using the binary name instead of the source
292 if any(package_in_distro(binary_name, distro='ubuntu')):283 # name.
284 if any(package_in_distro(binary_name, distro='ubuntu',
285 distroseries=distroseries)):
293 affected_sources[arch].add(binary_name)286 affected_sources[arch].add(binary_name)
294 elif any(package_in_distro(binary_name,287 elif any(package_in_distro(binary_name,
295 distro='ubuntu',288 distro='ubuntu',
289 distroseries=distroseries,
296 proposed=True)):290 proposed=True)):
297 affected_sources[arch].append(binary_name)291 affected_sources[arch].append(binary_name)
298292
@@ -328,8 +322,10 @@
328 depends = signature.split(' ')[0]322 depends = signature.split(' ')[0]
329 assistant.error("{} can not be satisfied".format(signature),323 assistant.error("{} can not be satisfied".format(signature),
330 status=ExcuseValue.FAIL)324 status=ExcuseValue.FAIL)
331 in_archive = package_in_distro(depends, distro='ubuntu')325 in_archive = package_in_distro(depends, distro='ubuntu',
326 distroseries=distroseries)
332 in_proposed = package_in_distro(depends, distro='ubuntu',327 in_proposed = package_in_distro(depends, distro='ubuntu',
328 distroseries=distroseries,
333 proposed=True)329 proposed=True)
334330
335 if any(in_archive) and not any(in_proposed):331 if any(in_archive) and not any(in_proposed):
@@ -350,7 +346,8 @@
350 "but not in Debian?",346 "but not in Debian?",
351 status=ExcuseValue.INFO)347 status=ExcuseValue.INFO)
352 elif not any(in_archive) and not any(in_proposed):348 elif not any(in_archive) and not any(in_proposed):
353 in_debian = package_in_distro(depends, distro='debian')349 in_debian = package_in_distro(depends, distro='debian',
350 distroseries=distroseries)
354 if any(in_debian):351 if any(in_debian):
355 assistant.warning("{} only exists in Debian".format(depends),352 assistant.warning("{} only exists in Debian".format(depends),
356 status=ExcuseValue.FAIL)353 status=ExcuseValue.FAIL)
@@ -426,7 +423,7 @@
426 status=ExcuseValue.INFO)423 status=ExcuseValue.INFO)
427424
428425
429def process_blocking(source, level):426def process_blocking(source, lp, level):
430 assistant = StatusAdapter(assistant_logger, {'depth': level + 1})427 assistant = StatusAdapter(assistant_logger, {'depth': level + 1})
431428
432 bugs = source.get('policy_info').get('block-bugs')429 bugs = source.get('policy_info').get('block-bugs')
@@ -506,7 +503,7 @@
506 find_excuses(blocker, level+2, seen)503 find_excuses(blocker, level+2, seen)
507504
508505
509def process_missing_builds(source, level):506def process_missing_builds(source, archive, series, level):
510 assistant = StatusAdapter(assistant_logger, {'depth': level + 1})507 assistant = StatusAdapter(assistant_logger, {'depth': level + 1})
511508
512 source_name = source.get('source')509 source_name = source.get('source')
@@ -569,7 +566,7 @@
569 anais = []566 anais = []
570 new_binaries = set()567 new_binaries = set()
571568
572 process_lp_build_results(source, level, uploads, failed)569 process_lp_build_results(source, archive, series, level, uploads, failed)
573570
574 if new_version in uploads:571 if new_version in uploads:
575 for arch, item in uploads[new_version].items():572 for arch, item in uploads[new_version].items():
@@ -578,7 +575,7 @@
578 new_binaries.add(binary_name)575 new_binaries.add(binary_name)
579 if binary.get('is_new'):576 if binary.get('is_new'):
580 new.append(binary)577 new.append(binary)
581 578
582 if not any(failed):579 if not any(failed):
583 assistant.error("No failed builds found", status=ExcuseValue.PASS)580 assistant.error("No failed builds found", status=ExcuseValue.PASS)
584581
@@ -598,9 +595,9 @@
598 "Admin to run:",595 "Admin to run:",
599 status=ExcuseValue.INFO)596 status=ExcuseValue.INFO)
600 assistant.info("remove-package %(arches)s -b %(bins)s"597 assistant.info("remove-package %(arches)s -b %(bins)s"
601 % ({ 'arches': " ".join(arch_o),598 % ({'arches': " ".join(arch_o),
602 'bins': " ".join(old_binaries),599 'bins': " ".join(old_binaries),
603 }), status=ExcuseValue.NONE)600 }), status=ExcuseValue.NONE)
604 except AttributeError:601 except AttributeError:
605 # Ignore a failure here, it just means we don't have602 # Ignore a failure here, it just means we don't have
606 # missing-builds to process after all.603 # missing-builds to process after all.
@@ -608,7 +605,7 @@
608605
609 if any(new):606 if any(new):
610 assistant.error("This package has NEW binaries to process:",607 assistant.error("This package has NEW binaries to process:",
611 status=ExcuseValue.INFO)608 status=ExcuseValue.INFO)
612 for binary in new:609 for binary in new:
613 assistant.warning("[{}] {}/{}".format(610 assistant.warning("[{}] {}/{}".format(
614 binary.get('architecture'),611 binary.get('architecture'),
@@ -617,11 +614,13 @@
617 status=ExcuseValue.FAIL)614 status=ExcuseValue.FAIL)
618615
619616
620617def process(lp, source, level, seen):
621
622def process(source, level, seen):
623 assistant = StatusAdapter(assistant_logger, {'depth': level})618 assistant = StatusAdapter(assistant_logger, {'depth': level})
624619
620 ubuntu = lp.distributions["ubuntu"]
621 archive = ubuntu.main_archive
622 series = ubuntu.current_series
623
625 source_name = source.get('source')624 source_name = source.get('source')
626 reasons = source.get('reason')625 reasons = source.get('reason')
627626
@@ -644,15 +643,15 @@
644 missing_builds = source.get('missing-builds')643 missing_builds = source.get('missing-builds')
645 if missing_builds is not None or 'no-binaries' in reasons:644 if missing_builds is not None or 'no-binaries' in reasons:
646 work_needed = True645 work_needed = True
647 process_missing_builds(source, level)646 process_missing_builds(source, archive, series, level)
648647
649 if 'depends' in reasons:648 if 'depends' in reasons:
650 work_needed = True649 work_needed = True
651 process_unsatisfiable_depends(source, level, seen)650 process_unsatisfiable_depends(source, series, level, seen)
652651
653 if 'block' in reasons:652 if 'block' in reasons:
654 work_needed = True653 work_needed = True
655 process_blocking(source, level)654 process_blocking(source, lp, level)
656655
657 if 'autopkgtest' in reasons:656 if 'autopkgtest' in reasons:
658 work_needed = True657 work_needed = True
@@ -691,7 +690,7 @@
691 src_num += 1690 src_num += 1
692691
693 while True:692 while True:
694 print (options)693 print(options)
695 print("\n".join(wrapper.wrap(msg)))694 print("\n".join(wrapper.wrap(msg)))
696 num = input("\nWhich package do you want to look at?")695 num = input("\nWhich package do you want to look at?")
697696
@@ -705,66 +704,71 @@
705 return num704 return num
706705
707 return options[choice]706 return options[choice]
708 707
709 708
710709if __name__ == '__main__':
711parser = argparse.ArgumentParser(710
712 description='Evaluate next steps for proposed migration')711 parser = argparse.ArgumentParser(
713parser.add_argument('-s', '--source', dest='source',712 description='Evaluate next steps for proposed migration')
714 help='the package to evaluate')713 parser.add_argument('-s', '--source', dest='source',
715parser.add_argument('--no-cache', dest='do_not_cache', action='store_const',714 help='the package to evaluate')
716 const=True, default=False,715 parser.add_argument('--no-cache', dest='do_not_cache', action='store_const',
717 help='Do not cache excuses')716 const=True, default=False,
718parser.add_argument('--refresh', action='store_const',717 help='Do not cache excuses')
719 const=True, default=False,718 parser.add_argument('--refresh', action='store_const',
720 help='Force refresh of cached excuses')719 const=True, default=False,
721parser.add_argument('--debug', action='store_const',720 help='Force refresh of cached excuses')
722 const=True, default=False,721 parser.add_argument('--debug', action='store_const',
723 help='Show debugging information for this tool.')722 const=True, default=False,
724723 help='Show debugging information for this tool.')
725args = parser.parse_args()724
726725 args = parser.parse_args()
727if args.debug:726
728 logging.basicConfig(level=logging.DEBUG, format="%(message)s")727 if args.debug:
729else:728 logging.basicConfig(level=logging.DEBUG, format="%(message)s")
730 logging.basicConfig(level=logging.INFO, format="%(message)s")729 else:
731730 logging.basicConfig(level=logging.INFO, format="%(message)s")
732refresh_due = False731
733xdg_cache = os.getenv('XDG_CACHE_HOME', '~/.cache')732 lp_cachedir = os.path.expanduser(os.path.join("~", ".launchpadlib/cache"))
734excuses_path = os.path.expanduser(os.path.join(xdg_cache, 'excuses.yaml'))733 lp = Launchpad.login_anonymously(
735if args.do_not_cache:734 'what-next', 'production', lp_cachedir, version='devel')
736 fp = tempfile.NamedTemporaryFile()735
737else:736 refresh_due = False
738 try:737 xdg_cache = os.getenv('XDG_CACHE_HOME', '~/.cache')
739 fp = open(excuses_path, 'r')738 excuses_path = os.path.expanduser(os.path.join(xdg_cache, 'excuses.yaml'))
740 except FileNotFoundError:739 if args.do_not_cache:
741 refresh_due = True740 fp = tempfile.NamedTemporaryFile()
742 pass741 else:
743 finally:742 try:
744 fp = open(excuses_path, 'a+')743 fp = open(excuses_path, 'r')
745744 except FileNotFoundError:
746 file_state = os.stat(excuses_path)745 refresh_due = True
747 mtime = file_state.st_mtime746 pass
748 now = time.time()747 finally:
749 if (now - mtime) > MAX_CACHE_AGE:748 fp = open(excuses_path, 'a+')
750 refresh_due = True749
751750 file_state = os.stat(excuses_path)
752with fp:751 mtime = file_state.st_mtime
753 if args.refresh or refresh_due:752 now = time.time()
754 url_opener = FancyURLopener()753 if (now - mtime) > MAX_CACHE_AGE:
755 excuses_url = ARCHIVE_PAGES + 'proposed-migration/update_excuses.yaml'754 refresh_due = True
756 excuses_data = url_opener.retrieve(excuses_url,755
757 fp.name,756 with fp:
758 report_download)757 if args.refresh or refresh_due:
759 fp.seek(0)758 url_opener = FancyURLopener()
760759 excuses_url = ARCHIVE_PAGES + 'proposed-migration/update_excuses.yaml'
761 # Use the C implementation of the SafeLoader, it's noticeably faster, and760 excuses_data = url_opener.retrieve(excuses_url,
762 # here we're dealing with large input files.761 fp.name,
763 excuses = yaml.load(fp, Loader=yaml.CSafeLoader)762 report_download)
764763 fp.seek(0)
765 if args.source is None:764
766 print("No source package name was provided. The following packages are "765 # Use the C implementation of the SafeLoader, it's noticeably faster, and
767 "blocked in proposed:\n")766 # here we're dealing with large input files.
768 args.source = choose_blocked_source(excuses)767 excuses = yaml.load(fp, Loader=yaml.CSafeLoader)
769768
770 find_excuses(args.source, 0, seen)769 if args.source is None:
770 print("No source package name was provided. The following packages are "
771 "blocked in proposed:\n")
772 args.source = choose_blocked_source(excuses)
773
774 find_excuses(lp, args.source, 0, seen)

Subscribers

People subscribed via source and target branches