compose: Add rpmdb option, default to bdb
The design of https://fedoraproject.org/wiki/Changes/Sqlite_Rpmdb is problematic for us for multiple reasons. The first big reason is that rpm-ostree is designed for "cross" builds and e.g. today we use a Fedora-derived container to build RHEL CoreOS images. However the default database lives inside the `rpm` package which means that if we e.g. upgrade the coreos-assembler container to F33 it will suddenly try to use sqlite for RHCOS which is obviously broken. Related to this, rebases from f32 to f33 w/layered packages are broken: https://bugzilla.redhat.com/show_bug.cgi?id=1876194#c3 With this we can configure things to continue to use bdb for f33 for ostree-based systems, so that by enforcing an upgrade order f32 → f33 [bdb] → f34 [sqlite] ... the intermediate f33 w/bdb still understands sqlite and hence rebases will work.
This commit is contained in:
parent
cdf2c47b46
commit
456a3ec7c2
@ -94,6 +94,10 @@ It supports the following parameters:
|
|||||||
specific filesystem drivers are included. If not specified,
|
specific filesystem drivers are included. If not specified,
|
||||||
`--no-hostonly` will be used.
|
`--no-hostonly` will be used.
|
||||||
|
|
||||||
|
* `rpmdb`: String, optional: The RPM database backend. Can be one of
|
||||||
|
`bdb`, `ndb`, or `sqlite`. If unspecified, defaults to `bdb` for
|
||||||
|
compatibility.
|
||||||
|
|
||||||
* `cliwrap`: boolean, optional. Defaults to `false`. If enabled,
|
* `cliwrap`: boolean, optional. Defaults to `false`. If enabled,
|
||||||
rpm-ostree will replace binaries such as `/usr/bin/rpm` with
|
rpm-ostree will replace binaries such as `/usr/bin/rpm` with
|
||||||
wrappers that intercept unsafe operations, or adjust functionality.
|
wrappers that intercept unsafe operations, or adjust functionality.
|
||||||
|
@ -306,6 +306,7 @@ fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) {
|
|||||||
releasever,
|
releasever,
|
||||||
automatic_version_prefix,
|
automatic_version_prefix,
|
||||||
automatic_version_suffix,
|
automatic_version_suffix,
|
||||||
|
rpmdb,
|
||||||
mutate_os_release,
|
mutate_os_release,
|
||||||
preserve_passwd,
|
preserve_passwd,
|
||||||
check_passwd,
|
check_passwd,
|
||||||
@ -681,6 +682,16 @@ enum Include {
|
|||||||
Multiple(Vec<String>),
|
Multiple(Vec<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
/// The database backend; see https://github.com/coreos/fedora-coreos-tracker/issues/609
|
||||||
|
/// and https://fedoraproject.org/wiki/Changes/Sqlite_Rpmdb
|
||||||
|
enum RpmdbBackend {
|
||||||
|
BDB,
|
||||||
|
Sqlite,
|
||||||
|
NDB,
|
||||||
|
}
|
||||||
|
|
||||||
// Because of how we handle includes, *everything* here has to be
|
// Because of how we handle includes, *everything* here has to be
|
||||||
// Option<T>. The defaults live in the code (e.g. machineid-compat defaults
|
// Option<T>. The defaults live in the code (e.g. machineid-compat defaults
|
||||||
// to `true`).
|
// to `true`).
|
||||||
@ -821,6 +832,10 @@ struct TreeComposeConfig {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
#[serde(rename = "add-commit-metadata")]
|
#[serde(rename = "add-commit-metadata")]
|
||||||
add_commit_metadata: Option<BTreeMap<String, serde_json::Value>>,
|
add_commit_metadata: Option<BTreeMap<String, serde_json::Value>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
#[serde(rename = "rpmdb")]
|
||||||
|
// The database backend
|
||||||
|
rpmdb: Option<RpmdbBackend>,
|
||||||
|
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
legacy_fields: LegacyTreeComposeConfigFields,
|
legacy_fields: LegacyTreeComposeConfigFields,
|
||||||
@ -1026,6 +1041,7 @@ mutate-os-release: ${releasever}
|
|||||||
assert!(treefile.releasever.unwrap() == "30");
|
assert!(treefile.releasever.unwrap() == "30");
|
||||||
assert!(treefile.automatic_version_prefix.unwrap() == "30");
|
assert!(treefile.automatic_version_prefix.unwrap() == "30");
|
||||||
assert!(treefile.mutate_os_release.unwrap() == "30");
|
assert!(treefile.mutate_os_release.unwrap() == "30");
|
||||||
|
assert!(treefile.rpmdb.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1043,12 +1059,14 @@ gpg_key: foo
|
|||||||
boot_location: new
|
boot_location: new
|
||||||
default_target: bar
|
default_target: bar
|
||||||
automatic_version_prefix: baz
|
automatic_version_prefix: baz
|
||||||
|
rpmdb: sqlite
|
||||||
",
|
",
|
||||||
);
|
);
|
||||||
assert!(treefile.gpg_key.unwrap() == "foo");
|
assert!(treefile.gpg_key.unwrap() == "foo");
|
||||||
assert!(treefile.boot_location.unwrap() == BootLocation::New);
|
assert!(treefile.boot_location.unwrap() == BootLocation::New);
|
||||||
assert!(treefile.default_target.unwrap() == "bar");
|
assert!(treefile.default_target.unwrap() == "bar");
|
||||||
assert!(treefile.automatic_version_prefix.unwrap() == "baz");
|
assert!(treefile.automatic_version_prefix.unwrap() == "baz");
|
||||||
|
assert!(treefile.rpmdb.unwrap() == RpmdbBackend::Sqlite);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1512,6 +1530,17 @@ mod ffi {
|
|||||||
tf.parsed.readonly_executables.unwrap_or(false)
|
tf.parsed.readonly_executables.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ror_treefile_get_rpmdb(tf: *mut Treefile) -> *mut libc::c_char {
|
||||||
|
let tf = ref_from_raw_ptr(tf);
|
||||||
|
let s: &str = match tf.parsed.rpmdb.as_ref().unwrap_or(&RpmdbBackend::BDB) {
|
||||||
|
RpmdbBackend::BDB => "bdb",
|
||||||
|
RpmdbBackend::Sqlite => "sqlite",
|
||||||
|
RpmdbBackend::NDB => "ndb",
|
||||||
|
};
|
||||||
|
s.to_string().to_glib_full()
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn ror_treefile_free(tf: *mut Treefile) {
|
pub extern "C" fn ror_treefile_free(tf: *mut Treefile) {
|
||||||
if tf.is_null() {
|
if tf.is_null() {
|
||||||
|
@ -753,6 +753,15 @@ rpmostree_context_setup (RpmOstreeContext *self,
|
|||||||
/* This is what we use as default. */
|
/* This is what we use as default. */
|
||||||
dnf_context_set_rpm_macro (self->dnfctx, "_dbpath", "/" RPMOSTREE_RPMDB_LOCATION);
|
dnf_context_set_rpm_macro (self->dnfctx, "_dbpath", "/" RPMOSTREE_RPMDB_LOCATION);
|
||||||
|
|
||||||
|
/* Set the database backend only in the compose path. It then becomes the default
|
||||||
|
* for any client side layering.
|
||||||
|
*/
|
||||||
|
if (self->treefile_rs)
|
||||||
|
{
|
||||||
|
g_autofree char *rpmdb_backend = ror_treefile_get_rpmdb (self->treefile_rs);
|
||||||
|
dnf_context_set_rpm_macro (self->dnfctx, "_db_backend", rpmdb_backend);
|
||||||
|
}
|
||||||
|
|
||||||
if (!dnf_context_setup (self->dnfctx, cancellable, error))
|
if (!dnf_context_setup (self->dnfctx, cancellable, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -95,6 +95,11 @@ ostree --repo=${repo} ls -R ${treeref} /usr/etc/selinux > ls.txt
|
|||||||
assert_not_file_has_content ls.txt 'LOCK'
|
assert_not_file_has_content ls.txt 'LOCK'
|
||||||
echo "ok no leftover files"
|
echo "ok no leftover files"
|
||||||
|
|
||||||
|
ostree --repo=${repo} ls ${treeref} /usr/share/rpm > ls.txt
|
||||||
|
assert_file_has_content ls.txt /usr/share/rpm/Packages
|
||||||
|
assert_not_file_has_content ls.txt rpmdb.sqlite
|
||||||
|
echo "ok rpmdb is bdb"
|
||||||
|
|
||||||
ostree --repo=${repo} show ${treeref} \
|
ostree --repo=${repo} show ${treeref} \
|
||||||
--print-metadata-key rpmostree.rpmdb.pkglist > pkglist.txt
|
--print-metadata-key rpmostree.rpmdb.pkglist > pkglist.txt
|
||||||
assert_file_has_content pkglist.txt 'systemd'
|
assert_file_has_content pkglist.txt 'systemd'
|
||||||
|
Loading…
Reference in New Issue
Block a user