From 8a3265d7b11a538a8b8f6fcff6eb302b7cdc4444 Mon Sep 17 00:00:00 2001 From: ljm42 Date: Tue, 3 Sep 2024 11:09:51 -0700 Subject: [PATCH] Feat: flash backup supports keyserver rate limits --- .../include/UpdateFlashBackup.php | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/UpdateFlashBackup.php b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/UpdateFlashBackup.php index 1c3a6b9be..27e178f64 100644 --- a/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/UpdateFlashBackup.php +++ b/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/include/UpdateFlashBackup.php @@ -321,16 +321,31 @@ if ($command != 'activate') { } } +if (!empty($loadingMessage)) { + save_flash_backup_state($loadingMessage); +} + +// check if being rate limited by keyserver +$rateLimitFile = "/var/log/gitratelimit"; +if (file_exists($rateLimitFile)) { + $rateLimitRetryTimestamp = (int)@file_get_contents($rateLimitFile); + $rateLimitRetryAfter = $rateLimitRetryTimestamp - time(); + if ($rateLimitRetryAfter > 0) { + $msg = !empty($arrState['remoteerror']) ? $arrState['remoteerror'] : 'You are being rate limited - try again in '.$rateLimitRetryAfter.' seconds.'; + response_complete(406, array('error' => $msg)); + } else { + unlink($rateLimitFile); + $arrState['remoteerror'] = ""; + save_flash_backup_state(); + } +} + // if flush command, invoke our background rc.flash_backup to flush if ($command == 'flush') { exec('/etc/rc.d/rc.flash_backup flush &>/dev/null'); response_complete(200, '{}'); } -if (!empty($loadingMessage)) { - save_flash_backup_state($loadingMessage); -} - if ($command == 'deactivate') { exec('/etc/rc.d/rc.flash_backup stop &>/dev/null'); deleteLocalRepo(); @@ -405,15 +420,30 @@ if ($result === false) { } $json = json_decode($result, true); -if (empty($json) || empty($json['ssh_privkey']) || empty($json['ssh_pubkey'])) { + +if (empty($json)) { response_complete(406, $result); } -// Show any warnings from the key-server +// Show any warnings from keyserver if (!empty($json['warn'])) { $arrState['remoteerror'] = $json['warn']; } +// check if being rate limited by keyserver +if ($json['retry_after']) { + // add five minute margin to ensure remote rate limit is cleared + $rateLimitRetryAfter = $json['retry_after'] + 5*60; + $rateLimitRetryTimestamp = time() + $rateLimitRetryAfter; + file_put_contents($rateLimitFile, $rateLimitRetryTimestamp); + $msg = !empty($arrState['remoteerror']) ? $arrState['remoteerror'] : 'You are being rate limited - try again in '.$rateLimitRetryAfter.' seconds.'; + response_complete(406, array('error' => $msg)); +} + +if (empty($json['ssh_privkey']) || empty($json['ssh_pubkey'])) { + response_complete(406, $result); +} + // save the public and private keys if (!file_exists('/root/.ssh')) { mkdir('/root/.ssh', 0700); @@ -559,6 +589,7 @@ if (! checkdnsrr("backup.unraid.net","A") ) { } // bail if too many recent git updates. +// this is a client-side rate limit on git commits, unrelated to the keyserver rate limit $cooldown = 3 * 60 * 60; // 180 mins / 3 hours $maxCommitCount = 20; // maxCommitCount per cooldown minutes $commitCountFile = "/var/log/gitcount";