Skip to content

Commit

Permalink
New method for appdata path determination
Browse files Browse the repository at this point in the history
  • Loading branch information
Commifreak committed Mar 30, 2023
1 parent c4cebb8 commit bdf7cc4
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 47 deletions.
63 changes: 35 additions & 28 deletions src/include/ABHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,18 +239,17 @@ public static function backupContainer($container, $destination) {

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

$volumes = self::examineContainerVolumes($container);
$dockerAppdataPath = self::getDockerAppdataPath();
if (empty($dockerAppdataPath)) {
$volumes = self::getContainerVolumes($container);
$dockerAppdataPaths = self::getDockerAppdataPaths();
if (empty($dockerAppdataPaths)) {
ABHelper::backupLog("Docker appdata path could not be examined!", self::LOGLEVEL_ERR);
return false;
}

if (true || $containerSettings['backupExtVolumes'] == 'no') {
if ($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);
if (!self::isVolumeWithinAppdata($volume)) {
unset($volumes[$index]);
}
}
Expand All @@ -266,9 +265,7 @@ public static function backupContainer($container, $destination) {
$destination = $destination . "/" . $container['Name'] . '.tar';

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

$tarOptions[] = $tarVerifyOptions[] = '-C ' . escapeshellarg($dockerAppdataPath);
$tarOptions = ['-c', '-P'];

switch ($abSettings->compression) {
case 'yes':
Expand All @@ -292,10 +289,6 @@ public static function backupContainer($container, $destination) {
foreach ($excludes as $exclude) {
$exclude = rtrim($exclude, "/");
if (!empty($exclude)) {
if (str_starts_with($exclude, $dockerAppdataPath)) {
self::backupLog("exclude is within appdata apth: stripping appdata path", self::LOGLEVEL_DEBUG);
$exclude = ltrim(str_replace($dockerAppdataPath, '', $exclude), '/');
}
array_unshift($tarOptions, '--exclude ' . escapeshellarg($exclude)); // Add excludes to the beginning - https://unix.stackexchange.com/a/33334
array_unshift($tarVerifyOptions, '--exclude ' . escapeshellarg($exclude)); // Add excludes to the beginning - https://unix.stackexchange.com/a/33334
}
Expand Down Expand Up @@ -339,7 +332,7 @@ public static function backupContainer($container, $destination) {
*/
foreach ($volumes as $volume) {
$output = null; // Reset exec lines
exec("lsof -nl +D " . escapeshellarg($dockerAppdataPath) . "/" . escapeshellarg($volume), $output);
exec("lsof -nl +D " . escapeshellarg($volume), $output);
self::backupLog("lsof($volume)" . PHP_EOL . print_r($output, true), self::LOGLEVEL_DEBUG);
}

Expand Down Expand Up @@ -372,12 +365,19 @@ public static function scriptRunning($externalCmd = false) {
}
}

/**
* @return bool
* @todo: register_shutdown_function? in beiden Scripts? Damit kill und goto :end?
*/
public static function abortRequested() {
return file_exists(ABSettings::$tempFolder . '/' . ABSettings::$stateFileAbort);
}

public static function getDockerAppdataPath() {
$dockerAppdataPath = '';
public static function getDockerAppdataPaths() {
$dockerAppdataPaths = [
'/mnt/user/appdata', // no trailing /!
'/mnt/cache/appdata'
];

// Get default docker storage path
if (empty(self::$dockerCfg)) {
Expand All @@ -398,26 +398,33 @@ public static function getDockerAppdataPath() {
$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);
if (isset($dockerCfg['DOCKER_APP_CONFIG_PATH']) && !in_array(rtrim($dockerCfg['DOCKER_APP_CONFIG_PATH'], '/'), $dockerAppdataPaths)) {
$dockerAppdataPaths[] = rtrim($dockerCfg['DOCKER_APP_CONFIG_PATH'], '/');
}
return rtrim($dockerAppdataPath, '/');
}

public static function examineContainerVolumes($container) {
return $dockerAppdataPaths;
}

$dockerAppdataPath = self::getDockerAppdataPath();
public static function getContainerVolumes($container) {

$volumes = [];
foreach ($container['Volumes'] ?? [] as $volume) {
$hostPath = explode(":", $volume)[0];
if (!empty($dockerAppdataPath) && str_starts_with($volume, $dockerAppdataPath)) {
$hostPath = ltrim(str_replace($dockerAppdataPath, '', $hostPath), '/');
}
$hostPath = explode(":", $volume)[0];
$volumes[] = rtrim($hostPath, '/');
}
return $volumes;
}

public static function isVolumeWithinAppdata($volume) {
$dockerAppdataPaths = self::getDockerAppdataPaths();

foreach ($dockerAppdataPaths as $appdataPath) {
ABHelper::backupLog("$appdataPath within $volume?", ABHelper::LOGLEVEL_DEBUG);
if (str_starts_with($volume, $appdataPath)) {
ABHelper::backupLog("YES!", ABHelper::LOGLEVEL_DEBUG);
return true;
}
}
return false;
}
}
11 changes: 6 additions & 5 deletions src/pages/content/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -389,13 +389,13 @@ 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 = ABHelper::examineContainerVolumes($container);
$volumes = ABHelper::getContainerVolumes($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[$index] = '<span class="fa ' . (!ABHelper::isVolumeWithinAppdata($volume) ? 'fa-external-link' : 'fa-folder') . '"> <code>' . $volume . '</code></span>';
}
$volumes = implode('<br />', $volumes);
}
Expand All @@ -415,14 +415,15 @@ class="fa fa-clock-o title"></i>Notifications, scheduling and retention</span>
<blockquote class='inline_help'>
<dl>
<dt>Configured volumes</dt>
<dt>Configured volumes<br /><small><i class="fa fa-folder"></i> Appdata volume | <i class="fa fa-external-link"></i> Other/Extra volume</small></dt>
<dd><div style="display: table">$volumes</div></dd>
<br />
<!--<dt>Save external volumes? <small>Those with an <i class="fa fa-external-link"></i></small></dt>
<dt>Save external volumes?</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>-->
</select></dd>
<dt>Verify Backup?</dt>
<dd><select id='{$container['Name']}_verifyBackup' name="containerSettings[{$container['Name']}][verifyBackup]" data-setting="{$containerSetting['verifyBackup']}" >
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/backup.php
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@
ABHelper::backupLog("The tested extra files list is empty! Skipping extra files", ABHelper::LOGLEVEL_WARN);
} else {
ABHelper::backupLog("Extra files to backup: " . implode(', ', $extrasChecked), ABHelper::LOGLEVEL_DEBUG);
$tarOptions = ['-c'];
$tarOptions = ['-c', '-P'];

$destination = $abDestination . '/extra_files.tar';

Expand Down
16 changes: 3 additions & 13 deletions src/scripts/restore.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
exec("rm " . ABSettings::$tempFolder . '/*.log');
} // Creation of tempFolder is handled by backupLog

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

ABHelper::backupLog("👋 WELCOME TO APPDATA.BACKUP (in restore mode)!! :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());

/**
* Some basic checks
*/
Expand Down Expand Up @@ -84,18 +84,11 @@
if (!isset($config['restoreItem']['containers'])) {
ABHelper::backupLog("Not restoring containers: not wanted");
} else {
$dockerCfg = parse_ini_file(ABSettings::$dockerIniFile);
if ($dockerCfg && isset($dockerCfg['DOCKER_APP_CONFIG_PATH'])) {
$appdataPath = $dockerCfg['DOCKER_APP_CONFIG_PATH'];
foreach ($config['restoreItem']['containers'] as $container => $on) {
if (file_exists($appdataPath . '/' . explode('.', $container)[0])) {
ABHelper::backupLog("The destination already exists! Skipping.", ABHelper::LOGLEVEL_WARN);
continue;
}
ABHelper::backupLog("Restoring $container");

$tarOptions = [
'-C ' . escapeshellarg($appdataPath),
'-C /',
'-x',
'-f ' . escapeshellarg($restoreSource . '/' . $container)
];
Expand All @@ -121,9 +114,6 @@
goto abort;
}
}
} else {
ABHelper::backupLog("docker.cfg not found!", ABHelper::LOGLEVEL_ERR);
}
}


Expand Down

0 comments on commit bdf7cc4

Please sign in to comment.