gboolean gs_plugin_app_install (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { g_autoptr(SnapdClient) client = NULL; SnapdInstallFlags flags = SNAPD_INSTALL_FLAGS_NONE; /* We can only install apps we know of */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; client = get_client (plugin, error); if (client == NULL) return FALSE; gs_app_set_state (app, AS_APP_STATE_INSTALLING); if (g_strcmp0 (gs_app_get_metadata_item (app, "snap::confinement"), "classic") == 0) flags |= SNAPD_INSTALL_FLAGS_CLASSIC; if (!snapd_client_install2_sync (client, flags, gs_app_get_metadata_item (app, "snap::name"), NULL, NULL, progress_cb, app, cancellable, error)) { gs_app_set_state_recover (app); snapd_error_convert (error); return FALSE; } gs_app_set_state (app, AS_APP_STATE_INSTALLED); return TRUE; }
static gboolean gs_plugin_fwupd_modify_source (GsPlugin *plugin, GsApp *app, gboolean enabled, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); const gchar *remote_id = gs_app_get_metadata_item (app, "fwupd::remote-id"); if (remote_id == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "not enough data for fwupd %s", gs_app_get_unique_id (app)); return FALSE; } gs_app_set_state (app, enabled ? AS_APP_STATE_INSTALLING : AS_APP_STATE_REMOVING); if (!fwupd_client_modify_remote (priv->client, remote_id, "Enabled", enabled ? "true" : "false", cancellable, error)) { gs_app_set_state_recover (app); return FALSE; } gs_app_set_state (app, enabled ? AS_APP_STATE_INSTALLED : AS_APP_STATE_AVAILABLE); return TRUE; }
gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { g_autoptr(SnapdClient) client = NULL; /* We can only remove apps we know of */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; client = get_client (plugin, error); if (client == NULL) return FALSE; gs_app_set_state (app, AS_APP_STATE_REMOVING); if (!snapd_client_remove_sync (client, gs_app_get_metadata_item (app, "snap::name"), progress_cb, app, cancellable, error)) { gs_app_set_state_recover (app); snapd_error_convert (error); return FALSE; } gs_app_set_state (app, AS_APP_STATE_AVAILABLE); return TRUE; }
/** * gs_plugin_update_app: */ gboolean gs_plugin_update_app (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); g_autoptr(XdgAppInstalledRef) xref = NULL; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; /* install */ gs_app_set_state (app, AS_APP_STATE_INSTALLING); xref = xdg_app_installation_update (priv->installation, XDG_APP_UPDATE_FLAGS_NONE, gs_app_get_xdgapp_kind (app), gs_app_get_xdgapp_name (app), gs_app_get_xdgapp_arch (app), gs_app_get_xdgapp_branch (app), gs_plugin_xdg_app_progress_cb, app, cancellable, error); if (xref == NULL) { gs_app_set_state_recover (app); return FALSE; } /* state is known */ gs_app_set_state (app, AS_APP_STATE_INSTALLED); return TRUE; }
/** * gs_plugin_app_remove: */ gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; /* remove */ gs_app_set_state (app, AS_APP_STATE_REMOVING); if (!xdg_app_installation_uninstall (priv->installation, XDG_APP_REF_KIND_APP, gs_app_get_xdgapp_name (app), gs_app_get_xdgapp_arch (app), gs_app_get_xdgapp_branch (app), gs_plugin_xdg_app_progress_cb, app, cancellable, error)) { gs_app_set_state_recover (app); return FALSE; } /* state is not known: we don't know if we can re-install this app */ gs_app_set_state (app, AS_APP_STATE_UNKNOWN); return TRUE; }
static gboolean gs_plugin_fwupd_install (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); const gchar *device_id; FwupdInstallFlags install_flags = 0; GFile *local_file; g_autofree gchar *filename = NULL; /* not set */ local_file = gs_app_get_local_file (app); if (local_file == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "not enough data for fwupd %s", filename); return FALSE; } /* file does not yet exist */ filename = g_file_get_path (local_file); if (!g_file_query_exists (local_file, cancellable)) { const gchar *uri = gs_fwupd_app_get_update_uri (app); gs_app_set_state (app, AS_APP_STATE_INSTALLING); if (!gs_plugin_download_file (plugin, app, uri, filename, cancellable, error)) return FALSE; } /* limit to single device? */ device_id = gs_fwupd_app_get_device_id (app); if (device_id == NULL) device_id = FWUPD_DEVICE_ID_ANY; /* set the last object */ g_set_object (&priv->app_current, app); /* only offline supported */ if (gs_app_get_metadata_item (app, "fwupd::OnlyOffline") != NULL) install_flags |= FWUPD_INSTALL_FLAG_OFFLINE; gs_app_set_state (app, AS_APP_STATE_INSTALLING); if (!fwupd_client_install (priv->client, device_id, filename, install_flags, cancellable, error)) { gs_plugin_fwupd_error_convert (error); gs_app_set_state_recover (app); return FALSE; } /* delete the file from the cache */ gs_app_set_state (app, AS_APP_STATE_INSTALLED); return g_file_delete (local_file, cancellable, error); }
/** * gs_plugin_app_upgrade_download: */ gboolean gs_plugin_app_upgrade_download (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); ProgressData data; g_autoptr(PkResults) results = NULL; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), "packagekit") != 0) return TRUE; data.app = app; data.plugin = plugin; /* check is distro-upgrade */ if (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "app %s is not a distro upgrade", gs_app_get_id (app)); return FALSE; } /* ask PK to download enough packages to upgrade the system */ gs_app_set_state (app, AS_APP_STATE_INSTALLING); results = pk_task_upgrade_system_sync (priv->task, gs_app_get_version (app), PK_UPGRADE_KIND_ENUM_COMPLETE, cancellable, gs_plugin_packagekit_progress_cb, &data, error); if (!gs_plugin_packagekit_results_valid (results, error)) { gs_app_set_state_recover (app); return FALSE; } /* state is known */ gs_app_set_state (app, AS_APP_STATE_UPDATABLE); return TRUE; }
gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { g_autofree gchar *macaroon = NULL; g_auto(GStrv) discharges = NULL; /* We can only remove apps we know of */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; get_macaroon (plugin, &macaroon, &discharges); gs_app_set_state (app, AS_APP_STATE_REMOVING); if (!gs_snapd_remove (macaroon, discharges, gs_app_get_id (app), progress_cb, app, cancellable, error)) { gs_app_set_state_recover (app); return FALSE; } gs_app_set_state (app, AS_APP_STATE_AVAILABLE); return TRUE; }
gboolean gs_plugin_app_install (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); GPtrArray *addons; GPtrArray *source_ids; ProgressData data; const gchar *package_id; guint i, j; g_autofree gchar *local_filename = NULL; g_auto(GStrv) package_ids = NULL; g_autoptr(GPtrArray) array_package_ids = NULL; g_autoptr(PkResults) results = NULL; data.app = app; data.plugin = plugin; data.ptask = NULL; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; /* we enable the repo */ if (gs_app_get_state (app) == AS_APP_STATE_UNAVAILABLE) { /* get everything up front we need */ source_ids = gs_app_get_source_ids (app); if (source_ids->len == 0) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, "installing not available"); return FALSE; } package_ids = g_new0 (gchar *, 2); package_ids[0] = g_strdup (g_ptr_array_index (source_ids, 0)); /* enable the source */ if (!gs_plugin_app_source_enable (plugin, app, cancellable, error)) return FALSE; /* FIXME: this is a hack, to allow PK time to re-initialize * everything in order to match an actual result. The root cause * is probably some kind of hard-to-debug race in the daemon. */ g_usleep (G_USEC_PER_SEC * 3); /* actually install the package */ gs_app_set_state (app, AS_APP_STATE_AVAILABLE); gs_app_set_state (app, AS_APP_STATE_INSTALLING); results = pk_task_install_packages_sync (priv->task, package_ids, cancellable, gs_plugin_packagekit_progress_cb, &data, error); if (!gs_plugin_packagekit_results_valid (results, error)) { gs_app_set_state_recover (app); return FALSE; } /* state is known */ gs_app_set_state (app, AS_APP_STATE_INSTALLED); /* no longer valid */ gs_app_clear_source_ids (app); return TRUE; }
/** * gs_plugin_app_install: */ gboolean gs_plugin_app_install (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); g_autoptr(XdgAppInstalledRef) xref = NULL; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; /* ensure we have metadata and state */ if (!gs_plugin_xdg_app_refine_app (plugin, app, 0, cancellable, error)) return FALSE; /* install */ gs_app_set_state (app, AS_APP_STATE_INSTALLING); /* install required runtime if not already installed */ if (gs_app_get_kind (app) == AS_APP_KIND_DESKTOP) { GsApp *runtime; runtime = gs_app_get_runtime (app); /* the runtime could come from a different remote to the app */ if (!gs_plugin_refine_item_metadata (plugin, runtime, cancellable, error)) return FALSE; if (!gs_plugin_refine_item_origin (plugin, runtime, cancellable, error)) return FALSE; if (!gs_plugin_refine_item_state (plugin, runtime, cancellable, error)) return FALSE; if (gs_app_get_state (runtime) == AS_APP_STATE_UNKNOWN) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, "Failed to find runtime %s", gs_app_get_source_default (runtime)); return FALSE; } /* not installed */ if (gs_app_get_state (runtime) == AS_APP_STATE_AVAILABLE) { g_debug ("%s is not already installed, so installing", gs_app_get_id (runtime)); gs_app_set_state (runtime, AS_APP_STATE_INSTALLING); xref = xdg_app_installation_install (priv->installation, gs_app_get_origin (runtime), gs_app_get_xdgapp_kind (runtime), gs_app_get_xdgapp_name (runtime), gs_app_get_xdgapp_arch (runtime), gs_app_get_xdgapp_branch (runtime), gs_plugin_xdg_app_progress_cb, app, cancellable, error); if (xref == NULL) { gs_app_set_state_recover (runtime); return FALSE; } gs_app_set_state (runtime, AS_APP_STATE_INSTALLED); } else { g_debug ("%s is already installed, so skipping", gs_app_get_id (runtime)); } } /* use the source for local apps */ if (gs_app_get_state (app) == AS_APP_STATE_AVAILABLE_LOCAL) { xref = xdg_app_installation_install_bundle (priv->installation, gs_app_get_local_file (app), gs_plugin_xdg_app_progress_cb, app, cancellable, error); } else { g_debug ("installing %s", gs_app_get_id (app)); xref = xdg_app_installation_install (priv->installation, gs_app_get_origin (app), gs_app_get_xdgapp_kind (app), gs_app_get_xdgapp_name (app), gs_app_get_xdgapp_arch (app), gs_app_get_xdgapp_branch (app), gs_plugin_xdg_app_progress_cb, app, cancellable, error); } if (xref == NULL) { gs_app_set_state_recover (app); return FALSE; } /* state is known */ gs_app_set_state (app, AS_APP_STATE_INSTALLED); return TRUE; }