New: Health Check warning if series folder is mounted with 'ro' option on linux

Closes #1867
pull/94/head
Kyse 7 years ago committed by Qstick
parent a37be66f34
commit 889b963429

@ -1,4 +1,5 @@
using System.IO;
using System.Collections.Generic;
using System.IO;
using NzbDrone.Common.Extensions;
namespace NzbDrone.Common.Disk
@ -8,10 +9,11 @@ namespace NzbDrone.Common.Disk
private readonly DriveInfo _driveInfo;
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;
_driveType = driveType;
MountOptions = mountOptions;
}
public long AvailableFreeSpace => _driveInfo.AvailableFreeSpace;
@ -33,6 +35,8 @@ namespace NzbDrone.Common.Disk
public bool IsReady => _driveInfo.IsReady;
public MountOptions MountOptions { get; private set; }
public string Name => _driveInfo.Name;
public string RootDirectory => _driveInfo.RootDirectory.FullName;

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.IO;
namespace NzbDrone.Common.Disk
@ -8,6 +9,7 @@ namespace NzbDrone.Common.Disk
string DriveFormat { get; }
DriveType DriveType { get; }
bool IsReady { get; }
MountOptions MountOptions { get; }
string Name { get; }
string RootDirectory { get; }
long TotalFreeSpace { get; }

@ -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");
}
}

@ -88,6 +88,7 @@
<Compile Include="Disk\FileSystemLookupService.cs" />
<Compile Include="Disk\DriveInfoMount.cs" />
<Compile Include="Disk\IMount.cs" />
<Compile Include="Disk\MountOptions.cs" />
<Compile Include="Disk\RelativeFileSystemModel.cs" />
<Compile Include="Disk\FileSystemModel.cs" />
<Compile Include="Disk\FileSystemResult.cs" />

@ -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());
}
}
}

@ -572,6 +572,8 @@
<Compile Include="HealthCheck\CheckHealthCommand.cs" />
<Compile Include="HealthCheck\Checks\AppDataLocationCheck.cs" />
<Compile Include="HealthCheck\Checks\DownloadClientCheck.cs" />
<Compile Include="HealthCheck\Checks\MountCheck.cs" />
<Compile Include="HealthCheck\Checks\DroneFactoryCheck.cs" />
<Compile Include="HealthCheck\Checks\ImportMechanismCheck.cs" />
<Compile Include="HealthCheck\Checks\IndexerRssCheck.cs" />
<Compile Include="HealthCheck\Checks\IndexerStatusCheck.cs" />

@ -86,11 +86,14 @@ namespace NzbDrone.Mono.Disk
public override List<IMount> GetMounts()
{
return GetDriveInfoMounts().Select(d => new DriveInfoMount(d, FindDriveType.Find(d.DriveFormat)))
.Where(d => d.DriveType == DriveType.Fixed || d.DriveType == DriveType.Network || d.DriveType == DriveType.Removable)
.Concat(_procMountProvider.GetMounts())
.DistinctBy(v => v.RootDirectory)
.ToList();
return _procMountProvider.GetMounts()
.Concat(GetDriveInfoMounts()
.Select(d => new DriveInfoMount(d, FindDriveType.Find(d.DriveFormat)))
.Where(d => d.DriveType == DriveType.Fixed ||
d.DriveType == DriveType.Network || d.DriveType ==
DriveType.Removable))
.DistinctBy(v => v.RootDirectory)
.ToList();
}
public override long? GetTotalSize(string path)

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using Mono.Unix;
using NzbDrone.Common.Disk;
@ -10,12 +10,13 @@ namespace NzbDrone.Mono.Disk
{
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;
Name = name;
RootDirectory = mount;
DriveFormat = type;
MountOptions = mountOptions;
_unixDriveInfo = new UnixDriveInfo(mount);
}
@ -28,6 +29,8 @@ namespace NzbDrone.Mono.Disk
public bool IsReady => _unixDriveInfo.IsReady;
public MountOptions MountOptions { get; private set; }
public string Name { get; private set; }
public string RootDirectory { get; private set; }

@ -130,7 +130,7 @@ namespace NzbDrone.Mono.Disk
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)

Loading…
Cancel
Save