mirror of
https://github.com/flatpak/flatpak.git
synced 2026-05-24 16:57:42 -04:00
common: Break out the parts of flatpak-utils that deal with FlatpakDir
This breaks the circular dependency between flatpak-utils and flatpak-dir. There is still a circular dependency between flatpak-dir and flatpak-dir-utils, but I don't want to make flatpak-dir even larger. Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
committed by
Georges Basile Stavracas Neto
parent
3c82620bab
commit
14db9d48cf
@@ -28,6 +28,7 @@
|
||||
#include "flatpak-tty-utils-private.h"
|
||||
#include "flatpak-utils-private.h"
|
||||
#include "flatpak-dir-private.h"
|
||||
#include "flatpak-dir-utils-private.h"
|
||||
#include "flatpak-xml-utils-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -346,22 +346,6 @@ GQuark flatpak_dir_error_quark (void);
|
||||
#define FLATPAK_DEPLOY_DATA_GVARIANT_STRING "(ssasta{sv})"
|
||||
#define FLATPAK_DEPLOY_DATA_GVARIANT_FORMAT G_VARIANT_TYPE (FLATPAK_DEPLOY_DATA_GVARIANT_STRING)
|
||||
|
||||
/**
|
||||
* FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT:
|
||||
*
|
||||
* dict
|
||||
* s: subset name
|
||||
* ->
|
||||
* ay - checksum of subsummary
|
||||
* aay - previous subsummary checksums
|
||||
* a{sv} - per subset metadata
|
||||
* a{sv} - metadata
|
||||
|
||||
*/
|
||||
#define FLATPAK_SUMMARY_INDEX_GVARIANT_STRING "(a{s(ayaaya{sv})}a{sv})"
|
||||
#define FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT G_VARIANT_TYPE (FLATPAK_SUMMARY_INDEX_GVARIANT_STRING)
|
||||
|
||||
|
||||
GPtrArray *flatpak_get_system_base_dir_locations (GCancellable *cancellable,
|
||||
GError **error);
|
||||
GFile * flatpak_get_system_default_base_dir_location (void);
|
||||
|
||||
85
common/flatpak-dir-utils-private.h
Normal file
85
common/flatpak-dir-utils-private.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright © 2014 Red Hat, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser 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 library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "libglnx.h"
|
||||
|
||||
#include "flatpak-ref-utils-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *id;
|
||||
char *installed_id;
|
||||
char *commit;
|
||||
FlatpakDecomposed *ref;
|
||||
char *directory;
|
||||
char *files_path;
|
||||
char *subdir_suffix;
|
||||
char *add_ld_path;
|
||||
char **merge_dirs;
|
||||
int priority;
|
||||
gboolean needs_tmpfs;
|
||||
gboolean is_unmaintained;
|
||||
} FlatpakExtension;
|
||||
|
||||
void flatpak_extension_free (FlatpakExtension *extension);
|
||||
|
||||
FlatpakDecomposed *flatpak_find_current_ref (const char *app_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GFile *flatpak_find_deploy_dir_for_ref (FlatpakDecomposed *ref,
|
||||
FlatpakDir **dir_out,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GFile * flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GFile * flatpak_find_unmaintained_extension_dir_if_exists (const char *name,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GCancellable *cancellable);
|
||||
FlatpakDeploy * flatpak_find_deploy_for_ref_in (GPtrArray *dirs,
|
||||
const char *ref,
|
||||
const char *commit,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
FlatpakDeploy * flatpak_find_deploy_for_ref (const char *ref,
|
||||
const char *commit,
|
||||
FlatpakDir *opt_user_dir,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
char ** flatpak_list_deployed_refs (const char *type,
|
||||
const char *name_prefix,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
char ** flatpak_list_unmaintained_refs (const char *name_prefix,
|
||||
const char *branch,
|
||||
const char *arch,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GList *flatpak_list_extensions (GKeyFile *metakey,
|
||||
const char *arch,
|
||||
const char *branch);
|
||||
|
||||
void flatpak_log_dir_access (FlatpakDir *dir);
|
||||
|
||||
G_END_DECLS
|
||||
586
common/flatpak-dir-utils.c
Normal file
586
common/flatpak-dir-utils.c
Normal file
@@ -0,0 +1,586 @@
|
||||
/* vi:set et sw=2 sts=2 cin cino=t0,f0,(0,{s,>2s,n-s,^-s,e-s:
|
||||
* Copyright © 1995-1998 Free Software Foundation, Inc.
|
||||
* Copyright © 2014-2019 Red Hat, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser 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 library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "flatpak-dir-utils-private.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "flatpak-dir-private.h"
|
||||
#include "flatpak-metadata-private.h"
|
||||
#include "flatpak-utils-private.h"
|
||||
|
||||
char **
|
||||
flatpak_list_deployed_refs (const char *type,
|
||||
const char *name_prefix,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gchar **ret = NULL;
|
||||
g_autoptr(GPtrArray) names = NULL;
|
||||
g_autoptr(GHashTable) hash = NULL;
|
||||
g_autoptr(FlatpakDir) user_dir = NULL;
|
||||
g_autoptr(GPtrArray) system_dirs = NULL;
|
||||
int i;
|
||||
|
||||
hash = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);
|
||||
|
||||
user_dir = flatpak_dir_get_user ();
|
||||
system_dirs = flatpak_dir_get_system_list (cancellable, error);
|
||||
if (system_dirs == NULL)
|
||||
goto out;
|
||||
|
||||
if (!flatpak_dir_collect_deployed_refs (user_dir, type, name_prefix,
|
||||
arch, branch, hash, cancellable,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < system_dirs->len; i++)
|
||||
{
|
||||
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
|
||||
if (!flatpak_dir_collect_deployed_refs (system_dir, type, name_prefix,
|
||||
arch, branch, hash, cancellable,
|
||||
error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
names = g_ptr_array_new ();
|
||||
|
||||
GLNX_HASH_TABLE_FOREACH (hash, FlatpakDecomposed *, ref)
|
||||
{
|
||||
g_ptr_array_add (names, flatpak_decomposed_dup_id (ref));
|
||||
}
|
||||
|
||||
g_ptr_array_sort (names, flatpak_strcmp0_ptr);
|
||||
g_ptr_array_add (names, NULL);
|
||||
|
||||
ret = (char **) g_ptr_array_free (names, FALSE);
|
||||
names = NULL;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
char **
|
||||
flatpak_list_unmaintained_refs (const char *name_prefix,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gchar **ret = NULL;
|
||||
g_autoptr(GPtrArray) names = NULL;
|
||||
g_autoptr(GHashTable) hash = NULL;
|
||||
g_autoptr(FlatpakDir) user_dir = NULL;
|
||||
const char *key;
|
||||
GHashTableIter iter;
|
||||
g_autoptr(GPtrArray) system_dirs = NULL;
|
||||
int i;
|
||||
|
||||
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
|
||||
user_dir = flatpak_dir_get_user ();
|
||||
|
||||
if (!flatpak_dir_collect_unmaintained_refs (user_dir, name_prefix,
|
||||
arch, branch, hash, cancellable,
|
||||
error))
|
||||
return NULL;
|
||||
|
||||
system_dirs = flatpak_dir_get_system_list (cancellable, error);
|
||||
if (system_dirs == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < system_dirs->len; i++)
|
||||
{
|
||||
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
|
||||
|
||||
if (!flatpak_dir_collect_unmaintained_refs (system_dir, name_prefix,
|
||||
arch, branch, hash, cancellable,
|
||||
error))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
names = g_ptr_array_new ();
|
||||
g_hash_table_iter_init (&iter, hash);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
|
||||
g_ptr_array_add (names, g_strdup (key));
|
||||
|
||||
g_ptr_array_sort (names, flatpak_strcmp0_ptr);
|
||||
g_ptr_array_add (names, NULL);
|
||||
|
||||
ret = (char **) g_ptr_array_free (names, FALSE);
|
||||
names = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GFile *
|
||||
flatpak_find_deploy_dir_for_ref (FlatpakDecomposed *ref,
|
||||
FlatpakDir **dir_out,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(FlatpakDir) user_dir = NULL;
|
||||
g_autoptr(GPtrArray) system_dirs = NULL;
|
||||
FlatpakDir *dir = NULL;
|
||||
g_autoptr(GFile) deploy = NULL;
|
||||
|
||||
user_dir = flatpak_dir_get_user ();
|
||||
system_dirs = flatpak_dir_get_system_list (cancellable, error);
|
||||
if (system_dirs == NULL)
|
||||
return NULL;
|
||||
|
||||
dir = user_dir;
|
||||
deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
|
||||
if (deploy == NULL)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; deploy == NULL && i < system_dirs->len; i++)
|
||||
{
|
||||
dir = g_ptr_array_index (system_dirs, i);
|
||||
deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
|
||||
if (deploy != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (deploy == NULL)
|
||||
{
|
||||
flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), flatpak_decomposed_get_ref (ref));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dir_out)
|
||||
*dir_out = g_object_ref (dir);
|
||||
return g_steal_pointer (&deploy);
|
||||
}
|
||||
|
||||
GFile *
|
||||
flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GFile) deploy = NULL;
|
||||
|
||||
deploy = flatpak_find_deploy_dir_for_ref (ref, NULL, cancellable, error);
|
||||
if (deploy == NULL)
|
||||
return NULL;
|
||||
|
||||
return g_file_get_child (deploy, "files");
|
||||
}
|
||||
|
||||
GFile *
|
||||
flatpak_find_unmaintained_extension_dir_if_exists (const char *name,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
g_autoptr(FlatpakDir) user_dir = NULL;
|
||||
g_autoptr(GFile) extension_dir = NULL;
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
|
||||
user_dir = flatpak_dir_get_user ();
|
||||
|
||||
extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (user_dir, name, arch, branch, cancellable);
|
||||
if (extension_dir == NULL)
|
||||
{
|
||||
g_autoptr(GPtrArray) system_dirs = NULL;
|
||||
int i;
|
||||
|
||||
system_dirs = flatpak_dir_get_system_list (cancellable, &local_error);
|
||||
if (system_dirs == NULL)
|
||||
{
|
||||
g_warning ("Could not get the system installations: %s", local_error->message);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < system_dirs->len; i++)
|
||||
{
|
||||
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
|
||||
extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (system_dir, name, arch, branch, cancellable);
|
||||
if (extension_dir != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (extension_dir == NULL)
|
||||
return NULL;
|
||||
|
||||
return g_steal_pointer (&extension_dir);
|
||||
}
|
||||
|
||||
FlatpakDecomposed *
|
||||
flatpak_find_current_ref (const char *app_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(FlatpakDecomposed) current_ref = NULL;
|
||||
g_autoptr(FlatpakDir) user_dir = flatpak_dir_get_user ();
|
||||
int i;
|
||||
|
||||
current_ref = flatpak_dir_current_ref (user_dir, app_id, NULL);
|
||||
if (current_ref == NULL)
|
||||
{
|
||||
g_autoptr(GPtrArray) system_dirs = NULL;
|
||||
|
||||
system_dirs = flatpak_dir_get_system_list (cancellable, error);
|
||||
if (system_dirs == NULL)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < system_dirs->len; i++)
|
||||
{
|
||||
FlatpakDir *dir = g_ptr_array_index (system_dirs, i);
|
||||
current_ref = flatpak_dir_current_ref (dir, app_id, cancellable);
|
||||
if (current_ref != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_ref)
|
||||
return g_steal_pointer (¤t_ref);
|
||||
|
||||
flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), app_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FlatpakDeploy *
|
||||
flatpak_find_deploy_for_ref_in (GPtrArray *dirs,
|
||||
const char *ref_str,
|
||||
const char *commit,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
FlatpakDeploy *deploy = NULL;
|
||||
int i;
|
||||
g_autoptr(GError) my_error = NULL;
|
||||
|
||||
g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_ref (ref_str, error);
|
||||
if (ref == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; deploy == NULL && i < dirs->len; i++)
|
||||
{
|
||||
FlatpakDir *dir = g_ptr_array_index (dirs, i);
|
||||
|
||||
flatpak_log_dir_access (dir);
|
||||
g_clear_error (&my_error);
|
||||
deploy = flatpak_dir_load_deployed (dir, ref, commit, cancellable, &my_error);
|
||||
}
|
||||
|
||||
if (deploy == NULL)
|
||||
g_propagate_error (error, g_steal_pointer (&my_error));
|
||||
|
||||
return deploy;
|
||||
}
|
||||
|
||||
FlatpakDeploy *
|
||||
flatpak_find_deploy_for_ref (const char *ref,
|
||||
const char *commit,
|
||||
FlatpakDir *opt_user_dir,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GPtrArray) dirs = NULL;
|
||||
|
||||
dirs = flatpak_dir_get_system_list (cancellable, error);
|
||||
if (dirs == NULL)
|
||||
return NULL;
|
||||
|
||||
/* If an custom dir was passed, use that instead of the user dir.
|
||||
* This is used when running apply-extra-data where if the target
|
||||
* is a custom installation location the regular user one may not
|
||||
* have the (possibly just installed in this transaction) runtime.
|
||||
*/
|
||||
if (opt_user_dir)
|
||||
g_ptr_array_insert (dirs, 0, g_object_ref (opt_user_dir));
|
||||
else
|
||||
g_ptr_array_insert (dirs, 0, flatpak_dir_get_user ());
|
||||
|
||||
return flatpak_find_deploy_for_ref_in (dirs, ref, commit, cancellable, error);
|
||||
}
|
||||
|
||||
void
|
||||
flatpak_extension_free (FlatpakExtension *extension)
|
||||
{
|
||||
g_free (extension->id);
|
||||
g_free (extension->installed_id);
|
||||
g_free (extension->commit);
|
||||
flatpak_decomposed_unref (extension->ref);
|
||||
g_free (extension->directory);
|
||||
g_free (extension->files_path);
|
||||
g_free (extension->add_ld_path);
|
||||
g_free (extension->subdir_suffix);
|
||||
g_strfreev (extension->merge_dirs);
|
||||
g_free (extension);
|
||||
}
|
||||
|
||||
static int
|
||||
flatpak_extension_compare (gconstpointer _a,
|
||||
gconstpointer _b)
|
||||
{
|
||||
const FlatpakExtension *a = _a;
|
||||
const FlatpakExtension *b = _b;
|
||||
|
||||
return b->priority - a->priority;
|
||||
}
|
||||
|
||||
static FlatpakExtension *
|
||||
flatpak_extension_new (const char *id,
|
||||
const char *extension,
|
||||
FlatpakDecomposed *ref,
|
||||
const char *directory,
|
||||
const char *add_ld_path,
|
||||
const char *subdir_suffix,
|
||||
char **merge_dirs,
|
||||
GFile *files,
|
||||
GFile *deploy_dir,
|
||||
gboolean is_unmaintained,
|
||||
OstreeRepo *repo)
|
||||
{
|
||||
FlatpakExtension *ext = g_new0 (FlatpakExtension, 1);
|
||||
g_autoptr(GBytes) deploy_data = NULL;
|
||||
|
||||
ext->id = g_strdup (id);
|
||||
ext->installed_id = g_strdup (extension);
|
||||
ext->ref = flatpak_decomposed_ref (ref);
|
||||
ext->directory = g_strdup (directory);
|
||||
ext->files_path = g_file_get_path (files);
|
||||
ext->add_ld_path = g_strdup (add_ld_path);
|
||||
ext->subdir_suffix = g_strdup (subdir_suffix);
|
||||
ext->merge_dirs = g_strdupv (merge_dirs);
|
||||
ext->is_unmaintained = is_unmaintained;
|
||||
|
||||
/* Unmaintained extensions won't have a deploy or commit; see
|
||||
* https://github.com/flatpak/flatpak/issues/167 */
|
||||
if (deploy_dir && !is_unmaintained)
|
||||
{
|
||||
deploy_data = flatpak_load_deploy_data (deploy_dir, ref, repo, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);
|
||||
if (deploy_data)
|
||||
ext->commit = g_strdup (flatpak_deploy_data_get_commit (deploy_data));
|
||||
}
|
||||
|
||||
if (is_unmaintained)
|
||||
ext->priority = 1000;
|
||||
else
|
||||
{
|
||||
g_autoptr(GKeyFile) keyfile = g_key_file_new ();
|
||||
g_autofree char *metadata_path = g_build_filename (ext->files_path, "../metadata", NULL);
|
||||
|
||||
if (g_key_file_load_from_file (keyfile, metadata_path, G_KEY_FILE_NONE, NULL))
|
||||
ext->priority = g_key_file_get_integer (keyfile,
|
||||
FLATPAK_METADATA_GROUP_EXTENSION_OF,
|
||||
FLATPAK_METADATA_KEY_PRIORITY,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return ext;
|
||||
}
|
||||
|
||||
static GList *
|
||||
add_extension (GKeyFile *metakey,
|
||||
const char *group,
|
||||
const char *extension,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GList *res)
|
||||
{
|
||||
FlatpakExtension *ext;
|
||||
g_autofree char *directory = g_key_file_get_string (metakey, group,
|
||||
FLATPAK_METADATA_KEY_DIRECTORY,
|
||||
NULL);
|
||||
g_autofree char *add_ld_path = g_key_file_get_string (metakey, group,
|
||||
FLATPAK_METADATA_KEY_ADD_LD_PATH,
|
||||
NULL);
|
||||
g_auto(GStrv) merge_dirs = g_key_file_get_string_list (metakey, group,
|
||||
FLATPAK_METADATA_KEY_MERGE_DIRS,
|
||||
NULL, NULL);
|
||||
g_autofree char *enable_if = g_key_file_get_string (metakey, group,
|
||||
FLATPAK_METADATA_KEY_ENABLE_IF,
|
||||
NULL);
|
||||
g_autofree char *subdir_suffix = g_key_file_get_string (metakey, group,
|
||||
FLATPAK_METADATA_KEY_SUBDIRECTORY_SUFFIX,
|
||||
NULL);
|
||||
g_autoptr(FlatpakDecomposed) ref = NULL;
|
||||
gboolean is_unmaintained = FALSE;
|
||||
g_autoptr(GFile) files = NULL;
|
||||
g_autoptr(GFile) deploy_dir = NULL;
|
||||
g_autoptr(FlatpakDir) dir = NULL;
|
||||
|
||||
if (directory == NULL)
|
||||
return res;
|
||||
|
||||
ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, extension, arch, branch, NULL);
|
||||
if (ref == NULL)
|
||||
return res;
|
||||
|
||||
files = flatpak_find_unmaintained_extension_dir_if_exists (extension, arch, branch, NULL);
|
||||
|
||||
if (files == NULL)
|
||||
{
|
||||
deploy_dir = flatpak_find_deploy_dir_for_ref (ref, &dir, NULL, NULL);
|
||||
if (deploy_dir)
|
||||
files = g_file_get_child (deploy_dir, "files");
|
||||
}
|
||||
else
|
||||
is_unmaintained = TRUE;
|
||||
|
||||
/* Prefer a full extension (org.freedesktop.Locale) over subdirectory ones (org.freedesktop.Locale.sv) */
|
||||
if (files != NULL)
|
||||
{
|
||||
if (flatpak_extension_matches_reason (extension, enable_if, TRUE))
|
||||
{
|
||||
ext = flatpak_extension_new (extension, extension, ref, directory,
|
||||
add_ld_path, subdir_suffix, merge_dirs,
|
||||
files, deploy_dir, is_unmaintained,
|
||||
is_unmaintained ? NULL : flatpak_dir_get_repo (dir));
|
||||
res = g_list_prepend (res, ext);
|
||||
}
|
||||
}
|
||||
else if (g_key_file_get_boolean (metakey, group,
|
||||
FLATPAK_METADATA_KEY_SUBDIRECTORIES, NULL))
|
||||
{
|
||||
g_autofree char *prefix = g_strconcat (extension, ".", NULL);
|
||||
g_auto(GStrv) ids = NULL;
|
||||
g_auto(GStrv) unmaintained_refs = NULL;
|
||||
int j;
|
||||
|
||||
ids = flatpak_list_deployed_refs ("runtime", prefix, arch, branch,
|
||||
NULL, NULL);
|
||||
for (j = 0; ids != NULL && ids[j] != NULL; j++)
|
||||
{
|
||||
const char *id = ids[j];
|
||||
g_autofree char *extended_dir = g_build_filename (directory, id + strlen (prefix), NULL);
|
||||
g_autoptr(FlatpakDecomposed) dir_ref = NULL;
|
||||
g_autoptr(GFile) subdir_deploy_dir = NULL;
|
||||
g_autoptr(GFile) subdir_files = NULL;
|
||||
g_autoptr(FlatpakDir) subdir_dir = NULL;
|
||||
|
||||
dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, id, arch, branch, NULL);
|
||||
if (dir_ref == NULL)
|
||||
continue;
|
||||
|
||||
subdir_deploy_dir = flatpak_find_deploy_dir_for_ref (dir_ref, &subdir_dir, NULL, NULL);
|
||||
if (subdir_deploy_dir)
|
||||
subdir_files = g_file_get_child (subdir_deploy_dir, "files");
|
||||
|
||||
if (subdir_files && flatpak_extension_matches_reason (id, enable_if, TRUE))
|
||||
{
|
||||
ext = flatpak_extension_new (extension, id, dir_ref, extended_dir,
|
||||
add_ld_path, subdir_suffix, merge_dirs,
|
||||
subdir_files, subdir_deploy_dir, FALSE,
|
||||
flatpak_dir_get_repo (subdir_dir));
|
||||
ext->needs_tmpfs = TRUE;
|
||||
res = g_list_prepend (res, ext);
|
||||
}
|
||||
}
|
||||
|
||||
unmaintained_refs = flatpak_list_unmaintained_refs (prefix, arch, branch,
|
||||
NULL, NULL);
|
||||
for (j = 0; unmaintained_refs != NULL && unmaintained_refs[j] != NULL; j++)
|
||||
{
|
||||
g_autofree char *extended_dir = g_build_filename (directory, unmaintained_refs[j] + strlen (prefix), NULL);
|
||||
g_autoptr(FlatpakDecomposed) dir_ref = NULL;
|
||||
g_autoptr(GFile) subdir_files = flatpak_find_unmaintained_extension_dir_if_exists (unmaintained_refs[j], arch, branch, NULL);
|
||||
|
||||
dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, unmaintained_refs[j], arch, branch, NULL);
|
||||
if (dir_ref == NULL)
|
||||
continue;
|
||||
|
||||
if (subdir_files && flatpak_extension_matches_reason (unmaintained_refs[j], enable_if, TRUE))
|
||||
{
|
||||
ext = flatpak_extension_new (extension, unmaintained_refs[j], dir_ref,
|
||||
extended_dir, add_ld_path, subdir_suffix,
|
||||
merge_dirs, subdir_files, NULL, TRUE, NULL);
|
||||
ext->needs_tmpfs = TRUE;
|
||||
res = g_list_prepend (res, ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
GList *
|
||||
flatpak_list_extensions (GKeyFile *metakey,
|
||||
const char *arch,
|
||||
const char *default_branch)
|
||||
{
|
||||
g_auto(GStrv) groups = NULL;
|
||||
int i, j;
|
||||
GList *res;
|
||||
|
||||
res = NULL;
|
||||
|
||||
if (arch == NULL)
|
||||
arch = flatpak_get_arch ();
|
||||
|
||||
groups = g_key_file_get_groups (metakey, NULL);
|
||||
for (i = 0; groups[i] != NULL; i++)
|
||||
{
|
||||
char *extension;
|
||||
|
||||
if (g_str_has_prefix (groups[i], FLATPAK_METADATA_GROUP_PREFIX_EXTENSION) &&
|
||||
*(extension = (groups[i] + strlen (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION))) != 0)
|
||||
{
|
||||
g_autofree char *version = g_key_file_get_string (metakey, groups[i],
|
||||
FLATPAK_METADATA_KEY_VERSION,
|
||||
NULL);
|
||||
g_auto(GStrv) versions = g_key_file_get_string_list (metakey, groups[i],
|
||||
FLATPAK_METADATA_KEY_VERSIONS,
|
||||
NULL, NULL);
|
||||
g_autofree char *name = NULL;
|
||||
const char *default_branches[] = { default_branch, NULL};
|
||||
const char **branches;
|
||||
|
||||
flatpak_parse_extension_with_tag (extension, &name, NULL);
|
||||
|
||||
if (versions)
|
||||
branches = (const char **) versions;
|
||||
else
|
||||
{
|
||||
if (version)
|
||||
default_branches[0] = version;
|
||||
branches = default_branches;
|
||||
}
|
||||
|
||||
for (j = 0; branches[j] != NULL; j++)
|
||||
res = add_extension (metakey, groups[i], name, arch, branches[j], res);
|
||||
}
|
||||
}
|
||||
|
||||
return g_list_sort (g_list_reverse (res), flatpak_extension_compare);
|
||||
}
|
||||
|
||||
void
|
||||
flatpak_log_dir_access (FlatpakDir *dir)
|
||||
{
|
||||
if (dir != NULL)
|
||||
{
|
||||
GFile *dir_path = NULL;
|
||||
g_autofree char *dir_path_str = NULL;
|
||||
g_autofree char *dir_name = NULL;
|
||||
|
||||
dir_path = flatpak_dir_get_path (dir);
|
||||
if (dir_path != NULL)
|
||||
dir_path_str = g_file_get_path (dir_path);
|
||||
dir_name = flatpak_dir_get_name (dir);
|
||||
g_info ("Opening %s flatpak installation at path %s", dir_name, dir_path_str);
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@
|
||||
|
||||
#include "flatpak-appdata-private.h"
|
||||
#include "flatpak-dir-private.h"
|
||||
#include "flatpak-dir-utils-private.h"
|
||||
#include "flatpak-error.h"
|
||||
#include "flatpak-locale-utils-private.h"
|
||||
#include "flatpak-oci-registry-private.h"
|
||||
@@ -8330,6 +8331,9 @@ apply_extra_data (FlatpakDir *self,
|
||||
{
|
||||
/* We pass in self here so that we ensure that we find the runtime in case it only
|
||||
exists in this installation (which might be custom) */
|
||||
/* TODO: This is a circular dependency between flatpak-dir (which
|
||||
* deals with a single installation) and flatpak-dir-utils (which
|
||||
* deals with all the installations on the system). */
|
||||
runtime_deploy = flatpak_find_deploy_for_ref (flatpak_decomposed_get_ref (runtime_ref), NULL, self, cancellable, error);
|
||||
if (runtime_deploy == NULL)
|
||||
return FALSE;
|
||||
@@ -15470,6 +15474,9 @@ add_related (FlatpakDir *self,
|
||||
auto_prune = TRUE;
|
||||
|
||||
/* Don't download if there is an unmaintained extension already installed */
|
||||
/* TODO: This is a circular dependency between flatpak-dir (which
|
||||
* deals with a single installation) and flatpak-dir-utils (which
|
||||
* deals with all the installations on the system). */
|
||||
unmaintained_path =
|
||||
flatpak_find_unmaintained_extension_dir_if_exists (id, arch, branch, NULL);
|
||||
if (unmaintained_path != NULL && deploy_data == NULL)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
#include "flatpak-dir-private.h"
|
||||
#include "flatpak-json-oci-private.h"
|
||||
#include "flatpak-utils-http-private.h"
|
||||
#include "flatpak-utils-private.h"
|
||||
|
||||
@@ -22,6 +22,21 @@
|
||||
|
||||
#include "libglnx.h"
|
||||
|
||||
/**
|
||||
* FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT:
|
||||
*
|
||||
* dict
|
||||
* s: subset name
|
||||
* ->
|
||||
* ay - checksum of subsummary
|
||||
* aay - previous subsummary checksums
|
||||
* a{sv} - per subset metadata
|
||||
* a{sv} - metadata
|
||||
|
||||
*/
|
||||
#define FLATPAK_SUMMARY_INDEX_GVARIANT_STRING "(a{s(ayaaya{sv})}a{sv})"
|
||||
#define FLATPAK_SUMMARY_INDEX_GVARIANT_FORMAT G_VARIANT_TYPE (FLATPAK_SUMMARY_INDEX_GVARIANT_STRING)
|
||||
|
||||
#define FLATPAK_REF_GROUP "Flatpak Ref"
|
||||
#define FLATPAK_REF_VERSION_KEY "Version"
|
||||
#define FLATPAK_REF_URL_KEY "Url"
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include "flatpak-run-sockets-private.h"
|
||||
#include "flatpak-utils-base-private.h"
|
||||
#include "flatpak-dir-private.h"
|
||||
#include "flatpak-dir-utils-private.h"
|
||||
#include "flatpak-instance-private.h"
|
||||
#include "flatpak-systemd-dbus-generated.h"
|
||||
#include "flatpak-document-dbus-generated.h"
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
#include <gio/gunixfdlist.h>
|
||||
#include "flatpak-error.h"
|
||||
#include "flatpak-glib-backports-private.h"
|
||||
#include "flatpak-ref-utils-private.h"
|
||||
#include "flatpak-variant-private.h"
|
||||
#include "flatpak-dir-private.h"
|
||||
#include <ostree.h>
|
||||
|
||||
#define AUTOFS_SUPER_MAGIC 0x0187
|
||||
@@ -138,42 +138,6 @@ gboolean flatpak_var_ref_map_lookup_ref (VarRefMapRef ref_map,
|
||||
const char *ref,
|
||||
VarRefInfoRef *out_info);
|
||||
|
||||
FlatpakDecomposed *flatpak_find_current_ref (const char *app_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GFile *flatpak_find_deploy_dir_for_ref (FlatpakDecomposed *ref,
|
||||
FlatpakDir **dir_out,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GFile * flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GFile * flatpak_find_unmaintained_extension_dir_if_exists (const char *name,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GCancellable *cancellable);
|
||||
FlatpakDeploy * flatpak_find_deploy_for_ref_in (GPtrArray *dirs,
|
||||
const char *ref,
|
||||
const char *commit,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
FlatpakDeploy * flatpak_find_deploy_for_ref (const char *ref,
|
||||
const char *commit,
|
||||
FlatpakDir *opt_user_dir,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
char ** flatpak_list_deployed_refs (const char *type,
|
||||
const char *name_prefix,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
char ** flatpak_list_unmaintained_refs (const char *name_prefix,
|
||||
const char *branch,
|
||||
const char *arch,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean flatpak_remove_dangling_symlinks (GFile *dir,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
@@ -358,32 +322,10 @@ gboolean flatpak_pull_from_bundle (OstreeRepo *repo,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *id;
|
||||
char *installed_id;
|
||||
char *commit;
|
||||
FlatpakDecomposed *ref;
|
||||
char *directory;
|
||||
char *files_path;
|
||||
char *subdir_suffix;
|
||||
char *add_ld_path;
|
||||
char **merge_dirs;
|
||||
int priority;
|
||||
gboolean needs_tmpfs;
|
||||
gboolean is_unmaintained;
|
||||
} FlatpakExtension;
|
||||
|
||||
void flatpak_extension_free (FlatpakExtension *extension);
|
||||
|
||||
void flatpak_parse_extension_with_tag (const char *extension,
|
||||
char **name,
|
||||
char **tag);
|
||||
|
||||
GList *flatpak_list_extensions (GKeyFile *metakey,
|
||||
const char *arch,
|
||||
const char *branch);
|
||||
|
||||
gboolean flatpak_argument_needs_quoting (const char *arg);
|
||||
char * flatpak_quote_argv (const char *argv[],
|
||||
gssize len);
|
||||
@@ -560,8 +502,6 @@ typedef OstreeAsyncProgress OstreeAsyncProgressFinish;
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeAsyncProgressFinish, flatpak_ostree_progress_finish);
|
||||
|
||||
|
||||
void flatpak_log_dir_access (FlatpakDir *dir);
|
||||
|
||||
gboolean flatpak_check_required_version (const char *ref,
|
||||
GKeyFile *metakey,
|
||||
GError **error);
|
||||
|
||||
@@ -43,9 +43,7 @@
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include <gio/gunixinputstream.h>
|
||||
|
||||
#include "flatpak-dir-private.h"
|
||||
#include "flatpak-error.h"
|
||||
#include "flatpak-metadata-private.h"
|
||||
#include "flatpak-repo-utils-private.h"
|
||||
#include "flatpak-utils-base-private.h"
|
||||
#include "flatpak-utils-private.h"
|
||||
@@ -864,297 +862,6 @@ flatpak_filters_allow_ref (GRegex *allow_refs,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char **
|
||||
flatpak_list_deployed_refs (const char *type,
|
||||
const char *name_prefix,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gchar **ret = NULL;
|
||||
g_autoptr(GPtrArray) names = NULL;
|
||||
g_autoptr(GHashTable) hash = NULL;
|
||||
g_autoptr(FlatpakDir) user_dir = NULL;
|
||||
g_autoptr(GPtrArray) system_dirs = NULL;
|
||||
int i;
|
||||
|
||||
hash = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal, (GDestroyNotify)flatpak_decomposed_unref, NULL);
|
||||
|
||||
user_dir = flatpak_dir_get_user ();
|
||||
system_dirs = flatpak_dir_get_system_list (cancellable, error);
|
||||
if (system_dirs == NULL)
|
||||
goto out;
|
||||
|
||||
if (!flatpak_dir_collect_deployed_refs (user_dir, type, name_prefix,
|
||||
arch, branch, hash, cancellable,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < system_dirs->len; i++)
|
||||
{
|
||||
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
|
||||
if (!flatpak_dir_collect_deployed_refs (system_dir, type, name_prefix,
|
||||
arch, branch, hash, cancellable,
|
||||
error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
names = g_ptr_array_new ();
|
||||
|
||||
GLNX_HASH_TABLE_FOREACH (hash, FlatpakDecomposed *, ref)
|
||||
{
|
||||
g_ptr_array_add (names, flatpak_decomposed_dup_id (ref));
|
||||
}
|
||||
|
||||
g_ptr_array_sort (names, flatpak_strcmp0_ptr);
|
||||
g_ptr_array_add (names, NULL);
|
||||
|
||||
ret = (char **) g_ptr_array_free (names, FALSE);
|
||||
names = NULL;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
char **
|
||||
flatpak_list_unmaintained_refs (const char *name_prefix,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gchar **ret = NULL;
|
||||
g_autoptr(GPtrArray) names = NULL;
|
||||
g_autoptr(GHashTable) hash = NULL;
|
||||
g_autoptr(FlatpakDir) user_dir = NULL;
|
||||
const char *key;
|
||||
GHashTableIter iter;
|
||||
g_autoptr(GPtrArray) system_dirs = NULL;
|
||||
int i;
|
||||
|
||||
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
|
||||
user_dir = flatpak_dir_get_user ();
|
||||
|
||||
if (!flatpak_dir_collect_unmaintained_refs (user_dir, name_prefix,
|
||||
arch, branch, hash, cancellable,
|
||||
error))
|
||||
return NULL;
|
||||
|
||||
system_dirs = flatpak_dir_get_system_list (cancellable, error);
|
||||
if (system_dirs == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < system_dirs->len; i++)
|
||||
{
|
||||
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
|
||||
|
||||
if (!flatpak_dir_collect_unmaintained_refs (system_dir, name_prefix,
|
||||
arch, branch, hash, cancellable,
|
||||
error))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
names = g_ptr_array_new ();
|
||||
g_hash_table_iter_init (&iter, hash);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
|
||||
g_ptr_array_add (names, g_strdup (key));
|
||||
|
||||
g_ptr_array_sort (names, flatpak_strcmp0_ptr);
|
||||
g_ptr_array_add (names, NULL);
|
||||
|
||||
ret = (char **) g_ptr_array_free (names, FALSE);
|
||||
names = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GFile *
|
||||
flatpak_find_deploy_dir_for_ref (FlatpakDecomposed *ref,
|
||||
FlatpakDir **dir_out,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(FlatpakDir) user_dir = NULL;
|
||||
g_autoptr(GPtrArray) system_dirs = NULL;
|
||||
FlatpakDir *dir = NULL;
|
||||
g_autoptr(GFile) deploy = NULL;
|
||||
|
||||
user_dir = flatpak_dir_get_user ();
|
||||
system_dirs = flatpak_dir_get_system_list (cancellable, error);
|
||||
if (system_dirs == NULL)
|
||||
return NULL;
|
||||
|
||||
dir = user_dir;
|
||||
deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
|
||||
if (deploy == NULL)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; deploy == NULL && i < system_dirs->len; i++)
|
||||
{
|
||||
dir = g_ptr_array_index (system_dirs, i);
|
||||
deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable);
|
||||
if (deploy != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (deploy == NULL)
|
||||
{
|
||||
flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), flatpak_decomposed_get_ref (ref));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dir_out)
|
||||
*dir_out = g_object_ref (dir);
|
||||
return g_steal_pointer (&deploy);
|
||||
}
|
||||
|
||||
GFile *
|
||||
flatpak_find_files_dir_for_ref (FlatpakDecomposed *ref,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GFile) deploy = NULL;
|
||||
|
||||
deploy = flatpak_find_deploy_dir_for_ref (ref, NULL, cancellable, error);
|
||||
if (deploy == NULL)
|
||||
return NULL;
|
||||
|
||||
return g_file_get_child (deploy, "files");
|
||||
}
|
||||
|
||||
GFile *
|
||||
flatpak_find_unmaintained_extension_dir_if_exists (const char *name,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
g_autoptr(FlatpakDir) user_dir = NULL;
|
||||
g_autoptr(GFile) extension_dir = NULL;
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
|
||||
user_dir = flatpak_dir_get_user ();
|
||||
|
||||
extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (user_dir, name, arch, branch, cancellable);
|
||||
if (extension_dir == NULL)
|
||||
{
|
||||
g_autoptr(GPtrArray) system_dirs = NULL;
|
||||
int i;
|
||||
|
||||
system_dirs = flatpak_dir_get_system_list (cancellable, &local_error);
|
||||
if (system_dirs == NULL)
|
||||
{
|
||||
g_warning ("Could not get the system installations: %s", local_error->message);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < system_dirs->len; i++)
|
||||
{
|
||||
FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i);
|
||||
extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (system_dir, name, arch, branch, cancellable);
|
||||
if (extension_dir != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (extension_dir == NULL)
|
||||
return NULL;
|
||||
|
||||
return g_steal_pointer (&extension_dir);
|
||||
}
|
||||
|
||||
FlatpakDecomposed *
|
||||
flatpak_find_current_ref (const char *app_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(FlatpakDecomposed) current_ref = NULL;
|
||||
g_autoptr(FlatpakDir) user_dir = flatpak_dir_get_user ();
|
||||
int i;
|
||||
|
||||
current_ref = flatpak_dir_current_ref (user_dir, app_id, NULL);
|
||||
if (current_ref == NULL)
|
||||
{
|
||||
g_autoptr(GPtrArray) system_dirs = NULL;
|
||||
|
||||
system_dirs = flatpak_dir_get_system_list (cancellable, error);
|
||||
if (system_dirs == NULL)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < system_dirs->len; i++)
|
||||
{
|
||||
FlatpakDir *dir = g_ptr_array_index (system_dirs, i);
|
||||
current_ref = flatpak_dir_current_ref (dir, app_id, cancellable);
|
||||
if (current_ref != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_ref)
|
||||
return g_steal_pointer (¤t_ref);
|
||||
|
||||
flatpak_fail_error (error, FLATPAK_ERROR_NOT_INSTALLED, _("%s not installed"), app_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FlatpakDeploy *
|
||||
flatpak_find_deploy_for_ref_in (GPtrArray *dirs,
|
||||
const char *ref_str,
|
||||
const char *commit,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
FlatpakDeploy *deploy = NULL;
|
||||
int i;
|
||||
g_autoptr(GError) my_error = NULL;
|
||||
|
||||
g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_ref (ref_str, error);
|
||||
if (ref == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; deploy == NULL && i < dirs->len; i++)
|
||||
{
|
||||
FlatpakDir *dir = g_ptr_array_index (dirs, i);
|
||||
|
||||
flatpak_log_dir_access (dir);
|
||||
g_clear_error (&my_error);
|
||||
deploy = flatpak_dir_load_deployed (dir, ref, commit, cancellable, &my_error);
|
||||
}
|
||||
|
||||
if (deploy == NULL)
|
||||
g_propagate_error (error, g_steal_pointer (&my_error));
|
||||
|
||||
return deploy;
|
||||
}
|
||||
|
||||
FlatpakDeploy *
|
||||
flatpak_find_deploy_for_ref (const char *ref,
|
||||
const char *commit,
|
||||
FlatpakDir *opt_user_dir,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GPtrArray) dirs = NULL;
|
||||
|
||||
dirs = flatpak_dir_get_system_list (cancellable, error);
|
||||
if (dirs == NULL)
|
||||
return NULL;
|
||||
|
||||
/* If an custom dir was passed, use that instead of the user dir.
|
||||
* This is used when running apply-extra-data where if the target
|
||||
* is a custom installation location the regular user one may not
|
||||
* have the (possibly just installed in this transaction) runtime.
|
||||
*/
|
||||
if (opt_user_dir)
|
||||
g_ptr_array_insert (dirs, 0, g_object_ref (opt_user_dir));
|
||||
else
|
||||
g_ptr_array_insert (dirs, 0, flatpak_dir_get_user ());
|
||||
|
||||
return flatpak_find_deploy_for_ref_in (dirs, ref, commit, cancellable, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
remove_dangling_symlinks (int parent_fd,
|
||||
const char *name,
|
||||
@@ -5494,83 +5201,6 @@ flatpak_repo_generate_appstream (OstreeRepo *repo,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
flatpak_extension_free (FlatpakExtension *extension)
|
||||
{
|
||||
g_free (extension->id);
|
||||
g_free (extension->installed_id);
|
||||
g_free (extension->commit);
|
||||
flatpak_decomposed_unref (extension->ref);
|
||||
g_free (extension->directory);
|
||||
g_free (extension->files_path);
|
||||
g_free (extension->add_ld_path);
|
||||
g_free (extension->subdir_suffix);
|
||||
g_strfreev (extension->merge_dirs);
|
||||
g_free (extension);
|
||||
}
|
||||
|
||||
static int
|
||||
flatpak_extension_compare (gconstpointer _a,
|
||||
gconstpointer _b)
|
||||
{
|
||||
const FlatpakExtension *a = _a;
|
||||
const FlatpakExtension *b = _b;
|
||||
|
||||
return b->priority - a->priority;
|
||||
}
|
||||
|
||||
static FlatpakExtension *
|
||||
flatpak_extension_new (const char *id,
|
||||
const char *extension,
|
||||
FlatpakDecomposed *ref,
|
||||
const char *directory,
|
||||
const char *add_ld_path,
|
||||
const char *subdir_suffix,
|
||||
char **merge_dirs,
|
||||
GFile *files,
|
||||
GFile *deploy_dir,
|
||||
gboolean is_unmaintained,
|
||||
OstreeRepo *repo)
|
||||
{
|
||||
FlatpakExtension *ext = g_new0 (FlatpakExtension, 1);
|
||||
g_autoptr(GBytes) deploy_data = NULL;
|
||||
|
||||
ext->id = g_strdup (id);
|
||||
ext->installed_id = g_strdup (extension);
|
||||
ext->ref = flatpak_decomposed_ref (ref);
|
||||
ext->directory = g_strdup (directory);
|
||||
ext->files_path = g_file_get_path (files);
|
||||
ext->add_ld_path = g_strdup (add_ld_path);
|
||||
ext->subdir_suffix = g_strdup (subdir_suffix);
|
||||
ext->merge_dirs = g_strdupv (merge_dirs);
|
||||
ext->is_unmaintained = is_unmaintained;
|
||||
|
||||
/* Unmaintained extensions won't have a deploy or commit; see
|
||||
* https://github.com/flatpak/flatpak/issues/167 */
|
||||
if (deploy_dir && !is_unmaintained)
|
||||
{
|
||||
deploy_data = flatpak_load_deploy_data (deploy_dir, ref, repo, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL);
|
||||
if (deploy_data)
|
||||
ext->commit = g_strdup (flatpak_deploy_data_get_commit (deploy_data));
|
||||
}
|
||||
|
||||
if (is_unmaintained)
|
||||
ext->priority = 1000;
|
||||
else
|
||||
{
|
||||
g_autoptr(GKeyFile) keyfile = g_key_file_new ();
|
||||
g_autofree char *metadata_path = g_build_filename (ext->files_path, "../metadata", NULL);
|
||||
|
||||
if (g_key_file_load_from_file (keyfile, metadata_path, G_KEY_FILE_NONE, NULL))
|
||||
ext->priority = g_key_file_get_integer (keyfile,
|
||||
FLATPAK_METADATA_GROUP_EXTENSION_OF,
|
||||
FLATPAK_METADATA_KEY_PRIORITY,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return ext;
|
||||
}
|
||||
|
||||
gboolean
|
||||
flatpak_extension_matches_reason (const char *extension_id,
|
||||
const char *reasons,
|
||||
@@ -5648,130 +5278,6 @@ flatpak_extension_matches_reason (const char *extension_id,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GList *
|
||||
add_extension (GKeyFile *metakey,
|
||||
const char *group,
|
||||
const char *extension,
|
||||
const char *arch,
|
||||
const char *branch,
|
||||
GList *res)
|
||||
{
|
||||
FlatpakExtension *ext;
|
||||
g_autofree char *directory = g_key_file_get_string (metakey, group,
|
||||
FLATPAK_METADATA_KEY_DIRECTORY,
|
||||
NULL);
|
||||
g_autofree char *add_ld_path = g_key_file_get_string (metakey, group,
|
||||
FLATPAK_METADATA_KEY_ADD_LD_PATH,
|
||||
NULL);
|
||||
g_auto(GStrv) merge_dirs = g_key_file_get_string_list (metakey, group,
|
||||
FLATPAK_METADATA_KEY_MERGE_DIRS,
|
||||
NULL, NULL);
|
||||
g_autofree char *enable_if = g_key_file_get_string (metakey, group,
|
||||
FLATPAK_METADATA_KEY_ENABLE_IF,
|
||||
NULL);
|
||||
g_autofree char *subdir_suffix = g_key_file_get_string (metakey, group,
|
||||
FLATPAK_METADATA_KEY_SUBDIRECTORY_SUFFIX,
|
||||
NULL);
|
||||
g_autoptr(FlatpakDecomposed) ref = NULL;
|
||||
gboolean is_unmaintained = FALSE;
|
||||
g_autoptr(GFile) files = NULL;
|
||||
g_autoptr(GFile) deploy_dir = NULL;
|
||||
g_autoptr(FlatpakDir) dir = NULL;
|
||||
|
||||
if (directory == NULL)
|
||||
return res;
|
||||
|
||||
ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, extension, arch, branch, NULL);
|
||||
if (ref == NULL)
|
||||
return res;
|
||||
|
||||
files = flatpak_find_unmaintained_extension_dir_if_exists (extension, arch, branch, NULL);
|
||||
|
||||
if (files == NULL)
|
||||
{
|
||||
deploy_dir = flatpak_find_deploy_dir_for_ref (ref, &dir, NULL, NULL);
|
||||
if (deploy_dir)
|
||||
files = g_file_get_child (deploy_dir, "files");
|
||||
}
|
||||
else
|
||||
is_unmaintained = TRUE;
|
||||
|
||||
/* Prefer a full extension (org.freedesktop.Locale) over subdirectory ones (org.freedesktop.Locale.sv) */
|
||||
if (files != NULL)
|
||||
{
|
||||
if (flatpak_extension_matches_reason (extension, enable_if, TRUE))
|
||||
{
|
||||
ext = flatpak_extension_new (extension, extension, ref, directory,
|
||||
add_ld_path, subdir_suffix, merge_dirs,
|
||||
files, deploy_dir, is_unmaintained,
|
||||
is_unmaintained ? NULL : flatpak_dir_get_repo (dir));
|
||||
res = g_list_prepend (res, ext);
|
||||
}
|
||||
}
|
||||
else if (g_key_file_get_boolean (metakey, group,
|
||||
FLATPAK_METADATA_KEY_SUBDIRECTORIES, NULL))
|
||||
{
|
||||
g_autofree char *prefix = g_strconcat (extension, ".", NULL);
|
||||
g_auto(GStrv) ids = NULL;
|
||||
g_auto(GStrv) unmaintained_refs = NULL;
|
||||
int j;
|
||||
|
||||
ids = flatpak_list_deployed_refs ("runtime", prefix, arch, branch,
|
||||
NULL, NULL);
|
||||
for (j = 0; ids != NULL && ids[j] != NULL; j++)
|
||||
{
|
||||
const char *id = ids[j];
|
||||
g_autofree char *extended_dir = g_build_filename (directory, id + strlen (prefix), NULL);
|
||||
g_autoptr(FlatpakDecomposed) dir_ref = NULL;
|
||||
g_autoptr(GFile) subdir_deploy_dir = NULL;
|
||||
g_autoptr(GFile) subdir_files = NULL;
|
||||
g_autoptr(FlatpakDir) subdir_dir = NULL;
|
||||
|
||||
dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, id, arch, branch, NULL);
|
||||
if (dir_ref == NULL)
|
||||
continue;
|
||||
|
||||
subdir_deploy_dir = flatpak_find_deploy_dir_for_ref (dir_ref, &subdir_dir, NULL, NULL);
|
||||
if (subdir_deploy_dir)
|
||||
subdir_files = g_file_get_child (subdir_deploy_dir, "files");
|
||||
|
||||
if (subdir_files && flatpak_extension_matches_reason (id, enable_if, TRUE))
|
||||
{
|
||||
ext = flatpak_extension_new (extension, id, dir_ref, extended_dir,
|
||||
add_ld_path, subdir_suffix, merge_dirs,
|
||||
subdir_files, subdir_deploy_dir, FALSE,
|
||||
flatpak_dir_get_repo (subdir_dir));
|
||||
ext->needs_tmpfs = TRUE;
|
||||
res = g_list_prepend (res, ext);
|
||||
}
|
||||
}
|
||||
|
||||
unmaintained_refs = flatpak_list_unmaintained_refs (prefix, arch, branch,
|
||||
NULL, NULL);
|
||||
for (j = 0; unmaintained_refs != NULL && unmaintained_refs[j] != NULL; j++)
|
||||
{
|
||||
g_autofree char *extended_dir = g_build_filename (directory, unmaintained_refs[j] + strlen (prefix), NULL);
|
||||
g_autoptr(FlatpakDecomposed) dir_ref = NULL;
|
||||
g_autoptr(GFile) subdir_files = flatpak_find_unmaintained_extension_dir_if_exists (unmaintained_refs[j], arch, branch, NULL);
|
||||
|
||||
dir_ref = flatpak_decomposed_new_from_parts (FLATPAK_KINDS_RUNTIME, unmaintained_refs[j], arch, branch, NULL);
|
||||
if (dir_ref == NULL)
|
||||
continue;
|
||||
|
||||
if (subdir_files && flatpak_extension_matches_reason (unmaintained_refs[j], enable_if, TRUE))
|
||||
{
|
||||
ext = flatpak_extension_new (extension, unmaintained_refs[j], dir_ref,
|
||||
extended_dir, add_ld_path, subdir_suffix,
|
||||
merge_dirs, subdir_files, NULL, TRUE, NULL);
|
||||
ext->needs_tmpfs = TRUE;
|
||||
res = g_list_prepend (res, ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
flatpak_parse_extension_with_tag (const char *extension,
|
||||
char **name,
|
||||
@@ -5798,57 +5304,6 @@ flatpak_parse_extension_with_tag (const char *extension,
|
||||
*tag = NULL;
|
||||
}
|
||||
|
||||
GList *
|
||||
flatpak_list_extensions (GKeyFile *metakey,
|
||||
const char *arch,
|
||||
const char *default_branch)
|
||||
{
|
||||
g_auto(GStrv) groups = NULL;
|
||||
int i, j;
|
||||
GList *res;
|
||||
|
||||
res = NULL;
|
||||
|
||||
if (arch == NULL)
|
||||
arch = flatpak_get_arch ();
|
||||
|
||||
groups = g_key_file_get_groups (metakey, NULL);
|
||||
for (i = 0; groups[i] != NULL; i++)
|
||||
{
|
||||
char *extension;
|
||||
|
||||
if (g_str_has_prefix (groups[i], FLATPAK_METADATA_GROUP_PREFIX_EXTENSION) &&
|
||||
*(extension = (groups[i] + strlen (FLATPAK_METADATA_GROUP_PREFIX_EXTENSION))) != 0)
|
||||
{
|
||||
g_autofree char *version = g_key_file_get_string (metakey, groups[i],
|
||||
FLATPAK_METADATA_KEY_VERSION,
|
||||
NULL);
|
||||
g_auto(GStrv) versions = g_key_file_get_string_list (metakey, groups[i],
|
||||
FLATPAK_METADATA_KEY_VERSIONS,
|
||||
NULL, NULL);
|
||||
g_autofree char *name = NULL;
|
||||
const char *default_branches[] = { default_branch, NULL};
|
||||
const char **branches;
|
||||
|
||||
flatpak_parse_extension_with_tag (extension, &name, NULL);
|
||||
|
||||
if (versions)
|
||||
branches = (const char **) versions;
|
||||
else
|
||||
{
|
||||
if (version)
|
||||
default_branches[0] = version;
|
||||
branches = default_branches;
|
||||
}
|
||||
|
||||
for (j = 0; branches[j] != NULL; j++)
|
||||
res = add_extension (metakey, groups[i], name, arch, branches[j], res);
|
||||
}
|
||||
}
|
||||
|
||||
return g_list_sort (g_list_reverse (res), flatpak_extension_compare);
|
||||
}
|
||||
|
||||
#define OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "(uayttay)"
|
||||
#define OSTREE_STATIC_DELTA_FALLBACK_FORMAT "(yaytt)"
|
||||
#define OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT "(a{sv}tayay" OSTREE_COMMIT_GVARIANT_STRING "aya" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT "a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT ")"
|
||||
@@ -6370,23 +5825,6 @@ flatpak_g_ptr_array_contains_string (GPtrArray *array, const char *str)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
flatpak_log_dir_access (FlatpakDir *dir)
|
||||
{
|
||||
if (dir != NULL)
|
||||
{
|
||||
GFile *dir_path = NULL;
|
||||
g_autofree char *dir_path_str = NULL;
|
||||
g_autofree char *dir_name = NULL;
|
||||
|
||||
dir_path = flatpak_dir_get_path (dir);
|
||||
if (dir_path != NULL)
|
||||
dir_path_str = g_file_get_path (dir_path);
|
||||
dir_name = flatpak_dir_get_name (dir);
|
||||
g_info ("Opening %s flatpak installation at path %s", dir_name, dir_path_str);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
flatpak_check_required_version (const char *ref,
|
||||
GKeyFile *metakey,
|
||||
|
||||
@@ -168,6 +168,7 @@ sources = [
|
||||
'flatpak-chain-input-stream.c',
|
||||
'flatpak-context.c',
|
||||
'flatpak-dir.c',
|
||||
'flatpak-dir-utils.c',
|
||||
'flatpak-error.c',
|
||||
'flatpak-exports.c',
|
||||
'flatpak-glib-backports.c',
|
||||
|
||||
@@ -49,6 +49,7 @@ app/flatpak-main.c
|
||||
app/flatpak-quiet-transaction.c
|
||||
common/flatpak-auth.c
|
||||
common/flatpak-context.c
|
||||
common/flatpak-dir-utils.c
|
||||
common/flatpak-dir.c
|
||||
common/flatpak-exports.c
|
||||
common/flatpak-glib-backports.c
|
||||
|
||||
Reference in New Issue
Block a user