MCPcopy Create free account
hub / github.com/78/tenbox / StartImageDownload

Method StartImageDownload

src/daemon/cloud_tunnel.cpp:1384–1575  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1382}
1383
1384nlohmann::json CloudTunnel::StartImageDownload(const nlohmann::json& payload) {
1385 const auto image = ImageFromJson(payload.value("image", nlohmann::json::object()));
1386 if (image.id.empty() || image.files.empty()) return Error("image_invalid", "invalid image metadata");
1387
1388 // Hard guard against host/image platform mismatch. Without this, a buggy
1389 // or stale console can hand us an x86_64 rootfs on an arm64 host, and we
1390 // happily download ~1.6 GB only to fail at boot with "invalid ARM64 Image
1391 // magic". Platform identity comes from the image manifest (authoritative)
1392 // and is matched against the host's compiled-in arch.
1393 const std::string host_platform = image_source::HostPlatform();
1394 const std::string image_platform = image_source::NormalizePlatform(image.platform);
1395 if (image_platform != host_platform) {
1396 return Error("image_arch_mismatch",
1397 "image platform '" + image_platform +
1398 "' does not match host platform '" + host_platform + "'");
1399 }
1400
1401 const std::string images_dir = ImagesDir(config_);
1402 if (image_source::IsImageCached(images_dir, image)) {
1403 return {{"job_id", ""}, {"cache_id", image.CacheId()}, {"status", "done"}};
1404 }
1405
1406 const std::string job_id = GenerateUuid();
1407 {
1408 std::lock_guard<std::mutex> lock(download_mu_);
1409 for (const auto& [id, job] : download_jobs_) {
1410 if (job.cache_id == image.CacheId() && (job.status == "running" || job.status == "pending")) {
1411 return {{"job_id", id}, {"cache_id", job.cache_id}, {"status", job.status}};
1412 }
1413 }
1414 DownloadJob job;
1415 job.job_id = job_id;
1416 job.cache_id = image.CacheId();
1417 job.image_name = image.display_name;
1418 job.status = "running";
1419 job.total_bytes = image.TotalSize();
1420 job.started_at = UnixNow();
1421 job.updated_at = job.started_at;
1422 download_jobs_[job_id] = job;
1423 }
1424
1425 std::thread([this, image, job_id, images_dir]() {
1426 pthread_setname_np(pthread_self(), "img-download");
1427 const std::string cache_dir = image_source::ImageCacheDir(images_dir, image);
1428 const auto started = std::chrono::steady_clock::now();
1429 // Browser-side progress is rate-limited to ~2Hz to avoid flooding the
1430 // WS with envelope traffic when curl reports tiny deltas faster than
1431 // the user can perceive.
1432 auto last_progress_push = std::chrono::steady_clock::now() -
1433 std::chrono::seconds(1);
1434 std::error_code ec;
1435 std::filesystem::create_directories(cache_dir, ec);
1436 bool ok = !ec;
1437 std::string error = ec ? ec.message() : "";
1438 uint64_t done = 0;
1439 for (const auto& file : image.files) {
1440 if (!ok) break;
1441 const auto dest = std::filesystem::path(cache_dir) / file.name;

Callers

nothing calls this directly

Calls 12

ImageFromJsonFunction · 0.85
HostPlatformFunction · 0.85
NormalizePlatformFunction · 0.85
ImagesDirFunction · 0.85
IsImageCachedFunction · 0.85
UnixNowFunction · 0.85
ImageCacheDirFunction · 0.85
SaveImageMetaFunction · 0.85
CacheIdMethod · 0.80
TotalSizeMethod · 0.80
ErrorFunction · 0.70
GenerateUuidFunction · 0.70

Tested by

no test coverage detected