Skip to content

Commit

Permalink
* Fixed default setting issue
Browse files Browse the repository at this point in the history
* Do not backup external volumes for now
  • Loading branch information
Commifreak committed Mar 29, 2023
1 parent 3125d11 commit 7dfa708
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 45 deletions.
96 changes: 69 additions & 27 deletions src/include/ABHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class ABHelper {
const LOGLEVEL_ERR = 'error';

private static $skipStartContainers = [];
private static $dockerCfg = null;

public static $targetLogLevel = '';

Expand Down Expand Up @@ -76,6 +77,13 @@ public static function backupLog(string $msg, string $level = self::LOGLEVEL_INF
mkdir(ABSettings::$tempFolder);
}

/**
* Do not log, if the script is not running
*/
if (!self::scriptRunning()) {
return;
}

if ($level != self::LOGLEVEL_DEBUG) {
file_put_contents(ABSettings::$tempFolder . '/' . ABSettings::$logfile, ($skipDate ? '' : "[" . date("d.m.Y H:i:s") . "][$level]") . " $msg" . ($newLine ? "\n" : ''), FILE_APPEND);
}
Expand Down Expand Up @@ -227,33 +235,25 @@ public static function sortContainers($containers, $order, $reverse = false, $re
public static function backupContainer($container, $destination) {
global $abSettings, $dockerClient;

self::backupLog("Backup {$container['Name']} - Container Volumeinfo: " . print_r($container['Volumes'], true), self::LOGLEVEL_DEBUG);
$containerSettings = $abSettings->getContainerSpecificSettings($container['Name']);

$stripAppdataPath = '';
self::backupLog("Backup {$container['Name']} - Container Volumeinfo: " . print_r($container['Volumes'], true), self::LOGLEVEL_DEBUG);

// Get default docker storage path
$dockerCfgFile = ABSettings::$dockerIniFile;
if (file_exists($dockerCfgFile)) {
self::backupLog("Parsing $dockerCfgFile", self::LOGLEVEL_DEBUG);
$dockerCfg = parse_ini_file($dockerCfgFile);
if ($dockerCfg) {
if (isset($dockerCfg['DOCKER_APP_CONFIG_PATH'])) {
$stripAppdataPath = $dockerCfg['DOCKER_APP_CONFIG_PATH'];
self::backupLog("Got default appdataPath: $stripAppdataPath", self::LOGLEVEL_DEBUG);
}
} else {
self::backupLog("Could not parse $dockerCfgFile", self::LOGLEVEL_DEBUG);
}
$volumes = self::examineContainerVolumes($container);
$dockerAppdataPath = self::getDockerAppdataPath();
if (empty($dockerAppdataPath)) {
ABHelper::backupLog("Docker appdata path could not be examined!", self::LOGLEVEL_ERR);
return false;
}


$volumes = [];
foreach ($container['Volumes'] ?? [] as $volume) {
$hostPath = explode(":", $volume)[0];
if (!empty($stripAppdataPath) && strpos($volume, $stripAppdataPath) === 0) {
$hostPath = ltrim(str_replace($stripAppdataPath, '', $hostPath), '/');
if (true || $containerSettings['backupExtVolumes'] == 'no') {
self::backupLog("Should NOT backup ext volumes, sanitizing...", self::LOGLEVEL_DEBUG);
foreach ($volumes as $index => $volume) {
if (str_starts_with($volume, '/')) {
self::backupLog("Removing volume " . $volume . " because ext volumes should be skipped", self::LOGLEVEL_DEBUG);
unset($volumes[$index]);
}
}
$volumes[] = $hostPath;
}

if (empty($volumes)) {
Expand All @@ -265,14 +265,10 @@ public static function backupContainer($container, $destination) {

$destination = $destination . "/" . $container['Name'] . '.tar';

$containerSettings = $abSettings->getContainerSpecificSettings($container['Name']);

$tarVerifyOptions = ['--diff'];
$tarOptions = ['-c'];

if (!empty($stripAppdataPath)) {
$tarOptions[] = $tarVerifyOptions[] = '-C ' . escapeshellarg($stripAppdataPath);
}
$tarOptions[] = $tarVerifyOptions[] = '-C ' . escapeshellarg($dockerAppdataPath);

switch ($abSettings->compression) {
case 'yes':
Expand Down Expand Up @@ -337,6 +333,7 @@ public static function backupContainer($container, $destination) {
/**
* Special debug: The creation was ok but verification failed: Something is accessing docker files! List docker info for this container
*/
$output = null; // Reset exec lines
exec("ps aux | grep docker", $output);
self::backupLog("ps aux docker:" . PHP_EOL . print_r($output, true), self::LOGLEVEL_DEBUG);
$nowRunning = $dockerClient->getDockerContainers();
Expand Down Expand Up @@ -371,4 +368,49 @@ public static function scriptRunning($externalCmd = false) {
public static function abortRequested() {
return file_exists(ABSettings::$tempFolder . '/' . ABSettings::$stateFileAbort);
}

public static function getDockerAppdataPath() {
$dockerAppdataPath = '';

// Get default docker storage path
if (empty(self::$dockerCfg)) {
$dockerCfgFile = ABSettings::$dockerIniFile;
if (file_exists($dockerCfgFile)) {
self::backupLog("Parsing $dockerCfgFile", self::LOGLEVEL_DEBUG);
$dockerCfg = parse_ini_file($dockerCfgFile);
ABHelper::backupLog("dockerCfg: " . PHP_EOL . print_r($dockerCfg, true), self::LOGLEVEL_DEBUG);
if ($dockerCfg) {
self::$dockerCfg = $dockerCfg;
} else {
self::backupLog("Could not parse $dockerCfgFile", self::LOGLEVEL_ERR);
return false;
}
}
} else {
ABHelper::backupLog("Got dockerCfg from cache.", ABHelper::LOGLEVEL_DEBUG);
$dockerCfg = self::$dockerCfg;
}

if (isset($dockerCfg['DOCKER_APP_CONFIG_PATH'])) {
$dockerAppdataPath = $dockerCfg['DOCKER_APP_CONFIG_PATH'];
} else {
self::backupLog("dockerCfg is there but no Appdata path iset set??", self::LOGLEVEL_ERR);
}
return $dockerAppdataPath;
}

public static function examineContainerVolumes($container) {

$dockerAppdataPath = self::getDockerAppdataPath();

$volumes = [];
foreach ($container['Volumes'] ?? [] as $volume) {
$hostPath = explode(":", $volume)[0];
if (!empty($dockerAppdataPath) && str_starts_with($volume, $dockerAppdataPath)) {
$hostPath = ltrim(str_replace($dockerAppdataPath, '', $hostPath), '/');
}
$volumes[] = rtrim($hostPath, '/');
}
return $volumes;
}
}
22 changes: 18 additions & 4 deletions src/include/ABSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,17 @@ class ABSettings {
public string|int $keepMinBackups = '3';
public string $destination = '';
public string $compression = 'yes';
public array $defaults = ['verifyBackup' => 'yes', 'ignoreBackupErrors' => 'no', 'updateContainer' => 'no'];
public array $defaults = [
'verifyBackup' => 'yes',
'ignoreBackupErrorss' => 'no',
'updateContainer' => 'no',

// The following are hidden, container special default settings
'skip' => 'no',
'exclude' => '',
'dontStop' => 'no',
'backupExtVolumes' => 'no'
];
public string $flashBackup = 'yes';
public string $notification = 'errors';
public string $backupFrequency = 'disabled';
Expand All @@ -61,7 +71,11 @@ public function __construct() {
if ($config) {
foreach ($config as $key => $value) {
if (property_exists($this, $key)) {
$this->$key = $value;
if ($key == 'defaults') {
$this->$key = array_merge($this->defaults, $value);
} else {
$this->$key = $value;
}
}
}
}
Expand Down Expand Up @@ -103,10 +117,10 @@ public function getContainerSpecificSettings($name, $setEmptyToDefault = true) {
foreach ($defaultSettings as $setting => $value) {
$defaultSettings[$setting] = '';
}
return array_merge($defaultSettings, ['skip' => 'no', 'exclude' => '', 'dontStop' => 'no']);
return $defaultSettings;
}

$settings = $this->containerSettings[$name];
$settings = array_merge($this->defaults, $this->containerSettings[$name]);

if ($setEmptyToDefault) {
foreach ($settings as $setting => $value) {
Expand Down
17 changes: 12 additions & 5 deletions src/pages/content/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,14 +295,15 @@ class="fa fa-clock-o title"></i>Notifications, scheduling and retention</span>

foreach ($allContainers as $container) {
$image = empty($container['Icon']) ? '/plugins/dynamix.docker.manager/images/question.png' : $container['Icon'];
$volumes = [];
foreach ($container['Volumes'] ?? [] as $volume) {
$volumes[] = explode(":", $volume)[0];
}
$volumes = implode("<br />", $volumes);
$volumes = ABHelper::examineContainerVolumes($container);

if (empty($volumes)) {
$volumes = "<b>No volumes - container will NOT being backed up!</b>";
} else {
foreach ($volumes as $index => $volume) {
$volumes[$index] = '<span class="fa ' . (str_starts_with($volume, '/') ? 'fa-external-link' : 'fa-folder') . '"> <code>' . $volume . '</code></span>';
}
$volumes = implode('<br />', $volumes);
}

$containerSetting = $abSettings->getContainerSpecificSettings($container['Name'], false);
Expand All @@ -323,6 +324,12 @@ class="fa fa-clock-o title"></i>Notifications, scheduling and retention</span>
<dt>Configured volumes</dt>
<dd><div style="display: table">$volumes</div></dd>
<!--<dt>Save external volumes? <small>Those with an <i class="fa fa-external-link"></i></small></dt>
<dd><select id='{$container['Name']}_backupExtVolumes' name="containerSettings[{$container['Name']}][backupExtVolumes]" data-setting="{$containerSetting['backupExtVolumes']}" >
<option value='no'>No</option>
<option value='yes'>Yes</option>
</select></dd>-->
<dt>Verify Backup?</dt>
<dd><select id='{$container['Name']}_verifyBackup' name="containerSettings[{$container['Name']}][verifyBackup]" data-setting="{$containerSetting['verifyBackup']}" >
<option value=''>Use standard</option>
Expand Down
18 changes: 9 additions & 9 deletions src/scripts/backup.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use unraid\plugins\AppdataBackup\ABSettings;

require_once("/usr/local/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php");
require_once __DIR__ . '/../include/ABHelper.php';
require_once dirname(__DIR__) . '/include/ABHelper.php';

/**
* Helper for later renaming of the backup folder to suffix -failed
Expand All @@ -29,13 +29,13 @@
exec("rm " . ABSettings::$tempFolder . '/*.log');
} // Creation of tempFolder is handled by backupLog

ABHelper::backupLog("👋 WELCOME TO APPDATA.BACKUP!! :D");

$unraidVersion = parse_ini_file('/etc/unraid-version');
ABHelper::backupLog("unraid-version: " . print_r($unraidVersion, true), ABHelper::LOGLEVEL_DEBUG);

file_put_contents(ABSettings::$tempFolder . '/' . ABSettings::$stateFileScriptRunning, getmypid());

ABHelper::backupLog("👋 WELCOME TO APPDATA.BACKUP!! :D");
ABHelper::backupLog("unraid-version: " . print_r($unraidVersion, true), ABHelper::LOGLEVEL_DEBUG);

/**
* Some basic checks
*/
Expand Down Expand Up @@ -362,7 +362,7 @@
$correctedItem = array_reverse(explode("/", $backupItem))[0];
$backupDate = date_create_from_format("??_Ymd_His", $correctedItem);
if (!$backupDate) {
ABHelper::backupLog("Cannot create date from " . $correctedItem, ABHelper::LOGLEVEL_ERR);
ABHelper::backupLog("Cannot create date from " . $correctedItem, ABHelper::LOGLEVEL_DEBUG);
continue;
}
if ($backupDate >= $nowDate && !in_array($backupItem, $toKeep)) {
Expand Down Expand Up @@ -402,11 +402,11 @@
ABHelper::backupLog("❤️");

if (!empty($abDestination)) {
copy(ABSettings::$tempFolder . '/' . ABSettings::$logfile, $abDestination . '/backup.log');
copy(ABSettings::getConfigPath(), $abDestination . '/' . ABSettings::$settingsFile);
if ($errorOccured) {
exec('rm -rf ' . escapeshellarg($abDestination));
} else {
copy(ABSettings::$tempFolder . '/' . ABSettings::$logfile, $abDestination . '/backup.log');
copy(ABSettings::getConfigPath(), $abDestination . '/' . ABSettings::$settingsFile);
copy(ABSettings::$tempFolder . '/' . ABSettings::$debugLogFile, $abDestination . '/backup.debug.log');
rename($abDestination, $abDestination . '-failed');
}
}
if (file_exists(ABSettings::$tempFolder . '/' . ABSettings::$stateFileAbort)) {
Expand Down

0 comments on commit 7dfa708

Please sign in to comment.