Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a default user_agent string #1590

Merged
merged 3 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions dnf5-plugins/copr_plugin/copr_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.

#include "copr_constants.hpp"

#include "libdnf5/utils/os_release.hpp"

#include <filesystem>


Expand All @@ -42,6 +44,8 @@ void CoprConfig::load_all_configuration() {
// https://github.com/rpm-software-management/dnf5/issues/513
etc_dir = "/etc";

libdnf5::utils::OSRelease os_release(etc_dir / "os-release");

load_copr_config_file("/usr/share/dnf/plugins/copr.vendor.conf");
load_copr_config_file(etc_dir / "dnf/plugins/copr.vendor.conf");
load_copr_config_file(etc_dir / "dnf/plugins/copr.conf");
Expand Down
3 changes: 0 additions & 3 deletions dnf5-plugins/copr_plugin/copr_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#ifndef DNF5_COMMANDS_COPR_COPR_CONFIG_HPP
#define DNF5_COMMANDS_COPR_COPR_CONFIG_HPP

#include "os_release.hpp"

#include <glob.h>
#include <libdnf5/base/base.hpp>
#include <libdnf5/conf/config_parser.hpp>
Expand All @@ -31,7 +29,6 @@ namespace dnf5 {
class CoprConfig : public libdnf5::ConfigParser {
private:
libdnf5::Base & base;
OSRelease os_release;

void load_copr_config_file(const std::string & filename);
void load_all_configuration();
Expand Down
53 changes: 0 additions & 53 deletions dnf5-plugins/copr_plugin/os_release.cpp

This file was deleted.

56 changes: 56 additions & 0 deletions include/libdnf5/utils/os_release.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
Copyright Contributors to the libdnf project.

This file is part of libdnf: https://github.com/rpm-software-management/libdnf/

Libdnf is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 of the License, or
(at your option) any later version.

Libdnf is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with libdnf. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef LIBDNF5_UTILS_OS_RELEASE_HPP
#define LIBDNF5_UTILS_OS_RELEASE_HPP

#include "libdnf5/defs.h"

#include <filesystem>
#include <map>
#include <string>
#include <utility>

namespace libdnf5::utils {

/// Object which loads and exposes values from an os-release file.
class LIBDNF_API OSRelease {
public:
/// Creates an instance of `OSRelease` from the file at `path`.
///
/// @param path The path to the os-release file to load and parse.
explicit OSRelease(std::filesystem::path path = "/etc/os-release") : path(std::move(path)) {}

/// Returns the corresponding os-release value for `key`.
/// If the value for `key` isn't set, `default_value` is returned.
///
/// @param key The os-release key to get the value of.
/// @param default_value Default value to return if the value for `key` isn't set.
std::string get_value(const std::string & key, const std::string & default_value = "UNSET");

private:
std::filesystem::path path;
bool initialized_ = false;
std::map<std::string, std::string> map = {};
void initialize();
};

} // namespace libdnf5::utils

#endif // LIBDNF5_UTILS_OS_RELEASE_HPP
14 changes: 13 additions & 1 deletion libdnf5/conf/config_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.

#include "config.h"
#include "config_utils.hpp"
#include "utils/system.hpp"

#include "libdnf5/common/xdg.hpp"
#include "libdnf5/conf/config_parser.hpp"
#include "libdnf5/conf/const.hpp"
#include "libdnf5/utils/bgettext/bgettext-mark-domain.h"
#include "libdnf5/utils/fs/file.hpp"
#include "libdnf5/utils/os_release.hpp"

#include <glob.h>
#include <libdnf5/rpm/arch.hpp>

#include <algorithm>
#include <array>
Expand Down Expand Up @@ -84,6 +87,15 @@ static int str_to_bytes(const std::string & str) {
return static_cast<int>(res);
}

static std::string get_user_agent() {
utils::OSRelease os_release;
return std::format("libdnf ({} {}; {}; {}.{})",
os_release.get_value("NAME"),
os_release.get_value("VERSION_ID"),
os_release.get_value("VARIANT_ID"),
lleyton marked this conversation as resolved.
Show resolved Hide resolved
utils::get_os(),
rpm::get_base_arch(utils::detect_arch()));
lleyton marked this conversation as resolved.
Show resolved Hide resolved
}

class ConfigMain::Impl {
friend class ConfigMain;
Expand Down Expand Up @@ -206,7 +218,7 @@ class ConfigMain::Impl {
OptionBool module_stream_switch{false};
OptionBool module_obsoletes{false};

OptionString user_agent{"libdnf"}; // TODO(jrohel): getUserAgent()
OptionString user_agent{get_user_agent()};
OptionBool countme{false};
OptionBool protect_running_kernel{true};
OptionBool build_cache{true};
Expand Down
64 changes: 3 additions & 61 deletions libdnf5/conf/vars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#include "libdnf5/conf/vars.hpp"

#include "rpm/rpm_log_guard.hpp"
#include "utils/system.hpp"

#include "libdnf5/base/base.hpp"
#include "libdnf5/common/exception.hpp"
Expand Down Expand Up @@ -53,19 +54,6 @@ namespace libdnf5 {

static const std::unordered_set<std::string> READ_ONLY_VARIABLES = {"releasever_major", "releasever_minor"};

// ==================================================================
// The following helper functions should be moved e.g. into a library

static void init_lib_rpm(const char * arch) {
static bool lib_rpm_initiated{false};
if (!lib_rpm_initiated) {
if (rpmReadConfigFiles(nullptr, arch) != 0) {
throw RuntimeError(M_("failed to read rpm config files"));
}
lib_rpm_initiated = true;
}
}

static constexpr const char * DISTROVERPKGS[] = {
"system-release(releasever)",
"system-release",
Expand All @@ -74,51 +62,6 @@ static constexpr const char * DISTROVERPKGS[] = {
"redhat-release",
"suse-release"};

/* ARM specific HWCAP defines may be missing on non-ARM devices */
#ifndef HWCAP_ARM_VFP
#define HWCAP_ARM_VFP (1 << 6)
#endif
#ifndef HWCAP_ARM_NEON
#define HWCAP_ARM_NEON (1 << 12)
#endif

static std::string detect_arch() {
struct utsname un;

if (uname(&un) < 0) {
throw RuntimeError(M_("Failed to execute uname()"));
}

if (!strncmp(un.machine, "armv", 4)) {
/* un.machine is armvXE, where X is version number and E is
* endianness (b or l); we need to add modifiers such as
* h (hardfloat), n (neon). Neon is a requirement of armv8 so
* as far as rpm is concerned armv8l is the equivalent of armv7hnl
* (or 7hnb) so we don't explicitly add 'n' for 8+ as it's expected. */
char endian = un.machine[strlen(un.machine) - 1];
char * modifier = un.machine + 5;
while (isdigit(*modifier)) /* keep armv7, armv8, armv9, armv10, armv100, ... */
modifier++;
if (getauxval(AT_HWCAP) & HWCAP_ARM_VFP)
*modifier++ = 'h';
if ((atoi(un.machine + 4) == 7) && (getauxval(AT_HWCAP) & HWCAP_ARM_NEON))
*modifier++ = 'n';
*modifier++ = endian;
*modifier = 0;
}
#ifdef __MIPSEL__
// support for little endian MIPS
if (!strcmp(un.machine, "mips"))
strcpy(un.machine, "mipsel");
else if (!strcmp(un.machine, "mips64"))
strcpy(un.machine, "mips64el");
#endif
return un.machine;
}


// ==================================================================


class Vars::Impl {
public:
Expand Down Expand Up @@ -442,10 +385,9 @@ void Vars::load(const std::string & installroot, const std::vector<std::string>
}

void Vars::detect_vars(const std::string & installroot) {
set_lazy(
"arch", []() -> auto { return std::make_unique<std::string>(detect_arch()); }, Priority::AUTO);
set_lazy("arch", []() -> auto { return std::make_unique<std::string>(utils::detect_arch()); }, Priority::AUTO);

init_lib_rpm(get_value("arch").c_str());
utils::init_lib_rpm(get_value("arch").c_str());

set_lazy(
"basearch",
Expand Down
62 changes: 62 additions & 0 deletions libdnf5/utils/os_release.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Copyright Contributors to the libdnf project.

This file is part of libdnf: https://github.com/rpm-software-management/libdnf/

Libdnf is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 of the License, or
(at your option) any later version.

Libdnf is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with libdnf. If not, see <https://www.gnu.org/licenses/>.
*/

#include "libdnf5/utils/os_release.hpp"

#include <filesystem>
#include <fstream>
#include <regex>

namespace libdnf5::utils {

std::string OSRelease::get_value(const std::string & key, const std::string & default_value) {
initialize();
if (map.find(key) == map.end())
return default_value;
return map[key];
}


void OSRelease::initialize() {
if (initialized_)
return;

initialized_ = true;
std::ifstream infile(path);
if (!std::filesystem::exists(path))
return;

const std::regex r_no_quotes("^([A-Z_]+)=(\\w+)");
const std::regex r_quotes("^([A-Z_]+)=\"([\\w\\s]+)\"");
lleyton marked this conversation as resolved.
Show resolved Hide resolved
std::smatch match;
std::string line;

while (std::getline(infile, line)) {
if (std::regex_match(line, match, r_no_quotes)) {
map[match[1]] = match[2];
continue;
}
if (std::regex_match(line, match, r_quotes)) {
map[match[1]] = match[2];
continue;
}
}
}

} // namespace libdnf5::utils
Loading
Loading