From 56e2d227ea0ffbba27bdc8b790238afa6a366524 Mon Sep 17 00:00:00 2001 From: Daniil Lyudvig Date: Sat, 8 Jun 2024 11:38:55 +0000 Subject: [PATCH] feat(daemon): implement sync disk check Resolves #35 --- .../alpm/ArchRepoSyncService.cpp | 30 +++++++++++++++++-- .../infrastructure/alpm/ArchRepoSyncService.h | 1 + 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/daemon/infrastructure/alpm/ArchRepoSyncService.cpp b/daemon/infrastructure/alpm/ArchRepoSyncService.cpp index e2cc14f2..2bdc1f72 100644 --- a/daemon/infrastructure/alpm/ArchRepoSyncService.cpp +++ b/daemon/infrastructure/alpm/ArchRepoSyncService.cpp @@ -33,6 +33,7 @@ #include #include #include +#include namespace bxt::Infrastructure { @@ -179,10 +180,14 @@ std::optional parse_descfile(auto& entry) { if (!hash.has_value()) { return {}; } + const auto package_size = desc.get("ISIZE"); + if (!package_size.has_value()) { return {}; } + return ArchRepoSyncService::PackageInfo {.name = *name, .filename = *filename, .version = *version, - .hash = *hash}; + .hash = *hash, + .package_size = *package_size}; } coro::task< ArchRepoSyncService::Result>> @@ -234,6 +239,8 @@ coro::task< std::move(open_ok.error()), path, "The archive cannot be opened"); } + uint64_t packages_size = 0; + for (auto& [header, entry] : reader) { std::string pname = archive_entry_pathname(*header); @@ -246,13 +253,16 @@ coro::task< "Unknown", fmt::format("Cannot parse descfile {}", pname)); } - const auto& [name, filename, version, hash] = *parsed_package_info; + const auto& [name, filename, version, hash, package_size] + = *parsed_package_info; if (is_excluded(section, name)) { logi("Package {} is excluded. Skipping.", name); continue; } + packages_size += std::stoull(package_size); + const auto existing_package = co_await m_package_repository.find_by_section_async( SectionDTOMapper::to_entity(section), name); @@ -264,6 +274,22 @@ coro::task< result.emplace_back(std::move(*parsed_package_info)); } } + + std::error_code ec; + const auto filepath = + m_options.sources[section].download_path / bxt::to_string(section); + const auto available_space = + std::filesystem::space(filepath, ec).available; + if (ec) { + co_return bxt::make_error( + "Unknown", fmt::format("Error checking disk space: {}.", ec.value())); + } + if (available_space <= packages_size) { + co_return bxt::make_error( + "Unknown", fmt::format("Not enough available disk space. Need: {}, available: {}.", + packages_size, available_space)); + } + co_return result; } diff --git a/daemon/infrastructure/alpm/ArchRepoSyncService.h b/daemon/infrastructure/alpm/ArchRepoSyncService.h index 2bea448c..122a023a 100644 --- a/daemon/infrastructure/alpm/ArchRepoSyncService.h +++ b/daemon/infrastructure/alpm/ArchRepoSyncService.h @@ -42,6 +42,7 @@ class ArchRepoSyncService : public bxt::Core::Application::SyncService { std::string filename; Core::Domain::PackageVersion version; std::string hash; + std::string package_size; }; ArchRepoSyncService(Utilities::EventBusDispatcher& dispatcher,