mirror of
https://github.com/ostreedev/ostree.git
synced 2025-03-19 22:50:35 +03:00
Add bare-user-only repo mode
This mode is similar to bare-user, but does not store the permission, ownership (uid/gid) and xattrs in an xattr on the file objects in the repo. Additionally it stores symlinks as symlinks rather than as regular files+xattrs, like the bare mode. The later is needed because we can't store the is-symlink in the xattr. This means that some metadata is lost, such as the uid. When reading a repo like this we always report uid, gid as 0, and no xattrs, so unless this is true in the commit the resulting repository will not fsck correctly. However, it the main usecase of the repository is to check out with --user-mode, then no information is lost, and the repository can work on filesystems without xattrs (such as tmpfs). Closes: #750 Approved by: cgwalters
This commit is contained in:
parent
612150f143
commit
be28c10849
@ -144,7 +144,8 @@ _ostree_repo_mode_is_bare (OstreeRepoMode mode)
|
||||
{
|
||||
return
|
||||
mode == OSTREE_REPO_MODE_BARE ||
|
||||
mode == OSTREE_REPO_MODE_BARE_USER;
|
||||
mode == OSTREE_REPO_MODE_BARE_USER ||
|
||||
mode == OSTREE_REPO_MODE_BARE_USER_ONLY;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
|
@ -179,6 +179,7 @@ typedef enum {
|
||||
* @OSTREE_REPO_MODE_BARE: Files are stored as themselves; checkouts are hardlinks; can only be written as root
|
||||
* @OSTREE_REPO_MODE_ARCHIVE_Z2: Files are compressed, should be owned by non-root. Can be served via HTTP
|
||||
* @OSTREE_REPO_MODE_BARE_USER: Files are stored as themselves, except ownership; can be written by user. Hardlinks work only in user checkouts.
|
||||
* @OSTREE_REPO_MODE_BARE_USER_ONLY: Same as BARE_USER, but all metadata is not stored, so it can only be used for user checkouts. Does not need xattrs.
|
||||
*
|
||||
* See the documentation of #OstreeRepo for more information about the
|
||||
* possible modes.
|
||||
@ -186,7 +187,8 @@ typedef enum {
|
||||
typedef enum {
|
||||
OSTREE_REPO_MODE_BARE,
|
||||
OSTREE_REPO_MODE_ARCHIVE_Z2,
|
||||
OSTREE_REPO_MODE_BARE_USER
|
||||
OSTREE_REPO_MODE_BARE_USER,
|
||||
OSTREE_REPO_MODE_BARE_USER_ONLY,
|
||||
} OstreeRepoMode;
|
||||
|
||||
_OSTREE_PUBLIC
|
||||
|
@ -473,7 +473,9 @@ checkout_one_file_at (OstreeRepo *repo,
|
||||
(current_repo->mode == OSTREE_REPO_MODE_BARE_USER
|
||||
&& options->mode == OSTREE_REPO_CHECKOUT_MODE_USER
|
||||
/* NOTE: bare-user symlinks are not stored as symlinks */
|
||||
&& !is_symlink));
|
||||
&& !is_symlink) ||
|
||||
(current_repo->mode == OSTREE_REPO_MODE_BARE_USER_ONLY
|
||||
&& options->mode == OSTREE_REPO_CHECKOUT_MODE_USER));
|
||||
gboolean current_can_cache = (options->enable_uncompressed_cache
|
||||
&& current_repo->enable_uncompressed_cache);
|
||||
gboolean is_archive_z2_with_cache = (current_repo->mode == OSTREE_REPO_MODE_ARCHIVE_Z2
|
||||
@ -862,6 +864,9 @@ ostree_repo_checkout_tree (OstreeRepo *self,
|
||||
{
|
||||
OstreeRepoCheckoutAtOptions options = { 0, };
|
||||
|
||||
if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_BARE_USER_ONLY)
|
||||
mode = OSTREE_REPO_CHECKOUT_MODE_USER;
|
||||
|
||||
options.mode = mode;
|
||||
options.overwrite_mode = overwrite_mode;
|
||||
/* Backwards compatibility */
|
||||
@ -948,6 +953,7 @@ ostree_repo_checkout_at (OstreeRepo *self,
|
||||
GError **error)
|
||||
{
|
||||
OstreeRepoCheckoutAtOptions default_options = { 0, };
|
||||
OstreeRepoCheckoutAtOptions real_options;
|
||||
|
||||
if (!options)
|
||||
{
|
||||
@ -955,6 +961,13 @@ ostree_repo_checkout_at (OstreeRepo *self,
|
||||
options = &default_options;
|
||||
}
|
||||
|
||||
/* Make a copy so we can modify the options */
|
||||
real_options = *options;
|
||||
options = &real_options;
|
||||
|
||||
if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_BARE_USER_ONLY)
|
||||
options->mode = OSTREE_REPO_CHECKOUT_MODE_USER;
|
||||
|
||||
g_autoptr(GFile) commit_root = (GFile*) _ostree_repo_file_new_for_commit (self, commit, error);
|
||||
if (!commit_root)
|
||||
return FALSE;
|
||||
|
@ -227,7 +227,11 @@ commit_loose_object_trusted (OstreeRepo *self,
|
||||
}
|
||||
|
||||
/* Special handling for symlinks in bare repositories */
|
||||
if (object_is_symlink && self->mode == OSTREE_REPO_MODE_BARE)
|
||||
if (object_is_symlink && self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY)
|
||||
{
|
||||
/* We don't store the metadata in bare-user-only, so we're done. */
|
||||
}
|
||||
else if (object_is_symlink && self->mode == OSTREE_REPO_MODE_BARE)
|
||||
{
|
||||
/* Now that we know the checksum is valid, apply uid/gid, mode bits,
|
||||
* and extended attributes.
|
||||
@ -283,7 +287,8 @@ commit_loose_object_trusted (OstreeRepo *self,
|
||||
}
|
||||
}
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE && self->mode == OSTREE_REPO_MODE_BARE_USER)
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE &&
|
||||
(self->mode == OSTREE_REPO_MODE_BARE_USER || self->mode == OSTREE_REPO_MODE_BARE_USER_ONLY))
|
||||
{
|
||||
if (!object_is_symlink)
|
||||
{
|
||||
@ -302,7 +307,8 @@ commit_loose_object_trusted (OstreeRepo *self,
|
||||
}
|
||||
}
|
||||
|
||||
if (!write_file_metadata_to_xattr (fd, uid, gid, mode, xattrs, error))
|
||||
if (self->mode == OSTREE_REPO_MODE_BARE_USER &&
|
||||
!write_file_metadata_to_xattr (fd, uid, gid, mode, xattrs, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -708,8 +714,10 @@ write_object (OstreeRepo *self,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else if (repo_mode == OSTREE_REPO_MODE_BARE && temp_file_is_symlink)
|
||||
else if (_ostree_repo_mode_is_bare (repo_mode) && temp_file_is_symlink)
|
||||
{
|
||||
/* Note: This will not be hit for bare-user mode because its converted to a
|
||||
regular file and take the branch above */
|
||||
if (!_ostree_make_temporary_symlink_at (self->tmp_dir_fd,
|
||||
g_file_info_get_symlink_target (file_info),
|
||||
&temp_filename,
|
||||
@ -959,6 +967,7 @@ scan_one_loose_devino (OstreeRepo *self,
|
||||
case OSTREE_REPO_MODE_ARCHIVE_Z2:
|
||||
case OSTREE_REPO_MODE_BARE:
|
||||
case OSTREE_REPO_MODE_BARE_USER:
|
||||
case OSTREE_REPO_MODE_BARE_USER_ONLY:
|
||||
skip = !g_str_has_suffix (name, ".file");
|
||||
break;
|
||||
default:
|
||||
|
@ -1754,6 +1754,9 @@ ostree_repo_mode_to_string (OstreeRepoMode mode,
|
||||
case OSTREE_REPO_MODE_BARE_USER:
|
||||
ret_mode = "bare-user";
|
||||
break;
|
||||
case OSTREE_REPO_MODE_BARE_USER_ONLY:
|
||||
ret_mode = "bare-user-only";
|
||||
break;
|
||||
case OSTREE_REPO_MODE_ARCHIVE_Z2:
|
||||
ret_mode ="archive-z2";
|
||||
break;
|
||||
@ -1781,6 +1784,8 @@ ostree_repo_mode_from_string (const char *mode,
|
||||
ret_mode = OSTREE_REPO_MODE_BARE;
|
||||
else if (strcmp (mode, "bare-user") == 0)
|
||||
ret_mode = OSTREE_REPO_MODE_BARE_USER;
|
||||
else if (strcmp (mode, "bare-user-only") == 0)
|
||||
ret_mode = OSTREE_REPO_MODE_BARE_USER_ONLY;
|
||||
else if (strcmp (mode, "archive-z2") == 0 ||
|
||||
strcmp (mode, "archive") == 0)
|
||||
ret_mode = OSTREE_REPO_MODE_ARCHIVE_Z2;
|
||||
@ -2907,6 +2912,37 @@ ostree_repo_load_file (OstreeRepo *self,
|
||||
g_file_info_set_symlink_target (ret_file_info, targetbuf);
|
||||
}
|
||||
}
|
||||
else if (repo_mode == OSTREE_REPO_MODE_BARE_USER_ONLY)
|
||||
{
|
||||
glnx_fd_close int fd = -1;
|
||||
|
||||
/* Canonical info is: uid/gid is 0 and no xattrs, which
|
||||
might be wrong and thus not validate correctly, but
|
||||
at least we report something consistent. */
|
||||
g_file_info_set_attribute_uint32 (ret_file_info, "unix::uid", 0);
|
||||
g_file_info_set_attribute_uint32 (ret_file_info, "unix::gid", 0);
|
||||
|
||||
if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR &&
|
||||
out_input)
|
||||
{
|
||||
fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret_input = g_unix_input_stream_new (fd, TRUE);
|
||||
fd = -1; /* Transfer ownership */
|
||||
}
|
||||
|
||||
if (out_xattrs)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)"));
|
||||
ret_xattrs = g_variant_ref_sink (g_variant_builder_end (&builder));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert (repo_mode == OSTREE_REPO_MODE_BARE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user