From c90ab3df5ba0c715fe954541c5bd6b9684136b6c Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 10 Apr 2020 15:03:17 +0100 Subject: [PATCH] Packages: consider checksum failures for retry. This means an out-of-sync mirror causes a retry on a different mirror server. --- simgear/io/untar.cxx | 2 +- simgear/package/Install.cxx | 19 ++++++++++++++----- simgear/package/pkgutil.cxx | 9 ++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/simgear/io/untar.cxx b/simgear/io/untar.cxx index 61746317..39e40e88 100644 --- a/simgear/io/untar.cxx +++ b/simgear/io/untar.cxx @@ -638,7 +638,7 @@ void ArchiveExtractor::extractBytes(const uint8_t* bytes, size_t count) d.reset(new ZipExtractorPrivate(this)); } else { - SG_LOG(SG_IO, SG_ALERT, "Invalid archive type"); + SG_LOG(SG_IO, SG_WARN, "Invalid archive type"); _invalidDataType = true; return; } diff --git a/simgear/package/Install.cxx b/simgear/package/Install.cxx index 93d09b9e..091af47a 100644 --- a/simgear/package/Install.cxx +++ b/simgear/package/Install.cxx @@ -57,7 +57,7 @@ public: m_extractPath = aOwner->path().dir(); m_extractPath.append("_extract_" + aOwner->package()->md5()); - // clean up any existing files + // clean up any existing files (eg from previous failed download) Dir d(m_extractPath); if (d.exists()) { d.remove(true /* recursive */); @@ -106,7 +106,9 @@ protected: Request::responseHeadersComplete(); Dir d(m_extractPath); - d.create(0755); + if (!d.create(0755)) { + SG_LOG(SG_GENERAL, SG_WARN, "Failed to create extraction directory" << d.path()); + } m_extractor.reset(new ArchiveExtractor(m_extractPath)); memset(&m_md5, 0, sizeof(SG_MD5_CTX)); @@ -117,13 +119,19 @@ protected: void gotBodyData(const char* s, int n) override { + // if there's a pre-existing error, discard byte sinstead of pushing + // more through the extactor + if (m_extractor->hasError()) { + return; + } + const uint8_t* ubytes = (uint8_t*) s; SG_MD5Update(&m_md5, ubytes, n); m_downloaded += n; m_owner->installProgress(m_downloaded, responseLength()); m_extractor->extractBytes(ubytes, n); if (m_extractor->hasError()) { - SG_LOG(SG_GENERAL, SG_WARN, "archive extraction failed"); + SG_LOG(SG_GENERAL, SG_WARN, "archive extraction failed (from " + m_activeURL + ")"); } } @@ -219,7 +227,9 @@ private: dir.remove(true /* recursive */); } - const auto canRetry = (aReason == Delegate::FAIL_NOT_FOUND) || (aReason == Delegate::FAIL_DOWNLOAD); + const auto canRetry = (aReason == Delegate::FAIL_NOT_FOUND) || + (aReason == Delegate::FAIL_DOWNLOAD) || (aReason == Delegate::FAIL_CHECKSUM); + if (canRetry && !m_urls.empty()) { SG_LOG(SG_GENERAL, SG_WARN, "archive download failed from:" << m_activeURL << "\n\twill retry with next mirror"); @@ -231,7 +241,6 @@ private: return; } - // TODO - try other mirrors m_owner->m_download.reset(); // ensure we get cleaned up m_owner->installResult(aReason); } diff --git a/simgear/package/pkgutil.cxx b/simgear/package/pkgutil.cxx index 1641126c..1088d001 100644 --- a/simgear/package/pkgutil.cxx +++ b/simgear/package/pkgutil.cxx @@ -122,14 +122,17 @@ void printPackageInfo(pkg::Package* pkg) int main(int argc, char** argv) { - + sglog().setLogLevels( SG_ALL, SG_INFO ); + HTTP::Client* http = new HTTP::Client(); - pkg::Root* root = new pkg::Root(Dir::current().path(), "2019.1.1"); + + SGPath rootPath = SGPath::fromEnv("SG_PKG_ROOT", Dir::current().path()); + pkg::Root* root = new pkg::Root(rootPath, "2019.1.1"); MyDelegate dlg; root->addDelegate(&dlg); - cout << "Package root is:" << Dir::current().path() << endl; + cout << "Package root is:" << rootPath << endl; cout << "have " << root->catalogs().size() << " catalog(s)" << endl; root->setHTTPClient(http);