lib/sysroot: Support /usr/lib/modules/$kver for kernel/initramfs

This is the new Fedora kernel standard layout; it has the advantage
of being in `/usr` like `/usr/lib/ostree-boot`, but it's not OSTree
specific.

Further, I think in practice forcing tree builders to compute the checksum is an
annoying stumbling block; since we already switched to e.g. computing checksums
always when doing pulls, the cost of doing another checksum for the
kernel/initramfs is tiny. The "bootcsum" becomes more of an internal
implementation detail.

Now, there is a transition; my current thought for this is that rpm-ostree will
change to default to injecting into both `/usr/lib/ostree-boot` and
`/usr/lib/modules`, and stop doing `/boot`, then maybe next year say we drop the
`/usr/lib/ostree-boot` by default.

A twist here is that the default Fedora kernel RPM layout (and what's in
rpm-ostree today) includes a kernel but *not* an initramfs in
`/usr/lib/modules`. If we looked only there, we'd just find the kernel. So we
need to look in both, and then special case this - pick the legacy layout if we
have `/usr/lib/modules` but not an initramfs.

While here, rework the code to have an `OstreeKernelLayout` struct which makes
dealing with all of the variables nicer.

Closes: #1079
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-08-15 11:22:21 -04:00 committed by Atomic Bot
parent 984d22303d
commit 3ab0d5e664
5 changed files with 364 additions and 128 deletions

View File

@ -43,8 +43,13 @@ to a filesystem tree that represents the underlying basis of a
deployment. For short, we will call this the "tree", to
distinguish it from the concept of a deployment.
First, the tree must include a kernel stored as
`vmlinuz(-.*)?-$checksum` in either `/boot` or `/usr/lib/ostree-boot`.
First, the tree must include a kernel (and optionally an initramfs). The
current standard locations for these are `/usr/lib/modules/$kver/vmlinuz` and
`/usr/lib/modules/$kver/initramfs`. The "boot checksum" will be computed
automatically. This follows the current Fedora kernel layout, and is
the current recommended path. However, older versions of libostree don't
support this; you may need to also put kernels in the previous (legacy)
paths, which are `vmlinuz(-.*)?-$checksum` in either `/boot` or `/usr/lib/ostree-boot`.
The checksum should be a SHA256 hash of the kernel contents; it must be
pre-computed before storing the kernel in the repository. Optionally,
the directory can also contain an initramfs, stored as

View File

@ -882,46 +882,173 @@ ostree_sysroot_write_origin_file (OstreeSysroot *sysroot,
cancellable, error);
}
/* Originally OSTree defined kernels to be found underneath /boot
* in the tree. But that means when mounting /boot at runtime
* we end up masking the content underneath, triggering a warning.
*
* For that reason, and also consistency with the "/usr defines the OS" model we
* later switched to defining the in-tree kernels to be found under
* /usr/lib/ostree-boot.
*/
static gboolean
get_kernel_from_tree (int deployment_dfd,
int *out_boot_dfd,
char **out_kernel_srcpath,
char **out_kernel_namever,
char **out_initramfs_srcpath,
char **out_initramfs_namever,
char **out_bootcsum,
GCancellable *cancellable,
GError **error)
typedef struct {
int boot_dfd;
char *kernel_srcpath;
char *kernel_namever;
char *initramfs_srcpath;
char *initramfs_namever;
char *bootcsum;
} OstreeKernelLayout;
static void
_ostree_kernel_layout_free (OstreeKernelLayout *layout)
{
g_autofree char *ret_kernel_srcpath = NULL;
g_autofree char *ret_kernel_namever = NULL;
g_autofree char *ret_initramfs_srcpath = NULL;
g_autofree char *ret_initramfs_namever = NULL;
g_autofree char *kernel_checksum = NULL;
g_autofree char *initramfs_checksum = NULL;
if (layout->boot_dfd != -1)
(void) close (layout->boot_dfd);
g_free (layout->kernel_srcpath);
g_free (layout->kernel_namever);
g_free (layout->initramfs_srcpath);
g_free (layout->initramfs_namever);
g_free (layout->bootcsum);
g_free (layout);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeKernelLayout, _ostree_kernel_layout_free);
glnx_fd_close int ret_boot_dfd = glnx_opendirat_with_errno (deployment_dfd, "usr/lib/ostree-boot", TRUE);
if (ret_boot_dfd == -1)
static OstreeKernelLayout*
_ostree_kernel_layout_new (void)
{
OstreeKernelLayout *ret = g_new0 (OstreeKernelLayout, 1);
ret->boot_dfd = -1;
return ret;
}
/* See get_kernel_from_tree() below */
static gboolean
get_kernel_from_tree_usrlib_modules (int deployment_dfd,
OstreeKernelLayout **out_layout,
GCancellable *cancellable,
GError **error)
{
g_autofree char *kver = NULL;
/* Look in usr/lib/modules */
g_auto(GLnxDirFdIterator) mod_dfditer = { 0, };
gboolean exists;
if (!ot_dfd_iter_init_allow_noent (deployment_dfd, "usr/lib/modules", &mod_dfditer,
&exists, error))
return FALSE;
if (!exists)
{
if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "%s", "openat(usr/lib/ostree-boot)");
else
{
if (!glnx_opendirat (deployment_dfd, "boot", TRUE, &ret_boot_dfd, error))
return FALSE;
}
/* No usr/lib/modules? We're done */
*out_layout = NULL;
return TRUE;
}
g_autoptr(OstreeKernelLayout) ret_layout = _ostree_kernel_layout_new ();
/* Reusable buffer for path string */
g_autoptr(GString) pathbuf = g_string_new ("");
/* Loop until we find something that looks like a valid /usr/lib/modules/$kver */
while (ret_layout->boot_dfd == -1)
{
struct dirent *dent;
struct stat stbuf;
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&mod_dfditer, &dent, cancellable, error))
return FALSE;
if (dent == NULL)
break;
if (dent->d_type != DT_DIR)
continue;
/* It's a directory, look for /vmlinuz as a regular file */
g_string_truncate (pathbuf, 0);
g_string_append_printf (pathbuf, "%s/vmlinuz", dent->d_name);
if (fstatat (mod_dfditer.fd, pathbuf->str, &stbuf, 0) < 0)
{
if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "fstatat(%s)", pathbuf->str);
else
continue;
}
else
{
/* Not a regular file? Loop again */
if (!S_ISREG (stbuf.st_mode))
continue;
}
/* Looks valid, this should exit the loop */
if (!glnx_opendirat (mod_dfditer.fd, dent->d_name, FALSE, &ret_layout->boot_dfd, error))
return FALSE;
kver = g_strdup (dent->d_name);
ret_layout->kernel_srcpath = g_strdup ("vmlinuz");
ret_layout->kernel_namever = g_strdup_printf ("vmlinuz-%s", kver);
}
if (ret_layout->boot_dfd == -1)
{
*out_layout = NULL;
/* No kernel found? We're done. */
return TRUE;
}
/* We found a module directory, compute the checksum */
g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256);
glnx_fd_close int fd = -1;
/* Checksum the kernel */
if (!glnx_openat_rdonly (ret_layout->boot_dfd, "vmlinuz", TRUE, &fd, error))
return FALSE;
g_autoptr(GInputStream) in = g_unix_input_stream_new (fd, FALSE);
if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error))
return FALSE;
g_clear_object (&in);
(void) close (fd); fd = -1;
/* Look for an initramfs, but it's optional */
if (!ot_openat_ignore_enoent (ret_layout->boot_dfd, "initramfs", &fd, error))
return FALSE;
if (fd != -1)
{
ret_layout->initramfs_srcpath = g_strdup ("initramfs");
ret_layout->initramfs_namever = g_strdup_printf ("initramfs-%s", kver);
in = g_unix_input_stream_new (fd, FALSE);
if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error))
return FALSE;
}
ret_layout->bootcsum = g_strdup (g_checksum_get_string (checksum));
*out_layout = g_steal_pointer (&ret_layout);
return TRUE;
}
/* See get_kernel_from_tree() below */
static gboolean
get_kernel_from_tree_legacy_layouts (int deployment_dfd,
OstreeKernelLayout **out_layout,
GCancellable *cancellable,
GError **error)
{
const char *legacy_paths[] = {"usr/lib/ostree-boot", "boot"};
g_autofree char *kernel_checksum = NULL;
g_autofree char *initramfs_checksum = NULL;
g_autoptr(OstreeKernelLayout) ret_layout = _ostree_kernel_layout_new ();
for (guint i = 0; i < G_N_ELEMENTS (legacy_paths); i++)
{
const char *path = legacy_paths[i];
ret_layout->boot_dfd = glnx_opendirat_with_errno (deployment_dfd, path, TRUE);
if (ret_layout->boot_dfd == -1)
{
if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "openat(%s)", path);
}
else
break;
}
if (ret_layout->boot_dfd == -1)
{
/* No legacy found? We're done */
*out_layout = NULL;
return TRUE;
}
/* ret_layout->boot_dfd will point to either /usr/lib/ostree-boot or /boot, let's
* inspect it.
*/
g_auto(GLnxDirFdIterator) dfditer = { 0, };
if (!glnx_dirfd_iterator_init_at (ret_boot_dfd, ".", FALSE, &dfditer, error))
if (!glnx_dirfd_iterator_init_at (ret_layout->boot_dfd, ".", FALSE, &dfditer, error))
return FALSE;
while (TRUE)
@ -930,62 +1057,143 @@ get_kernel_from_tree (int deployment_dfd,
if (!glnx_dirfd_iterator_next_dent (&dfditer, &dent, cancellable, error))
return FALSE;
if (dent == NULL)
break;
const char *name = dent->d_name;
if (ret_kernel_srcpath == NULL && g_str_has_prefix (name, "vmlinuz-"))
/* See if this is the kernel */
if (ret_layout->kernel_srcpath == NULL && g_str_has_prefix (name, "vmlinuz-"))
{
const char *dash = strrchr (name, '-');
g_assert (dash);
/* In this version, we require that the tree builder generated a
* sha256 of the kernel+initramfs and appended it to the file names.
*/
if (ostree_validate_structureof_checksum_string (dash + 1, NULL))
{
kernel_checksum = g_strdup (dash + 1);
ret_kernel_srcpath = g_strdup (name);
ret_kernel_namever = g_strndup (name, dash - name);
ret_layout->kernel_srcpath = g_strdup (name);
ret_layout->kernel_namever = g_strndup (name, dash - name);
}
}
else if (ret_initramfs_srcpath == NULL && g_str_has_prefix (name, "initramfs-"))
/* See if this is the initramfs */
else if (ret_layout->initramfs_srcpath == NULL && g_str_has_prefix (name, "initramfs-"))
{
const char *dash = strrchr (name, '-');
g_assert (dash);
if (ostree_validate_structureof_checksum_string (dash + 1, NULL))
{
initramfs_checksum = g_strdup (dash + 1);
ret_initramfs_srcpath = g_strdup (name);
ret_initramfs_namever = g_strndup (name, dash - name);
ret_layout->initramfs_srcpath = g_strdup (name);
ret_layout->initramfs_namever = g_strndup (name, dash - name);
}
}
if (ret_kernel_srcpath != NULL && ret_initramfs_srcpath != NULL)
/* If we found both a kernel and initramfs, break out of the loop */
if (ret_layout->kernel_srcpath != NULL && ret_layout->initramfs_srcpath != NULL)
break;
}
if (ret_kernel_srcpath == NULL)
/* No kernel found? We're done */
if (ret_layout->kernel_srcpath == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Failed to find kernel in /usr/lib/ostree-boot or /boot");
return FALSE;
*out_layout = NULL;
return TRUE;
}
if (ret_initramfs_srcpath != NULL)
/* The kernel/initramfs checksums must be the same */
if (ret_layout->initramfs_srcpath != NULL)
{
g_assert (kernel_checksum != NULL);
g_assert (initramfs_checksum != NULL);
if (strcmp (kernel_checksum, initramfs_checksum) != 0)
return glnx_throw (error, "Mismatched kernel checksum vs initrd");
ret_layout->bootcsum = g_steal_pointer (&kernel_checksum);
}
*out_layout = g_steal_pointer (&ret_layout);
return TRUE;
}
/* Locate kernel/initramfs in the tree; the current standard is to look in
* /usr/lib/modules/$kver/vmlinuz first.
*
* Originally OSTree defined kernels to be found underneath /boot
* in the tree. But that means when mounting /boot at runtime
* we end up masking the content underneath, triggering a warning.
*
* For that reason, and also consistency with the "/usr defines the OS" model we
* later switched to defining the in-tree kernels to be found under
* /usr/lib/ostree-boot. But since then, Fedora at least switched to storing the
* kernel in /usr/lib/modules, which makes sense and isn't ostree-specific, so
* we prefer that now. However, the default Fedora layout doesn't put the
* initramfs there, so we need to look in /usr/lib/ostree-boot first.
*/
static gboolean
get_kernel_from_tree (int deployment_dfd,
OstreeKernelLayout **out_layout,
GCancellable *cancellable,
GError **error)
{
g_autoptr(OstreeKernelLayout) usrlib_modules_layout = NULL;
g_autoptr(OstreeKernelLayout) legacy_layout = NULL;
/* First, gather from usr/lib/modules/$kver if it exists */
if (!get_kernel_from_tree_usrlib_modules (deployment_dfd, &usrlib_modules_layout, cancellable, error))
return FALSE;
/* Gather the legacy layout */
if (!get_kernel_from_tree_legacy_layouts (deployment_dfd, &legacy_layout, cancellable, error))
return FALSE;
/* Evaluate the state of both layouts. If there's no legacy layout
* If a legacy layout exists, and it has
* an initramfs but the module layout doesn't, the legacy layout wins. This is
* what happens with rpm-ostree with Fedora today, until rpm-ostree learns the
* new layout.
*/
if (legacy_layout == NULL)
{
/* No legacy layout, let's see if we have a module layout...*/
if (usrlib_modules_layout == NULL)
{
/* Both layouts are not found? Throw. */
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Mismatched kernel checksum vs initrd");
"Failed to find kernel in /usr/lib/modules, /usr/lib/ostree-boot or /boot");
return FALSE;
}
else
{
/* No legacy, just usr/lib/modules? We're done */
*out_layout = g_steal_pointer (&usrlib_modules_layout);
return TRUE;
}
}
else if (usrlib_modules_layout != NULL &&
usrlib_modules_layout->initramfs_srcpath == NULL &&
legacy_layout->initramfs_srcpath != NULL)
{
/* Does the module path not have an initramfs, but the legacy does? Prefer
* the latter then, to make rpm-ostree work as is today.
*/
*out_layout = g_steal_pointer (&legacy_layout);
return TRUE;
}
/* Prefer module layout */
else if (usrlib_modules_layout != NULL)
{
*out_layout = g_steal_pointer (&usrlib_modules_layout);
return TRUE;
}
else
{
/* And finally fall back to legacy; we know one exists since we
* checked first above.
*/
g_assert (legacy_layout->kernel_srcpath);
*out_layout = g_steal_pointer (&legacy_layout);
return TRUE;
}
*out_boot_dfd = glnx_steal_fd (&ret_boot_dfd);
*out_kernel_srcpath = g_steal_pointer (&ret_kernel_srcpath);
*out_kernel_namever = g_steal_pointer (&ret_kernel_namever);
*out_initramfs_srcpath = g_steal_pointer (&ret_initramfs_srcpath);
*out_initramfs_namever = g_steal_pointer (&ret_initramfs_namever);
*out_bootcsum = g_steal_pointer (&kernel_checksum);
return TRUE;
}
/* We used to syncfs(), but that doesn't flush the journal on XFS,
@ -1315,18 +1523,8 @@ install_deployment_kernel (OstreeSysroot *sysroot,
return FALSE;
/* Find the kernel/initramfs in the tree */
glnx_fd_close int tree_boot_dfd = -1;
g_autofree char *tree_kernel_srcpath = NULL;
g_autofree char *tree_kernel_namever = NULL;
g_autofree char *tree_initramfs_srcpath = NULL;
g_autofree char *tree_initramfs_namever = NULL;
g_autofree char *tree_bootcsum = NULL;
if (!get_kernel_from_tree (deployment_dfd, &tree_boot_dfd,
&tree_kernel_srcpath,
&tree_kernel_namever,
&tree_initramfs_srcpath,
&tree_initramfs_namever,
&tree_bootcsum,
g_autoptr(OstreeKernelLayout) kernel_layout = NULL;
if (!get_kernel_from_tree (deployment_dfd, &kernel_layout,
cancellable, error))
return FALSE;
@ -1336,7 +1534,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
const char *osname = ostree_deployment_get_osname (deployment);
const char *bootcsum = ostree_deployment_get_bootcsum (deployment);
g_assert_cmpstr (bootcsum, ==, tree_bootcsum);
g_assert_cmpstr (kernel_layout->bootcsum, ==, bootcsum);
g_autofree char *bootcsumdir = g_strdup_printf ("ostree/%s-%s", osname, bootcsum);
g_autofree char *bootconfdir = g_strdup_printf ("loader.%d/entries", new_bootversion);
g_autofree char *bootconf_name = g_strdup_printf ("ostree-%s-%d.conf", osname,
@ -1355,12 +1553,13 @@ install_deployment_kernel (OstreeSysroot *sysroot,
* it doesn't exist already.
*/
struct stat stbuf;
if (fstatat (bootcsum_dfd, tree_kernel_namever, &stbuf, 0) != 0)
if (fstatat (bootcsum_dfd, kernel_layout->kernel_namever, &stbuf, 0) != 0)
{
if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "fstat %s", tree_kernel_namever);
if (!hardlink_or_copy_at (tree_boot_dfd, tree_kernel_srcpath,
bootcsum_dfd, tree_kernel_namever,
return glnx_throw_errno_prefix (error, "fstat %s", kernel_layout->kernel_namever);
if (!hardlink_or_copy_at (kernel_layout->boot_dfd,
kernel_layout->kernel_srcpath,
bootcsum_dfd, kernel_layout->kernel_namever,
sysroot->debug_flags,
cancellable, error))
return FALSE;
@ -1369,15 +1568,15 @@ install_deployment_kernel (OstreeSysroot *sysroot,
/* If we have an initramfs, then install it into
* /boot/ostree/osname-${bootcsum} if it doesn't exist already.
*/
if (tree_initramfs_srcpath)
if (kernel_layout->initramfs_srcpath)
{
g_assert (tree_initramfs_namever);
if (fstatat (bootcsum_dfd, tree_initramfs_namever, &stbuf, 0) != 0)
g_assert (kernel_layout->initramfs_namever);
if (fstatat (bootcsum_dfd, kernel_layout->initramfs_namever, &stbuf, 0) != 0)
{
if (errno != ENOENT)
return glnx_throw_errno_prefix (error, "fstat %s", tree_initramfs_namever);
if (!hardlink_or_copy_at (tree_boot_dfd, tree_initramfs_srcpath,
bootcsum_dfd, tree_initramfs_namever,
return glnx_throw_errno_prefix (error, "fstat %s", kernel_layout->initramfs_namever);
if (!hardlink_or_copy_at (kernel_layout->boot_dfd, kernel_layout->initramfs_srcpath,
bootcsum_dfd, kernel_layout->initramfs_namever,
sysroot->debug_flags,
cancellable, error))
return FALSE;
@ -1458,12 +1657,12 @@ install_deployment_kernel (OstreeSysroot *sysroot,
g_autofree char *version_key = g_strdup_printf ("%d", n_deployments - ostree_deployment_get_index (deployment));
ostree_bootconfig_parser_set (bootconfig, OSTREE_COMMIT_META_KEY_VERSION, version_key);
g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", tree_kernel_namever, NULL);
g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", kernel_layout->kernel_namever, NULL);
ostree_bootconfig_parser_set (bootconfig, "linux", boot_relpath);
if (tree_initramfs_namever)
if (kernel_layout->initramfs_namever)
{
g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", tree_initramfs_namever, NULL);
g_autofree char * boot_relpath = g_strconcat ("/", bootcsumdir, "/", kernel_layout->initramfs_namever, NULL);
ostree_bootconfig_parser_set (bootconfig, "initrd", boot_relpath);
}
@ -2084,22 +2283,12 @@ ostree_sysroot_deploy_tree (OstreeSysroot *self,
return FALSE;
}
glnx_fd_close int tree_boot_dfd = -1;
g_autofree char *tree_kernel_srcpath = NULL;
g_autofree char *tree_kernel_namever = NULL;
g_autofree char *tree_initramfs_srcpath = NULL;
g_autofree char *tree_initramfs_namever = NULL;
g_autofree char *tree_bootcsum = NULL;
if (!get_kernel_from_tree (deployment_dfd, &tree_boot_dfd,
&tree_kernel_srcpath,
&tree_kernel_namever,
&tree_initramfs_srcpath,
&tree_initramfs_namever,
&new_bootcsum,
g_autoptr(OstreeKernelLayout) kernel_layout = NULL;
if (!get_kernel_from_tree (deployment_dfd, &kernel_layout,
cancellable, error))
return FALSE;
_ostree_deployment_set_bootcsum (new_deployment, new_bootcsum);
_ostree_deployment_set_bootcsum (new_deployment, kernel_layout->bootcsum);
/* Create an empty boot configuration; we will merge things into
* it as we go.

View File

@ -366,7 +366,7 @@ setup_os_repository () {
shift
bootmode=$1
shift
bootdir=${1:-usr/lib/ostree-boot}
bootdir=${1:-usr/lib/modules/3.6.0}
oldpwd=`pwd`
@ -381,17 +381,24 @@ setup_os_repository () {
cd ${test_tmpdir}
mkdir osdata
cd osdata
mkdir -p usr/bin usr/lib/modules/3.6.0 usr/share usr/etc
mkdir -p ${bootdir}
echo "a kernel" > ${bootdir}/vmlinuz-3.6.0
echo "an initramfs" > ${bootdir}/initramfs-3.6.0
bootcsum=$(cat ${bootdir}/vmlinuz-3.6.0 ${bootdir}/initramfs-3.6.0 | sha256sum | cut -f 1 -d ' ')
mkdir -p usr/bin ${bootdir} usr/lib/modules/3.6.0 usr/share usr/etc
kernel_path=${bootdir}/vmlinuz
initramfs_path=${bootdir}/initramfs
# /usr/lib/modules just uses "vmlinuz", since the version is in the module
# directory name.
if [[ $bootdir != usr/lib/modules/* ]]; then
kernel_path=${kernel_path}-3.6.0
initramfs_path=${initramfs_path}-3.6.0
fi
echo "a kernel" > ${kernel_path}
echo "an initramfs" > ${initramfs_path}
bootcsum=$(cat ${kernel_path} ${initramfs_path} | sha256sum | cut -f 1 -d ' ')
export bootcsum
# Add the checksum for legacy dirs (/boot, /usr/lib/ostree-boot), but not
# /usr/lib/modules.
if [[ $bootdir != usr/lib/modules ]]; then
mv ${bootdir}/vmlinuz-3.6.0{,-${bootcsum}}
mv ${bootdir}/initramfs-3.6.0{,-${bootcsum}}
if [[ $bootdir != usr/lib/modules/* ]]; then
mv ${kernel_path}{,-${bootcsum}}
mv ${initramfs_path}{,-${bootcsum}}
fi
echo "an executable" > usr/bin/sh
@ -412,7 +419,7 @@ EOF
echo "a default daemon file" > usr/etc/testdirectory/test
${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string version=1.0.9 -b testos/buildmaster/x86_64-runtime -s "Build"
# Ensure these commits have distinct second timestamps
sleep 2
echo "a new executable" > usr/bin/sh
@ -447,7 +454,7 @@ EOF
setup_os_boot_grub2 "${bootmode}"
;;
esac
cd ${test_tmpdir}
mkdir ${test_tmpdir}/httpd
cd httpd
@ -465,17 +472,30 @@ os_repository_new_commit ()
branch=${3:-testos/buildmaster/x86_64-runtime}
echo "BOOT ITERATION: $boot_checksum_iteration"
cd ${test_tmpdir}/osdata
bootdir=usr/lib/ostree-boot
if ! test -d ${bootdir}; then
bootdir=boot
if test -f usr/lib/modules/3.6.0/vmlinuz; then
bootdir=usr/lib/modules/3.6.0
else
if test -d usr/lib/ostree-boot; then
bootdir=usr/lib/ostree-boot
else
bootdir=boot
fi
fi
rm ${bootdir}/*
echo "new: a kernel ${boot_checksum_iteration}" > ${bootdir}/vmlinuz-3.6.0
echo "new: an initramfs ${boot_checksum_iteration}" > ${bootdir}/initramfs-3.6.0
bootcsum=$(cat ${bootdir}/vmlinuz-3.6.0 ${bootdir}/initramfs-3.6.0 | sha256sum | cut -f 1 -d ' ')
kernel_path=${bootdir}/vmlinuz
initramfs_path=${bootdir}/initramfs
if [[ $bootdir != usr/lib/modules/* ]]; then
kernel_path=${kernel_path}-3.6.0
initramfs_path=${initramfs_path}-3.6.0
fi
echo "new: a kernel ${boot_checksum_iteration}" > ${kernel_path}
echo "new: an initramfs ${boot_checksum_iteration}" > ${initramfs_path}
bootcsum=$(cat ${kernel_path} ${initramfs_path} | sha256sum | cut -f 1 -d ' ')
export bootcsum
mv ${bootdir}/vmlinuz-3.6.0 ${bootdir}/vmlinuz-3.6.0-${bootcsum}
mv ${bootdir}/initramfs-3.6.0 ${bootdir}/initramfs-3.6.0-${bootcsum}
if [[ $bootdir != usr/lib/modules/* ]]; then
mv ${kernel_path}{,-${bootcsum}}
mv ${initramfs_path}{,-${bootcsum}}
fi
echo "a new default config file" > usr/etc/a-new-default-config-file
mkdir -p usr/etc/new-default-dir

View File

@ -19,7 +19,7 @@
set -euo pipefail
echo "1..20"
echo "1..22"
. $(dirname $0)/libtest.sh
@ -28,22 +28,43 @@ setup_os_repository "archive-z2" "syslinux"
. $(dirname $0)/admin-test.sh
# Test the legacy dirs
for test_bootdir in "boot" "usr/lib/ostree-boot"; do
cd ${test_tmpdir}
rm httpd osdata testos-repo sysroot -rf
setup_os_repository "archive" "syslinux" $test_bootdir
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmaster/x86_64-runtime
rev=$(${CMD_PREFIX} ostree --repo=sysroot/ostree/repo rev-parse testos/buildmaster/x86_64-runtime)
${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:testos/buildmaster/x86_64-runtime
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.* root=LABEL=MOO'
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.* quiet'
assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/vmlinuz-3.6.0 'a kernel'
assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/initramfs-3.6.0 'an initramfs'
# kernel/initrams should also be in the tree's /boot with the checksum
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/$test_bootdir/vmlinuz-3.6.0-${bootcsum} 'a kernel'
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/$test_bootdir/initramfs-3.6.0-${bootcsum} 'an initramfs'
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/etc/os-release 'NAME=TestOS'
assert_file_has_content sysroot/ostree/boot.1/testos/${bootcsum}/0/etc/os-release 'NAME=TestOS'
${CMD_PREFIX} ostree admin status
validate_bootloader
echo "ok kernel in $test_bootdir"
done
# And test that legacy overrides /usr/lib/modules
cd ${test_tmpdir}
rm httpd osdata testos-repo sysroot -rf
setup_os_repository "archive-z2" "syslinux" "boot"
setup_os_repository "archive" "syslinux" "usr/lib/ostree-boot"
cd osdata
echo "this is a kernel without an initramfs like Fedora 26" > usr/lib/modules/3.6.0/vmlinuz
usrlib_modules_bootcsum=$(cat usr/lib/modules/3.6.0/vmlinuz | sha256sum | cut -f 1 -d ' ')
${CMD_PREFIX} ostree --repo=${test_tmpdir}/testos-repo commit --add-metadata-string version=1.0.9 -b testos/buildmaster/x86_64-runtime -s "Build"
cd ${test_tmpdir}
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmaster/x86_64-runtime
rev=$(${CMD_PREFIX} ostree --repo=sysroot/ostree/repo rev-parse testos/buildmaster/x86_64-runtime)
${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:testos/buildmaster/x86_64-runtime
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.* root=LABEL=MOO'
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.* quiet'
assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/vmlinuz-3.6.0 'a kernel'
assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/initramfs-3.6.0 'an initramfs'
# kernel/initrams should also be in the tree's /boot with the checksum
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/boot/vmlinuz-3.6.0-${bootcsum} 'a kernel'
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/boot/initramfs-3.6.0-${bootcsum} 'an initramfs'
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/etc/os-release 'NAME=TestOS'
assert_file_has_content sysroot/ostree/boot.1/testos/${bootcsum}/0/etc/os-release 'NAME=TestOS'
${CMD_PREFIX} ostree admin status
validate_bootloader
echo "ok kernel in tree's /boot"
# Note this bootcsum shouldn't be the modules one
assert_not_streq "${bootcsum}" "${usrlib_modules_bootcsum}"
echo "ok kernel in /usr/lib/modules and /usr/lib/ostree-boot"

View File

@ -30,6 +30,7 @@ setup_os_repository "archive-z2" "uboot"
. $(dirname $0)/admin-test.sh
cd ${test_tmpdir}
mkdir -p osdata/usr/lib/ostree-boot
cat << 'EOF' > osdata/usr/lib/ostree-boot/uEnv.txt
loaduimage=load mmc ${bootpart} ${loadaddr} ${kernel_image}
loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}${fdtfile}