From 0b9177a8cef69e01087674ae9ce9edc31c4831d2 Mon Sep 17 00:00:00 2001 From: Bryson Steck Date: Thu, 31 Jul 2025 23:12:56 -0600 Subject: [PATCH] init --- .devcontainer/Dockerfile | 28 ++++++++++++ .gitignore | 13 ++++++ CMakeLists.txt | 31 ++++++++++++++ Justfile | 37 ++++++++++++++++ src/CMakeLists.txt | 11 +++++ src/lifi.conf | 6 +++ src/lifi.cpp | 93 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 219 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 Justfile create mode 100644 src/CMakeLists.txt create mode 100644 src/lifi.conf create mode 100644 src/lifi.cpp diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..76ed434 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,28 @@ +FROM fedora:latest AS devcontainer +ARG UID="1000" +ARG GID="1000" +ARG BASENAME="workdir" + +# setup packages +USER root +RUN dnf update -y +RUN dnf install -y dnf5-devel libdnf5-devel libdnf5-cli-devel openssh-server vim cmake gcc g++ git just + +# setup environment +RUN ssh-keygen -A +RUN sed -i "s|#Port 22|Port 2222|g" /etc/ssh/sshd_config +RUN sed -i "s|AuthorizedKeysFile.*|AuthorizedKeysFile /etc/ssh/authorized_keys|g" /etc/ssh/sshd_config +RUN --mount=type=secret,id=key,target=/root/id.pub \ + cp /root/id.pub /etc/ssh/authorized_keys + +# setup user and permissions +RUN groupadd -g $GID dev +RUN useradd -u $UID -g $GID -lN dev +RUN chown dev:dev /etc/ssh/ssh_host* /etc/ssh/authorized_keys /etc/ssh/sshd_config +USER dev +WORKDIR /volume/${BASENAME} +EXPOSE 2222/tcp +CMD ["/usr/sbin/sshd", "-D"] + +# use docker exec or SSH to access container OR +# use docker compose to specify entrypoint diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..15e5148 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +build/ +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps +CMakeUserPresets.json \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a12e948 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.6) + +project(lifi LANGUAGES CXX C VERSION 0.1.0) + +# includes +include(GNUInstallDirs) + +find_package(PkgConfig REQUIRED) + +# C++ standard +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Give inline methods hidden visibility by default +set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) + +# warnings +add_compile_options(-Wall -Wextra -Werror) +add_compile_options(-Wcast-align -Wformat-nonliteral -Wmissing-format-attribute -Wredundant-decls -Wsign-compare -Wsign-conversion -Wtype-limits -Wuninitialized -Wwrite-strings) +add_compile_options(-Werror=unused-result -Wodr) + +# not sure about the conversion warnings being errors; review later +add_compile_options(-Wconversion) + +# linker options +if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") + # clang doesn't support this option + add_compile_options(-Wl,--as-needed) +endif() + +add_subdirectory("src") diff --git a/Justfile b/Justfile new file mode 100644 index 0000000..4b80cc1 --- /dev/null +++ b/Justfile @@ -0,0 +1,37 @@ +alias dev := devcontainer +alias t := transaction + +workdir := `pwd` +basename := `basename $(pwd)` +dockerfile := '.devcontainer/Dockerfile' +container := basename + '-devcontainer' +uid := `id -u` +gid := `id -g` +image := container + '-img' +ssh_key := env('HOME') + '/.ssh/id_rsa.pub' + +# for use in dev container +build: + mkdir -p build + cd build && cmake .. && make + +# test a transaction +transaction: + docker exec -u root -it {{container}} dnf reinstall libdnf5 --setopt=pluginpath=build/src \ + --setopt=pluginconfpath=src -y + +clean: + docker container stop {{container}} || : + docker container rm {{container}} || : + docker image rm {{image}} || : + rm -rf build + +# (re)start Docker dev container +devcontainer: + (docker container ls --all | grep -q {{container}} && docker container stop {{container}} \ + && docker container rm {{container}}) || : + docker build --secret id=key,src={{ssh_key}} --build-arg UID={{uid}} --build-arg GID={{gid}} \ + --build-arg BASENAME={{basename}} -t {{image}} -f {{dockerfile}} . + docker container create --name {{container}} -v {{workdir}}:/volume/{{basename}} \ + -p 2222:2222 {{image}} + docker container start {{container}} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..7f8578c --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,11 @@ +add_library(lifi MODULE lifi.cpp) + +# disable the 'lib' prefix in order to create lifi.so +set_target_properties(lifi PROPERTIES PREFIX "") +set_target_properties(lifi PROPERTIES OUTPUT_NAME "lifi") + +pkg_check_modules(LIBDNF5 REQUIRED libdnf5) +target_link_libraries(lifi PRIVATE ${LIBDNF5_LIBRARIES}) + +install(TARGETS lifi LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/libdnf5/plugins/") +install(FILES "lifi.conf" DESTINATION "${CMAKE_INSTALL_FULL_SYSCONFDIR}/dnf/libdnf5-plugins") diff --git a/src/lifi.conf b/src/lifi.conf new file mode 100644 index 0000000..e473030 --- /dev/null +++ b/src/lifi.conf @@ -0,0 +1,6 @@ +[main] +name = lifi +enabled = 1 + +[new] +custom_thing = hi there \ No newline at end of file diff --git a/src/lifi.cpp b/src/lifi.cpp new file mode 100644 index 0000000..42ce4e7 --- /dev/null +++ b/src/lifi.cpp @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace libdnf5; + +namespace { + +constexpr const char *PLUGIN_NAME = "lifi"; +constexpr plugin::Version PLUGIN_VERSION{0, 1, 0}; + +constexpr const char *attrs[]{"author.name", "author.email", "description", + nullptr}; +constexpr const char *attrs_value[]{"Bryson Steck", "bryson@steck.dev", + "a LIcense FIlter for dnf"}; + +class Lifi final : public plugin::IPlugin { +public: + ConfigParser config; + Lifi(libdnf5::plugin::IPluginData &data, libdnf5::ConfigParser &config) + : IPlugin(data) { + config = config; + this->config.read( + get_base().get_config().get_pluginconfpath_option().get_value() + + "/lifi.conf"); + } + virtual ~Lifi() = default; + + PluginAPIVersion get_api_version() const noexcept override { + return PLUGIN_API_VERSION; + } + + const char *get_name() const noexcept override { return PLUGIN_NAME; } + + plugin::Version get_version() const noexcept override { + return PLUGIN_VERSION; + } + + const char *const *get_attributes() const noexcept override { return attrs; } + + const char *get_attribute(const char *attribute) const noexcept override { + for (size_t i = 0; attrs[i]; ++i) { + if (std::strcmp(attribute, attrs[i]) == 0) { + return attrs_value[i]; + } + } + return nullptr; + } + + void pre_transaction( + [[maybe_unused]] const libdnf5::base::Transaction &transaction) override { + std::cout << "----- executing Lifi::pre_transaction() method -----" + << std ::endl; + auto packages = transaction.get_transaction_packages(); + + for (auto pkg : packages) { + std::cout << pkg.get_package().get_license() << std::endl; + } + std::cout << config.get_value("new", "custom_thing") << std::endl; + } + +private: +}; + +} // namespace + +PluginAPIVersion libdnf_plugin_get_api_version(void) { + return PLUGIN_API_VERSION; +} + +const char *libdnf_plugin_get_name(void) { return PLUGIN_NAME; } + +plugin::Version libdnf_plugin_get_version(void) { return PLUGIN_VERSION; } + +plugin::IPlugin * +libdnf_plugin_new_instance([[maybe_unused]] LibraryVersion library_version, + libdnf5::plugin::IPluginData &data, + libdnf5::ConfigParser &parser) try { + return new Lifi(data, parser); +} catch (...) { + return nullptr; +} + +void libdnf_plugin_delete_instance(plugin::IPlugin *plugin_object) { + delete plugin_object; +}