Move "ignored script list" to Rust, drop gperf

Rust has a nice crate for doing perfect hashing.  Move that
code into Rust and drop the dependency on `gperf`.  This also
helps move away from Autotools.
This commit is contained in:
Colin Walters 2020-12-23 17:01:33 +00:00 committed by OpenShift Merge Robot
parent c96ad53dcf
commit 562acedbaa
10 changed files with 132 additions and 130 deletions

61
Cargo.lock generated
View File

@ -771,6 +771,50 @@ dependencies = [
"system-deps",
]
[[package]]
name = "phf"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
dependencies = [
"phf_macros",
"phf_shared",
"proc-macro-hack",
]
[[package]]
name = "phf_generator"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_macros"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c"
dependencies = [
"phf_generator",
"phf_shared",
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "phf_shared"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
dependencies = [
"siphasher",
]
[[package]]
name = "pin-project"
version = "0.4.27"
@ -893,6 +937,7 @@ dependencies = [
"rand_chacha",
"rand_core",
"rand_hc",
"rand_pcg",
]
[[package]]
@ -923,6 +968,15 @@ dependencies = [
"rand_core",
]
[[package]]
name = "rand_pcg"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
dependencies = [
"rand_core",
]
[[package]]
name = "rayon"
version = "1.5.0"
@ -1002,6 +1056,7 @@ dependencies = [
"openat-ext",
"ostree",
"ostree-sys",
"phf",
"rand",
"rayon",
"serde",
@ -1076,6 +1131,12 @@ dependencies = [
"yaml-rust",
]
[[package]]
name = "siphasher"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
[[package]]
name = "slab"
version = "0.4.2"

View File

@ -28,6 +28,7 @@ curl = "0.4.34"
rayon = "1.5.0"
c_utf8 = "0.1.0"
rand = "0.7.3"
phf = { version = "0.8", features = ["macros"] }
systemd = "0.8.1"
indicatif = "0.15.0"
lazy_static = "1.4.0"

View File

@ -69,20 +69,6 @@ librpmostreepriv_sources += \
$(NULL)
endif
gperf_gperf_sources = src/libpriv/rpmostree-script-gperf.gperf
BUILT_SOURCES += $(gperf_gperf_sources:-gperf.gperf=-gperf.c)
CLEANFILES += $(gperf_gperf_sources:-gperf.gperf=-gperf.c)
nodist_librpmostreepriv_sources = src/libpriv/rpmostree-script-gperf.c
AM_V_GPERF = $(AM_V_GPERF_$(V))
AM_V_GPERF_ = $(AM_V_GPERF_$(AM_DEFAULT_VERBOSITY))
AM_V_GPERF_0 = @echo " GPERF " $@;
src/%.c: src/%.gperf Makefile
$(AM_V_at)$(MKDIR_P) $(dir $@)
$(AM_V_GPERF)$(GPERF) < $< > $@.tmp && mv $@.tmp $@
# Also we now use cxx.rs
rpmostree-cxxrs.h: rust/src/lib.rs
$(AM_V_GEN) cxxbridge rust/src/lib.rs --header > $@

View File

@ -115,31 +115,6 @@ AC_PATH_PROG([XSLTPROC], [xsltproc])
GLIB_TESTS
LIBGLNX_CONFIGURE
AC_CHECK_TOOL(GPERF, gperf)
AS_IF([test -z "$GPERF"],
AC_MSG_ERROR([*** gperf not found])
)
dnl stolen from https://github.com/systemd/systemd/commit/c9f7b4d
GPERF_TEST="$(echo foo,bar | ${GPERF} -L ANSI-C)"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([
#include <string.h>
const char * in_word_set(const char *, size_t);
$GPERF_TEST]
)],
[GPERF_LEN_TYPE=size_t],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([
#include <string.h>
const char * in_word_set(const char *, unsigned);
$GPERF_TEST]
)],
[GPERF_LEN_TYPE=unsigned],
[AC_MSG_ERROR([** unable to determine gperf len type])]
)]
)
AC_DEFINE_UNQUOTED([GPERF_LEN_TYPE], [$GPERF_LEN_TYPE], [gperf len type])
m4_ifdef([GOBJECT_INTROSPECTION_CHECK], [
GOBJECT_INTROSPECTION_CHECK([1.34.0])
])

View File

@ -41,7 +41,6 @@ BuildRequires: autoconf automake libtool git
# For docs
BuildRequires: chrpath
BuildRequires: gtk-doc
BuildRequires: gperf
BuildRequires: gnome-common
BuildRequires: /usr/bin/g-ir-scanner
# Core requirements

View File

@ -27,6 +27,11 @@ mod ffi {
fn get_dracut_random_cpio() -> &'static [u8];
}
// scripts.rs
extern "Rust" {
fn script_is_ignored(pkg: &str, script: &str) -> bool;
}
// utils.rs
extern "Rust" {
fn download_to_fd(url: &str) -> Result<i32>;
@ -53,6 +58,8 @@ mod ostree_diff;
mod ostree_utils;
mod progress;
pub use self::progress::*;
mod scripts;
pub(crate) use self::scripts::*;
mod testutils;
pub use self::testutils::*;
mod treefile;

57
rust/src/scripts.rs Normal file
View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2020 Red Hat, Inc.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/
use phf::phf_set;
/// Some RPM scripts we don't want to execute. A notable example is the kernel ones;
/// we want rpm-ostree to own running dracut, installing the kernel to /boot etc.
/// Ideally more of these migrate out, e.g. in the future we should change the kernel
/// package to do nothing if `/run/ostree-booted` exists.
///
/// NOTE FOR GIT history: This list used to live in src/libpriv/rpmostree-script-gperf.gperf
static IGNORED_PKG_SCRIPTS: phf::Set<&'static str> = phf_set! {
"glibc.prein",
// We take over depmod/dracut etc. It's `kernel` in C7 and kernel-core in F25+
"kernel.posttrans",
"kernel-core.posttrans",
// Legacy workaround
"glibc-headers.prein",
// workaround for old bug?
"coreutils.prein",
// Looks like legacy...
"ca-certificates.prein",
"libgcc.post",
"setup.post",
"pinentry.prein",
"fedora-release.posttrans",
// These add the vagrant group which IMO is really
// a libvirt-user group
"vagrant.prein",
"vagrant-libvirt.prein",
// This one is in lua; the setup package seems to be generating the value.
// Should probably be ported to a drop-in dir or a %posttrans
"bash.post",
// Seems to be another case of legacy workaround
"gdb.prein",
// Just does a daemon-reload which we don't want offline
"systemd.transfiletriggerin",
// https://bugzilla.redhat.com/show_bug.cgi?id=1473402
"man-db.transfiletriggerin",
// https://src.fedoraproject.org/rpms/nfs-utils/pull-request/1
"nfs-utils.post",
// There is some totally insane stuff going on here in RHEL7
"microcode_ctl.post",
// https://bugzilla.redhat.com/show_bug.cgi?id=1199582
"microcode_ctl.posttrans",
};
/// Returns true if we should simply ignore (not execute) an RPM script.
/// The format is <packagename>.<script>
pub(crate) fn script_is_ignored(pkg: &str, script: &str) -> bool {
let script = script.trim_start_matches('%');
let pkgscript = format!("{}.{}", pkg, script);
IGNORED_PKG_SCRIPTS.contains(pkgscript.as_str())
}

View File

@ -1,45 +0,0 @@
%{
#include "config.h"
#include "rpmostree-scripts.h"
%}
struct RpmOstreePackageScriptHandler;
%language=ANSI-C
%define slot-name package_script
%define hash-function-name rpmostree_script_gperf_hash
%define lookup-function-name rpmostree_script_gperf_lookup
%readonly-tables
%omit-struct-type
%struct-type
%includes
%%
glibc.prein, RPMOSTREE_SCRIPT_ACTION_IGNORE
# We take over depmod/dracut etc. It's `kernel` in C7 and kernel-core in F25+
kernel.posttrans, RPMOSTREE_SCRIPT_ACTION_IGNORE
kernel-core.posttrans, RPMOSTREE_SCRIPT_ACTION_IGNORE
# Legacy workaround
glibc-headers.prein, RPMOSTREE_SCRIPT_ACTION_IGNORE
# workaround for old bug?
coreutils.prein, RPMOSTREE_SCRIPT_ACTION_IGNORE
# Looks like legacy...
ca-certificates.prein, RPMOSTREE_SCRIPT_ACTION_IGNORE
libgcc.post, RPMOSTREE_SCRIPT_ACTION_IGNORE
setup.post, RPMOSTREE_SCRIPT_ACTION_IGNORE
pinentry.prein, RPMOSTREE_SCRIPT_ACTION_IGNORE
fedora-release.posttrans, RPMOSTREE_SCRIPT_ACTION_IGNORE
# These add the vagrant group which IMO is really
# a libvirt-user group
vagrant.prein, RPMOSTREE_SCRIPT_ACTION_IGNORE
vagrant-libvirt.prein, RPMOSTREE_SCRIPT_ACTION_IGNORE
bash.post, RPMOSTREE_SCRIPT_ACTION_TODO_SHELL_POSTTRANS
# Seems to be another case of legacy workaround
gdb.prein, RPMOSTREE_SCRIPT_ACTION_IGNORE
# Just does a daemon-reload which we don't want offline
systemd.transfiletriggerin, RPMOSTREE_SCRIPT_ACTION_IGNORE
# https://bugzilla.redhat.com/show_bug.cgi?id=1473402
man-db.transfiletriggerin, RPMOSTREE_SCRIPT_ACTION_IGNORE
# https://src.fedoraproject.org/rpms/nfs-utils/pull-request/1
nfs-utils.post, RPMOSTREE_SCRIPT_ACTION_IGNORE
# There is some totally insane stuff going on here in RHEL7
microcode_ctl.post, RPMOSTREE_SCRIPT_ACTION_IGNORE
# https://bugzilla.redhat.com/show_bug.cgi?id=1199582
microcode_ctl.posttrans, RPMOSTREE_SCRIPT_ACTION_IGNORE

View File

@ -24,6 +24,7 @@
#include <systemd/sd-journal.h>
#include "rpmostree-output.h"
#include "rpmostree-util.h"
#include "rpmostree-cxxrs.h"
#include "rpmostree-bwrap.h"
#include <err.h>
#include <systemd/sd-journal.h>
@ -229,17 +230,6 @@ fail_if_interp_is_lua (const char *interp,
return TRUE;
}
static RpmOstreeScriptAction
lookup_script_action (const char *pkg_name,
const char *scriptdesc)
{
const char *pkg_script = glnx_strjoina (pkg_name, ".", scriptdesc+1);
const struct RpmOstreePackageScriptHandler *handler = rpmostree_script_gperf_lookup (pkg_script, strlen (pkg_script));
if (!handler)
return RPMOSTREE_SCRIPT_ACTION_DEFAULT;
return handler->action;
}
gboolean
rpmostree_script_txn_validate (DnfPackage *package,
Header hdr,
@ -255,14 +245,10 @@ rpmostree_script_txn_validate (DnfPackage *package,
if (!(headerIsEntry (hdr, tagval) || headerIsEntry (hdr, progtagval)))
continue;
RpmOstreeScriptAction action = lookup_script_action (dnf_package_get_name (package), desc);
switch (action)
if (!rpmostreecxx::script_is_ignored (dnf_package_get_name (package), desc))
{
case RPMOSTREE_SCRIPT_ACTION_DEFAULT:
return glnx_throw (error, "Package '%s' has (currently) unsupported script of type '%s'; see https://github.com/coreos/rpm-ostree/issues/749",
dnf_package_get_name (package), desc);
case RPMOSTREE_SCRIPT_ACTION_IGNORE:
continue;
}
}
@ -691,14 +677,8 @@ run_script (const KnownRpmScriptKind *rpmscript,
return TRUE;
const char *desc = rpmscript->desc;
RpmOstreeScriptAction action = lookup_script_action (dnf_package_get_name (pkg), desc);
switch (action)
{
case RPMOSTREE_SCRIPT_ACTION_IGNORE:
if (rpmostreecxx::script_is_ignored (dnf_package_get_name (pkg), desc))
return TRUE; /* Note early return */
case RPMOSTREE_SCRIPT_ACTION_DEFAULT:
break; /* Continue below */
}
*out_did_run = TRUE;
return impl_run_rpm_script (rpmscript, pkg, hdr, rootfs_fd, var_lib_rpm_statedir,
@ -869,14 +849,8 @@ rpmostree_transfiletriggers_run_sync (Header hdr,
g_autofree char *error_prefix = g_strconcat ("Executing %transfiletriggerin for ", pkg_name, NULL);
GLNX_AUTO_PREFIX_ERROR (error_prefix, error);
RpmOstreeScriptAction action = lookup_script_action (pkg_name, "%transfiletriggerin");
switch (action)
{
case RPMOSTREE_SCRIPT_ACTION_IGNORE:
if (rpmostreecxx::script_is_ignored (pkg_name, "%transfiletriggerin"))
return TRUE; /* Note early return */
case RPMOSTREE_SCRIPT_ACTION_DEFAULT:
break; /* Continue below */
}
headerGetFlags hgflags = HEADERGET_MINMEM;
struct rpmtd_s tname, tscripts, tprogs, tflags, tscriptflags;

View File

@ -34,19 +34,6 @@
G_BEGIN_DECLS
typedef enum {
RPMOSTREE_SCRIPT_ACTION_DEFAULT = 0,
RPMOSTREE_SCRIPT_ACTION_IGNORE,
RPMOSTREE_SCRIPT_ACTION_TODO_SHELL_POSTTRANS = RPMOSTREE_SCRIPT_ACTION_IGNORE,
} RpmOstreeScriptAction;
struct RpmOstreePackageScriptHandler {
const char *package_script;
RpmOstreeScriptAction action;
};
const struct RpmOstreePackageScriptHandler* rpmostree_script_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
typedef enum {
RPMOSTREE_SCRIPT_PREIN,
RPMOSTREE_SCRIPT_POSTIN,