sftp-backup: Add hostname prefix and allow usage of filedrop sftp server (#4602)

* Add possibility for hostname prefix for backups and allow usage of filedrop only sftp server

* Move config variable into else block

* Set value in case no backups where found on the server and housekeeping is disabled.

---------

Co-authored-by: Ad Schellevis <AdSchellevis@users.noreply.github.com>
This commit is contained in:
beposec
2025-03-19 22:16:31 +01:00
committed by Ad Schellevis
co-authored by Ad Schellevis
parent 6dfe5ab003
commit 037cb532ea
2 changed files with 58 additions and 34 deletions
@@ -74,11 +74,20 @@ class Sftp extends Base implements IBackupProvider
"help" => gettext("The private key used to setup the connection."),
"value" => null
],
[
"name" => "prefixhostname",
"type" => "checkbox",
"label" => gettext("Prefix hostname to backupfile"),
"help" => gettext("Normally the config xml will be written as config-stamp.xml, with this option set " .
"the filename will use the systems host and domain name."),
"value" => null
],
[
"name" => "backupcount",
"type" => "text",
"label" => gettext("Backup Count"),
"value" => null
"help" => gettext("Amount of backups to be kept at remote location. Set to 0 to upload latest only without housekeeping"),
"value" => 60
],
[
"name" => "password",
@@ -221,41 +230,52 @@ class Sftp extends Base implements IBackupProvider
*/
public function backup()
{
if ($this->model->enabled->isEmpty()) {
$cnf = Config::getInstance();
if (!$this->model->enabled->isEmpty() && $cnf->isValid()) {
if ($this->model->prefixhostname->isEmpty()) {
$fileprefix = "config-";
} else {
$config = $cnf->object();
$fileprefix = sprintf('%s.%s-', (string)$config->system->hostname, (string)$config->system->domain);
}
/**
* Collect most recent backup, since /conf/backup/ always contains the latests, we can use the filename
* for easy comparison.
**/
$all_backups = glob('/conf/backup/config-*.xml');
$most_recent = $all_backups[count($all_backups) - 1];
$confdata = file_get_contents($most_recent);
if (!$this->model->password->isEmpty()) {
$confdata = $this->encrypt($confdata, (string)$this->model->password);
}
$remote_backups = $this->ls(sprintf('%s*.xml', $fileprefix));
$target_filename = strtolower(preg_replace('/^config-/', $fileprefix, basename($most_recent)));
if (!in_array($target_filename, $remote_backups)) {
syslog(LOG_NOTICE, "backup configuration as " . $target_filename);
$tmpfilename = sprintf("/conf/backup/sftp/%s", $target_filename);
File::file_put_contents($tmpfilename, $confdata, 0600);
$this->put($tmpfilename, $target_filename);
unlink($tmpfilename);
$remote_backups = $this->ls(sprintf('%s*.xml', $fileprefix));
}
/* cleanup only if backup count is > 0*/
if ($this->model->backupcount->asFloat() > 0) {
rsort($remote_backups);
if (count($remote_backups) > (int)$this->model->backupcount->getCurrentValue()) {
for ($i = $this->model->backupcount->getCurrentValue() ; $i < count($remote_backups); $i++) {
$this->del($remote_backups[$i]);
}
$remote_backups = $this->ls(sprintf('%s*.xml', $fileprefix));
}
return $remote_backups;
} else {
return $this->ls(sprintf('%s*.xml', $fileprefix)) ?: [];
}
} else {
/* disabled */
return;
}
/**
* Collect most recent backup, since /conf/backup/ always contains the latests, we can use the filename
* for easy comparison.
**/
$all_backups = glob('/conf/backup/config-*.xml');
$most_recent = $all_backups[count($all_backups) - 1];
$confdata = file_get_contents($most_recent);
if (!$this->model->password->isEmpty()) {
$confdata = $this->encrypt($confdata, (string)$this->model->password);
}
/* backup filename when not already on remote location */
$remote_backups = $this->ls('config-*.xml');
$target_filename = basename($most_recent);
if (!in_array($target_filename, $remote_backups)) {
syslog(LOG_NOTICE, "backup configuration as " . $target_filename);
$tmpfilename = sprintf("/conf/backup/sftp/%s", $target_filename);
File::file_put_contents($tmpfilename, $confdata, 0600);
$this->put($tmpfilename, $target_filename);
unlink($tmpfilename);
$remote_backups = $this->ls('config-*.xml');
}
/* cleanup */
rsort($remote_backups);
if (count($remote_backups) > (int)$this->model->backupcount->getCurrentValue()) {
for ($i = $this->model->backupcount->getCurrentValue(); $i < count($remote_backups); $i++) {
$this->del($remote_backups[$i]);
}
$remote_backups = $this->ls('config-*.xml');
}
return $remote_backups;
}
/**
@@ -46,7 +46,11 @@
<backupcount type="IntegerField">
<Default>60</Default>
<Required>Y</Required>
<MinimumValue>1</MinimumValue>
<MinimumValue>0</MinimumValue>
</backupcount>
<prefixhostname type="BooleanField">
<Default>0</Default>
<Required>N</Required>
</prefixhostname>
</items>
</model>