Major refactor
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user