From 63ebac5114a55d80e2e55453b6cf5b4ae2758501 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 06:45:30 +0100 Subject: [PATCH 01/17] Add helper script and policy file --- data/io.elementary.settings-daemon.policy.in | 20 ++++++ ...tary.settings-daemon.system-upgrade.helper | 61 +++++++++++++++++++ data/meson.build | 24 ++++++++ .../etc/apt/sources.list.d/elementary.list | 2 + .../jammy/etc/apt/sources.list.d/patches.list | 2 + meson.build | 7 +++ po/POTFILES | 1 + 7 files changed, 117 insertions(+) create mode 100644 data/io.elementary.settings-daemon.policy.in create mode 100644 data/io.elementary.settings-daemon.system-upgrade.helper create mode 100644 data/system-upgrades/jammy/etc/apt/sources.list.d/elementary.list create mode 100644 data/system-upgrades/jammy/etc/apt/sources.list.d/patches.list diff --git a/data/io.elementary.settings-daemon.policy.in b/data/io.elementary.settings-daemon.policy.in new file mode 100644 index 00000000..5f78c8a8 --- /dev/null +++ b/data/io.elementary.settings-daemon.policy.in @@ -0,0 +1,20 @@ + + + + elementary + https://elementary.io/ + + + Authentication is required to upgrade elementary OS + system-os-installer + + no + no + auth_admin_keep + + @PKGDATADIR@/io.elementary.settings-daemon.system-upgrade.helper + + + diff --git a/data/io.elementary.settings-daemon.system-upgrade.helper b/data/io.elementary.settings-daemon.system-upgrade.helper new file mode 100644 index 00000000..7672065a --- /dev/null +++ b/data/io.elementary.settings-daemon.system-upgrade.helper @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +import argparse +import os +import re +import shutil + + +def update_third_party_repository(current, next, repository_file): + r = re.compile("[deb|deb-src].* ({}).*$".format(current)) + + if os.path.isfile(repository_file): + should_delete = False + should_update = False + with repository_file.open("r") as f: + content = [] + for line in f.read().split("\n"): + if r.match(line): + should_update = True + line = line.replace(current, next) + content.append(line) + + if "ppa.launchpad.net/elementary-os" in line: + should_delete = True + elif "packages.elementary.io" in line: + should_delete = True + + if should_delete: + repository_file.unlink() + + if should_update: + with repository_file.open("w") as f: + f.write("\n".join(content)) + + +def install_files(next): + update_files = os.path.join( + "/", "usr", "share", "io.elementary.settings-daemon", "system-upgrades", next) + shutil.copytree(update_files, "/", dirs_exist_ok=True) + + +def main(): + parser = argparse.ArgumentParser( + description="Helper to upgrade elementary OS") + + parser.add_argument("--update-third-party-repository", action="store_true") + parser.add_argument("--install-files", action="store_true") + + parser.add_argument("--current", nargs="?", default=None) + parser.add_argument("--next", nargs="?", default=None) + parser.add_argument("--repository-file", nargs="?", default=None) + + args = parser.parse_args() + + if args.update_third_party_repository and args.current and args.next and args.repository_file: + return update_third_party_repository(args.current, args.next, args.repository_file) + elif args.install_files and args.next: + return install_files(args.next) + + +if __name__ == "__main__": + main() diff --git a/data/meson.build b/data/meson.build index 4db0d403..3065e009 100644 --- a/data/meson.build +++ b/data/meson.build @@ -34,3 +34,27 @@ i18n.merge_file( install: true, install_dir: join_paths(get_option('datadir'), 'metainfo'), ) + +conf = configuration_data() +conf.set('PKGDATADIR', pkgdatadir) +conf.set('GETTEXT_PACKAGE', meson.project_name()) + +gettext_declaration = configure_file( + configuration: conf, + input: meson.project_name() + '.policy.in', + output: '@BASENAME@' +) + +i18n.merge_file( + input: gettext_declaration, + output: '@BASENAME@', + po_dir: join_paths(meson.source_root(), 'po'), + install: true, + install_dir: polkit_actiondir +) + +install_data( + meson.project_name() + '.system-upgrade.helper', + install_mode: 'r-xr--r--', + install_dir: pkgdatadir +) diff --git a/data/system-upgrades/jammy/etc/apt/sources.list.d/elementary.list b/data/system-upgrades/jammy/etc/apt/sources.list.d/elementary.list new file mode 100644 index 00000000..702873e8 --- /dev/null +++ b/data/system-upgrades/jammy/etc/apt/sources.list.d/elementary.list @@ -0,0 +1,2 @@ +deb http://ppa.launchpad.net/elementary-os/daily/ubuntu jammy main +deb-src http://ppa.launchpad.net/elementary-os/daily/ubuntu jammy main diff --git a/data/system-upgrades/jammy/etc/apt/sources.list.d/patches.list b/data/system-upgrades/jammy/etc/apt/sources.list.d/patches.list new file mode 100644 index 00000000..c52be081 --- /dev/null +++ b/data/system-upgrades/jammy/etc/apt/sources.list.d/patches.list @@ -0,0 +1,2 @@ +deb http://ppa.launchpad.net/elementary-os/os-patches/ubuntu jammy main +deb-src http://ppa.launchpad.net/elementary-os/os-patches/ubuntu jammy main diff --git a/meson.build b/meson.build index c0befceb..1b2e15de 100644 --- a/meson.build +++ b/meson.build @@ -4,6 +4,10 @@ project('io.elementary.settings-daemon', license: 'GPL3', ) +prefix = get_option('prefix') +datadir = join_paths(prefix, get_option('datadir')) +pkgdatadir = join_paths(datadir, meson.project_name()) + gio_dep = dependency ('gio-2.0') glib_dep = dependency('glib-2.0') granite_dep = dependency('granite', version: '>= 5.3.0') @@ -12,6 +16,9 @@ i18n = import('i18n') cc = meson.get_compiler('c') m_dep = cc.find_library('m', required : false) libgeoclue_dep = dependency ('libgeoclue-2.0') +polkit_dep = dependency('polkit-gobject-1') + +polkit_actiondir = polkit_dep.get_pkgconfig_variable('actiondir', define_variable: ['prefix', prefix]) conf_data = configuration_data() conf_data.set('PROJECT_NAME', meson.project_name()) diff --git a/po/POTFILES b/po/POTFILES index 31a08460..1b2b0b33 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1 +1,2 @@ +data/io.elementary.settings-daemon.policy.in data/settings-daemon.appdata.xml.in From fc19871ae8b4768d4700fd36d3fa330d0493238d Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 13:07:33 +0100 Subject: [PATCH 02/17] Implement offline upgrade --- meson.build | 7 ++ src/Application.vala | 18 +++ src/Backends/SystemUpgrade.vala | 161 ++++++++++++++++++++++++++ src/Utils/SystemUpgradeHelper.vala | 174 +++++++++++++++++++++++++++++ src/meson.build | 5 + 5 files changed, 365 insertions(+) create mode 100644 src/Backends/SystemUpgrade.vala create mode 100644 src/Utils/SystemUpgradeHelper.vala diff --git a/meson.build b/meson.build index 1b2e15de..a2e5afef 100644 --- a/meson.build +++ b/meson.build @@ -4,6 +4,11 @@ project('io.elementary.settings-daemon', license: 'GPL3', ) +add_project_arguments( + '-DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE', + language:'c' +) + prefix = get_option('prefix') datadir = join_paths(prefix, get_option('datadir')) pkgdatadir = join_paths(datadir, meson.project_name()) @@ -16,7 +21,9 @@ i18n = import('i18n') cc = meson.get_compiler('c') m_dep = cc.find_library('m', required : false) libgeoclue_dep = dependency ('libgeoclue-2.0') +packagekit_dep = dependency('packagekit-glib2') polkit_dep = dependency('polkit-gobject-1') +posix_dep = meson.get_compiler('vala').find_library('posix') polkit_actiondir = polkit_dep.get_pkgconfig_variable('actiondir', define_variable: ['prefix', prefix]) diff --git a/src/Application.vala b/src/Application.vala index 39c8a5e1..674419ab 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -128,6 +128,24 @@ public class SettingsDaemon.Application : GLib.Application { } } + public override bool dbus_register (DBusConnection connection, string object_path) throws Error { + // We must chain up to the parent class: + base.dbus_register (connection, object_path); + + // Now we can do our own stuff here. For example, we could export some D-Bus objects + connection.register_object (object_path, new Backends.SystemUpgrade ()); + + return true; + } + + public override void dbus_unregister (DBusConnection connection, string object_path) { + // Do our own stuff here, e.g. unexport any D-Bus objects we exported in the dbus_register + // hook above. Be sure to check that we actually did export them, since the hook + // above might have returned early due to the parent class' hook returning false! + + base.dbus_unregister (connection, object_path); + } + public static int main (string[] args) { var application = new Application (); return application.run (args); diff --git a/src/Backends/SystemUpgrade.vala b/src/Backends/SystemUpgrade.vala new file mode 100644 index 00000000..6bda720b --- /dev/null +++ b/src/Backends/SystemUpgrade.vala @@ -0,0 +1,161 @@ +/* + * Copyright 2022 elementary, Inc. (https://elementary.io) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * Authored by: Marius Meisenzahl + */ + +[DBus (name = "io.elementary.SystemUpgrade")] +public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { + public bool system_upgrade_available { + get { + return true; + } + } + + public signal void system_upgrade_progress (int percentage); + + public signal void system_upgrade_finished (); + + public void start_upgrade () { + upgrade_async.begin (); + } + + private async void upgrade_async () { + Pk.Results? results = null; + + debug ("Refresh cache"); + results = yield task.refresh_cache_async (true, cancellable, (t, p) => { }); + + debug ("Get repositories"); + results = yield task.get_repo_list_async (Pk.Bitfield.from_enums (Pk.Filter.NONE), cancellable, (p, t) => { }); + + var repo_files = new Array (); + var repos = results.get_repo_detail_array (); + for (int i = 0; i < repos.length; i++) { + var repo = repos[i]; + + // TODO: check for ppas + + var parts = repo.repo_id.split (":", 2); + var f = parts[0]; + + if (!FileUtils.test (f, FileTest.EXISTS)) { + continue; + } + + bool found = false; + for (int j = 0; j < repo_files.length; j++) { + if (repo_files.index (j) == f) { + found = true; + break; + } + } + + if (!found) { + repo_files.append_val (f); + } + } + + var helper = new Utils.SystemUpgradeHelper (); + + debug ("Update repositories"); + for (int i = 0; i < repo_files.length; i++) { + var repository_file = repo_files.index (i); + debug (" %s", repository_file); + + if (!helper.update_third_party_repository ("focal", "jammy", repository_file)) { + error ("Could not update repository: %s\n", repository_file); + return; + } + } + + if (!helper.install_files ("jammy")) { + error ("Could not install files\n"); + return; + } + + debug ("Refresh cache"); + results = yield task.refresh_cache_async (true, cancellable, (p, t) => { }); + + if (results == null) { + error ("Could not refresh cache"); + return; + } + + debug ("Get updates"); + results = yield task.get_updates_async (Pk.Bitfield.from_enums (Pk.Filter.NEWEST), cancellable, (t, p) => { }); + + if (results == null) { + error ("Could not get updates"); + return; + } + + var sack = results.get_package_sack (); + sack.remove_by_filter (update_system_filter_helper); + var package_ids = sack.get_ids (); + + task.only_download = true; + + debug ("Download packages"); + var status = Pk.Status.UNKNOWN; + int percentage = -1; + results = yield task.update_packages_async (package_ids, cancellable, ((p, t) => { + if (t == Pk.ProgressType.STATUS) { + status = p.get_status (); + } + + int new_percentage = percentage; + if (t == Pk.ProgressType.PERCENTAGE && status == Pk.Status.DOWNLOAD) { + new_percentage = p.percentage; + } + + if (status == Pk.Status.FINISHED) { + new_percentage = 100; + } + + if (new_percentage != percentage) { + percentage = new_percentage; + system_upgrade_progress (percentage); + } + })); + + if (results == null) { + error ("Could not download packages"); + return; + } + + debug ("Set PackageKit reboot action"); + Pk.offline_trigger (Pk.OfflineAction.REBOOT, cancellable); + + debug ("Ready to reboot"); + + system_upgrade_finished (); + } + + construct { + task = new Pk.Task (); + cancellable = new Cancellable (); + } + + private static Pk.Task task; + private static Cancellable cancellable; + + private bool update_system_filter_helper (Pk.Package package) { + var info = package.get_info (); + return (info != Pk.Info.OBSOLETING && info != Pk.Info.REMOVING); + } +} diff --git a/src/Utils/SystemUpgradeHelper.vala b/src/Utils/SystemUpgradeHelper.vala new file mode 100644 index 00000000..76b907e3 --- /dev/null +++ b/src/Utils/SystemUpgradeHelper.vala @@ -0,0 +1,174 @@ +/* + * Copyright 2022 elementary, Inc. (https://elementary.io) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * Authored by: Marius Meisenzahl + */ + +public class SettingsDaemon.Utils.SystemUpgradeHelper : GLib.Object { + public bool update_third_party_repository (string current, string next, string repository_file) { + if (!authenticate ()) { + var message = "Unable to authenticate"; + warning (message); + on_standard_error (message); + return false; + } + + var cmd = "update-third-party-repository"; + + if (!run ("pkexec %s/io.elementary.settings-daemon.system-upgrade.helper --%s --current %s --next %s --repository-file %s".printf ( + "/usr/share/io.elementary.settings-daemon", cmd, current, next, repository_file) + )) { + on_error (); + return false; + } + + return true; + } + + public bool install_files (string next) { + if (!authenticate ()) { + var message = "Unable to authenticate"; + warning (message); + on_standard_error (message); + return false; + } + + var cmd = "install-files"; + + if (!run ("pkexec %s/io.elementary.settings-daemon.system-upgrade.helper --%s --next %s ".printf ( + "/usr/share/io.elementary.settings-daemon", cmd, next) + )) { + on_error (); + return false; + } + + return true; + } + + public signal void on_standard_output (string line); + public signal void on_standard_error (string line); + public signal void on_error (); + + private static Polkit.Permission? permission = null; + + private bool authenticate () { + if (permission == null) { + try { + permission = new Polkit.Permission.sync ( + "io.elementary.upgrade", + new Polkit.UnixProcess (Posix.getpid ()) + ); + } catch (Error e) { + // warning ("Can't get permission to upgrade without prompting for admin: %s", e.message); + return false; + } + } + + try { + if (!permission.allowed) { + permission.acquire (null); + } + } catch (Error e) { + // warning ("Can't get permission to upgrade without prompting for admin: %s", e.message); + return false; + } + + return permission.allowed; + } + + private bool process_line (IOChannel channel, IOCondition condition, string stream_name) { + if (condition == IOCondition.HUP) { + // debug ("%s: The fd has been closed.", stream_name); + return false; + } + + try { + string line; + channel.read_line (out line, null, null); + + switch (stream_name) { + case "stdout": + // debug ("%s", line); + on_standard_output (line); + break; + case "stderr": + // warning ("\033[0;31m%s\033[0m", line); + on_standard_error (line); + break; + } + } catch (IOChannelError e) { + // warning ("%s: IOChannelError: %s", stream_name, e.message); + return false; + } catch (ConvertError e) { + // warning ("%s: ConvertError: %s", stream_name, e.message); + return false; + } + + return true; + } + + private bool run (string cmd) { + MainLoop loop = new MainLoop (); + try { + string[] spawn_args = cmd.split (" "); + string[] spawn_env = Environ.get (); + Pid child_pid; + + int standard_input; + int standard_output; + int standard_error; + + bool exit_status = false; + + Process.spawn_async_with_pipes ("/", + spawn_args, + spawn_env, + SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD, + null, + out child_pid, + out standard_input, + out standard_output, + out standard_error); + + // stdout: + IOChannel output = new IOChannel.unix_new (standard_output); + output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { + return process_line (channel, condition, "stdout"); + }); + + // stderr: + IOChannel error = new IOChannel.unix_new (standard_error); + error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { + return process_line (channel, condition, "stderr"); + }); + + ChildWatch.add (child_pid, (pid, status) => { + // Triggered when the child indicated by child_pid exits + Process.close_pid (pid); + exit_status = (status == 0); + loop.quit (); + }); + + loop.run (); + + return exit_status; + } catch (Error e) { + // warning ("Error: %s", e.message); + return false; + } + } +} diff --git a/src/meson.build b/src/meson.build index 7c726d97..900def3b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -6,7 +6,9 @@ sources = files( 'Backends/KeyboardSettings.vala', 'Backends/MouseSettings.vala', 'Backends/PrefersColorSchemeSettings.vala', + 'Backends/SystemUpgrade.vala', 'Utils/SunriseSunsetCalculator.vala', + 'Utils/SystemUpgradeHelper.vala', ) executable( @@ -19,6 +21,9 @@ executable( granite_dep, libgeoclue_dep, m_dep, + packagekit_dep, + polkit_dep, + posix_dep, ], install: true, ) From 60c7047c0ea39ce5e9f79cba025451c718c78ed9 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 15:46:37 +0100 Subject: [PATCH 03/17] Fix PolicyKit action --- data/meson.build | 21 ++++++++------------- src/Utils/SystemUpgradeHelper.vala | 6 +++--- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/data/meson.build b/data/meson.build index 3065e009..6ea1a02f 100644 --- a/data/meson.build +++ b/data/meson.build @@ -35,22 +35,17 @@ i18n.merge_file( install_dir: join_paths(get_option('datadir'), 'metainfo'), ) -conf = configuration_data() -conf.set('PKGDATADIR', pkgdatadir) -conf.set('GETTEXT_PACKAGE', meson.project_name()) - -gettext_declaration = configure_file( - configuration: conf, +i18n.merge_file( input: meson.project_name() + '.policy.in', - output: '@BASENAME@' + output: meson.project_name() + '.policy', + po_dir: join_paths(meson.source_root (), 'po'), + install_dir: join_paths(get_option('datadir'), 'polkit-1', 'actions'), + install: true ) -i18n.merge_file( - input: gettext_declaration, - output: '@BASENAME@', - po_dir: join_paths(meson.source_root(), 'po'), - install: true, - install_dir: polkit_actiondir +install_subdir( + 'system-upgrades', + install_dir: pkgdatadir ) install_data( diff --git a/src/Utils/SystemUpgradeHelper.vala b/src/Utils/SystemUpgradeHelper.vala index 76b907e3..9fc9c778 100644 --- a/src/Utils/SystemUpgradeHelper.vala +++ b/src/Utils/SystemUpgradeHelper.vala @@ -69,11 +69,11 @@ public class SettingsDaemon.Utils.SystemUpgradeHelper : GLib.Object { if (permission == null) { try { permission = new Polkit.Permission.sync ( - "io.elementary.upgrade", + "io.elementary.settings-daemon.system-upgrade", new Polkit.UnixProcess (Posix.getpid ()) ); } catch (Error e) { - // warning ("Can't get permission to upgrade without prompting for admin: %s", e.message); + warning ("Can't get permission to upgrade without prompting for admin: %s", e.message); return false; } } @@ -83,7 +83,7 @@ public class SettingsDaemon.Utils.SystemUpgradeHelper : GLib.Object { permission.acquire (null); } } catch (Error e) { - // warning ("Can't get permission to upgrade without prompting for admin: %s", e.message); + warning ("Can't get permission to upgrade without prompting for admin: %s", e.message); return false; } From 9ed5376ac772af03283cd4c487e8caf19e234af7 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 16:24:24 +0100 Subject: [PATCH 04/17] Fix helper script --- ...ntary.settings-daemon.system-upgrade.helper | 6 +++--- data/meson.build | 18 ++++++++++++++---- src/Utils/SystemUpgradeHelper.vala | 14 ++++++++------ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/data/io.elementary.settings-daemon.system-upgrade.helper b/data/io.elementary.settings-daemon.system-upgrade.helper index 7672065a..4116b066 100644 --- a/data/io.elementary.settings-daemon.system-upgrade.helper +++ b/data/io.elementary.settings-daemon.system-upgrade.helper @@ -11,7 +11,7 @@ def update_third_party_repository(current, next, repository_file): if os.path.isfile(repository_file): should_delete = False should_update = False - with repository_file.open("r") as f: + with open(repository_file, "r") as f: content = [] for line in f.read().split("\n"): if r.match(line): @@ -25,10 +25,10 @@ def update_third_party_repository(current, next, repository_file): should_delete = True if should_delete: - repository_file.unlink() + os.remove(repository_file) if should_update: - with repository_file.open("w") as f: + with open(repository_file, "w") as f: f.write("\n".join(content)) diff --git a/data/meson.build b/data/meson.build index 6ea1a02f..3a1cc626 100644 --- a/data/meson.build +++ b/data/meson.build @@ -35,12 +35,22 @@ i18n.merge_file( install_dir: join_paths(get_option('datadir'), 'metainfo'), ) -i18n.merge_file( +conf = configuration_data() +conf.set('PKGDATADIR', pkgdatadir) +conf.set('GETTEXT_PACKAGE', meson.project_name()) + +gettext_declaration = configure_file( + configuration: conf, input: meson.project_name() + '.policy.in', + output: meson.project_name() + '.policy.in' +) + +i18n.merge_file( + input: gettext_declaration, output: meson.project_name() + '.policy', - po_dir: join_paths(meson.source_root (), 'po'), - install_dir: join_paths(get_option('datadir'), 'polkit-1', 'actions'), - install: true + po_dir: join_paths(meson.source_root(), 'po'), + install: true, + install_dir: polkit_actiondir ) install_subdir( diff --git a/src/Utils/SystemUpgradeHelper.vala b/src/Utils/SystemUpgradeHelper.vala index 9fc9c778..cc2c57de 100644 --- a/src/Utils/SystemUpgradeHelper.vala +++ b/src/Utils/SystemUpgradeHelper.vala @@ -29,9 +29,10 @@ public class SettingsDaemon.Utils.SystemUpgradeHelper : GLib.Object { var cmd = "update-third-party-repository"; - if (!run ("pkexec %s/io.elementary.settings-daemon.system-upgrade.helper --%s --current %s --next %s --repository-file %s".printf ( - "/usr/share/io.elementary.settings-daemon", cmd, current, next, repository_file) - )) { + var command = "pkexec %s/io.elementary.settings-daemon.system-upgrade.helper --%s --current %s --next %s --repository-file %s".printf ( + "/usr/share/io.elementary.settings-daemon", cmd, current, next, repository_file); + + if (!run (command)) { on_error (); return false; } @@ -49,9 +50,10 @@ public class SettingsDaemon.Utils.SystemUpgradeHelper : GLib.Object { var cmd = "install-files"; - if (!run ("pkexec %s/io.elementary.settings-daemon.system-upgrade.helper --%s --next %s ".printf ( - "/usr/share/io.elementary.settings-daemon", cmd, next) - )) { + var command = "pkexec %s/io.elementary.settings-daemon.system-upgrade.helper --%s --next %s ".printf ( + "/usr/share/io.elementary.settings-daemon", cmd, next); + + if (!run (command)) { on_error (); return false; } From 20303707e7e8a164545c1fee9e00709ba79e88e5 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sat, 29 Jan 2022 16:33:41 +0100 Subject: [PATCH 05/17] Fix typo --- src/Utils/SystemUpgradeHelper.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/SystemUpgradeHelper.vala b/src/Utils/SystemUpgradeHelper.vala index cc2c57de..314d8ea0 100644 --- a/src/Utils/SystemUpgradeHelper.vala +++ b/src/Utils/SystemUpgradeHelper.vala @@ -50,7 +50,7 @@ public class SettingsDaemon.Utils.SystemUpgradeHelper : GLib.Object { var cmd = "install-files"; - var command = "pkexec %s/io.elementary.settings-daemon.system-upgrade.helper --%s --next %s ".printf ( + var command = "pkexec %s/io.elementary.settings-daemon.system-upgrade.helper --%s --next %s".printf ( "/usr/share/io.elementary.settings-daemon", cmd, next); if (!run (command)) { From 9084bdc2887afd2f8a92cee5eb84c9f45978ae44 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 30 Jan 2022 16:11:16 +0100 Subject: [PATCH 06/17] Add repositories for focal --- .../focal/etc/apt/sources.list.d/elementary.list | 2 ++ data/system-upgrades/focal/etc/apt/sources.list.d/patches.list | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 data/system-upgrades/focal/etc/apt/sources.list.d/elementary.list create mode 100644 data/system-upgrades/focal/etc/apt/sources.list.d/patches.list diff --git a/data/system-upgrades/focal/etc/apt/sources.list.d/elementary.list b/data/system-upgrades/focal/etc/apt/sources.list.d/elementary.list new file mode 100644 index 00000000..ee649af3 --- /dev/null +++ b/data/system-upgrades/focal/etc/apt/sources.list.d/elementary.list @@ -0,0 +1,2 @@ +deb http://ppa.launchpad.net/elementary-os/stable/ubuntu focal main +deb-src http://ppa.launchpad.net/elementary-os/stable/ubuntu focal main diff --git a/data/system-upgrades/focal/etc/apt/sources.list.d/patches.list b/data/system-upgrades/focal/etc/apt/sources.list.d/patches.list new file mode 100644 index 00000000..937d3e94 --- /dev/null +++ b/data/system-upgrades/focal/etc/apt/sources.list.d/patches.list @@ -0,0 +1,2 @@ +deb http://ppa.launchpad.net/elementary-os/os-patches/ubuntu focal main +deb-src http://ppa.launchpad.net/elementary-os/os-patches/ubuntu focal main From 0ceb0384e66afab538e970eeb6cdfcb4c0558c70 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 30 Jan 2022 16:33:32 +0100 Subject: [PATCH 07/17] Revert "Add repositories for focal" This reverts commit 9084bdc2887afd2f8a92cee5eb84c9f45978ae44. --- .../focal/etc/apt/sources.list.d/elementary.list | 2 -- data/system-upgrades/focal/etc/apt/sources.list.d/patches.list | 2 -- 2 files changed, 4 deletions(-) delete mode 100644 data/system-upgrades/focal/etc/apt/sources.list.d/elementary.list delete mode 100644 data/system-upgrades/focal/etc/apt/sources.list.d/patches.list diff --git a/data/system-upgrades/focal/etc/apt/sources.list.d/elementary.list b/data/system-upgrades/focal/etc/apt/sources.list.d/elementary.list deleted file mode 100644 index ee649af3..00000000 --- a/data/system-upgrades/focal/etc/apt/sources.list.d/elementary.list +++ /dev/null @@ -1,2 +0,0 @@ -deb http://ppa.launchpad.net/elementary-os/stable/ubuntu focal main -deb-src http://ppa.launchpad.net/elementary-os/stable/ubuntu focal main diff --git a/data/system-upgrades/focal/etc/apt/sources.list.d/patches.list b/data/system-upgrades/focal/etc/apt/sources.list.d/patches.list deleted file mode 100644 index 937d3e94..00000000 --- a/data/system-upgrades/focal/etc/apt/sources.list.d/patches.list +++ /dev/null @@ -1,2 +0,0 @@ -deb http://ppa.launchpad.net/elementary-os/os-patches/ubuntu focal main -deb-src http://ppa.launchpad.net/elementary-os/os-patches/ubuntu focal main From 44207a5982273d719e607b4969cc255cf3756ca7 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 30 Jan 2022 16:38:42 +0100 Subject: [PATCH 08/17] GitHub CI: Install dependencies --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 985b0dbc..93d86eb3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ jobs: - name: Install Dependencies run: | apt update - apt install -y libaccountsservice-dev libdbus-1-dev libgranite-dev libgeoclue-2-dev meson valac + apt install -y libaccountsservice-dev libdbus-1-dev libgranite-dev libgeoclue-2-dev libpackagekit-glib2-dev libpolkit-gobject-1-dev meson valac - name: Build env: DESTDIR: out From e0659cfa2ba16c511d3671d3857b202c95a5c89b Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 1 Feb 2022 19:16:29 +0100 Subject: [PATCH 09/17] SystemUpgrade: inhibit during update --- src/Backends/SystemUpgrade.vala | 4 ++ src/Utils/Inhibitor.vala | 102 ++++++++++++++++++++++++++++++++ src/meson.build | 1 + 3 files changed, 107 insertions(+) create mode 100644 src/Utils/Inhibitor.vala diff --git a/src/Backends/SystemUpgrade.vala b/src/Backends/SystemUpgrade.vala index 6bda720b..59ba6074 100644 --- a/src/Backends/SystemUpgrade.vala +++ b/src/Backends/SystemUpgrade.vala @@ -35,6 +35,8 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { } private async void upgrade_async () { + Inhibitor.get_instance ().inhibit (); + Pk.Results? results = null; debug ("Refresh cache"); @@ -144,6 +146,8 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { debug ("Ready to reboot"); system_upgrade_finished (); + + Inhibitor.get_instance ().uninhibit (); } construct { diff --git a/src/Utils/Inhibitor.vala b/src/Utils/Inhibitor.vala new file mode 100644 index 00000000..8221f0ff --- /dev/null +++ b/src/Utils/Inhibitor.vala @@ -0,0 +1,102 @@ +/*- + * Copyright (c) 2016 elementary LLC. (https://elementary.io) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program. If not, see . + */ + +[DBus (name = "org.freedesktop.ScreenSaver")] +public interface ScreenSaverIface : Object { + public abstract uint32 inhibit (string app_name, string reason) throws Error; + public abstract void un_inhibit (uint32 cookie) throws Error; + public abstract void simulate_user_activity () throws Error; +} + +public class Inhibitor : Object { + private const string IFACE = "org.freedesktop.ScreenSaver"; + private const string IFACE_PATH = "/ScreenSaver"; + + private static Inhibitor? instance = null; + + private uint32? inhibit_cookie = null; + + private ScreenSaverIface? screensaver_iface = null; + + private bool inhibited = false; + private bool simulator_started = false; + + private Inhibitor () { + try { + screensaver_iface = Bus.get_proxy_sync (BusType.SESSION, IFACE, IFACE_PATH, DBusProxyFlags.NONE); + } catch (Error e) { + warning ("Could not start screensaver interface: %s", e.message); + } + } + + public static Inhibitor get_instance () { + if (instance == null) { + instance = new Inhibitor (); + } + + return instance; + } + + public void inhibit () { + if (screensaver_iface != null && !inhibited) { + try { + inhibited = true; + inhibit_cookie = screensaver_iface.inhibit ("Installer", "Installing"); + simulate_activity (); + debug ("Inhibiting screen"); + } catch (Error e) { + warning ("Could not inhibit screen: %s", e.message); + } + } + } + + public void uninhibit () { + if (screensaver_iface != null && inhibited) {//&& inhibit_cookie != null) { + try { + inhibited = false; + screensaver_iface.un_inhibit (inhibit_cookie); + debug ("Uninhibiting screen"); + } catch (Error e) { + warning ("Could not uninhibit screen: %s", e.message); + } + } + } + + /* + * Inhibit currently does not block a suspend from ocurring, + * so we simulate user activity every 2 mins to prevent it + */ + private void simulate_activity () { + if (simulator_started) return; + + simulator_started = true; + Timeout.add_full (Priority.DEFAULT, 120000, ()=> { + if (inhibited) { + try { + debug ("Simulating activity"); + screensaver_iface.simulate_user_activity (); + } catch (Error e) { + warning ("Could not simulate user activity: %s", e.message); + } + } else { + simulator_started = false; + } + + return inhibited; + }); + } +} diff --git a/src/meson.build b/src/meson.build index 900def3b..baf43b2b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -7,6 +7,7 @@ sources = files( 'Backends/MouseSettings.vala', 'Backends/PrefersColorSchemeSettings.vala', 'Backends/SystemUpgrade.vala', + 'Utils/Inhibitor.vala', 'Utils/SunriseSunsetCalculator.vala', 'Utils/SystemUpgradeHelper.vala', ) From 9f3165ecde8973f99cc281638d45ba8c30e08c92 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 1 Feb 2022 19:36:00 +0100 Subject: [PATCH 10/17] Application: Satisfy linter --- src/Application.vala | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Application.vala b/src/Application.vala index 674419ab..eee06dcf 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -129,22 +129,22 @@ public class SettingsDaemon.Application : GLib.Application { } public override bool dbus_register (DBusConnection connection, string object_path) throws Error { - // We must chain up to the parent class: - base.dbus_register (connection, object_path); + // We must chain up to the parent class: + base.dbus_register (connection, object_path); - // Now we can do our own stuff here. For example, we could export some D-Bus objects + // Now we can do our own stuff here. For example, we could export some D-Bus objects connection.register_object (object_path, new Backends.SystemUpgrade ()); - return true; - } + return true; + } - public override void dbus_unregister (DBusConnection connection, string object_path) { - // Do our own stuff here, e.g. unexport any D-Bus objects we exported in the dbus_register - // hook above. Be sure to check that we actually did export them, since the hook - // above might have returned early due to the parent class' hook returning false! + public override void dbus_unregister (DBusConnection connection, string object_path) { + // Do our own stuff here, e.g. unexport any D-Bus objects we exported in the dbus_register + // hook above. Be sure to check that we actually did export them, since the hook + // above might have returned early due to the parent class' hook returning false! - base.dbus_unregister (connection, object_path); - } + base.dbus_unregister (connection, object_path); + } public static int main (string[] args) { var application = new Application (); From 93180c02148a5a18c5d4edffc7b82133979b64b0 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Tue, 1 Feb 2022 19:38:17 +0100 Subject: [PATCH 11/17] GitHub CI: Remove meson destdir --- .github/workflows/main.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 93d86eb3..612a872c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,8 +17,6 @@ jobs: apt update apt install -y libaccountsservice-dev libdbus-1-dev libgranite-dev libgeoclue-2-dev libpackagekit-glib2-dev libpolkit-gobject-1-dev meson valac - name: Build - env: - DESTDIR: out run: | meson build ninja -C build From 89c32a65b7d62a1e7076442b46f14dac4840d868 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 6 Feb 2022 14:24:49 +0100 Subject: [PATCH 12/17] SystemUpgrade: Handle errors --- src/Backends/SystemUpgrade.vala | 161 ++++++++++++++++---------------- 1 file changed, 82 insertions(+), 79 deletions(-) diff --git a/src/Backends/SystemUpgrade.vala b/src/Backends/SystemUpgrade.vala index 59ba6074..ee0bd55f 100644 --- a/src/Backends/SystemUpgrade.vala +++ b/src/Backends/SystemUpgrade.vala @@ -30,7 +30,9 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { public signal void system_upgrade_finished (); - public void start_upgrade () { + public signal void system_upgrade_failed (string text); + + public void start_upgrade () throws Error { upgrade_async.begin (); } @@ -39,113 +41,114 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { Pk.Results? results = null; - debug ("Refresh cache"); - results = yield task.refresh_cache_async (true, cancellable, (t, p) => { }); + try { + debug ("Refresh cache"); + results = yield task.refresh_cache_async (true, cancellable, (t, p) => { }); - debug ("Get repositories"); - results = yield task.get_repo_list_async (Pk.Bitfield.from_enums (Pk.Filter.NONE), cancellable, (p, t) => { }); + debug ("Get repositories"); + results = yield task.get_repo_list_async (Pk.Bitfield.from_enums (Pk.Filter.NONE), cancellable, (p, t) => { }); - var repo_files = new Array (); - var repos = results.get_repo_detail_array (); - for (int i = 0; i < repos.length; i++) { - var repo = repos[i]; + var repo_files = new Array (); + var repos = results.get_repo_detail_array (); + for (int i = 0; i < repos.length; i++) { + var repo = repos[i]; - // TODO: check for ppas + // TODO: check for ppas - var parts = repo.repo_id.split (":", 2); - var f = parts[0]; + var parts = repo.repo_id.split (":", 2); + var f = parts[0]; - if (!FileUtils.test (f, FileTest.EXISTS)) { - continue; - } + if (!FileUtils.test (f, FileTest.EXISTS)) { + continue; + } - bool found = false; - for (int j = 0; j < repo_files.length; j++) { - if (repo_files.index (j) == f) { - found = true; - break; + bool found = false; + for (int j = 0; j < repo_files.length; j++) { + if (repo_files.index (j) == f) { + found = true; + break; + } } - } - if (!found) { - repo_files.append_val (f); + if (!found) { + repo_files.append_val (f); + } } - } - var helper = new Utils.SystemUpgradeHelper (); + var helper = new Utils.SystemUpgradeHelper (); - debug ("Update repositories"); - for (int i = 0; i < repo_files.length; i++) { - var repository_file = repo_files.index (i); - debug (" %s", repository_file); + debug ("Update repositories"); + for (int i = 0; i < repo_files.length; i++) { + var repository_file = repo_files.index (i); + debug (" %s", repository_file); - if (!helper.update_third_party_repository ("focal", "jammy", repository_file)) { - error ("Could not update repository: %s\n", repository_file); - return; + if (!helper.update_third_party_repository ("focal", "jammy", repository_file)) { + throw new Error (0, 0, "Could not update repository: %s\n", repository_file); + } } - } - if (!helper.install_files ("jammy")) { - error ("Could not install files\n"); - return; - } + if (!helper.install_files ("jammy")) { + throw new Error (0, 0, "Could not install files\n"); + } - debug ("Refresh cache"); - results = yield task.refresh_cache_async (true, cancellable, (p, t) => { }); + debug ("Refresh cache"); + results = yield task.refresh_cache_async (true, cancellable, (p, t) => { }); - if (results == null) { - error ("Could not refresh cache"); - return; - } + if (results == null) { + throw new Error (0, 0, "Could not refresh cache"); + } - debug ("Get updates"); - results = yield task.get_updates_async (Pk.Bitfield.from_enums (Pk.Filter.NEWEST), cancellable, (t, p) => { }); + debug ("Get updates"); + results = yield task.get_updates_async (Pk.Bitfield.from_enums (Pk.Filter.NEWEST), cancellable, (t, p) => { }); - if (results == null) { - error ("Could not get updates"); - return; - } + if (results == null) { + throw new Error (0, 0, "Could not get updates"); + } - var sack = results.get_package_sack (); - sack.remove_by_filter (update_system_filter_helper); - var package_ids = sack.get_ids (); + var sack = results.get_package_sack (); + sack.remove_by_filter (update_system_filter_helper); + var package_ids = sack.get_ids (); - task.only_download = true; + task.only_download = true; - debug ("Download packages"); - var status = Pk.Status.UNKNOWN; - int percentage = -1; - results = yield task.update_packages_async (package_ids, cancellable, ((p, t) => { - if (t == Pk.ProgressType.STATUS) { - status = p.get_status (); - } + debug ("Download packages"); + var status = Pk.Status.UNKNOWN; + int percentage = -1; + results = yield task.update_packages_async (package_ids, cancellable, ((p, t) => { + if (t == Pk.ProgressType.STATUS) { + status = p.get_status (); + } - int new_percentage = percentage; - if (t == Pk.ProgressType.PERCENTAGE && status == Pk.Status.DOWNLOAD) { - new_percentage = p.percentage; - } + int new_percentage = percentage; + if (t == Pk.ProgressType.PERCENTAGE && status == Pk.Status.DOWNLOAD) { + new_percentage = p.percentage; + } - if (status == Pk.Status.FINISHED) { - new_percentage = 100; - } + if (status == Pk.Status.FINISHED) { + new_percentage = 100; + } + + if (new_percentage != percentage) { + percentage = new_percentage; + system_upgrade_progress (percentage); + } + })); - if (new_percentage != percentage) { - percentage = new_percentage; - system_upgrade_progress (percentage); + if (results == null) { + throw new Error (0, 0, "Could not download packages"); } - })); - if (results == null) { - error ("Could not download packages"); - return; - } + debug ("Set PackageKit reboot action"); + Pk.offline_trigger (Pk.OfflineAction.REBOOT, cancellable); - debug ("Set PackageKit reboot action"); - Pk.offline_trigger (Pk.OfflineAction.REBOOT, cancellable); + debug ("Ready to reboot"); - debug ("Ready to reboot"); + system_upgrade_finished (); + } catch (Error e) { + warning ("Upgrade failed: %s", e.message); - system_upgrade_finished (); + system_upgrade_failed (e.message); + } Inhibitor.get_instance ().uninhibit (); } From ab9333312ed7fd21ac2f39130e34253c61752479 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 6 Feb 2022 14:28:31 +0100 Subject: [PATCH 13/17] SystemUpgrade: Implement cancel method --- src/Backends/SystemUpgrade.vala | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Backends/SystemUpgrade.vala b/src/Backends/SystemUpgrade.vala index ee0bd55f..8f6f59c8 100644 --- a/src/Backends/SystemUpgrade.vala +++ b/src/Backends/SystemUpgrade.vala @@ -32,11 +32,21 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { public signal void system_upgrade_failed (string text); + public signal void system_upgrade_cancelled (); + public void start_upgrade () throws Error { upgrade_async.begin (); } + public void cancel () throws Error { + cancellable.cancel (); + } + private async void upgrade_async () { + if (cancellable.is_cancelled ()) { + cancellable.reset (); + } + Inhibitor.get_instance ().inhibit (); Pk.Results? results = null; @@ -156,6 +166,8 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { construct { task = new Pk.Task (); cancellable = new Cancellable (); + + cancellable.cancelled.connect (() => { system_upgrade_cancelled (); }); } private static Pk.Task task; From 1c8dd840fa96996956ed0145fbb2a8759d3c1e34 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Thu, 24 Feb 2022 19:09:13 +0100 Subject: [PATCH 14/17] Add option to cancel upgrade --- src/Backends/SystemUpgrade.vala | 44 +++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/Backends/SystemUpgrade.vala b/src/Backends/SystemUpgrade.vala index 8f6f59c8..6f6235ce 100644 --- a/src/Backends/SystemUpgrade.vala +++ b/src/Backends/SystemUpgrade.vala @@ -40,13 +40,23 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { public void cancel () throws Error { cancellable.cancel (); + + if (is_system_upgrade_running) { + is_system_upgrade_running = false; + } } private async void upgrade_async () { + if (is_system_upgrade_running) { + return; + } + if (cancellable.is_cancelled ()) { cancellable.reset (); } + is_system_upgrade_running = true; + Inhibitor.get_instance ().inhibit (); Pk.Results? results = null; @@ -55,9 +65,19 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { debug ("Refresh cache"); results = yield task.refresh_cache_async (true, cancellable, (t, p) => { }); + if (cancellable.is_cancelled ()) { + Inhibitor.get_instance ().uninhibit (); + return; + } + debug ("Get repositories"); results = yield task.get_repo_list_async (Pk.Bitfield.from_enums (Pk.Filter.NONE), cancellable, (p, t) => { }); + if (cancellable.is_cancelled ()) { + Inhibitor.get_instance ().uninhibit (); + return; + } + var repo_files = new Array (); var repos = results.get_repo_detail_array (); for (int i = 0; i < repos.length; i++) { @@ -104,6 +124,11 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { debug ("Refresh cache"); results = yield task.refresh_cache_async (true, cancellable, (p, t) => { }); + if (cancellable.is_cancelled ()) { + Inhibitor.get_instance ().uninhibit (); + return; + } + if (results == null) { throw new Error (0, 0, "Could not refresh cache"); } @@ -111,6 +136,11 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { debug ("Get updates"); results = yield task.get_updates_async (Pk.Bitfield.from_enums (Pk.Filter.NEWEST), cancellable, (t, p) => { }); + if (cancellable.is_cancelled ()) { + Inhibitor.get_instance ().uninhibit (); + return; + } + if (results == null) { throw new Error (0, 0, "Could not get updates"); } @@ -144,6 +174,11 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { } })); + if (cancellable.is_cancelled ()) { + Inhibitor.get_instance ().uninhibit (); + return; + } + if (results == null) { throw new Error (0, 0, "Could not download packages"); } @@ -151,6 +186,11 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { debug ("Set PackageKit reboot action"); Pk.offline_trigger (Pk.OfflineAction.REBOOT, cancellable); + if (cancellable.is_cancelled ()) { + Inhibitor.get_instance ().uninhibit (); + return; + } + debug ("Ready to reboot"); system_upgrade_finished (); @@ -160,6 +200,8 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { system_upgrade_failed (e.message); } + is_system_upgrade_running = false; + Inhibitor.get_instance ().uninhibit (); } @@ -173,6 +215,8 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { private static Pk.Task task; private static Cancellable cancellable; + private bool is_system_upgrade_running = false; + private bool update_system_filter_helper (Pk.Package package) { var info = package.get_info (); return (info != Pk.Info.OBSOLETING && info != Pk.Info.REMOVING); From 83b5ac766d50b1c29a93f560ae3d48060baf3272 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Sun, 25 Dec 2022 12:21:58 +0100 Subject: [PATCH 15/17] Update sources to stable --- .../jammy/etc/apt/sources.list.d/elementary.list | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/system-upgrades/jammy/etc/apt/sources.list.d/elementary.list b/data/system-upgrades/jammy/etc/apt/sources.list.d/elementary.list index 702873e8..555895ab 100644 --- a/data/system-upgrades/jammy/etc/apt/sources.list.d/elementary.list +++ b/data/system-upgrades/jammy/etc/apt/sources.list.d/elementary.list @@ -1,2 +1,2 @@ -deb http://ppa.launchpad.net/elementary-os/daily/ubuntu jammy main -deb-src http://ppa.launchpad.net/elementary-os/daily/ubuntu jammy main +deb http://ppa.launchpad.net/elementary-os/stable/ubuntu jammy main +deb-src http://ppa.launchpad.net/elementary-os/stable/ubuntu jammy main From 41194dd31fbb8bc51963d3e19b3c1b6851287624 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Mon, 30 Jan 2023 12:08:59 +0100 Subject: [PATCH 16/17] Disable user interaction during offline upgrade --- src/Backends/SystemUpgrade.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Backends/SystemUpgrade.vala b/src/Backends/SystemUpgrade.vala index 6f6235ce..d89074c4 100644 --- a/src/Backends/SystemUpgrade.vala +++ b/src/Backends/SystemUpgrade.vala @@ -184,7 +184,7 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { } debug ("Set PackageKit reboot action"); - Pk.offline_trigger (Pk.OfflineAction.REBOOT, cancellable); + Pk.offline_trigger_with_flags (Pk.OfflineAction.REBOOT, Pk.OfflineFlags.NONE, cancellable); if (cancellable.is_cancelled ()) { Inhibitor.get_instance ().uninhibit (); From 038677ba2d66afa7e36b5820d51545d2b215cb30 Mon Sep 17 00:00:00 2001 From: Marius Meisenzahl Date: Mon, 30 Jan 2023 14:58:22 +0100 Subject: [PATCH 17/17] Revert "Disable user interaction during offline upgrade" This reverts commit 41194dd31fbb8bc51963d3e19b3c1b6851287624. --- src/Backends/SystemUpgrade.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Backends/SystemUpgrade.vala b/src/Backends/SystemUpgrade.vala index d89074c4..6f6235ce 100644 --- a/src/Backends/SystemUpgrade.vala +++ b/src/Backends/SystemUpgrade.vala @@ -184,7 +184,7 @@ public class SettingsDaemon.Backends.SystemUpgrade : GLib.Object { } debug ("Set PackageKit reboot action"); - Pk.offline_trigger_with_flags (Pk.OfflineAction.REBOOT, Pk.OfflineFlags.NONE, cancellable); + Pk.offline_trigger (Pk.OfflineAction.REBOOT, cancellable); if (cancellable.is_cancelled ()) { Inhibitor.get_instance ().uninhibit ();