mirror of
https://github.com/ostreedev/ostree.git
synced 2025-01-18 10:04:17 +03:00
Merge pull request #2958 from cgwalters/deploy-loosen-etc-usretc
deploy: Support an empty `/etc` and populated `/usr/etc`
This commit is contained in:
commit
c57c00569c
@ -114,6 +114,7 @@ _installed_or_uninstalled_test_scripts = \
|
|||||||
tests/test-admin-deploy-none.sh \
|
tests/test-admin-deploy-none.sh \
|
||||||
tests/test-admin-deploy-bootid-gc.sh \
|
tests/test-admin-deploy-bootid-gc.sh \
|
||||||
tests/test-admin-deploy-whiteouts.sh \
|
tests/test-admin-deploy-whiteouts.sh \
|
||||||
|
tests/test-admin-deploy-emptyetc.sh \
|
||||||
tests/test-osupdate-dtb.sh \
|
tests/test-osupdate-dtb.sh \
|
||||||
tests/test-admin-instutil-set-kargs.sh \
|
tests/test-admin-instutil-set-kargs.sh \
|
||||||
tests/test-admin-upgrade-not-backwards.sh \
|
tests/test-admin-upgrade-not-backwards.sh \
|
||||||
|
@ -872,26 +872,80 @@ prepare_deployment_etc (OstreeSysroot *sysroot, OstreeRepo *repo, OstreeDeployme
|
|||||||
{
|
{
|
||||||
GLNX_AUTO_PREFIX_ERROR ("Preparing /etc", error);
|
GLNX_AUTO_PREFIX_ERROR ("Preparing /etc", error);
|
||||||
|
|
||||||
struct stat stbuf;
|
enum DirectoryState
|
||||||
if (!glnx_fstatat_allow_noent (deployment_dfd, "etc", &stbuf, AT_SYMLINK_NOFOLLOW, error))
|
{
|
||||||
|
DIRSTATE_NONEXISTENT,
|
||||||
|
DIRSTATE_EMPTY,
|
||||||
|
DIRSTATE_POPULATED,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DirectoryState etc_state;
|
||||||
|
{
|
||||||
|
gboolean exists = FALSE;
|
||||||
|
g_auto (GLnxDirFdIterator) dfd_iter = {
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
if (!ot_dfd_iter_init_allow_noent (deployment_dfd, "etc", &dfd_iter, &exists, error))
|
||||||
|
return glnx_prefix_error (error, "Failed to stat etc in deployment");
|
||||||
|
if (!exists)
|
||||||
|
{
|
||||||
|
etc_state = DIRSTATE_NONEXISTENT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct dirent *dent;
|
||||||
|
if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, NULL, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
gboolean etc_exists = (errno == 0);
|
if (dent)
|
||||||
|
etc_state = DIRSTATE_POPULATED;
|
||||||
|
else
|
||||||
|
etc_state = DIRSTATE_EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct stat stbuf;
|
||||||
if (!glnx_fstatat_allow_noent (deployment_dfd, "usr/etc", &stbuf, AT_SYMLINK_NOFOLLOW, error))
|
if (!glnx_fstatat_allow_noent (deployment_dfd, "usr/etc", &stbuf, AT_SYMLINK_NOFOLLOW, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
gboolean usretc_exists = (errno == 0);
|
gboolean usretc_exists = (errno == 0);
|
||||||
|
|
||||||
if (etc_exists)
|
switch (etc_state)
|
||||||
|
{
|
||||||
|
case DIRSTATE_NONEXISTENT:
|
||||||
|
break;
|
||||||
|
case DIRSTATE_EMPTY:
|
||||||
{
|
{
|
||||||
if (usretc_exists)
|
if (usretc_exists)
|
||||||
|
{
|
||||||
|
/* For now it's actually simpler to just remove the empty directory
|
||||||
|
* and have a symmetrical code path.
|
||||||
|
*/
|
||||||
|
if (unlinkat (deployment_dfd, "etc", AT_REMOVEDIR) < 0)
|
||||||
|
return glnx_throw_errno_prefix (error, "Failed to remove empty etc");
|
||||||
|
etc_state = DIRSTATE_NONEXISTENT;
|
||||||
|
}
|
||||||
|
/* Otherwise, there's no /etc or /usr/etc, we'll assume they know what they're doing... */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIRSTATE_POPULATED:
|
||||||
|
{
|
||||||
|
if (usretc_exists)
|
||||||
|
{
|
||||||
return glnx_throw (error, "Tree contains both /etc and /usr/etc");
|
return glnx_throw (error, "Tree contains both /etc and /usr/etc");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Compatibility hack */
|
/* Compatibility hack */
|
||||||
if (!glnx_renameat (deployment_dfd, "etc", deployment_dfd, "usr/etc", error))
|
if (!glnx_renameat (deployment_dfd, "etc", deployment_dfd, "usr/etc", error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
etc_state = DIRSTATE_NONEXISTENT;
|
||||||
usretc_exists = TRUE;
|
usretc_exists = TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (usretc_exists)
|
if (usretc_exists)
|
||||||
{
|
{
|
||||||
|
g_assert (etc_state == DIRSTATE_NONEXISTENT);
|
||||||
/* We need copies of /etc from /usr/etc (so admins can use vi), and if
|
/* We need copies of /etc from /usr/etc (so admins can use vi), and if
|
||||||
* SELinux is enabled, we need to relabel.
|
* SELinux is enabled, we need to relabel.
|
||||||
*/
|
*/
|
||||||
|
33
tests/test-admin-deploy-emptyetc.sh
Executable file
33
tests/test-admin-deploy-emptyetc.sh
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: LGPL-2.0+
|
||||||
|
#
|
||||||
|
# This library 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 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
. $(dirname $0)/libtest.sh
|
||||||
|
|
||||||
|
setup_os_repository "archive" "syslinux"
|
||||||
|
|
||||||
|
echo "1..1"
|
||||||
|
cd ${test_tmpdir}/osdata
|
||||||
|
mkdir etc
|
||||||
|
${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string "version=42.etc" -b testos/buildmain/x86_64-runtime
|
||||||
|
cd -
|
||||||
|
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmain/x86_64-runtime
|
||||||
|
${CMD_PREFIX} ostree admin deploy --os=testos testos:testos/buildmain/x86_64-runtime
|
||||||
|
origdeployment=$(${CMD_PREFIX} ostree admin --sysroot=sysroot --print-current-dir)
|
||||||
|
assert_file_has_content ${origdeployment}/etc/NetworkManager/nm.conf "a default daemon file"
|
||||||
|
echo "ok empty etc"
|
Loading…
x
Reference in New Issue
Block a user