"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "common/flatpak-dir.c" between
flatpak-1.15.0.tar.xz and flatpak-1.15.1.tar.xz

About: Flatpak is a Linux application sandboxing and distribution framework. Pre-release.

flatpak-dir.c  (flatpak-1.15.0.tar.xz):flatpak-dir.c  (flatpak-1.15.1.tar.xz)
skipping to change at line 4545 skipping to change at line 4545
if (!glnx_fstatat (dir_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW, NULL)) if (!glnx_fstatat (dir_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW, NULL))
continue; continue;
if (stbuf.st_mtime >= now || if (stbuf.st_mtime >= now ||
now - stbuf.st_mtime < SECS_PER_DAY) now - stbuf.st_mtime < SECS_PER_DAY)
continue; continue;
tmp = g_file_get_child (dir, dent->d_name); tmp = g_file_get_child (dir, dent->d_name);
/* We ignore errors here, no need to worry anyone */ /* We ignore errors here, no need to worry anyone */
g_debug ("Deleting stale appstream deploy tmpdir %s", flatpak_file_get_pat
h_cached (tmp));
(void)flatpak_rm_rf (tmp, NULL, NULL);
}
}
/* Like the function above, this looks for old temporary directories created by
* previous versions of flatpak_dir_deploy().
* These are all directories starting with a dot. Such directories can be from a
* concurrent deploy, so we only remove directories older than a day to avoid
* races.
*/
static void
remove_old_deploy_tmpdirs (GFile *dir)
{
g_auto(GLnxDirFdIterator) dir_iter = { 0 };
time_t now = time (NULL);
if (!glnx_dirfd_iterator_init_at (AT_FDCWD, flatpak_file_get_path_cached (dir)
,
FALSE, &dir_iter, NULL))
return;
while (TRUE)
{
struct stat stbuf;
struct dirent *dent;
g_autoptr(GFile) tmp = NULL;
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dir_iter, &dent, NULL, N
ULL))
break;
if (dent == NULL)
break;
/* We ignore non-dotfiles and .timestamps as they are not tempfiles */
if (dent->d_name[0] != '.' ||
strcmp (dent->d_name, ".timestamp") == 0)
continue;
/* Check for right types and names. The format we’re looking for is:
* .[0-9a-f]{64}-[0-9A-Z]{6} */
if (dent->d_type == DT_DIR)
{
if (strlen (dent->d_name) != 72 ||
dent->d_name[65] != '-')
continue;
}
else
continue;
/* Check that the file is at least a day old to avoid races */
if (!glnx_fstatat (dir_iter.fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW,
NULL))
continue;
if (stbuf.st_mtime >= now ||
now - stbuf.st_mtime < SECS_PER_DAY)
continue;
tmp = g_file_get_child (dir, dent->d_name);
/* We ignore errors here, no need to worry anyone */
g_debug ("Deleting stale deploy tmpdir %s", flatpak_file_get_path_cached (
tmp));
(void)flatpak_rm_rf (tmp, NULL, NULL); (void)flatpak_rm_rf (tmp, NULL, NULL);
} }
} }
gboolean gboolean
flatpak_dir_deploy_appstream (FlatpakDir *self, flatpak_dir_deploy_appstream (FlatpakDir *self,
const char *remote, const char *remote,
const char *arch, const char *arch,
gboolean *out_changed, gboolean *out_changed,
GCancellable *cancellable, GCancellable *cancellable,
skipping to change at line 8507 skipping to change at line 8568
const char *checksum_or_latest, const char *checksum_or_latest,
const char * const * subpaths, const char * const * subpaths,
const char * const * previous_ids, const char * const * previous_ids,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
g_autofree char *resolved_ref = NULL; g_autofree char *resolved_ref = NULL;
g_autofree char *ref_id = NULL; g_autofree char *ref_id = NULL;
g_autoptr(GFile) root = NULL; g_autoptr(GFile) root = NULL;
g_autoptr(GFile) deploy_base = NULL; g_autoptr(GFile) deploy_base = NULL;
glnx_autofd int deploy_base_dfd = -1;
g_autoptr(GFile) checkoutdir = NULL; g_autoptr(GFile) checkoutdir = NULL;
g_autoptr(GFile) bindir = NULL; g_autoptr(GFile) bindir = NULL;
g_autofree char *checkoutdirpath = NULL; g_autofree char *checkoutdirpath = NULL;
const char *checkoutdir_basename;
g_autoptr(GFile) real_checkoutdir = NULL; g_autoptr(GFile) real_checkoutdir = NULL;
g_autoptr(GFile) dotref = NULL; g_autoptr(GFile) dotref = NULL;
g_autoptr(GFile) files_etc = NULL; g_autoptr(GFile) files_etc = NULL;
g_autoptr(GFile) deploy_data_file = NULL; g_autoptr(GFile) deploy_data_file = NULL;
g_autoptr(GVariant) commit_data = NULL; g_autoptr(GVariant) commit_data = NULL;
g_autoptr(GBytes) deploy_data = NULL; g_autoptr(GBytes) deploy_data = NULL;
g_autoptr(GFile) export = NULL; g_autoptr(GFile) export = NULL;
g_autoptr(GFile) extradir = NULL; g_autoptr(GFile) extradir = NULL;
g_autoptr(GKeyFile) keyfile = NULL; g_autoptr(GKeyFile) keyfile = NULL;
guint64 installed_size = 0; guint64 installed_size = 0;
OstreeRepoCheckoutAtOptions options = { 0, }; OstreeRepoCheckoutAtOptions options = { 0, };
const char *checksum; const char *checksum;
glnx_autofd int checkoutdir_dfd = -1; glnx_autofd int checkoutdir_dfd = -1;
g_autoptr(GFile) tmp_dir_template = NULL;
g_autofree char *tmp_dir_path = NULL;
const char *xa_ref = NULL; const char *xa_ref = NULL;
g_autofree char *checkout_basename = NULL; g_autofree char *checkout_basename = NULL;
gboolean created_extra_data = FALSE; gboolean created_extra_data = FALSE;
g_autoptr(GVariant) commit_metadata = NULL; g_autoptr(GVariant) commit_metadata = NULL;
g_auto(GLnxLockFile) lock = { 0, }; g_auto(GLnxLockFile) lock = { 0, };
g_autoptr(GFile) metadata_file = NULL; g_autoptr(GFile) metadata_file = NULL;
g_autofree char *metadata_contents = NULL; g_autofree char *metadata_contents = NULL;
gsize metadata_size = 0; gsize metadata_size = 0;
const char *flatpak; const char *flatpak;
g_auto(GLnxTmpDir) tmp_dir_handle = { 0, };
if (!flatpak_dir_ensure_repo (self, cancellable, error)) if (!flatpak_dir_ensure_repo (self, cancellable, error))
return FALSE; return FALSE;
ref_id = flatpak_decomposed_dup_id (ref); ref_id = flatpak_decomposed_dup_id (ref);
/* Keep a shared repo lock to avoid prunes removing objects we're relying on /* Keep a shared repo lock to avoid prunes removing objects we're relying on
* while we do the checkout. This could happen if the ref changes after we * while we do the checkout. This could happen if the ref changes after we
* read its current value for the checkout. */ * read its current value for the checkout. */
if (!flatpak_dir_repo_lock (self, &lock, LOCK_SH, cancellable, error)) if (!flatpak_dir_repo_lock (self, &lock, LOCK_SH, cancellable, error))
return FALSE; return FALSE;
deploy_base = flatpak_dir_get_deploy_dir (self, ref); deploy_base = flatpak_dir_get_deploy_dir (self, ref);
if (!glnx_opendirat (AT_FDCWD, flatpak_file_get_path_cached (deploy_base), TRU
E, &deploy_base_dfd, error))
return FALSE;
/* There used to be a bug here where temporary files beneath @deploy_base were
not removed,
* which could use quite a lot of space over time, so we check for these and r
emove them.
* We only do so for the current app to avoid every deploy operation iterating
over
* every app directory and all their immediate descendents. That would be a bi
t much I/O. */
remove_old_deploy_tmpdirs (deploy_base);
if (checksum_or_latest == NULL) if (checksum_or_latest == NULL)
{ {
g_debug ("No checksum specified, getting tip of %s from origin %s", flatpa k_decomposed_get_ref (ref), origin); g_debug ("No checksum specified, getting tip of %s from origin %s", flatpa k_decomposed_get_ref (ref), origin);
resolved_ref = flatpak_dir_read_latest (self, origin, flatpak_decomposed_g et_ref (ref), NULL, cancellable, error); resolved_ref = flatpak_dir_read_latest (self, origin, flatpak_decomposed_g et_ref (ref), NULL, cancellable, error);
if (resolved_ref == NULL) if (resolved_ref == NULL)
{ {
g_prefix_error (error, _("While trying to resolve ref %s: "), flatpak_ decomposed_get_ref (ref)); g_prefix_error (error, _("While trying to resolve ref %s: "), flatpak_ decomposed_get_ref (ref));
return FALSE; return FALSE;
} }
skipping to change at line 8582 skipping to change at line 8653
commit_metadata = g_variant_get_child_value (commit_data, 0); commit_metadata = g_variant_get_child_value (commit_data, 0);
checkout_basename = flatpak_dir_get_deploy_subdir (self, checksum, subpaths); checkout_basename = flatpak_dir_get_deploy_subdir (self, checksum, subpaths);
real_checkoutdir = g_file_get_child (deploy_base, checkout_basename); real_checkoutdir = g_file_get_child (deploy_base, checkout_basename);
if (g_file_query_exists (real_checkoutdir, cancellable)) if (g_file_query_exists (real_checkoutdir, cancellable))
return flatpak_fail_error (error, FLATPAK_ERROR_ALREADY_INSTALLED, return flatpak_fail_error (error, FLATPAK_ERROR_ALREADY_INSTALLED,
_("%s commit %s already installed"), flatpak_deco mposed_get_ref (ref), checksum); _("%s commit %s already installed"), flatpak_deco mposed_get_ref (ref), checksum);
g_autofree char *template = g_strdup_printf (".%s-XXXXXX", checkout_basename); g_autofree char *template = g_strdup_printf (".%s-XXXXXX", checkout_basename);
tmp_dir_template = g_file_get_child (deploy_base, template);
tmp_dir_path = g_file_get_path (tmp_dir_template);
if (g_mkdtemp_full (tmp_dir_path, 0755) == NULL) if (!glnx_mkdtempat (deploy_base_dfd, template, 0755, &tmp_dir_handle, NULL))
{ {
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Can't create deploy directory")); _("Can't create deploy directory"));
return FALSE; return FALSE;
} }
checkoutdir = g_file_new_for_path (tmp_dir_path); checkoutdir = g_file_get_child (deploy_base, tmp_dir_handle.path);
if (!ostree_repo_read_commit (self->repo, checksum, &root, NULL, cancellable, error)) if (!ostree_repo_read_commit (self->repo, checksum, &root, NULL, cancellable, error))
{ {
g_prefix_error (error, _("Failed to read commit %s: "), checksum); g_prefix_error (error, _("Failed to read commit %s: "), checksum);
return FALSE; return FALSE;
} }
if (!flatpak_repo_collect_sizes (self->repo, root, &installed_size, NULL, canc ellable, error)) if (!flatpak_repo_collect_sizes (self->repo, root, &installed_size, NULL, canc ellable, error))
return FALSE; return FALSE;
options.mode = OSTREE_REPO_CHECKOUT_MODE_USER; options.mode = OSTREE_REPO_CHECKOUT_MODE_USER;
options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES; options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
options.enable_fsync = FALSE; /* We checkout to a temp dir and sync before mov ing it in place */ options.enable_fsync = FALSE; /* We checkout to a temp dir and sync before mov ing it in place */
options.bareuseronly_dirs = TRUE; /* https://github.com/ostreedev/ostree/pull/ 927 */ options.bareuseronly_dirs = TRUE; /* https://github.com/ostreedev/ostree/pull/ 927 */
checkoutdirpath = g_file_get_path (checkoutdir); checkoutdirpath = g_file_get_path (checkoutdir);
checkoutdir_basename = tmp_dir_handle.path; /* so checkoutdirpath = deploy_ba se_dfd / checkoutdir_basename */
if (subpaths == NULL || *subpaths == NULL) if (subpaths == NULL || *subpaths == NULL)
{ {
if (!ostree_repo_checkout_at (self->repo, &options, if (!ostree_repo_checkout_at (self->repo, &options,
AT_FDCWD, checkoutdirpath, deploy_base_dfd, checkoutdir_basename,
checksum, checksum,
cancellable, error)) cancellable, error))
{ {
g_prefix_error (error, _("While trying to checkout %s into %s: "), che cksum, checkoutdirpath); g_prefix_error (error, _("While trying to checkout %s into %s: "), che cksum, checkoutdirpath);
return FALSE; return FALSE;
} }
} }
else else
{ {
g_autoptr(GFile) files = g_file_get_child (checkoutdir, "files"); g_autoptr(GFile) files = g_file_get_child (checkoutdir, "files");
int i; int i;
if (!g_file_make_directory_with_parents (files, cancellable, error)) if (!g_file_make_directory_with_parents (files, cancellable, error))
return FALSE; return FALSE;
options.subpath = "metadata"; options.subpath = "metadata";
if (!ostree_repo_checkout_at (self->repo, &options, if (!ostree_repo_checkout_at (self->repo, &options,
AT_FDCWD, checkoutdirpath, deploy_base_dfd, checkoutdir_basename,
checksum, checksum,
cancellable, error)) cancellable, error))
{ {
g_prefix_error (error, _("While trying to checkout metadata subpath: " )); g_prefix_error (error, _("While trying to checkout metadata subpath: " ));
return FALSE; return FALSE;
} }
for (i = 0; subpaths[i] != NULL; i++) for (i = 0; subpaths[i] != NULL; i++)
{ {
g_autofree char *subpath = g_build_filename ("files", subpaths[i], NUL L); g_autofree char *subpath = g_build_filename ("files", subpaths[i], NUL L);
g_autofree char *dstpath = g_build_filename (checkoutdirpath, "/files" , subpaths[i], NULL); g_autofree char *dstpath = g_build_filename (checkoutdirpath, "/files" , subpaths[i], NULL);
g_autofree char *dstpath_parent = g_path_get_dirname (dstpath); g_autofree char *dstpath_parent = g_path_get_dirname (dstpath);
g_autofree char *dstpath_relative_to_deploy_base = g_build_filename (c heckoutdir_basename, "/files", subpaths[i], NULL);
g_autoptr(GFile) child = NULL; g_autoptr(GFile) child = NULL;
child = g_file_resolve_relative_path (root, subpath); child = g_file_resolve_relative_path (root, subpath);
if (!g_file_query_exists (child, cancellable)) if (!g_file_query_exists (child, cancellable))
{ {
g_debug ("subpath %s not in tree", subpaths[i]); g_debug ("subpath %s not in tree", subpaths[i]);
continue; continue;
} }
if (g_mkdir_with_parents (dstpath_parent, 0755)) if (g_mkdir_with_parents (dstpath_parent, 0755))
{ {
glnx_set_error_from_errno (error); glnx_set_error_from_errno (error);
return FALSE; return FALSE;
} }
options.subpath = subpath; options.subpath = subpath;
if (!ostree_repo_checkout_at (self->repo, &options, if (!ostree_repo_checkout_at (self->repo, &options,
AT_FDCWD, dstpath, deploy_base_dfd, dstpath_relative_to_dep loy_base,
checksum, checksum,
cancellable, error)) cancellable, error))
{ {
g_prefix_error (error, _("While trying to checkout subpath ‘%s’: " ), subpath); g_prefix_error (error, _("While trying to checkout subpath ‘%s’: " ), subpath);
return FALSE; return FALSE;
} }
} }
} }
/* Extract any extra data */ /* Extract any extra data */
skipping to change at line 8878 skipping to change at line 8949
/* Check the app is actually allowed to be used by this user. This can block /* Check the app is actually allowed to be used by this user. This can block
* on getting authorisation. */ * on getting authorisation. */
if (!flatpak_dir_check_parental_controls (self, flatpak_decomposed_get_ref (re f), deploy_data, cancellable, error)) if (!flatpak_dir_check_parental_controls (self, flatpak_decomposed_get_ref (re f), deploy_data, cancellable, error))
return FALSE; return FALSE;
deploy_data_file = g_file_get_child (checkoutdir, "deploy"); deploy_data_file = g_file_get_child (checkoutdir, "deploy");
if (!flatpak_bytes_save (deploy_data_file, deploy_data, cancellable, error)) if (!flatpak_bytes_save (deploy_data_file, deploy_data, cancellable, error))
return FALSE; return FALSE;
if (!glnx_opendirat (AT_FDCWD, checkoutdirpath, TRUE, &checkoutdir_dfd, error) ) if (!glnx_opendirat (deploy_base_dfd, checkoutdir_basename, TRUE, &checkoutdir _dfd, error))
return FALSE; return FALSE;
if (syncfs (checkoutdir_dfd) != 0) if (syncfs (checkoutdir_dfd) != 0)
{ {
glnx_set_error_from_errno (error); glnx_set_error_from_errno (error);
return FALSE; return FALSE;
} }
if (!g_file_move (checkoutdir, real_checkoutdir, G_FILE_COPY_NO_FALLBACK_FOR_M OVE, if (!g_file_move (checkoutdir, real_checkoutdir, G_FILE_COPY_NO_FALLBACK_FOR_M OVE,
cancellable, NULL, NULL, error)) cancellable, NULL, NULL, error))
return FALSE; return FALSE;
glnx_tmpdir_unset (&tmp_dir_handle);
if (!flatpak_dir_set_active (self, ref, checkout_basename, cancellable, error) ) if (!flatpak_dir_set_active (self, ref, checkout_basename, cancellable, error) )
return FALSE; return FALSE;
if (!flatpak_dir_update_deploy_ref (self, flatpak_decomposed_get_ref (ref), ch ecksum, error)) if (!flatpak_dir_update_deploy_ref (self, flatpak_decomposed_get_ref (ref), ch ecksum, error))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
/* -origin remotes are deleted when the last ref referring to it is undeployed * / /* -origin remotes are deleted when the last ref referring to it is undeployed * /
 End of changes. 16 change blocks. 
10 lines changed or deleted 93 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)