mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-04 10:02:40 +01:00
New: Health Check warning if series folder is mounted with 'ro' option on linux
Closes #1867
This commit is contained in:
parent
cd7368512d
commit
1b32411219
@ -1,4 +1,5 @@
|
|||||||
using System.IO;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
|
||||||
namespace NzbDrone.Common.Disk
|
namespace NzbDrone.Common.Disk
|
||||||
@ -8,10 +9,11 @@ public class DriveInfoMount : IMount
|
|||||||
private readonly DriveInfo _driveInfo;
|
private readonly DriveInfo _driveInfo;
|
||||||
private readonly DriveType _driveType;
|
private readonly DriveType _driveType;
|
||||||
|
|
||||||
public DriveInfoMount(DriveInfo driveInfo, DriveType driveType = DriveType.Unknown)
|
public DriveInfoMount(DriveInfo driveInfo, DriveType driveType = DriveType.Unknown, MountOptions mountOptions = null)
|
||||||
{
|
{
|
||||||
_driveInfo = driveInfo;
|
_driveInfo = driveInfo;
|
||||||
_driveType = driveType;
|
_driveType = driveType;
|
||||||
|
MountOptions = mountOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long AvailableFreeSpace => _driveInfo.AvailableFreeSpace;
|
public long AvailableFreeSpace => _driveInfo.AvailableFreeSpace;
|
||||||
@ -33,6 +35,8 @@ public DriveType DriveType
|
|||||||
|
|
||||||
public bool IsReady => _driveInfo.IsReady;
|
public bool IsReady => _driveInfo.IsReady;
|
||||||
|
|
||||||
|
public MountOptions MountOptions { get; private set; }
|
||||||
|
|
||||||
public string Name => _driveInfo.Name;
|
public string Name => _driveInfo.Name;
|
||||||
|
|
||||||
public string RootDirectory => _driveInfo.RootDirectory.FullName;
|
public string RootDirectory => _driveInfo.RootDirectory.FullName;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace NzbDrone.Common.Disk
|
namespace NzbDrone.Common.Disk
|
||||||
@ -8,6 +9,7 @@ public interface IMount
|
|||||||
string DriveFormat { get; }
|
string DriveFormat { get; }
|
||||||
DriveType DriveType { get; }
|
DriveType DriveType { get; }
|
||||||
bool IsReady { get; }
|
bool IsReady { get; }
|
||||||
|
MountOptions MountOptions { get; }
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
string RootDirectory { get; }
|
string RootDirectory { get; }
|
||||||
long TotalFreeSpace { get; }
|
long TotalFreeSpace { get; }
|
||||||
|
16
src/NzbDrone.Common/Disk/MountOptions.cs
Normal file
16
src/NzbDrone.Common/Disk/MountOptions.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NzbDrone.Common.Disk
|
||||||
|
{
|
||||||
|
public class MountOptions
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, string> _options;
|
||||||
|
|
||||||
|
public MountOptions(Dictionary<string, string> options)
|
||||||
|
{
|
||||||
|
_options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsReadOnly => _options.ContainsKey("ro");
|
||||||
|
}
|
||||||
|
}
|
@ -85,6 +85,7 @@
|
|||||||
<Compile Include="Disk\FileSystemLookupService.cs" />
|
<Compile Include="Disk\FileSystemLookupService.cs" />
|
||||||
<Compile Include="Disk\DriveInfoMount.cs" />
|
<Compile Include="Disk\DriveInfoMount.cs" />
|
||||||
<Compile Include="Disk\IMount.cs" />
|
<Compile Include="Disk\IMount.cs" />
|
||||||
|
<Compile Include="Disk\MountOptions.cs" />
|
||||||
<Compile Include="Disk\RelativeFileSystemModel.cs" />
|
<Compile Include="Disk\RelativeFileSystemModel.cs" />
|
||||||
<Compile Include="Disk\FileSystemModel.cs" />
|
<Compile Include="Disk\FileSystemModel.cs" />
|
||||||
<Compile Include="Disk\FileSystemResult.cs" />
|
<Compile Include="Disk\FileSystemResult.cs" />
|
||||||
|
36
src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs
Normal file
36
src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.HealthCheck.Checks
|
||||||
|
{
|
||||||
|
public class MountCheck : HealthCheckBase
|
||||||
|
{
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly ISeriesService _seriesService;
|
||||||
|
|
||||||
|
public MountCheck(IDiskProvider diskProvider, ISeriesService seriesService)
|
||||||
|
{
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_seriesService = seriesService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override HealthCheck Check()
|
||||||
|
{
|
||||||
|
// Not best for optimization but due to possible symlinks and junctions, we get mounts based on series path so internals can handle mount resolution.
|
||||||
|
var mounts = _seriesService.GetAllSeries()
|
||||||
|
.Select(series => _diskProvider.GetMount(series.Path))
|
||||||
|
.DistinctBy(m => m.RootDirectory)
|
||||||
|
.Where(m => m.MountOptions != null && m.MountOptions.IsReadOnly)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (mounts.Any())
|
||||||
|
{
|
||||||
|
return new HealthCheck(GetType(), HealthCheckResult.Error, "Mount containing a series path is mounted read-only: " + string.Join(",", mounts.Select(m => m.Name)), "#series-mount-ro");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HealthCheck(GetType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -557,6 +557,7 @@
|
|||||||
<Compile Include="HealthCheck\CheckHealthCommand.cs" />
|
<Compile Include="HealthCheck\CheckHealthCommand.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\AppDataLocationCheck.cs" />
|
<Compile Include="HealthCheck\Checks\AppDataLocationCheck.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\DownloadClientCheck.cs" />
|
<Compile Include="HealthCheck\Checks\DownloadClientCheck.cs" />
|
||||||
|
<Compile Include="HealthCheck\Checks\MountCheck.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\DroneFactoryCheck.cs" />
|
<Compile Include="HealthCheck\Checks\DroneFactoryCheck.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\ImportMechanismCheck.cs" />
|
<Compile Include="HealthCheck\Checks\ImportMechanismCheck.cs" />
|
||||||
<Compile Include="HealthCheck\Checks\IndexerRssCheck.cs" />
|
<Compile Include="HealthCheck\Checks\IndexerRssCheck.cs" />
|
||||||
|
@ -86,11 +86,14 @@ public override void SetPermissions(string path, string mask, string user, strin
|
|||||||
|
|
||||||
public override List<IMount> GetMounts()
|
public override List<IMount> GetMounts()
|
||||||
{
|
{
|
||||||
return GetDriveInfoMounts().Select(d => new DriveInfoMount(d, FindDriveType.Find(d.DriveFormat)))
|
return _procMountProvider.GetMounts()
|
||||||
.Where(d => d.DriveType == DriveType.Fixed || d.DriveType == DriveType.Network || d.DriveType == DriveType.Removable)
|
.Concat(GetDriveInfoMounts()
|
||||||
.Concat(_procMountProvider.GetMounts())
|
.Select(d => new DriveInfoMount(d, FindDriveType.Find(d.DriveFormat)))
|
||||||
.DistinctBy(v => v.RootDirectory)
|
.Where(d => d.DriveType == DriveType.Fixed ||
|
||||||
.ToList();
|
d.DriveType == DriveType.Network || d.DriveType ==
|
||||||
|
DriveType.Removable))
|
||||||
|
.DistinctBy(v => v.RootDirectory)
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override long? GetTotalSize(string path)
|
public override long? GetTotalSize(string path)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Mono.Unix;
|
using Mono.Unix;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
@ -10,12 +10,13 @@ public class ProcMount : IMount
|
|||||||
{
|
{
|
||||||
private readonly UnixDriveInfo _unixDriveInfo;
|
private readonly UnixDriveInfo _unixDriveInfo;
|
||||||
|
|
||||||
public ProcMount(DriveType driveType, string name, string mount, string type, Dictionary<string, string> options)
|
public ProcMount(DriveType driveType, string name, string mount, string type, MountOptions mountOptions)
|
||||||
{
|
{
|
||||||
DriveType = driveType;
|
DriveType = driveType;
|
||||||
Name = name;
|
Name = name;
|
||||||
RootDirectory = mount;
|
RootDirectory = mount;
|
||||||
DriveFormat = type;
|
DriveFormat = type;
|
||||||
|
MountOptions = mountOptions;
|
||||||
|
|
||||||
_unixDriveInfo = new UnixDriveInfo(mount);
|
_unixDriveInfo = new UnixDriveInfo(mount);
|
||||||
}
|
}
|
||||||
@ -28,6 +29,8 @@ public ProcMount(DriveType driveType, string name, string mount, string type, Di
|
|||||||
|
|
||||||
public bool IsReady => _unixDriveInfo.IsReady;
|
public bool IsReady => _unixDriveInfo.IsReady;
|
||||||
|
|
||||||
|
public MountOptions MountOptions { get; private set; }
|
||||||
|
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
|
|
||||||
public string RootDirectory { get; private set; }
|
public string RootDirectory { get; private set; }
|
||||||
|
@ -130,7 +130,7 @@ private IMount ParseLine(string line)
|
|||||||
driveType = DriveType.Network;
|
driveType = DriveType.Network;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ProcMount(driveType, name, mount, type, options);
|
return new ProcMount(driveType, name, mount, type, new MountOptions(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, string> ParseOptions(string options)
|
private Dictionary<string, string> ParseOptions(string options)
|
||||||
|
Loading…
Reference in New Issue
Block a user