Storage limit: 80% warning and limit in the web interface
CI / unit (8.2) (push) Has been cancelled
CI / unit (8.3) (push) Has been cancelled
CI / unit (8.4) (push) Has been cancelled
CI / integration (mariadb, 32) (push) Has been cancelled
CI / integration (mariadb, 33) (push) Has been cancelled
CI / integration (mariadb, 34) (push) Has been cancelled
CI / integration (mariadb, 35) (push) Has been cancelled
CI / integration (pgsql, 32) (push) Has been cancelled
CI / integration (pgsql, 33) (push) Has been cancelled
CI / integration (pgsql, 34) (push) Has been cancelled
CI / integration (pgsql, 35) (push) Has been cancelled
CI / integration (sqlite, 32) (push) Has been cancelled
CI / integration (sqlite, 33) (push) Has been cancelled
CI / integration (sqlite, 34) (push) Has been cancelled
CI / integration (sqlite, 35) (push) Has been cancelled
CI / unit (8.2) (push) Has been cancelled
CI / unit (8.3) (push) Has been cancelled
CI / unit (8.4) (push) Has been cancelled
CI / integration (mariadb, 32) (push) Has been cancelled
CI / integration (mariadb, 33) (push) Has been cancelled
CI / integration (mariadb, 34) (push) Has been cancelled
CI / integration (mariadb, 35) (push) Has been cancelled
CI / integration (pgsql, 32) (push) Has been cancelled
CI / integration (pgsql, 33) (push) Has been cancelled
CI / integration (pgsql, 34) (push) Has been cancelled
CI / integration (pgsql, 35) (push) Has been cancelled
CI / integration (sqlite, 32) (push) Has been cancelled
CI / integration (sqlite, 33) (push) Has been cancelled
CI / integration (sqlite, 34) (push) Has been cancelled
CI / integration (sqlite, 35) (push) Has been cancelled
- after each successful backup the stored size is recorded; at 80% of a
location's limit administrators get a notification (once a day)
- locations list shows stored size and limit; the add form has a
'maximum size' field that explains that empty means unlimited and
billed by the provider; PUT /api/targets/{id}/limit (password
confirmation)
Tested on NC34 with the OVH test bucket: a backup above the limit stops,
a successful one at 81% sends the warning.
This commit is contained in:
@@ -54,6 +54,36 @@ class AlertService {
|
||||
['kind' => $run->getKind(), 'target' => $targetName, 'error' => mb_strimwidth((string)$run->getError(), 0, 300, '…')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remember how much is stored on a location (for the settings page) and warn administrators
|
||||
* once a day when it is at 80% of its limit or more.
|
||||
*/
|
||||
public function storedBytes(Target $target, int $bytes): void {
|
||||
$this->appConfig->setValueString(Application::APP_ID, 'stored_' . $target->getId(), (string)$bytes);
|
||||
$limit = $target->getMaxBytes();
|
||||
if ($limit === null || $limit <= 0 || $bytes < 0.8 * $limit) {
|
||||
return;
|
||||
}
|
||||
$key = 'quota_notified_' . $target->getId();
|
||||
if ($this->appConfig->getValueString(Application::APP_ID, $key, '') === date('Y-m-d')) {
|
||||
return;
|
||||
}
|
||||
$this->appConfig->setValueString(Application::APP_ID, $key, date('Y-m-d'));
|
||||
$this->notifyAdmins('quota_warning', 'quota-' . $target->getId() . '-' . date('Y-m-d'), [
|
||||
'target' => $target->getName(), 'percent' => (string)round($bytes / $limit * 100),
|
||||
'used' => self::gib($bytes), 'limit' => self::gib($limit)]);
|
||||
}
|
||||
|
||||
private static function gib(int $bytes): string {
|
||||
$g = $bytes / 1073741824;
|
||||
return sprintf($g < 10 ? '%.2f GiB' : '%.1f GiB', $g);
|
||||
}
|
||||
|
||||
public function lastStoredBytes(Target $target): ?int {
|
||||
$v = $this->appConfig->getValueString(Application::APP_ID, 'stored_' . $target->getId(), '');
|
||||
return $v === '' ? null : (int)$v;
|
||||
}
|
||||
|
||||
/** At most one notification per location per day. */
|
||||
public function checkStale(Target $target): void {
|
||||
$last = $this->runs->lastFinished($target->getId(), BackupService::KIND_FULL);
|
||||
|
||||
@@ -149,6 +149,7 @@ class BackupService {
|
||||
$state['files'] = BackupRun::step($repo, $state['files'], $deadline);
|
||||
if ($state['files']['phase'] === 'done') {
|
||||
$this->recordSnapshot($run, $state['files']);
|
||||
$this->alerts->storedBytes($target, $repo->storedBytes());
|
||||
$run->setStatus(Run::DONE);
|
||||
$run->setPhase('done');
|
||||
$run->setFinishedAt(time());
|
||||
|
||||
Reference in New Issue
Block a user