# rpm-ostree Third-Party Tools Integration ## Overview rpm-ostree integrates with various third-party tools and external systems to provide comprehensive system management capabilities. This document explains how rpm-ostree implements integration with these tools. ## Core Third-Party Dependencies ### libdnf Integration rpm-ostree uses libdnf for RPM package management: ```c // libdnf integration in rpmostree-core.cxx #include #include #include class RpmOstreeDnfIntegration { private: DnfContext *dnf_context; DnfGoal *dnf_goal; public: // Initialize DNF context for OSTree operations gboolean initialize_dnf_context( RpmOstreeSysroot *sysroot, const char *deployment_path, GCancellable *cancellable, GError **error) { // Create DNF context dnf_context = dnf_context_new(); // Configure for OSTree deployment dnf_context_set_install_root(dnf_context, deployment_path); dnf_context_set_release_ver(dnf_context, "39"); dnf_context_set_platform_module(dnf_context, "platform:39"); // Load repositories dnf_context_setup(dnf_context, cancellable, error); return TRUE; } // Resolve package dependencies gboolean resolve_package_dependencies( const char *package_name, GPtrArray **resolved_packages, GCancellable *cancellable, GError **error) { // Create DNF goal dnf_goal = dnf_goal_new(dnf_context); // Add package to goal dnf_goal_install(dnf_goal, package_name); // Resolve dependencies DnfGoalActions actions = dnf_goal_resolve(dnf_goal, error); if (actions == DNF_GOAL_ACTION_ERROR) { return FALSE; } // Get resolved packages GPtrArray *packages = dnf_goal_get_packages(dnf_goal, DNF_PACKAGE_INFO_INSTALL); *resolved_packages = packages; return TRUE; } // Download packages gboolean download_packages( GPtrArray *packages, const char *download_path, GCancellable *cancellable, GError **error) { // Download packages to specified path return dnf_context_download_packages( dnf_context, packages, download_path, cancellable, error); } }; ``` ### Bubblewrap Integration rpm-ostree uses bubblewrap for secure package script execution: ```c // Bubblewrap integration in rpmostree-core.cxx #include class RpmOstreeBubblewrap { public: // Execute package scripts in sandboxed environment gboolean execute_package_script( const char *script_path, const char *deployment_path, const char *package_name, GCancellable *cancellable, GError **error) { // Create bubblewrap arguments g_autoptr(GPtrArray) args = g_ptr_array_new(); g_ptr_array_add(args, (gpointer)"bwrap"); g_ptr_array_add(args, (gpointer)"--dev-bind"); g_ptr_array_add(args, (gpointer)"/dev"); g_ptr_array_add(args, (gpointer)"/dev"); g_ptr_array_add(args, (gpointer)"--proc"); g_ptr_array_add(args, (gpointer)"/proc"); g_ptr_array_add(args, (gpointer)"--bind"); g_ptr_array_add(args, (gpointer)deployment_path); g_ptr_array_add(args, (gpointer)"/"); g_ptr_array_add(args, (gpointer)"--chdir"); g_ptr_array_add(args, (gpointer)"/"); g_ptr_array_add(args, (gpointer)script_path); g_ptr_array_add(args, NULL); // Execute script in sandbox return rpmostree_sysroot_run_sync( sysroot, (char**)args->pdata, cancellable, error); } // Execute post-installation scripts gboolean execute_postinstall_scripts( const char *deployment_path, GPtrArray *packages, GCancellable *cancellable, GError **error) { // Execute post-installation scripts for each package for (guint i = 0; i < packages->len; i++) { DnfPackage *package = g_ptr_array_index(packages, i); const char *package_name = dnf_package_get_name(package); // Find and execute post-installation script g_autofree char *script_path = g_strdup_printf( "%s/var/lib/rpm-postinst/%s", deployment_path, package_name); if (g_file_test(script_path, G_FILE_TEST_EXISTS)) { execute_package_script(script_path, deployment_path, package_name, cancellable, error); } } return TRUE; } }; ``` ### systemd Integration rpm-ostree integrates with systemd for service management: ```c // systemd integration in rpmostreed-daemon.cxx #include #include class RpmOstreeSystemdIntegration { private: sd_bus *system_bus; public: // Initialize systemd integration gboolean initialize_systemd_integration(GError **error) { // Connect to system bus int ret = sd_bus_open_system(&system_bus); if (ret < 0) { g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to connect to system bus: %s", strerror(-ret)); return FALSE; } return TRUE; } // Reload systemd units after package installation gboolean reload_systemd_units( GPtrArray *installed_packages, GCancellable *cancellable, GError **error) { // Reload systemd daemon sd_bus_message *reply = NULL; int ret = sd_bus_call_method(system_bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reload", NULL, &reply, NULL); if (ret < 0) { g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to reload systemd: %s", strerror(-ret)); return FALSE; } sd_bus_message_unref(reply); return TRUE; } // Enable/disable systemd services gboolean manage_systemd_services( GPtrArray *services, gboolean enable, GCancellable *cancellable, GError **error) { for (guint i = 0; i < services->len; i++) { const char *service = g_ptr_array_index(services, i); // Enable or disable service const char *method = enable ? "EnableUnitFiles" : "DisableUnitFiles"; sd_bus_message *reply = NULL; int ret = sd_bus_call_method(system_bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", method, NULL, &reply, "as", 1, &service); if (ret < 0) { g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to %s service %s: %s", enable ? "enable" : "disable", service, strerror(-ret)); return FALSE; } sd_bus_message_unref(reply); } return TRUE; } }; ``` ## External Tool Integration ### PolicyKit Integration rpm-ostree uses PolicyKit for authentication: ```c // PolicyKit integration in rpmostreed-daemon.cxx #include class RpmOstreePolicyKit { private: PolkitAuthority *authority; public: // Initialize PolicyKit integration gboolean initialize_polkit(GError **error) { authority = polkit_authority_get_sync(NULL, error); if (!authority) { return FALSE; } return TRUE; } // Check if user has required privileges gboolean check_privileges( const char *action_id, const char *subject, GCancellable *cancellable, GError **error) { // Create subject for authentication PolkitSubject *polkit_subject = polkit_system_bus_name_new(subject); // Check authorization PolkitAuthorizationResult *result = polkit_authority_check_authorization_sync( authority, polkit_subject, action_id, NULL, POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, cancellable, error); if (!result) { return FALSE; } gboolean authorized = polkit_authorization_result_get_is_authorized(result); polkit_authorization_result_unref(result); polkit_subject_unref(polkit_subject); return authorized; } // Required action IDs for rpm-ostree operations static const char *REQUIRED_ACTIONS[] = { "org.projectatomic.rpmostree1.upgrade", "org.projectatomic.rpmostree1.rollback", "org.projectatomic.rpmostree1.deploy", "org.projectatomic.rpmostree1.rebase", "org.projectatomic.rpmostree1.pkg-change", NULL }; }; ``` ### SELinux Integration rpm-ostree integrates with SELinux for security policy management: ```c // SELinux integration in rpmostree-core.cxx #include #include class RpmOstreeSELinux { public: // Apply SELinux labels to deployment gboolean apply_selinux_labels( const char *deployment_path, GCancellable *cancellable, GError **error) { // Initialize SELinux labeling struct selabel_handle *handle = selabel_open(SELABEL_CTX_FILE, NULL, 0); if (!handle) { g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to initialize SELinux labeling"); return FALSE; } // Apply labels recursively gboolean success = apply_labels_recursive(deployment_path, handle, error); selabel_close(handle); return success; } private: // Apply labels recursively to directory tree gboolean apply_labels_recursive( const char *path, struct selabel_handle *handle, GError **error) { // Apply label to current path char *con; if (selabel_lookup(handle, &con, path, S_IFDIR) == 0) { if (setfilecon(path, con) < 0) { g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to set SELinux context on %s", path); freecon(con); return FALSE; } freecon(con); } // Recursively process subdirectories GDir *dir = g_dir_open(path, 0, error); if (!dir) { return FALSE; } const char *name; while ((name = g_dir_read_name(dir))) { g_autofree char *subpath = g_build_filename(path, name, NULL); if (g_file_test(subpath, G_FILE_TEST_IS_DIR)) { if (!apply_labels_recursive(subpath, handle, error)) { g_dir_close(dir); return FALSE; } } } g_dir_close(dir); return TRUE; } }; ``` ## Development Tools Integration ### Git Integration rpm-ostree uses Git for version control of configuration: ```c // Git integration in rpmostree-core.cxx #include class RpmOstreeGit { public: // Initialize Git repository for configuration tracking gboolean initialize_git_repo( const char *config_path, GCancellable *cancellable, GError **error) { // Initialize Git repository git_repository *repo; int ret = git_repository_init(&repo, config_path, 0); if (ret < 0) { g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to initialize Git repository: %s", git_error_last()->message); return FALSE; } git_repository_free(repo); return TRUE; } // Commit configuration changes gboolean commit_config_changes( const char *config_path, const char *message, GCancellable *cancellable, GError **error) { git_repository *repo; int ret = git_repository_open(&repo, config_path); if (ret < 0) { g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to open Git repository: %s", git_error_last()->message); return FALSE; } // Stage all changes git_index *index; ret = git_repository_index(&index, repo); if (ret < 0) { git_repository_free(repo); g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to get repository index: %s", git_error_last()->message); return FALSE; } ret = git_index_add_all(index, NULL, 0, NULL, NULL); if (ret < 0) { git_index_free(index); git_repository_free(repo); g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to stage changes: %s", git_error_last()->message); return FALSE; } // Create commit git_oid tree_id, commit_id; ret = git_index_write_tree(&tree_id, index); if (ret < 0) { git_index_free(index); git_repository_free(repo); g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to write tree: %s", git_error_last()->message); return FALSE; } git_tree *tree; ret = git_tree_lookup(&tree, repo, &tree_id); if (ret < 0) { git_index_free(index); git_repository_free(repo); g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to lookup tree: %s", git_error_last()->message); return FALSE; } // Get HEAD commit as parent git_oid parent_id; git_commit *parent = NULL; if (git_reference_name_to_id(&parent_id, repo, "HEAD") == 0) { git_commit_lookup(&parent, repo, &parent_id); } // Create commit git_signature *signature; ret = git_signature_default(&signature, repo); if (ret < 0) { git_tree_free(tree); git_commit_free(parent); git_index_free(index); git_repository_free(repo); g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to create signature: %s", git_error_last()->message); return FALSE; } const git_commit *parents[] = { parent }; ret = git_commit_create(&commit_id, repo, "HEAD", signature, signature, NULL, message, tree, parent ? 1 : 0, parents); git_signature_free(signature); git_tree_free(tree); git_commit_free(parent); git_index_free(index); git_repository_free(repo); if (ret < 0) { g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to create commit: %s", git_error_last()->message); return FALSE; } return TRUE; } }; ``` ## Testing Tools Integration ### Integration Testing rpm-ostree integrates with various testing tools: ```c // Testing integration in tests/ class RpmOstreeTesting { public: // Run integration tests gboolean run_integration_tests( const char *test_suite, GCancellable *cancellable, GError **error) { // Run specific test suite g_autofree char *test_command = g_strdup_printf( "make check TEST_SUITE=%s", test_suite); return rpmostree_sysroot_run_sync( sysroot, test_command, cancellable, error); } // Run unit tests gboolean run_unit_tests( const char *test_binary, GCancellable *cancellable, GError **error) { // Run unit test binary g_autofree char *test_command = g_strdup_printf( "./%s", test_binary); return rpmostree_sysroot_run_sync( sysroot, test_command, cancellable, error); } // Run performance benchmarks gboolean run_performance_benchmarks( const char *benchmark_suite, GCancellable *cancellable, GError **error) { // Run performance benchmarks g_autofree char *benchmark_command = g_strdup_printf( "make benchmark BENCHMARK_SUITE=%s", benchmark_suite); return rpmostree_sysroot_run_sync( sysroot, benchmark_command, cancellable, error); } }; ``` ## Monitoring and Logging Tools ### Journald Integration rpm-ostree integrates with systemd-journald for logging: ```c // Journald integration in rpmostreed-daemon.cxx #include class RpmOstreeJournald { public: // Log rpm-ostree events to journald void log_event( const char *event_type, const char *message, const char *package_name) { sd_journal_send( "MESSAGE=%s", message, "EVENT_TYPE=%s", event_type, "PACKAGE_NAME=%s", package_name ?: "", "SYSLOG_IDENTIFIER=rpm-ostree", "PRIORITY=6", // INFO level NULL); } // Log error events void log_error( const char *error_message, const char *operation, GError *error) { sd_journal_send( "MESSAGE=%s", error_message, "ERROR_DOMAIN=%s", g_quark_to_string(g_error_domain(error)), "ERROR_CODE=%d", g_error_code(error), "OPERATION=%s", operation, "SYSLOG_IDENTIFIER=rpm-ostree", "PRIORITY=3", // ERROR level NULL); } // Log transaction events void log_transaction( const char *transaction_id, const char *operation, const char *status) { sd_journal_send( "MESSAGE=Transaction %s %s: %s", transaction_id, operation, status, "TRANSACTION_ID=%s", transaction_id, "OPERATION=%s", operation, "STATUS=%s", status, "SYSLOG_IDENTIFIER=rpm-ostree", "PRIORITY=6", // INFO level NULL); } }; ``` ## Future Tool Integrations ### Planned Integrations 1. **OCI Container Tools**: Integration with container tools for image management 2. **Bootc Compatibility**: Integration with bootc for container-native deployments 3. **Composefs Integration**: Enhanced filesystem layering with composefs 4. **Enhanced Monitoring**: Integration with Prometheus and Grafana for metrics ### Integration Roadmap - **Phase 1**: Core tool integrations (✅ Complete) - **Phase 2**: Security tool integrations (✅ Complete) - **Phase 3**: Monitoring and logging (✅ Complete) - **Phase 4**: Container tool integrations (🔄 In Progress) - **Phase 5**: Advanced monitoring (📋 Planned)