Conversation
New features include flatpak backing up and restoring. Output file includes APT packages and Flatpaks.
|
Hi @SethyM12, I noticed we are addressing the same issue. I have proposed a fix in PR #100, but since I do not currently have a machine running Linux Mint to perform a full live test, could you please verify if my approach works on your system? Your feedback would be very helpful to ensure this gets resolved correctly. |
|
Hello @hthienloc, I downloaded the source project from the issue you linked and ran the code. Unfortunately, trying to back up the installed apps causes the backup tool to crash. As of now, I am not able to diagnose the issue. |
There was a problem hiding this comment.
Pull request overview
Adds Flatpak backup/restore capability to MintBackup’s software selection flow, aiming to include Flatpaks alongside APT packages.
Changes:
- Adds Flatpak discovery during software backup and writes Flatpak entries into the generated
.listfile. - Introduces a new
FlatpakHandlerclass to backup Flatpak apps/remotes toflatpaks.jsonand restore them later. - Includes various formatting-only cleanups in
mintbackup.py.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
usr/lib/linuxmint/mintbackup/mintbackup.py |
Adds Flatpak listing into the package selection UI/save file and triggers Flatpak restore after APT installs. |
usr/lib/linuxmint/mintbackup/flatpak_handler.py |
New helper to backup Flatpak remotes/apps to JSON and restore via flatpak remote-add / flatpak install. |
usr/lib/linuxmint/mintbackup/__pycache__/flatpak_handler.cpython-312.pyc |
Adds a compiled Python bytecode artifact to the repo (should not be committed). |
Comments suppressed due to low confidence (1)
usr/lib/linuxmint/mintbackup/mintbackup.py:12
jsonis imported but never used in this file. Please remove the unused import (or use it) to avoid dead code and keep imports minimal.
import subprocess
import json
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if app["installation"] == "user": | ||
| cmd.insert(2, "--user") |
There was a problem hiding this comment.
restore() only treats installation == "user" specially; system installs or named installations (as returned by Flatpak’s installation column) aren’t handled. This can cause restores to target the wrong installation or fail under a non-root run. Consider using --installation=... / --system appropriately based on the stored installation value.
| if app["installation"] == "user": | |
| cmd.insert(2, "--user") | |
| installation = app.get("installation") | |
| if installation == "user": | |
| cmd.insert(2, "--user") | |
| elif installation == "system": | |
| cmd.insert(2, "--system") | |
| elif installation: | |
| # Named installation (as returned by flatpak list --columns=...,installation) | |
| cmd.insert(2, installation) | |
| cmd.insert(2, "--installation") |
| # Backup Flatpaks in same directory | ||
| flatpak_handler = FlatpakHandler(BACKUP_DIR) | ||
| flatpak_handler.backup() | ||
|
|
There was a problem hiding this comment.
Flatpak state is being backed up to a separate flatpaks.json in BACKUP_DIR, but restore is driven by a user-selected .list file (self.package_source). If the .list file is moved to another machine or location, Flatpak restore will fail or restore the wrong selection because it still reads BACKUP_DIR/flatpaks.json. Consider storing Flatpak metadata alongside the selected list file (same directory / same basename) and restoring relative to self.package_source instead of BACKUP_DIR.
| apt_packages = [] | ||
| flatpak_packages = [] |
There was a problem hiding this comment.
flatpak_packages is collected during restore but never used, which makes the Flatpak selection logic dead code. Either remove it, or use it to drive Flatpak installation so the user’s selections in the list actually affect what gets restored.
| client = aptkit.simpleclient.SimpleAPTClient(self.main_window) | ||
| client.set_cancelled_callback(self.on_apt_install_finished) | ||
| client.set_finished_callback(self.on_apt_install_finished) | ||
| client.install_packages(packages) | ||
| client.install_packages(apt_packages) |
There was a problem hiding this comment.
If the selection contains only Flatpaks, apt_packages can be empty and client.install_packages(apt_packages) may not execute any transaction/callback, which can prevent Flatpaks from being restored. Handle the empty-APT case explicitly (e.g., run Flatpak restore directly when apt_packages is empty).
| "flatpak", "install", "-y", | ||
| app["origin"], | ||
| f"{app['app_id']}//{app['branch']}" | ||
| ] | ||
|
|
||
| if app["installation"] == "user": | ||
| cmd.insert(2, "--user") | ||
|
|
There was a problem hiding this comment.
backup() records an arch field for each app, but the restore install command doesn’t use it. Either pass the arch through on install (e.g., --arch=...) or stop storing arch to avoid misleading backup data and potential restore mismatches on non-default architectures.
| "flatpak", "install", "-y", | |
| app["origin"], | |
| f"{app['app_id']}//{app['branch']}" | |
| ] | |
| if app["installation"] == "user": | |
| cmd.insert(2, "--user") | |
| "flatpak", "install", "-y" | |
| ] | |
| # Use the same installation scope as in the backup | |
| if app.get("installation") == "user": | |
| cmd.append("--user") | |
| # If an architecture was recorded, pass it through to flatpak | |
| arch = app.get("arch") | |
| if arch: | |
| cmd.append(f"--arch={arch}") | |
| cmd.extend([ | |
| app["origin"], | |
| f"{app['app_id']}//{app['branch']}" | |
| ]) |
| if name.startswith("flatpak:"): | ||
| flatpak_ref = name.replace("flatpak:", "") | ||
| status = "%s\n<small>Flatpak application</small>" % flatpak_ref | ||
| model.append([True, status, True, flatpak_ref]) |
There was a problem hiding this comment.
Flatpak lines from the .list file are detected via name.startswith("flatpak:"), but you then store flatpak_ref (with the prefix removed) in column 3. Later installation code checks row[3].startswith("flatpak:"), so Flatpaks loaded here will never be recognized for installation. Keep a consistent identifier format between load and install (either keep the prefix in column 3 or adjust the install check).
| model.append([True, status, True, flatpak_ref]) | |
| model.append([True, status, True, name]) |
| def on_apt_install_finished(self, transaction, exit_state): | ||
| # Restore flatpaks after apt finishes | ||
| flatpak_handler = FlatpakHandler(BACKUP_DIR) | ||
| flatpak_handler.restore() | ||
|
|
There was a problem hiding this comment.
on_apt_install_finished() restores Flatpaks unconditionally even when the APT transaction is cancelled or fails (this callback is registered for both cancelled and finished). Please gate Flatpak restore on a successful exit_state (and/or only run it from the finished callback) to avoid applying Flatpak changes after a failed APT operation.
A class was added that gives the ability to add and restore flatpaks.
Flatpaks installed on the system are added to the same list file as APT packages.
Then, that list file can be restored.