Major refactor

This commit is contained in:
j
2025-12-30 08:43:06 +13:00
parent a9ccdedf89
commit b0d11eb08c
10 changed files with 84 additions and 177 deletions

View File

@@ -48,7 +48,7 @@
return std::filesystem::exists(path);
}
template_info template_source_local::get_template_info(const std::string& template_name, bool fast) {
template_info template_source_local::get_template_info(const std::string& template_name, bool skip_update) {
std::filesystem::path path = mLocalPath / template_name;
if (!std::filesystem::exists(path))
@@ -58,7 +58,7 @@
template_name,
mLocalPath.string(),
path,
fast
skip_update
);
}
@@ -183,7 +183,7 @@
return std::filesystem::exists(template_cache_dir);
}
template_info template_source_registry::get_template_info(const std::string& template_name, bool fast)
template_info template_source_registry::get_template_info(const std::string& template_name, bool skip_update)
{
// Get cache directory
std::filesystem::path cache_dir = get_cache_dir();
@@ -203,13 +203,13 @@
return template_info();
}
// fast: don't bother updating anything - if we have a cached version use that.
if (fast && have_cache) {
// skip_update: don't bother updating anything - if we have a cached version use that.
if (skip_update && have_cache) {
return template_info(
template_name,
"Registry: " + mRegistry.name + " (cached)",
template_cache_dir,
fast
skip_update
);
}
@@ -248,7 +248,7 @@
template_name,
"Registry: " + mRegistry.name + " (cached)",
template_cache_dir,
fast
skip_update
);
}
warning << "Failed to get metadata for template: " << template_name << std::endl;
@@ -258,7 +258,7 @@
// Check if we need to download/update the template
bool need_download = true;
std::string registry_version = "unknown";
std::string registry_hash = "";
std::string registry_unpacked_hash = "";
// Extract version and hash from registry metadata
if (registry_metadata.contains("metadata")) {
@@ -268,7 +268,7 @@
}
// REQUIRED: unpackedhash - the hash of extracted contents
if (metadata.contains("unpackedhash")) {
registry_hash = metadata["unpackedhash"].get<std::string>();
registry_unpacked_hash = metadata["unpackedhash"].get<std::string>();
//debug << "Found unpackedhash in metadata: " << registry_hash << std::endl;
} else {
// unpackedhash is required for security
@@ -289,17 +289,11 @@
cache_file.close();
// Compare versions or hashes
if (cache_json.contains("hash") && !registry_hash.empty()) {
if (cache_json["hash"].get<std::string>() == registry_hash) {
if (cache_json.contains("unpacked_hash") && !registry_unpacked_hash.empty())
if (cache_json["unpacked_hash"].get<std::string>() == registry_unpacked_hash)
need_download = false;
}
} else if (cache_json.contains("version")) {
std::string cached_version = cache_json["version"].get<std::string>();
if (cached_version == registry_version) {
need_download = false;
}
}
} catch (...) {
catch (...) {
// If reading cache fails, re-download
need_download = true;
}
@@ -336,21 +330,21 @@
std::filesystem::remove(temp_tgz);
// Calculate actual hash of extracted template
std::string actual_hash = hash_directory_recursive(template_cache_dir.string());
std::string actual_unpacked_hash = hash_directory_recursive(template_cache_dir.string());
// Verify the extracted template hash matches what registry claimed
// unpackedhash is required, so registry_hash should always be set here
if (registry_hash.empty()) {
if (registry_unpacked_hash.empty()) {
// This shouldn't happen as we check for it above, but handle it just in case
error << "Internal error: unpackedhash was not properly set" << std::endl;
std::filesystem::remove_all(template_cache_dir);
return template_info();
}
if (actual_hash != registry_hash) {
if (actual_unpacked_hash != registry_unpacked_hash) {
error << "Template hash verification failed!" << std::endl;
error << "Expected hash: " << registry_hash << std::endl;
error << "Actual hash: " << actual_hash << std::endl;
error << "Expected unpacked hash: " << registry_unpacked_hash << std::endl;
error << "Actual unpacked hash: " << actual_unpacked_hash << std::endl;
error << "The downloaded template '" << template_name << "' may be corrupted or tampered with." << std::endl;
// Remove the corrupted template
@@ -358,32 +352,16 @@
return template_info();
}
info << "Template extracted successfully. SHA256: " << actual_hash << std::endl;
info << "Note: Hash verification temporarily disabled during migration from XXHash64 to SHA256" << std::endl;
info << "Template extracted successfully. SHA256: " << actual_unpacked_hash << std::endl;
// Generate .template_info.env if it doesn't exist
std::filesystem::path template_info_env_path = template_cache_dir / "config" / filenames::template_info_env;
if (!std::filesystem::exists(template_info_env_path)) {
// Create config directory if needed
std::filesystem::create_directories(template_cache_dir / "config");
// Write .template_info.env file
std::ofstream info_file(template_info_env_path);
info_file << "# Template information" << std::endl;
info_file << "TEMPLATE=" << template_name << std::endl;
info_file << "TEMPLATE_SOURCE=registry" << std::endl;
info_file << "TEMPLATE_REGISTRY=" << mRegistry.name << std::endl;
info_file << "TEMPLATE_VERSION=" << registry_version << std::endl;
// Always write the actual calculated hash
info_file << "TEMPLATE_HASH=" << actual_hash << std::endl;
info_file.close();
}
std::filesystem::path template_info_env_path = template_cache_dir / filenames::template_info_env;
ASSERT( std::filesystem::exists( template_info_env_path ), "template_info.env doesn't exist in the template." );
// Update cache JSON file
nlohmann::json cache_json;
cache_json["template"] = template_name;
cache_json["version"] = registry_version;
cache_json["hash"] = actual_hash; // Store actual calculated hash
cache_json["unpacked_hash"] = actual_unpacked_hash; // Store actual calculated hash
cache_json["registry"] = mRegistry.name;
cache_json["last_updated"] = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
@@ -399,7 +377,7 @@
template_name,
"Registry: " + mRegistry.name,
template_cache_dir,
fast
skip_update
);
}
@@ -471,12 +449,12 @@
return true;
}
template_info template_manager::get_template_info(const std::string &template_name, bool fast) const
template_info template_manager::get_template_info(const std::string &template_name, bool skip_update) const
{
ASSERT(mLoaded && mSources.size() > 0, "Template manager not loaded, or no template sources found.");
template_source_interface* source = get_source(template_name);
if (source)
return source->get_template_info(template_name, fast);
return source->get_template_info(template_name, skip_update);
// fail
return template_info();
@@ -797,7 +775,7 @@ For full documentation, see: dropshell help templates
std::vector<std::string> required_files = {
"config/" + filenames::service_env,
"config/" + filenames::template_info_env,
filenames::template_info_env,
"install.sh",
"uninstall.sh"
};
@@ -899,13 +877,12 @@ For full documentation, see: dropshell help templates
return instance;
}
template_info::template_info(const std::string &template_name, const std::string &location_id, const std::filesystem::path &local_template_path, bool fast) :
template_info::template_info(const std::string &template_name, const std::string &location_id, const std::filesystem::path &local_template_path, bool skip_update) :
mTemplateName(template_name),
mLocationID(location_id),
mTemplateLocalPath(local_template_path),
mTemplateValid(template_manager::test_template(local_template_path.string())),
mIsSet(!template_name.empty() && !location_id.empty() && !local_template_path.empty()),\
mHash("")
mIsSet(!template_name.empty() && !location_id.empty() && !local_template_path.empty())
{
if (!std::filesystem::exists(local_template_path))
{
@@ -913,8 +890,13 @@ For full documentation, see: dropshell help templates
return;
}
if (!fast)
mHash = hash_directory_recursive(local_template_path);
// if (!skip_update)
// mHash = hash_directory_recursive(local_template_path);
}
std::filesystem::path template_info::local_template_info_env_path()
{
return mTemplateLocalPath / filenames::template_info_env ;
}
} // namespace dropshell