[Merge] lp:~marcustomlinson/update-manager/update-manager into lp:update-manager
Marcus Tomlinson
marcus.tomlinson at canonical.com
Thu Apr 2 11:54:10 UTC 2020
Alright, changes made:
- I've split the large update_snaps() function into smaller parts.
- Snap updates now occur _after_ the user has opted in to the updates.
- snapd-glib for (un)installs means just one polkit prompt now for the all snap updates.
- debs with a snap replacement that were not installed manually get marked for deletion.
- The thread is still there, sorry, though I'm not sure why it's a bad idea really.
Diff comments:
> === modified file 'UpdateManager/backend/__init__.py'
> --- UpdateManager/backend/__init__.py 2019-04-08 17:00:30 +0000
> +++ UpdateManager/backend/__init__.py 2020-03-02 11:23:45 +0000
> @@ -67,6 +74,154 @@
> """Commit the cache changes """
> raise NotImplementedError
>
> + def update_snaps(self):
> + # update status and progress bar
> + def update_status(status):
> + GLib.idle_add(self.label_details.set_label, status)
> +
> + def update_progress(progress_bar):
> + progress_bar.pulse()
> + return True
> +
> + update_status(_("Updating snaps"))
> +
> + progress_timer = None
> + progress_bars = self.progressbar_slot.get_children()
> + if progress_bars and isinstance(progress_bars[0], Gtk.ProgressBar):
> + progress_timer = GLib.timeout_add(100, update_progress, progress_bars[0])
> +
> + # update and grab the latest cache
> + try:
> + if self.window_main.cache is None:
> + self.window_main.cache = MyCache(None)
> + else:
> + self.window_main.cache.open(None)
> + self.window_main.cache._initDepCache()
> + cache = self.window_main.cache
> + except:
> + cache = None
> +
> + # populate snap_list with deb2snap transitions
> + snap_list = {}
> + seeded_snaps = {}
> + unseeded_snaps = {}
> +
> + release = subprocess.Popen(["lsb_release", "-r", "-s"],
> + universal_newlines=True,
> + stdout=subprocess.PIPE).communicate()
> + release = release[0].split()[0]
> + curr_channel = "stable/ubuntu-" + release
> +
> + try:
> + d2s_file = open('/usr/share/ubuntu-release-upgrader/deb2snap.json', 'r')
> + d2s = json.load(d2s_file)
> + d2s_file.close()
> +
> + for snap in d2s["seeded"]:
> + seed = d2s["seeded"][snap]
> + deb = seed.get("deb", None)
> + to_channel = seed.get("to_channel", curr_channel)
> + seeded_snaps[snap] = (deb, to_channel)
> +
> + for snap in d2s["unseeded"]:
> + unseed = d2s["unseeded"][snap]
> + from_channel = unseed.get("from_channel", curr_channel)
> + unseeded_snaps[snap] = (from_channel)
> + except Exception as e:
> + logging.debug("error reading deb2snap.json file (%s)" % e)
> +
> + for snap, (deb, to_channel) in seeded_snaps.items():
> + snap_object = {}
> + # check if the snap is already installed
> + snap_info = subprocess.Popen(["snap", "info", snap],
Apologies, a major advantage to using snapd-glib at least for the (un)installs is that you only get one polk it prompt for all updates. I've updated this logic.
> + universal_newlines=True,
> + stdout=subprocess.PIPE).communicate()
> + if re.search("^installed: ", snap_info[0], re.MULTILINE):
> + logging.debug("Snap %s is installed" % snap)
> + continue
> + elif deb and cache:
> + # Do not replace packages not marked for deletion
> + if (deb not in cache or not cache[deb].marked_delete):
> + logging.debug("Deb package %s is not marked for deletion. "
> + "Skipping %s installation" % (deb, snap))
> + continue
> +
> + snap_object['command'] = 'install'
> + snap_object['channel'] = to_channel
> + snap_list[snap] = snap_object
> + else:
> + logging.debug("Could not determine which deb %s replaces" % snap)
> + continue
> + for snap, (from_channel) in unseeded_snaps.items():
> + snap_object = {}
> + # check if the snap is already installed
> + snap_info = subprocess.Popen(["snap", "info", snap],
> + universal_newlines=True,
> + stdout=subprocess.PIPE).communicate()
> + if re.search("^installed: ", snap_info[0], re.MULTILINE):
> + logging.debug("Snap %s is installed" % snap)
> + # its not tracking the release channel so don't remove
> + if not re.search(r"^tracking:.*%s" % from_channel,
> + snap_info[0], re.MULTILINE):
> + logging.debug("Snap %s is not tracking the release channel"
> + % snap)
> + continue
> +
> + snap_object['command'] = 'remove'
> +
> + # check if this snap is being used by any other snaps
> + conns = subprocess.Popen(["snap", "connections", snap],
> + universal_newlines=True,
> + stdout=subprocess.PIPE).communicate()
> +
> + for conn in conns[0].split('\n'):
> + conn_cols = conn.split()
> + if len(conn_cols) != 4:
> + continue
> + plug = conn_cols[1]
> + slot = conn_cols[2]
> +
> + if slot.startswith(snap + ':'):
> + plug_snap = plug.split(':')[0]
> + if plug_snap != '-' and \
> + plug_snap not in unseeded_snaps:
> + logging.debug("Snap %s is being used by %s. "
> + "Switching it to stable track"
> + % (snap, plug_snap))
> + snap_object['command'] = 'refresh'
> + snap_object['channel'] = 'stable'
> + break
> +
> + snap_list[snap] = snap_object
> +
> + # (un)install (un)seeded snap(s)
> + for snap, snap_object in snap_list.items():
> + command = snap_object['command']
> + if command == 'refresh':
> + update_status(_("Refreshing %s snap" % snap))
> + popenargs = ["snap", command,
> + "--channel", snap_object['channel'], snap]
> + elif command == 'remove':
> + update_status(_("Removing %s snap" % snap))
> + popenargs = ["snap", command, snap]
> + else:
> + update_status(_("Installing %s snap" % snap))
> + popenargs = ["snap", command,
> + "--channel", snap_object['channel'], snap]
> + try:
> + proc = subprocess.run(popenargs,
> + stdout=subprocess.PIPE,
> + check=True)
> + except subprocess.CalledProcessError:
> + logging.debug("%s of snap %s failed" % (command, snap))
> + continue
> + if proc.returncode == 0:
> + logging.debug("%s of snap %s succeeded" % (command, snap))
> +
> + # continue with the rest of the updates
> + if progress_timer: GLib.source_remove(progress_timer)
> + GLib.idle_add(self.window_main.start_available)
> +
> def _action_done(self, action, authorized, success, error_string,
> error_desc, trans_failed=False):
>
--
https://code.launchpad.net/~marcustomlinson/update-manager/update-manager/+merge/380060
Your team Ubuntu Core Development Team is requested to review the proposed merge of lp:~marcustomlinson/update-manager/update-manager into lp:update-manager.
More information about the Ubuntu-reviews
mailing list