mirror of
https://github.com/ostreedev/ostree.git
synced 2025-01-21 22:04:15 +03:00
checkout: add an extra checkout_overwrite mode
This is for issue projectatomic/rpm-ostree#365, an extra option of overwrite mode is added to the checkout command so that when there is "non-directory" file already exist during checkout, the error will be handled. Some tests are added for regression Closes: #1116 Approved by: cgwalters
This commit is contained in:
parent
12114ce382
commit
f07432d4ce
@ -696,6 +696,7 @@ _ostree_checkout() {
|
|||||||
--require-hardlinks -H
|
--require-hardlinks -H
|
||||||
--union
|
--union
|
||||||
--union-add
|
--union-add
|
||||||
|
--disjoint-union
|
||||||
--user-mode -U
|
--user-mode -U
|
||||||
--whiteouts
|
--whiteouts
|
||||||
"
|
"
|
||||||
|
@ -97,6 +97,14 @@ Boston, MA 02111-1307, USA.
|
|||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--disjoint-union</option></term>
|
||||||
|
|
||||||
|
<listitem><para>
|
||||||
|
When layering checkouts, error out if a file would be replaced, but add new files and directories
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--allow-noent</option></term>
|
<term><option>--allow-noent</option></term>
|
||||||
|
|
||||||
|
@ -654,7 +654,8 @@ checkout_tree_at_recurse (OstreeRepo *self,
|
|||||||
{
|
{
|
||||||
if (errno == EEXIST &&
|
if (errno == EEXIST &&
|
||||||
(options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES
|
(options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES
|
||||||
|| options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES))
|
|| options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES
|
||||||
|
|| options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_DISJOINT_UNION_FILES))
|
||||||
did_exist = TRUE;
|
did_exist = TRUE;
|
||||||
else
|
else
|
||||||
return glnx_throw_errno (error);
|
return glnx_throw_errno (error);
|
||||||
|
@ -832,11 +832,13 @@ typedef enum {
|
|||||||
* @OSTREE_REPO_CHECKOUT_OVERWRITE_NONE: No special options
|
* @OSTREE_REPO_CHECKOUT_OVERWRITE_NONE: No special options
|
||||||
* @OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES: When layering checkouts, unlink() and replace existing files, but do not modify existing directories
|
* @OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES: When layering checkouts, unlink() and replace existing files, but do not modify existing directories
|
||||||
* @OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES: Only add new files/directories
|
* @OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES: Only add new files/directories
|
||||||
|
* @OSTREE_REPO_CHECKOUT_OVERWRITE_DISJOINT_UNION_FILES: When layering checkouts, error out if a file would be replaced, but add new files and directories
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OSTREE_REPO_CHECKOUT_OVERWRITE_NONE = 0,
|
OSTREE_REPO_CHECKOUT_OVERWRITE_NONE = 0,
|
||||||
OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES = 1,
|
OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES = 1,
|
||||||
OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES = 2, /* Since: 2017.3 */
|
OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES = 2, /* Since: 2017.3 */
|
||||||
|
OSTREE_REPO_CHECKOUT_OVERWRITE_DISJOINT_UNION_FILES = 3 /* Since: 2017.11 */
|
||||||
} OstreeRepoCheckoutOverwriteMode;
|
} OstreeRepoCheckoutOverwriteMode;
|
||||||
|
|
||||||
_OSTREE_PUBLIC
|
_OSTREE_PUBLIC
|
||||||
|
@ -37,6 +37,7 @@ static gboolean opt_disable_cache;
|
|||||||
static char *opt_subpath;
|
static char *opt_subpath;
|
||||||
static gboolean opt_union;
|
static gboolean opt_union;
|
||||||
static gboolean opt_union_add;
|
static gboolean opt_union_add;
|
||||||
|
static gboolean opt_disjoint_union;
|
||||||
static gboolean opt_whiteouts;
|
static gboolean opt_whiteouts;
|
||||||
static gboolean opt_from_stdin;
|
static gboolean opt_from_stdin;
|
||||||
static char *opt_from_file;
|
static char *opt_from_file;
|
||||||
@ -72,6 +73,7 @@ static GOptionEntry options[] = {
|
|||||||
{ "subpath", 0, 0, G_OPTION_ARG_FILENAME, &opt_subpath, "Checkout sub-directory PATH", "PATH" },
|
{ "subpath", 0, 0, G_OPTION_ARG_FILENAME, &opt_subpath, "Checkout sub-directory PATH", "PATH" },
|
||||||
{ "union", 0, 0, G_OPTION_ARG_NONE, &opt_union, "Keep existing directories, overwrite existing files", NULL },
|
{ "union", 0, 0, G_OPTION_ARG_NONE, &opt_union, "Keep existing directories, overwrite existing files", NULL },
|
||||||
{ "union-add", 0, 0, G_OPTION_ARG_NONE, &opt_union_add, "Keep existing files/directories, only add new", NULL },
|
{ "union-add", 0, 0, G_OPTION_ARG_NONE, &opt_union_add, "Keep existing files/directories, only add new", NULL },
|
||||||
|
{ "disjoint-union", 0, 0, G_OPTION_ARG_NONE, &opt_disjoint_union, "When layering checkouts, error out if a file would be replaced, but add new files and directories", NULL },
|
||||||
{ "whiteouts", 0, 0, G_OPTION_ARG_NONE, &opt_whiteouts, "Process 'whiteout' (Docker style) entries", NULL },
|
{ "whiteouts", 0, 0, G_OPTION_ARG_NONE, &opt_whiteouts, "Process 'whiteout' (Docker style) entries", NULL },
|
||||||
{ "allow-noent", 0, 0, G_OPTION_ARG_NONE, &opt_allow_noent, "Do nothing if specified path does not exist", NULL },
|
{ "allow-noent", 0, 0, G_OPTION_ARG_NONE, &opt_allow_noent, "Do nothing if specified path does not exist", NULL },
|
||||||
{ "from-stdin", 0, 0, G_OPTION_ARG_NONE, &opt_from_stdin, "Process many checkouts from standard input", NULL },
|
{ "from-stdin", 0, 0, G_OPTION_ARG_NONE, &opt_from_stdin, "Process many checkouts from standard input", NULL },
|
||||||
@ -99,7 +101,7 @@ process_one_checkout (OstreeRepo *repo,
|
|||||||
* convenient infrastructure for testing C APIs with data.
|
* convenient infrastructure for testing C APIs with data.
|
||||||
*/
|
*/
|
||||||
if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks ||
|
if (opt_disable_cache || opt_whiteouts || opt_require_hardlinks ||
|
||||||
opt_union_add || opt_force_copy || opt_bareuseronly_dirs)
|
opt_union_add || opt_force_copy || opt_bareuseronly_dirs || opt_disjoint_union)
|
||||||
{
|
{
|
||||||
OstreeRepoCheckoutAtOptions options = { 0, };
|
OstreeRepoCheckoutAtOptions options = { 0, };
|
||||||
|
|
||||||
@ -112,6 +114,18 @@ process_one_checkout (OstreeRepo *repo,
|
|||||||
"Cannot specify both --union and --union-add");
|
"Cannot specify both --union and --union-add");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if (opt_union && opt_disjoint_union)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Cannot specify both --union and --disjoint-union");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (opt_union_add && opt_disjoint_union)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
"Cannot specify both --union-add and --disjoint-union ");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (opt_require_hardlinks && opt_force_copy)
|
if (opt_require_hardlinks && opt_force_copy)
|
||||||
{
|
{
|
||||||
glnx_throw (error, "Cannot specify both --require-hardlinks and --force-copy");
|
glnx_throw (error, "Cannot specify both --require-hardlinks and --force-copy");
|
||||||
@ -121,6 +135,8 @@ process_one_checkout (OstreeRepo *repo,
|
|||||||
options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
|
options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
|
||||||
else if (opt_union_add)
|
else if (opt_union_add)
|
||||||
options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES;
|
options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES;
|
||||||
|
else if (opt_disjoint_union)
|
||||||
|
options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_DISJOINT_UNION_FILES;
|
||||||
if (opt_whiteouts)
|
if (opt_whiteouts)
|
||||||
options.process_whiteouts = TRUE;
|
options.process_whiteouts = TRUE;
|
||||||
if (subpath)
|
if (subpath)
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "1..$((70 + ${extra_basic_tests:-0}))"
|
echo "1..$((72 + ${extra_basic_tests:-0}))"
|
||||||
|
|
||||||
$CMD_PREFIX ostree --version > version.yaml
|
$CMD_PREFIX ostree --version > version.yaml
|
||||||
python -c 'import yaml; yaml.safe_load(open("version.yaml"))'
|
python -c 'import yaml; yaml.safe_load(open("version.yaml"))'
|
||||||
@ -469,6 +469,32 @@ assert_file_has_content checkout-test-union-add/union-add-test 'existing file fo
|
|||||||
assert_file_has_content checkout-test-union-add/union-add-test2 'another file for union add testing'
|
assert_file_has_content checkout-test-union-add/union-add-test2 'another file for union add testing'
|
||||||
echo "ok checkout union add"
|
echo "ok checkout union add"
|
||||||
|
|
||||||
|
# Create some new files for testing
|
||||||
|
cd ${test_tmpdir}
|
||||||
|
mkdir disjoint-union-test
|
||||||
|
mkdir disjoint-union-test/test_one
|
||||||
|
chmod a+w disjoint-union-test/test_one
|
||||||
|
echo 'file for add dirs testing' > disjoint-union-test/test_one/test_file
|
||||||
|
$OSTREE commit ${COMMIT_ARGS} -b test-disjoint-union --tree=dir=disjoint-union-test
|
||||||
|
$OSTREE checkout --disjoint-union test-disjoint-union checkout-test-disjoint-union
|
||||||
|
echo "ok adding new directories and new file"
|
||||||
|
# Make a new file, and try the checkout again
|
||||||
|
echo 'second test file' > disjoint-union-test/test_one/test_second_file
|
||||||
|
$OSTREE commit ${COMMIT_ARGS} -b test-disjoint-union --tree=dir=disjoint-union-test
|
||||||
|
# Check out the latest commit, should fail due to presence of existing files
|
||||||
|
if $OSTREE checkout --disjoint-union test-disjoint-union checkout-test-disjoint-union 2> err.txt; then
|
||||||
|
assert_not_reached "checking out files unexpectedly succeeded!"
|
||||||
|
fi
|
||||||
|
assert_file_has_content err.txt 'File exists'
|
||||||
|
# Verify that Union mode still functions properly
|
||||||
|
rm checkout-test-disjoint-union/test_one/test_file
|
||||||
|
echo 'file for testing union mode alongwith disjoint-union mode' > checkout-test-disjoint-union/test_one/test_file
|
||||||
|
$OSTREE checkout --union test-disjoint-union checkout-test-disjoint-union
|
||||||
|
assert_has_file checkout-test-disjoint-union/test_one/test_second_file
|
||||||
|
# This shows the file with same name has been successfully overwriten
|
||||||
|
assert_file_has_content checkout-test-disjoint-union/test_one/test_file 'file for add dirs testing'
|
||||||
|
echo "ok checkout disjoint union"
|
||||||
|
|
||||||
cd ${test_tmpdir}
|
cd ${test_tmpdir}
|
||||||
rm files -rf && mkdir files
|
rm files -rf && mkdir files
|
||||||
mkdir files/worldwritable-dir
|
mkdir files/worldwritable-dir
|
||||||
|
Loading…
x
Reference in New Issue
Block a user