Skip to content

Commit

Permalink
Expose librepo's checksum functions via SWIG
Browse files Browse the repository at this point in the history
DNF has been carrying around yum's old checksum function. These
functions duplicate code in librepo. They are slower because librepo can
employ caching of digests. Lastly, these functions in Python do not know
about changes in checksum logic like
rpm-software-management/librepo#222

The choices here are:

1. Replicate `lr_checksum_cow_fd()` and caching logic in Python
2. Just use librepo from dnf.

This is 2. Note there was bug in librepo that forces no caching
for `checksum_value()`
(rpm-software-management/librepo#233). This is
now fixed, so we depend on librepo-1.13.1 to ensure this fix is present.

This change goes hand in hand with a change to `dnf` itself to make use
of the new functions and eliminate the old ones. This is
rpm-software-management/dnf#1743. We bump the
version of this library to ensure this dependency is expressed properly.

On errors, these functions raise libdnf.error.Error which can be easily
mapped into MiscError in dnf
  • Loading branch information
malmond77 committed Mar 17, 2021
1 parent ddf5adf commit 3899f5a
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 3 deletions.
2 changes: 1 addition & 1 deletion VERSION.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
set (DEFAULT_LIBDNF_MAJOR_VERSION 0)
set (DEFAULT_LIBDNF_MINOR_VERSION 45)
set (DEFAULT_LIBDNF_MICRO_VERSION 1)
set (DEFAULT_LIBDNF_MICRO_VERSION 2)

if(DEFINED LIBDNF_MAJOR_VERSION)
if(NOT ${DEFAULT_LIBDNF_MAJOR_VERSION} STREQUAL ${LIBDNF_MAJOR_VERSION})
Expand Down
3 changes: 3 additions & 0 deletions bindings/swig/utils.i
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,7 @@ namespace libdnf { namespace filesystem {

void decompress(const char * inPath, const char * outPath, mode_t outMode, const char * compressType = nullptr);

bool checksum_check(const char * type, const char * inPath, const char * checksum_valid);
std::string checksum_value(const char * type, const char * inPath);

}}
4 changes: 2 additions & 2 deletions libdnf.spec
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
%global libsolv_version 0.7.7
%global libmodulemd_version 2.5.0
%global librepo_version 1.11.0
%global librepo_version 1.13.1
%global dnf_conflict 4.2.13
%global swig_version 3.0.12
%global libdnf_major_version 0
%global libdnf_minor_version 45
%global libdnf_micro_version 1
%global libdnf_micro_version 2

# set sphinx package name according to distro
%global requires_python2_sphinx python2-sphinx
Expand Down
50 changes: 50 additions & 0 deletions libdnf/utils/utils.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "utils.hpp"
#include "libdnf/dnf-sack-private.hpp"
#include "libdnf/sack/advisorymodule.hpp"
#include <librepo/librepo.h>

#include <tinyformat/tinyformat.hpp>

Expand Down Expand Up @@ -311,6 +312,55 @@ void decompress(const char * inPath, const char * outPath, mode_t outMode, const
fclose(inFile);
}

void checksum(const char * type, const char * inPath, const char * checksum_valid, bool * valid_out, gchar ** calculated_out)
{
GError * errP{nullptr};
gboolean valid;
LrChecksumType lr_type = lr_checksum_type(type);

if (lr_type == LR_CHECKSUM_UNKNOWN)
throw libdnf::Error(tfm::format("Unknown checksum type %s", type));

auto inFd = open(inPath, O_RDONLY);

if (inFd == -1)
throw libdnf::Error(tfm::format("Error opening %s: %s", inPath, strerror(errno)));

auto ret = lr_checksum_fd_compare(lr_type,
inFd,
/**
* If checksum_valid references a string, pass it in, else use
* an empty string
*/
checksum_valid ? checksum_valid : "",
TRUE,
&valid,
calculated_out,
&errP);

close(inFd);
if (!ret)
throw libdnf::Error(tfm::format("Error calculating checksum %s: (%d, %s)", inPath, errP->code, errP->message));
if (valid_out)
*valid_out = valid == TRUE; /* gboolean -> bool */
}


bool checksum_check(const char * type, const char * inPath, const char * checksum_valid)
{
bool valid;
checksum(type, inPath, checksum_valid, &valid, NULL);
return valid;
}

std::string checksum_value(const char * type, const char * inPath)
{
g_autofree gchar *calculated = NULL;
checksum(type, inPath, NULL, NULL, &calculated);
std::string out(calculated);
return out;
}

}

namespace numeric {
Expand Down
16 changes: 16 additions & 0 deletions libdnf/utils/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@ std::vector<std::string> getDirContent(const std::string &dirPath);
* @param compressType Type of compression (".bz2", ".gz", ...), nullptr - detect from inPath filename. Defaults to nullptr.
*/
void decompress(const char * inPath, const char * outPath, mode_t outMode, const char * compressType = nullptr);

/**
* @brief checksum file and return if matching.
*
* @param type Checksum type ("sha", "sha1", "sha256" etc). Raises libdnf::Error if invalid.
* @param inPath Path to input file
* @param valid_checksum hexadecimal encoded checksum string.
*/
bool checksum_check(const char * type, const char * inPath, const char * valid_checksum);
/**
* @brief checksum file and return checksum.
*
* @param type Checksum type ("sha", "sha1", "sha256" etc). Raises libdnf::Error if invalid.
* @param inPath Path to input file
*/
std::string checksum_value(const char * type, const char * inPath);
}

namespace numeric {
Expand Down

0 comments on commit 3899f5a

Please sign in to comment.