Fix/deb kernel meta package series check#1
Conversation
Bumps [requests](https://github.com/psf/requests) from 2.32.4 to 2.33.0. - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](psf/requests@v2.32.4...v2.33.0) --- updated-dependencies: - dependency-name: requests dependency-version: 2.33.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
remove find_osrelease_repo_updates which duplicated find_host_repo_updates logic without host-repo filtering. the host_repos_only branch was the only caller differentiator — now handled in a single find_repo_updates.
rename to match codebase convention: get_deb_kernel_flavour, get_running_kernel_flavour, find_rpm_kernel_updates, find_deb_kernel_updates, find_arch_kernel_updates, deb_kernel_prefixes.
repo names are set at creation via get_or_create_repo and should not be overwritten by subsequent client reports. the admin may have renamed the repo in the web ui, and mixed client versions can report different name formats for the same mirror url, causing unique constraint errors.
prevent HWE kernels (e.g. 6.17) from being offered as updates to GA kernel hosts (e.g. 6.8) when both tracks ship in the same repository at the same priority. extract major.minor series from the deb kernel package name and only compare within the same series.
- add PackageUpdateTable with installed/available package links and security badges - add package_update_list view with security type and search filters - add /packages/updates/ url route - add packages submenu in navbar (packages + updates) - add 6 view tests
annotate package querysets with host_count, repo_count, affected_count, fixed_count to replace N+1 template calls. make repositories, hosts, affected, and fixed columns sortable on the package list view. convert package name detail from raw html table to django-tables2. add sortable hosts column to the package name list view.
Bumps [django](https://github.com/django/django) from 4.2.29 to 4.2.30. - [Commits](django/django@4.2.29...4.2.30) --- updated-dependencies: - dependency-name: django dependency-version: 4.2.30 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
- close stale db connections before each task via task_prerun signal (mirrors what django does for http requests) - add Restart=on-failure to worker and beat systemd services - add --loglevel info to worker service for diagnostics
- override get_new_connection to set journal_mode=wal automatically - eliminates need for manual pragma calls in post-install scripts
first assignment was meant to be verbose_name (singular).
five bulk action views passed raw POST filter_params into redirects without calling sanitize_filter_params(), unlike the rest of the codebase.
find() returns None when the element doesn't exist, causing AttributeError on the subsequent findall() call.
missing return after except meant code fell through to iterate an unassigned variable, causing UnboundLocalError.
- skip references with null urls in parse_osv_dev_cve_data - bail early from fixup_reference when urlparse has no hostname
tqdm.write(file=sys.stdout) replaces logger.info() for info messages so that patchman -lh, -lr etc. can be piped through grep and other standard unix tools. warnings and errors remain on stderr.
- optimize scan_for_security_updates with queryset update and __in filter - add _mark_updates_security helper with bulk update and IntegrityError fallback - optimize parse_osv_dev_data with Q batch filter for affected versions - bulk M2M add for add_fixed_packages/add_affected_packages - add get_matching_packages_q for batch version lookups - batch cve adds in parse_osv_dev_data
| if hostname == 'ubuntu.com' and url.path.startswith('/security/notices/USN'): | ||
| ref_type = 'USN' | ||
| if 'launchpad.net' in url.hostname: | ||
| if 'launchpad.net' in hostname: |
There was a problem hiding this comment.
Pull request overview
This PR improves update detection and UI around package updates, with a focus on preventing incorrect Debian kernel “cross-series” update suggestions (e.g., GA vs HWE), plus several hardening and operational tweaks across the app.
Changes:
- Refine host update detection (notably Debian kernel update selection) to avoid cross-series kernel updates; add/adjust tests for the new behavior.
- Add a “Package Updates” listing UI (new view/table/template), link it into the navbar, and add count annotations to avoid expensive per-row counting.
- Harden parsing and operations: sanitize bulk-action
filter_params, handle missing/invalid reference data, ensure early returns on YAML/XML edge cases, and improve Celery/SQLite/systemd runtime behavior.
Reviewed changes
Copilot reviewed 28 out of 29 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| util/templates/navbar.html | Convert “Packages” nav item into a submenu with an “Updates” entry. |
| security/utils.py | Avoid crashes when parsing references with URLs lacking a hostname; reuse parsed hostname. |
| security/models.py | Skip OSV references missing a URL (but still needs a guard for missing type). |
| requirements.txt | Bump Django and requests versions. |
| repos/views.py | Sanitize filter_params in bulk actions to prevent query-string injection. |
| repos/repo_types/yum.py | Return early on YAML parse errors to prevent downstream failures. |
| reports/views.py | Sanitize filter_params in report bulk actions. |
| reports/utils.py | Stop overwriting repo names during report processing; add coverage elsewhere. |
| reports/tests/test_utils.py | Add regression test ensuring repo names aren’t overwritten by client reports. |
| reports/models.py | Fix Django admin naming (verbose_name/verbose_name_plural). |
| patchman/sqlite3/base.py | Enable WAL mode per connection (SQLite) to reduce “database is locked” issues. |
| patchman/receivers.py | Switch info output to tqdm.write (but this drops logging capture). |
| patchman/celery.py | Close stale DB connections before each Celery task via task_prerun. |
| packages/views.py | Add package update list view; annotate host/repo/errata counts for tables; update package-name detail to use django-tables2. |
| packages/utils.py | Add get_matching_packages_q for batch Q-based version matching. |
| packages/urls.py | Add route for the new package updates list. |
| packages/tests/test_views.py | Add view tests for the new package updates list + filtering/search/login requirement. |
| packages/templates/packages/package_update_list.html | New template page for the package updates listing (extends shared object list template). |
| packages/templates/packages/package_name_detail.html | Render versions via django-tables2 instead of a manually-built table. |
| packages/tables.py | Add/update tables (incl. PackageUpdateTable) and switch to annotated counts for ordering/performance. |
| operatingsystems/views.py | Sanitize filter_params in OS bulk actions. |
| hosts/views.py | Add host list filter by update id (update_id). |
| hosts/tests/test_models.py | Add/adjust tests for Debian kernel series filtering and helper renames. |
| hosts/tables.py | Link security/bugfix update counts to filtered package-update list. |
| hosts/models.py | Refactor update-id collection to sets; add Debian kernel series parsing and filter repo candidates by series. |
| etc/systemd/system/patchman-celery-worker@.service | Add restart policy and set explicit log level. |
| etc/systemd/system/patchman-celery-beat.service | Add restart policy. |
| errata/sources/repos/yum.py | Handle missing <references> nodes safely. |
| errata/models.py | Batch-mark updates as security; speed up OSV affected package matching via Q-based queries; bulk-add M2M entries. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ref_type = reference.get('type').capitalize() | ||
| get_or_create_reference(ref_type, url) |
There was a problem hiding this comment.
reference.get('type') can be missing/None from OSV responses; calling .capitalize() will raise an AttributeError. Please guard for a missing type (e.g., default to 'Link' or skip the reference similarly to the missing-url case).
| ref_type = reference.get('type').capitalize() | |
| get_or_create_reference(ref_type, url) | |
| ref_type = reference.get('type') or 'Link' | |
| get_or_create_reference(ref_type.capitalize(), url) |
| text = str(kwargs.get('text')) | ||
| if not get_quiet_mode(): | ||
| with logging_redirect_tqdm(loggers=[logger]): | ||
| for line in text.splitlines(): | ||
| logger.info(Style.RESET_ALL + Fore.RESET + line) | ||
| tqdm.write(text, file=sys.stdout) |
There was a problem hiding this comment.
print_info_message now writes directly to stdout via tqdm.write instead of going through the configured logger. This means info messages won’t be captured in log files/handlers and formatting will differ from warning/error/debug. Consider keeping logger.info(...) (optionally within logging_redirect_tqdm) and only using tqdm.write for progress-bar-safe console output.
No description provided.