Merge pull request #2193 from alexlarsson/preparatory-cleanup
Preparatory cleanup for summary work
This commit is contained in:
commit
71acef2d33
|
|
@ -17,7 +17,7 @@
|
||||||
Boston, MA 02111-1307, USA.
|
Boston, MA 02111-1307, USA.
|
||||||
***/
|
***/
|
||||||
|
|
||||||
LIBOSTREE_2020.5 {
|
LIBOSTREE_2020.6 {
|
||||||
global:
|
global:
|
||||||
/* Add symbols here, and uncomment the bits in
|
/* Add symbols here, and uncomment the bits in
|
||||||
* Makefile-libostree.am to enable this too.
|
* Makefile-libostree.am to enable this too.
|
||||||
|
|
|
||||||
|
|
@ -593,6 +593,9 @@ global:
|
||||||
ostree_sysroot_set_mount_namespace_in_use;
|
ostree_sysroot_set_mount_namespace_in_use;
|
||||||
} LIBOSTREE_2019.6;
|
} LIBOSTREE_2019.6;
|
||||||
|
|
||||||
|
/* No new symbols in 2020.2 */
|
||||||
|
/* No new symbols in 2020.3 */
|
||||||
|
|
||||||
/* Add new symbols here. Release commits should copy this section into -released.sym. */
|
/* Add new symbols here. Release commits should copy this section into -released.sym. */
|
||||||
LIBOSTREE_2020.4 {
|
LIBOSTREE_2020.4 {
|
||||||
global:
|
global:
|
||||||
|
|
@ -615,7 +618,7 @@ global:
|
||||||
ostree_sign_summary;
|
ostree_sign_summary;
|
||||||
} LIBOSTREE_2020.1;
|
} LIBOSTREE_2020.1;
|
||||||
|
|
||||||
/* No new symbols in 2020.2 */
|
/* No new symbols in 2020.5 */
|
||||||
|
|
||||||
/* NOTE: Only add more content here in release commits! See the
|
/* NOTE: Only add more content here in release commits! See the
|
||||||
* comments at the top of this file.
|
* comments at the top of this file.
|
||||||
|
|
|
||||||
|
|
@ -2675,7 +2675,7 @@ _ostree_detached_metadata_append_gpg_sig (GVariant *existing_metadata,
|
||||||
_OSTREE_METADATA_GPGSIGS_NAME,
|
_OSTREE_METADATA_GPGSIGS_NAME,
|
||||||
g_variant_builder_end (signature_builder));
|
g_variant_builder_end (signature_builder));
|
||||||
|
|
||||||
return g_variant_dict_end (&metadata_dict);
|
return g_variant_ref_sink (g_variant_dict_end (&metadata_dict));
|
||||||
}
|
}
|
||||||
#endif /* OSTREE_DISABLE_GPGME */
|
#endif /* OSTREE_DISABLE_GPGME */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2513,10 +2513,7 @@ on_superblock_fetched (GObject *src,
|
||||||
const guchar *expected_summary_digest = g_hash_table_lookup (pull_data->summary_deltas_checksums, delta);
|
const guchar *expected_summary_digest = g_hash_table_lookup (pull_data->summary_deltas_checksums, delta);
|
||||||
guint8 actual_summary_digest[OSTREE_SHA256_DIGEST_LEN];
|
guint8 actual_summary_digest[OSTREE_SHA256_DIGEST_LEN];
|
||||||
|
|
||||||
g_auto(OtChecksum) hasher = { 0, };
|
ot_checksum_bytes (delta_superblock_data, actual_summary_digest);
|
||||||
ot_checksum_init (&hasher);
|
|
||||||
ot_checksum_update_bytes (&hasher, delta_superblock_data);
|
|
||||||
ot_checksum_get_digest (&hasher, actual_summary_digest, sizeof (actual_summary_digest));
|
|
||||||
|
|
||||||
#ifndef OSTREE_DISABLE_GPGME
|
#ifndef OSTREE_DISABLE_GPGME
|
||||||
/* At this point we've GPG verified the data, so in theory
|
/* At this point we've GPG verified the data, so in theory
|
||||||
|
|
@ -2626,54 +2623,180 @@ validate_variant_is_csum (GVariant *csum,
|
||||||
return ostree_validate_structureof_csum_v (csum, error);
|
return ostree_validate_structureof_csum_v (csum, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_ostree_repo_verify_summary (OstreeRepo *self,
|
||||||
|
const char *name,
|
||||||
|
gboolean gpg_verify_summary,
|
||||||
|
GPtrArray *signapi_summary_verifiers,
|
||||||
|
GBytes *summary,
|
||||||
|
GBytes *signatures,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
if (gpg_verify_summary)
|
||||||
|
{
|
||||||
|
if (summary == NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||||
|
"GPG verification enabled, but no summary found (check that the configured URL in remote config is correct)");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signatures == NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE,
|
||||||
|
"GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify any summary signatures. */
|
||||||
|
if (summary != NULL && signatures != NULL)
|
||||||
|
{
|
||||||
|
g_autoptr(OstreeGpgVerifyResult) result = NULL;
|
||||||
|
|
||||||
|
result = ostree_repo_verify_summary (self,
|
||||||
|
name,
|
||||||
|
summary,
|
||||||
|
signatures,
|
||||||
|
cancellable,
|
||||||
|
error);
|
||||||
|
if (!ostree_gpg_verify_result_require_valid_signature (result, error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signapi_summary_verifiers)
|
||||||
|
{
|
||||||
|
if (summary == NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||||
|
"Signature verification enabled, but no summary found (check that the configured URL in remote config is correct)");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signatures == NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||||
|
"Signature verification enabled, but no summary signatures found (use sign-verify-summary=false in remote config to disable)");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify any summary signatures. */
|
||||||
|
if (summary != NULL && signatures != NULL)
|
||||||
|
{
|
||||||
|
g_autoptr(GVariant) sig_variant = NULL;
|
||||||
|
|
||||||
|
sig_variant = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT,
|
||||||
|
signatures, FALSE);
|
||||||
|
|
||||||
|
if (!_sign_verify_for_remote (signapi_summary_verifiers, summary, sig_variant, NULL, error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_ostree_repo_load_cache_summary_file (OstreeRepo *self,
|
||||||
|
const char *filename,
|
||||||
|
const char *extension,
|
||||||
|
GBytes **out_data,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
const char *file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", filename, extension);
|
||||||
|
glnx_autofd int fd = -1;
|
||||||
|
g_autoptr(GBytes) data = NULL;
|
||||||
|
|
||||||
|
*out_data = NULL;
|
||||||
|
|
||||||
|
if (self->cache_dir_fd == -1)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
fd = openat (self->cache_dir_fd, file, O_CLOEXEC | O_RDONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT)
|
||||||
|
return TRUE;
|
||||||
|
return glnx_throw_errno_prefix (error, "openat(%s)", file);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = ot_fd_readall_or_mmap (fd, 0, error);
|
||||||
|
if (!data)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*out_data =g_steal_pointer (&data);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Load the summary from the cache if the provided .sig file is the same as the
|
/* Load the summary from the cache if the provided .sig file is the same as the
|
||||||
cached version. */
|
cached version. */
|
||||||
static gboolean
|
static gboolean
|
||||||
_ostree_repo_load_cache_summary_if_same_sig (OstreeRepo *self,
|
_ostree_repo_load_cache_summary_if_same_sig (OstreeRepo *self,
|
||||||
const char *remote,
|
const char *remote,
|
||||||
GBytes *summary_sig,
|
GBytes *summary_sig,
|
||||||
GBytes **summary,
|
GBytes **out_summary,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
g_autoptr(GBytes) old_sig_contents = NULL;
|
||||||
|
|
||||||
|
*out_summary = NULL;
|
||||||
|
|
||||||
|
if (!_ostree_repo_load_cache_summary_file (self, remote, ".sig",
|
||||||
|
&old_sig_contents,
|
||||||
|
cancellable, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (old_sig_contents != NULL &&
|
||||||
|
g_bytes_compare (old_sig_contents, summary_sig) == 0)
|
||||||
|
{
|
||||||
|
g_autoptr(GBytes) summary_data = NULL;
|
||||||
|
|
||||||
|
if (!_ostree_repo_load_cache_summary_file (self, remote, NULL,
|
||||||
|
&summary_data,
|
||||||
|
cancellable, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (summary_data == NULL)
|
||||||
|
{
|
||||||
|
/* Cached signature without cached summary, remove the signature */
|
||||||
|
const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote, ".sig");
|
||||||
|
(void) unlinkat (self->cache_dir_fd, summary_cache_sig_file, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*out_summary = g_steal_pointer (&summary_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_ostree_repo_save_cache_summary_file (OstreeRepo *self,
|
||||||
|
const char *filename,
|
||||||
|
const char *extension,
|
||||||
|
GBytes *data,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
const char *file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", filename, extension);
|
||||||
|
glnx_autofd int fd = -1;
|
||||||
|
|
||||||
if (self->cache_dir_fd == -1)
|
if (self->cache_dir_fd == -1)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote, ".sig");
|
if (!glnx_shutil_mkdir_p_at (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, DEFAULT_DIRECTORY_MODE, cancellable, error))
|
||||||
glnx_autofd int prev_fd = -1;
|
|
||||||
if (!ot_openat_ignore_enoent (self->cache_dir_fd, summary_cache_sig_file, &prev_fd, error))
|
|
||||||
return FALSE;
|
|
||||||
if (prev_fd < 0)
|
|
||||||
return TRUE; /* Note early return */
|
|
||||||
|
|
||||||
g_autoptr(GBytes) old_sig_contents = ot_fd_readall_or_mmap (prev_fd, 0, error);
|
|
||||||
if (!old_sig_contents)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (g_bytes_compare (old_sig_contents, summary_sig) == 0)
|
if (!glnx_file_replace_contents_at (self->cache_dir_fd,
|
||||||
{
|
file,
|
||||||
const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote);
|
g_bytes_get_data (data, NULL),
|
||||||
glnx_autofd int summary_fd = -1;
|
g_bytes_get_size (data),
|
||||||
GBytes *summary_data;
|
self->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW,
|
||||||
|
cancellable, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
|
||||||
summary_fd = openat (self->cache_dir_fd, summary_cache_file, O_CLOEXEC | O_RDONLY);
|
|
||||||
if (summary_fd < 0)
|
|
||||||
{
|
|
||||||
if (errno == ENOENT)
|
|
||||||
{
|
|
||||||
(void) unlinkat (self->cache_dir_fd, summary_cache_sig_file, 0);
|
|
||||||
return TRUE; /* Note early return */
|
|
||||||
}
|
|
||||||
|
|
||||||
return glnx_throw_errno_prefix (error, "openat(%s)", summary_cache_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
summary_data = glnx_fd_readall_bytes (summary_fd, cancellable, error);
|
|
||||||
if (!summary_data)
|
|
||||||
return FALSE;
|
|
||||||
*summary = summary_data;
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2686,28 +2809,12 @@ _ostree_repo_cache_summary (OstreeRepo *self,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
if (self->cache_dir_fd == -1)
|
if (!_ostree_repo_save_cache_summary_file (self, remote, NULL,
|
||||||
return TRUE;
|
summary, cancellable, error))
|
||||||
|
|
||||||
if (!glnx_shutil_mkdir_p_at (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, DEFAULT_DIRECTORY_MODE, cancellable, error))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote);
|
if (!_ostree_repo_save_cache_summary_file (self, remote, ".sig",
|
||||||
if (!glnx_file_replace_contents_at (self->cache_dir_fd,
|
summary_sig, cancellable, error))
|
||||||
summary_cache_file,
|
|
||||||
g_bytes_get_data (summary, NULL),
|
|
||||||
g_bytes_get_size (summary),
|
|
||||||
self->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW,
|
|
||||||
cancellable, error))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote, ".sig");
|
|
||||||
if (!glnx_file_replace_contents_at (self->cache_dir_fd,
|
|
||||||
summary_cache_sig_file,
|
|
||||||
g_bytes_get_data (summary_sig, NULL),
|
|
||||||
g_bytes_get_size (summary_sig),
|
|
||||||
self->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW,
|
|
||||||
cancellable, error))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
@ -2717,6 +2824,8 @@ static OstreeFetcher *
|
||||||
_ostree_repo_remote_new_fetcher (OstreeRepo *self,
|
_ostree_repo_remote_new_fetcher (OstreeRepo *self,
|
||||||
const char *remote_name,
|
const char *remote_name,
|
||||||
gboolean gzip,
|
gboolean gzip,
|
||||||
|
GVariant *extra_headers,
|
||||||
|
const char *append_user_agent,
|
||||||
OstreeFetcherSecurityState *out_state,
|
OstreeFetcherSecurityState *out_state,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
|
@ -2830,6 +2939,12 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self,
|
||||||
_ostree_fetcher_set_cookie_jar (fetcher, jar_path);
|
_ostree_fetcher_set_cookie_jar (fetcher, jar_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extra_headers)
|
||||||
|
_ostree_fetcher_set_extra_headers (fetcher, extra_headers);
|
||||||
|
|
||||||
|
if (append_user_agent)
|
||||||
|
_ostree_fetcher_set_extra_user_agent (fetcher, append_user_agent);
|
||||||
|
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
@ -2977,127 +3092,43 @@ fetch_mirrorlist (OstreeFetcher *fetcher,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
repo_remote_fetch_summary (OstreeRepo *self,
|
compute_effective_mirrorlist (OstreeRepo *self,
|
||||||
const char *name,
|
const char *remote_name_or_baseurl,
|
||||||
const char *metalink_url_string,
|
const char *url_override,
|
||||||
GVariant *options,
|
OstreeFetcher *fetcher,
|
||||||
GBytes **out_summary,
|
guint n_network_retries,
|
||||||
GBytes **out_signatures,
|
GPtrArray **out_mirrorlist,
|
||||||
gboolean *out_from_cache,
|
GCancellable *cancellable,
|
||||||
GCancellable *cancellable,
|
GError **error)
|
||||||
GError **error)
|
|
||||||
{
|
{
|
||||||
g_autoptr(OstreeFetcher) fetcher = NULL;
|
g_autofree char *baseurl = NULL;
|
||||||
g_autoptr(GMainContext) mainctx = NULL;
|
|
||||||
gboolean ret = FALSE;
|
|
||||||
gboolean from_cache = FALSE;
|
|
||||||
const char *url_override = NULL;
|
|
||||||
g_autoptr(GVariant) extra_headers = NULL;
|
|
||||||
g_autoptr(GPtrArray) mirrorlist = NULL;
|
|
||||||
const char *append_user_agent = NULL;
|
|
||||||
guint n_network_retries = DEFAULT_N_NETWORK_RETRIES;
|
|
||||||
|
|
||||||
if (options)
|
if (url_override != NULL)
|
||||||
|
baseurl = g_strdup (url_override);
|
||||||
|
else if (!ostree_repo_remote_get_url (self, remote_name_or_baseurl, &baseurl, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (g_str_has_prefix (baseurl, "mirrorlist="))
|
||||||
{
|
{
|
||||||
(void) g_variant_lookup (options, "override-url", "&s", &url_override);
|
if (!fetch_mirrorlist (fetcher,
|
||||||
(void) g_variant_lookup (options, "http-headers", "@a(ss)", &extra_headers);
|
baseurl + strlen ("mirrorlist="),
|
||||||
(void) g_variant_lookup (options, "append-user-agent", "&s", &append_user_agent);
|
n_network_retries,
|
||||||
(void) g_variant_lookup (options, "n-network-retries", "&u", &n_network_retries);
|
out_mirrorlist,
|
||||||
|
cancellable, error))
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mainctx = g_main_context_new ();
|
|
||||||
g_main_context_push_thread_default (mainctx);
|
|
||||||
|
|
||||||
fetcher = _ostree_repo_remote_new_fetcher (self, name, TRUE, NULL, error);
|
|
||||||
if (fetcher == NULL)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (extra_headers)
|
|
||||||
_ostree_fetcher_set_extra_headers (fetcher, extra_headers);
|
|
||||||
|
|
||||||
if (append_user_agent)
|
|
||||||
_ostree_fetcher_set_extra_user_agent (fetcher, append_user_agent);
|
|
||||||
|
|
||||||
{
|
|
||||||
g_autofree char *url_string = NULL;
|
|
||||||
if (metalink_url_string)
|
|
||||||
url_string = g_strdup (metalink_url_string);
|
|
||||||
else if (url_override)
|
|
||||||
url_string = g_strdup (url_override);
|
|
||||||
else if (!ostree_repo_remote_get_url (self, name, &url_string, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (metalink_url_string == NULL &&
|
|
||||||
g_str_has_prefix (url_string, "mirrorlist="))
|
|
||||||
{
|
|
||||||
if (!fetch_mirrorlist (fetcher, url_string + strlen ("mirrorlist="),
|
|
||||||
n_network_retries, &mirrorlist, cancellable, error))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_autoptr(OstreeFetcherURI) uri = _ostree_fetcher_uri_parse (url_string, error);
|
|
||||||
|
|
||||||
if (!uri)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
mirrorlist =
|
|
||||||
g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free);
|
|
||||||
g_ptr_array_add (mirrorlist, g_steal_pointer (&uri));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Send the ETag from the cache with the request for summary.sig to
|
|
||||||
* avoid downloading summary.sig unnecessarily. This won’t normally provide
|
|
||||||
* any benefits (but won’t do any harm) since summary.sig is typically 500B
|
|
||||||
* in size. But if a repository has multiple keys, the signature file will
|
|
||||||
* grow and this optimisation may be useful. */
|
|
||||||
if (!_ostree_preload_metadata_file (self,
|
|
||||||
fetcher,
|
|
||||||
mirrorlist,
|
|
||||||
"summary.sig",
|
|
||||||
metalink_url_string ? TRUE : FALSE,
|
|
||||||
n_network_retries,
|
|
||||||
out_signatures,
|
|
||||||
cancellable,
|
|
||||||
error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (*out_signatures)
|
|
||||||
{
|
|
||||||
if (!_ostree_repo_load_cache_summary_if_same_sig (self,
|
|
||||||
name,
|
|
||||||
*out_signatures,
|
|
||||||
out_summary,
|
|
||||||
cancellable,
|
|
||||||
error))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*out_summary)
|
|
||||||
from_cache = TRUE;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!_ostree_preload_metadata_file (self,
|
g_autoptr(OstreeFetcherURI) baseuri = _ostree_fetcher_uri_parse (baseurl, error);
|
||||||
fetcher,
|
|
||||||
mirrorlist,
|
if (!baseuri)
|
||||||
"summary",
|
return FALSE;
|
||||||
metalink_url_string ? TRUE : FALSE,
|
|
||||||
n_network_retries,
|
*out_mirrorlist =
|
||||||
out_summary,
|
g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free);
|
||||||
cancellable,
|
g_ptr_array_add (*out_mirrorlist, g_steal_pointer (&baseuri));
|
||||||
error))
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
ret = TRUE;
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (mainctx)
|
|
||||||
g_main_context_pop_thread_default (mainctx);
|
|
||||||
|
|
||||||
*out_from_cache = from_cache;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the fetcher by unioning options from the remote config, plus
|
/* Create the fetcher by unioning options from the remote config, plus
|
||||||
|
|
@ -3109,17 +3140,13 @@ reinitialize_fetcher (OtPullData *pull_data, const char *remote_name,
|
||||||
{
|
{
|
||||||
g_clear_object (&pull_data->fetcher);
|
g_clear_object (&pull_data->fetcher);
|
||||||
pull_data->fetcher = _ostree_repo_remote_new_fetcher (pull_data->repo, remote_name, FALSE,
|
pull_data->fetcher = _ostree_repo_remote_new_fetcher (pull_data->repo, remote_name, FALSE,
|
||||||
|
pull_data->extra_headers,
|
||||||
|
pull_data->append_user_agent,
|
||||||
&pull_data->fetcher_security_state,
|
&pull_data->fetcher_security_state,
|
||||||
error);
|
error);
|
||||||
if (pull_data->fetcher == NULL)
|
if (pull_data->fetcher == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (pull_data->extra_headers)
|
|
||||||
_ostree_fetcher_set_extra_headers (pull_data->fetcher, pull_data->extra_headers);
|
|
||||||
|
|
||||||
if (pull_data->append_user_agent)
|
|
||||||
_ostree_fetcher_set_extra_user_agent (pull_data->fetcher, pull_data->append_user_agent);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3631,33 +3658,13 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||||
|
|
||||||
if (!metalink_url_str)
|
if (!metalink_url_str)
|
||||||
{
|
{
|
||||||
g_autofree char *baseurl = NULL;
|
if (!compute_effective_mirrorlist (self, remote_name_or_baseurl,
|
||||||
|
url_override,
|
||||||
if (url_override != NULL)
|
pull_data->fetcher,
|
||||||
baseurl = g_strdup (url_override);
|
pull_data->n_network_retries,
|
||||||
else if (!ostree_repo_remote_get_url (self, remote_name_or_baseurl, &baseurl, error))
|
&pull_data->meta_mirrorlist,
|
||||||
|
cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (g_str_has_prefix (baseurl, "mirrorlist="))
|
|
||||||
{
|
|
||||||
if (!fetch_mirrorlist (pull_data->fetcher,
|
|
||||||
baseurl + strlen ("mirrorlist="),
|
|
||||||
pull_data->n_network_retries,
|
|
||||||
&pull_data->meta_mirrorlist,
|
|
||||||
cancellable, error))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_autoptr(OstreeFetcherURI) baseuri = _ostree_fetcher_uri_parse (baseurl, error);
|
|
||||||
|
|
||||||
if (!baseuri)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
pull_data->meta_mirrorlist =
|
|
||||||
g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free);
|
|
||||||
g_ptr_array_add (pull_data->meta_mirrorlist, g_steal_pointer (&baseuri));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -3716,27 +3723,13 @@ ostree_repo_pull_with_options (OstreeRepo *self,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (g_str_has_prefix (contenturl, "mirrorlist="))
|
if (!compute_effective_mirrorlist (self, remote_name_or_baseurl,
|
||||||
{
|
contenturl,
|
||||||
if (!fetch_mirrorlist (pull_data->fetcher,
|
pull_data->fetcher,
|
||||||
contenturl + strlen ("mirrorlist="),
|
pull_data->n_network_retries,
|
||||||
pull_data->n_network_retries,
|
&pull_data->content_mirrorlist,
|
||||||
&pull_data->content_mirrorlist,
|
cancellable, error))
|
||||||
cancellable, error))
|
goto out;
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_autoptr(OstreeFetcherURI) contenturi = _ostree_fetcher_uri_parse (contenturl, error);
|
|
||||||
|
|
||||||
if (!contenturi)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
pull_data->content_mirrorlist =
|
|
||||||
g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free);
|
|
||||||
g_ptr_array_add (pull_data->content_mirrorlist,
|
|
||||||
g_steal_pointer (&contenturi));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5471,7 +5464,7 @@ find_remotes_cb (GObject *obj,
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
fetcher = _ostree_repo_remote_new_fetcher (self, result->remote->name,
|
fetcher = _ostree_repo_remote_new_fetcher (self, result->remote->name,
|
||||||
TRUE, NULL, &error);
|
TRUE, NULL, NULL, NULL, &error);
|
||||||
if (fetcher == NULL)
|
if (fetcher == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
@ -6093,95 +6086,107 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self,
|
||||||
g_autoptr(GBytes) signatures = NULL;
|
g_autoptr(GBytes) signatures = NULL;
|
||||||
gboolean gpg_verify_summary;
|
gboolean gpg_verify_summary;
|
||||||
g_autoptr(GPtrArray) signapi_summary_verifiers = NULL;
|
g_autoptr(GPtrArray) signapi_summary_verifiers = NULL;
|
||||||
gboolean ret = FALSE;
|
gboolean summary_is_from_cache = FALSE;
|
||||||
gboolean summary_is_from_cache;
|
g_autoptr(OstreeFetcher) fetcher = NULL;
|
||||||
|
g_autoptr(GMainContextPopDefault) mainctx = NULL;
|
||||||
|
const char *url_override = NULL;
|
||||||
|
g_autoptr(GVariant) extra_headers = NULL;
|
||||||
|
g_autoptr(GPtrArray) mirrorlist = NULL;
|
||||||
|
const char *append_user_agent = NULL;
|
||||||
|
guint n_network_retries = DEFAULT_N_NETWORK_RETRIES;
|
||||||
|
|
||||||
g_return_val_if_fail (OSTREE_REPO (self), FALSE);
|
g_return_val_if_fail (OSTREE_REPO (self), FALSE);
|
||||||
g_return_val_if_fail (name != NULL, FALSE);
|
g_return_val_if_fail (name != NULL, FALSE);
|
||||||
|
|
||||||
if (!ostree_repo_get_remote_option (self, name, "metalink", NULL,
|
if (!ostree_repo_get_remote_option (self, name, "metalink", NULL,
|
||||||
&metalink_url_string, error))
|
&metalink_url_string, error))
|
||||||
goto out;
|
return FALSE;
|
||||||
|
|
||||||
if (!repo_remote_fetch_summary (self,
|
if (options)
|
||||||
name,
|
{
|
||||||
metalink_url_string,
|
(void) g_variant_lookup (options, "override-url", "&s", &url_override);
|
||||||
options,
|
(void) g_variant_lookup (options, "http-headers", "@a(ss)", &extra_headers);
|
||||||
&summary,
|
(void) g_variant_lookup (options, "append-user-agent", "&s", &append_user_agent);
|
||||||
&signatures,
|
(void) g_variant_lookup (options, "n-network-retries", "&u", &n_network_retries);
|
||||||
&summary_is_from_cache,
|
}
|
||||||
cancellable,
|
|
||||||
error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!ostree_repo_remote_get_gpg_verify_summary (self, name, &gpg_verify_summary, error))
|
if (!ostree_repo_remote_get_gpg_verify_summary (self, name, &gpg_verify_summary, error))
|
||||||
goto out;
|
return FALSE;
|
||||||
|
|
||||||
if (gpg_verify_summary)
|
|
||||||
{
|
|
||||||
if (summary == NULL)
|
|
||||||
{
|
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
|
||||||
"GPG verification enabled, but no summary found (check that the configured URL in remote config is correct)");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (signatures == NULL)
|
|
||||||
{
|
|
||||||
g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE,
|
|
||||||
"GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify any summary signatures. */
|
|
||||||
if (summary != NULL && signatures != NULL)
|
|
||||||
{
|
|
||||||
g_autoptr(OstreeGpgVerifyResult) result = NULL;
|
|
||||||
|
|
||||||
result = ostree_repo_verify_summary (self,
|
|
||||||
name,
|
|
||||||
summary,
|
|
||||||
signatures,
|
|
||||||
cancellable,
|
|
||||||
error);
|
|
||||||
if (!ostree_gpg_verify_result_require_valid_signature (result, error))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_signapi_init_for_remote (self, name, NULL,
|
if (!_signapi_init_for_remote (self, name, NULL,
|
||||||
&signapi_summary_verifiers,
|
&signapi_summary_verifiers,
|
||||||
error))
|
error))
|
||||||
goto out;
|
return FALSE;
|
||||||
|
|
||||||
if (signapi_summary_verifiers)
|
mainctx = _ostree_main_context_new_default ();
|
||||||
|
|
||||||
|
fetcher = _ostree_repo_remote_new_fetcher (self, name, TRUE, extra_headers, append_user_agent, NULL, error);
|
||||||
|
if (fetcher == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (metalink_url_string)
|
||||||
{
|
{
|
||||||
if (summary == NULL)
|
g_autoptr(OstreeFetcherURI) uri = _ostree_fetcher_uri_parse (metalink_url_string, error);
|
||||||
{
|
if (!uri)
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
return FALSE;
|
||||||
"Signature verification enabled, but no summary found (check that the configured URL in remote config is correct)");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (signatures == NULL)
|
mirrorlist =
|
||||||
{
|
g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free);
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
g_ptr_array_add (mirrorlist, g_steal_pointer (&uri));
|
||||||
"Signature verification enabled, but no summary signatures found (use sign-verify-summary=false in remote config to disable)");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify any summary signatures. */
|
|
||||||
if (summary != NULL && signatures != NULL)
|
|
||||||
{
|
|
||||||
g_autoptr(GVariant) sig_variant = NULL;
|
|
||||||
|
|
||||||
sig_variant = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT,
|
|
||||||
signatures, FALSE);
|
|
||||||
|
|
||||||
if (!_sign_verify_for_remote (signapi_summary_verifiers, summary, sig_variant, NULL, error))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (!compute_effective_mirrorlist (self, name, url_override,
|
||||||
|
fetcher, n_network_retries,
|
||||||
|
&mirrorlist, cancellable, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* FIXME: Send the ETag from the cache with the request for summary.sig to
|
||||||
|
* avoid downloading summary.sig unnecessarily. This won’t normally provide
|
||||||
|
* any benefits (but won’t do any harm) since summary.sig is typically 500B
|
||||||
|
* in size. But if a repository has multiple keys, the signature file will
|
||||||
|
* grow and this optimisation may be useful. */
|
||||||
|
if (!_ostree_preload_metadata_file (self,
|
||||||
|
fetcher,
|
||||||
|
mirrorlist,
|
||||||
|
"summary.sig",
|
||||||
|
metalink_url_string ? TRUE : FALSE,
|
||||||
|
n_network_retries,
|
||||||
|
&signatures,
|
||||||
|
cancellable,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (signatures)
|
||||||
|
{
|
||||||
|
if (!_ostree_repo_load_cache_summary_if_same_sig (self,
|
||||||
|
name,
|
||||||
|
signatures,
|
||||||
|
&summary,
|
||||||
|
cancellable,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (summary)
|
||||||
|
summary_is_from_cache = TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!_ostree_preload_metadata_file (self,
|
||||||
|
fetcher,
|
||||||
|
mirrorlist,
|
||||||
|
"summary",
|
||||||
|
metalink_url_string ? TRUE : FALSE,
|
||||||
|
n_network_retries,
|
||||||
|
&summary,
|
||||||
|
cancellable,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_ostree_repo_verify_summary (self, name,
|
||||||
|
gpg_verify_summary, signapi_summary_verifiers,
|
||||||
|
summary, signatures,
|
||||||
|
cancellable, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (!summary_is_from_cache && summary && signatures)
|
if (!summary_is_from_cache && summary && signatures)
|
||||||
{
|
{
|
||||||
|
|
@ -6199,7 +6204,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_propagate_error (error, g_steal_pointer (&temp_error));
|
g_propagate_error (error, g_steal_pointer (&temp_error));
|
||||||
goto out;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6210,10 +6215,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self,
|
||||||
if (out_signatures != NULL)
|
if (out_signatures != NULL)
|
||||||
*out_signatures = g_steal_pointer (&signatures);
|
*out_signatures = g_steal_pointer (&signatures);
|
||||||
|
|
||||||
ret = TRUE;
|
return TRUE;
|
||||||
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* HAVE_LIBCURL_OR_LIBSOUP */
|
#else /* HAVE_LIBCURL_OR_LIBSOUP */
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,28 @@ _ostree_static_delta_parse_checksum_array (GVariant *array,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GVariant *
|
||||||
|
_ostree_repo_static_delta_superblock_digest (OstreeRepo *repo,
|
||||||
|
const char *from,
|
||||||
|
const char *to,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_autofree char *superblock = _ostree_get_relative_static_delta_superblock_path ((from && from[0]) ? from : NULL, to);
|
||||||
|
glnx_autofd int superblock_file_fd = -1;
|
||||||
|
guint8 digest[OSTREE_SHA256_DIGEST_LEN];
|
||||||
|
|
||||||
|
if (!glnx_openat_rdonly (repo->repo_dir_fd, superblock, TRUE, &superblock_file_fd, error))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
g_autoptr(GBytes) superblock_content = ot_fd_readall_or_mmap (superblock_file_fd, 0, error);
|
||||||
|
if (!superblock_content)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ot_checksum_bytes (superblock_content, digest);
|
||||||
|
|
||||||
|
return ot_gvariant_new_bytearray (digest, sizeof (digest));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ostree_repo_list_static_delta_names:
|
* ostree_repo_list_static_delta_names:
|
||||||
|
|
@ -109,7 +131,7 @@ ostree_repo_list_static_delta_names (OstreeRepo *self,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (sub_dent == NULL)
|
if (sub_dent == NULL)
|
||||||
break;
|
break;
|
||||||
if (dent->d_type != DT_DIR)
|
if (sub_dent->d_type != DT_DIR)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const char *name1 = dent->d_name;
|
const char *name1 = dent->d_name;
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,12 @@ _ostree_repo_static_delta_query_exists (OstreeRepo *repo,
|
||||||
gboolean *out_exists,
|
gboolean *out_exists,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
GVariant *
|
||||||
|
_ostree_repo_static_delta_superblock_digest (OstreeRepo *repo,
|
||||||
|
const char *from,
|
||||||
|
const char *to,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_ostree_repo_static_delta_dump (OstreeRepo *repo,
|
_ostree_repo_static_delta_dump (OstreeRepo *repo,
|
||||||
|
|
|
||||||
|
|
@ -5793,25 +5793,18 @@ ostree_repo_regenerate_summary (OstreeRepo *self,
|
||||||
{
|
{
|
||||||
g_autofree char *from = NULL;
|
g_autofree char *from = NULL;
|
||||||
g_autofree char *to = NULL;
|
g_autofree char *to = NULL;
|
||||||
|
GVariant *digest;
|
||||||
|
|
||||||
if (!_ostree_parse_delta_name (delta_names->pdata[i], &from, &to, error))
|
if (!_ostree_parse_delta_name (delta_names->pdata[i], &from, &to, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
g_autofree char *superblock = _ostree_get_relative_static_delta_superblock_path ((from && from[0]) ? from : NULL, to);
|
digest = _ostree_repo_static_delta_superblock_digest (self,
|
||||||
glnx_autofd int superblock_file_fd = -1;
|
(from && from[0]) ? from : NULL,
|
||||||
|
to, cancellable, error);
|
||||||
if (!glnx_openat_rdonly (self->repo_dir_fd, superblock, TRUE, &superblock_file_fd, error))
|
if (digest == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
g_autoptr(GBytes) superblock_content = ot_fd_readall_or_mmap (superblock_file_fd, 0, error);
|
g_variant_dict_insert_value (&deltas_builder, delta_names->pdata[i], digest);
|
||||||
if (!superblock_content)
|
|
||||||
return FALSE;
|
|
||||||
g_auto(OtChecksum) hasher = { 0, };
|
|
||||||
ot_checksum_init (&hasher);
|
|
||||||
ot_checksum_update_bytes (&hasher, superblock_content);
|
|
||||||
guint8 digest[OSTREE_SHA256_DIGEST_LEN];
|
|
||||||
ot_checksum_get_digest (&hasher, digest, sizeof (digest));
|
|
||||||
|
|
||||||
g_variant_dict_insert_value (&deltas_builder, delta_names->pdata[i], ot_gvariant_new_bytearray (digest, sizeof (digest)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delta_names->len > 0)
|
if (delta_names->len > 0)
|
||||||
|
|
|
||||||
|
|
@ -275,3 +275,13 @@ ot_checksum_file_at (int dfd,
|
||||||
ot_checksum_get_hexdigest (&checksum, hexdigest, sizeof (hexdigest));
|
ot_checksum_get_hexdigest (&checksum, hexdigest, sizeof (hexdigest));
|
||||||
return g_strdup (hexdigest);
|
return g_strdup (hexdigest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ot_checksum_bytes (GBytes *data,
|
||||||
|
guint8 out_digest[_OSTREE_SHA256_DIGEST_LEN])
|
||||||
|
{
|
||||||
|
g_auto(OtChecksum) hasher = { 0, };
|
||||||
|
ot_checksum_init (&hasher);
|
||||||
|
ot_checksum_update_bytes (&hasher, data);
|
||||||
|
ot_checksum_get_digest (&hasher, out_digest, _OSTREE_SHA256_DIGEST_LEN);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,4 +96,7 @@ char * ot_checksum_file_at (int dfd,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
void ot_checksum_bytes (GBytes *data,
|
||||||
|
guint8 out_digest[_OSTREE_SHA256_DIGEST_LEN]);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,31 @@
|
||||||
#define ot_journal_print(...) {}
|
#define ot_journal_print(...) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef GMainContext GMainContextPopDefault;
|
||||||
|
static inline void
|
||||||
|
_ostree_main_context_pop_default_destroy (void *p)
|
||||||
|
{
|
||||||
|
GMainContext *main_context = p;
|
||||||
|
|
||||||
|
if (main_context)
|
||||||
|
{
|
||||||
|
g_main_context_pop_thread_default (main_context);
|
||||||
|
g_main_context_unref (main_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline GMainContextPopDefault *
|
||||||
|
_ostree_main_context_new_default (void)
|
||||||
|
{
|
||||||
|
GMainContext *main_context = g_main_context_new ();
|
||||||
|
|
||||||
|
g_main_context_push_thread_default (main_context);
|
||||||
|
return main_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GMainContextPopDefault, _ostree_main_context_pop_default_destroy)
|
||||||
|
|
||||||
|
|
||||||
#include <ot-keyfile-utils.h>
|
#include <ot-keyfile-utils.h>
|
||||||
#include <ot-gio-utils.h>
|
#include <ot-gio-utils.h>
|
||||||
#include <ot-fs-utils.h>
|
#include <ot-fs-utils.h>
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ echo 'ok documented symbols'
|
||||||
|
|
||||||
# ONLY update this checksum in release commits!
|
# ONLY update this checksum in release commits!
|
||||||
cat > released-sha256.txt <<EOF
|
cat > released-sha256.txt <<EOF
|
||||||
1f83814b9a785f9f612ee8f707dadb86d0dcbdc22603937575b7beefb26b50cc ${released_syms}
|
55f21380aa7f9ecc447a680b5c091692f2a0b98aa96ea00fba6aa6406aa69a5a ${released_syms}
|
||||||
EOF
|
EOF
|
||||||
sha256sum -c released-sha256.txt
|
sha256sum -c released-sha256.txt
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue