Fixed #1760 and improvements on the auto updater.

We may now support windows services... #1460
pull/1653/merge
Jamie 7 years ago
parent 3edb4a485a
commit 02135bc550

@ -0,0 +1,10 @@
using System.Runtime.InteropServices;
using Ombi.Settings.Settings.Models;
namespace Ombi.Core.Models.UI
{
public class UpdateSettingsViewModel : UpdateSettings
{
public bool IsWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
}
}

@ -1,5 +1,6 @@
using System.Security.Principal;
using System.Threading.Tasks;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Core.Authentication;
using Ombi.Core.Rule.Interfaces;
using Ombi.Helpers;
using Ombi.Store.Entities;
@ -9,40 +10,38 @@ namespace Ombi.Core.Rule.Rules.Specific
{
public class SendNotificationRule : SpecificRule, ISpecificRule<object>
{
public SendNotificationRule(IPrincipal principal)
public SendNotificationRule(OmbiUserManager um)
{
User = principal;
UserManager = um;
}
public override SpecificRules Rule => SpecificRules.CanSendNotification;
private IPrincipal User { get; }
private OmbiUserManager UserManager { get; }
public Task<RuleResult> Execute(object obj)
public async Task<RuleResult> Execute(object obj)
{
var req = (BaseRequest)obj;
var sendNotification = !req.Approved; /*|| !prSettings.IgnoreNotifyForAutoApprovedRequests;*/
var requestedUser = await UserManager.Users.FirstOrDefaultAsync(x => x.Id == req.RequestedUserId);
if (req.RequestType == RequestType.Movie)
{
sendNotification = !User.IsInRole(OmbiRoles.AutoApproveMovie);
sendNotification = !await UserManager.IsInRoleAsync(requestedUser, OmbiRoles.AutoApproveMovie);
}
else if(req.RequestType == RequestType.TvShow)
{
sendNotification = !User.IsInRole(OmbiRoles.AutoApproveTv);
sendNotification = !await UserManager.IsInRoleAsync(requestedUser, OmbiRoles.AutoApproveTv);
}
if (User.IsInRole(OmbiRoles.Admin))
if (await UserManager.IsInRoleAsync(requestedUser, OmbiRoles.Admin))
{
sendNotification = false; // Don't bother sending a notification if the user is an admin
}
return Task.FromResult(new RuleResult
return new RuleResult
{
Success = sendNotification
});
};
}
}
}

@ -1,5 +1,6 @@
using AutoMapper;
using Ombi.Core.Models.UI;
using Ombi.Settings.Settings.Models;
using Ombi.Settings.Settings.Models.Notifications;
namespace Ombi.Mapping.Profiles
@ -15,6 +16,7 @@ namespace Ombi.Mapping.Profiles
CreateMap<PushoverNotificationViewModel, PushoverSettings>().ReverseMap();
CreateMap<MattermostNotificationsViewModel, MattermostNotificationSettings>().ReverseMap();
CreateMap<TelegramNotificationsViewModel, TelegramSettings>().ReverseMap();
CreateMap<UpdateSettingsViewModel, UpdateSettings>().ReverseMap();
}
}
}

@ -8,6 +8,7 @@ using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Hangfire;
using Hangfire.Console;
@ -144,7 +145,8 @@ namespace Ombi.Schedule.Jobs.Ombi
// Temp Path
Directory.CreateDirectory(tempPath);
if (settings.UseScript)
if (settings.UseScript && !settings.WindowsService)
{
RunScript(settings, download.Url);
return;
@ -188,7 +190,6 @@ namespace Ombi.Schedule.Jobs.Ombi
var updaterFile = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
"TempUpdate", $"Ombi.Updater{updaterExtension}");
// There must be an update
var start = new ProcessStartInfo
{
@ -229,7 +230,31 @@ namespace Ombi.Schedule.Jobs.Ombi
var currentLocation = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var processName = (settings.ProcessName.HasValue() ? settings.ProcessName : "Ombi");
return string.Join(" ", currentLocation, processName, url?.Value ?? string.Empty, storage?.Value ?? string.Empty);
var sb = new StringBuilder();
sb.Append($"--applicationPath \"{currentLocation}\" --processname \"{processName}\" " );
if (settings.WindowsService)
{
sb.Append($"--windowsServiceName \"{settings.WindowsServiceName}\" ");
}
var sb2 = new StringBuilder();
var hasStartupArgs = false;
if (url?.Value.HasValue() ?? false)
{
hasStartupArgs = true;
sb2.Append(url.Value);
}
if (storage?.Value.HasValue() ?? false)
{
hasStartupArgs = true;
sb2.Append(storage.Value);
}
if (hasStartupArgs)
{
sb.Append($"--startupArgs {sb2.ToString()}");
}
return sb.ToString();
//return string.Join(" ", currentLocation, processName, url?.Value ?? string.Empty, storage?.Value ?? string.Empty);
}
private void RunScript(UpdateSettings settings, string downloadUrl)

@ -6,8 +6,9 @@
public string Username { get; set; }
public string Password { get; set; }
public string ProcessName { get; set; }
public bool UseScript { get; set; }
public string ScriptLocation { get; set; }
public string WindowsServiceName { get; set; }
public bool WindowsService { get; set; }
}
}

@ -11,7 +11,7 @@ namespace Ombi.Updater
ProcessInfo GetCurrentProcess();
int GetCurrentProcessId();
ProcessInfo GetProcessById(int id);
void Kill(int processId);
void Kill(StartupOptions opts);
void KillAll(string processName);
void SetPriority(int processId, ProcessPriorityClass priority);
void WaitForExit(Process process);

@ -21,7 +21,7 @@ namespace Ombi.Updater
{
// Kill Ombi Process
var p = new ProcessProvider();
p.Kill(opt.OmbiProcessId);
p.Kill(opt);
// Make sure the process has been killed
while (p.FindProcessByName(opt.ProcessName).Any())
@ -32,7 +32,8 @@ namespace Ombi.Updater
if (proc != null)
{
_log.LogDebug($"[{proc.Id}] - {proc.Name} - Path: {proc.StartPath}");
p.Kill(proc.Id);
opt.OmbiProcessId = proc.Id;
p.Kill(opt);
}
}
@ -51,18 +52,36 @@ namespace Ombi.Updater
{
fileName = "Ombi";
}
var start = new ProcessStartInfo
if (options.IsWindowsService)
{
UseShellExecute = false,
FileName = Path.Combine(options.ApplicationPath,fileName),
WorkingDirectory = options.ApplicationPath,
Arguments = options.StartupArgs
};
using (var proc = new Process { StartInfo = start })
var startInfo =
new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = $"/C net start \"{options.WindowsServiceName}\""
};
using (var process = new Process{StartInfo = startInfo})
{
process.Start();
}
}
else
{
proc.Start();
var start = new ProcessStartInfo
{
UseShellExecute = false,
FileName = Path.Combine(options.ApplicationPath, fileName),
WorkingDirectory = options.ApplicationPath,
Arguments = options.StartupArgs
};
using (var proc = new Process { StartInfo = start })
{
proc.Start();
}
}
_log.LogDebug("Ombi started, now exiting");
Environment.Exit(0);
}

@ -11,19 +11,13 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
<PackageReference Include="Serilog" Version="2.6.0-dev-00892" />

@ -73,29 +73,46 @@ namespace Ombi.Updater
process.PriorityClass = priority;
}
public void Kill(int processId)
public void Kill(StartupOptions opts)
{
var process = Process.GetProcesses().FirstOrDefault(p => p.Id == processId);
if (process == null)
if (opts.IsWindowsService)
{
Console.WriteLine("Cannot find process with id: {0}", processId);
return;
Console.WriteLine("Stopping Service {0}", opts.WindowsServiceName);
var process = new Process();
var startInfo =
new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = $"/C net stop \"{opts.WindowsServiceName}\""
};
process.StartInfo = startInfo;
process.Start();
}
else
{
var process = Process.GetProcesses().FirstOrDefault(p => p.Id == opts.OmbiProcessId);
process.Refresh();
if (process == null)
{
Console.WriteLine("Cannot find process with id: {0}", opts.OmbiProcessId);
return;
}
if (process.Id != Process.GetCurrentProcess().Id && process.HasExited)
{
Console.WriteLine("Process has already exited");
return;
}
process.Refresh();
Console.WriteLine("[{0}]: Killing process", process.Id);
process.Kill();
Console.WriteLine("[{0}]: Waiting for exit", process.Id);
process.WaitForExit();
Console.WriteLine("[{0}]: Process terminated successfully", process.Id);
if (process.Id != Process.GetCurrentProcess().Id && process.HasExited)
{
Console.WriteLine("Process has already exited");
return;
}
Console.WriteLine("[{0}]: Killing process", process.Id);
process.Kill();
Console.WriteLine("[{0}]: Waiting for exit", process.Id);
process.WaitForExit();
Console.WriteLine("[{0}]: Process terminated successfully", process.Id);
}
}
public void KillAll(string processName)
@ -113,7 +130,7 @@ namespace Ombi.Updater
}
Console.WriteLine("Killing process: {0} [{1}]", processInfo.Id, processInfo.ProcessName);
Kill(processInfo.Id);
Kill(new StartupOptions{OmbiProcessId = processInfo.Id});
}
}

@ -2,6 +2,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using CommandLine;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -62,39 +63,26 @@ namespace Ombi.Updater
private static StartupOptions CheckArgs(string[] args)
{
if(args.Length <= 1)
{
Console.WriteLine("No Args Provided... Exiting");
Environment.Exit(1);
}
var startup = new StartupOptions
{
ApplicationPath = args[0],
ProcessName = args[1],
};
if (args.Length == 4)
{
startup.StartupArgs = args[2] + " " + args[3];
}
else if (args.Length == 3)
{
startup.StartupArgs = args[2];
}
var p = new ProcessProvider();
var ombiProc = p.FindProcessByName(startup.ProcessName).FirstOrDefault();
startup.OmbiProcessId = ombiProc?.Id ?? -1;
return startup;
var result = Parser.Default.ParseArguments<StartupOptions>(args);
StartupOptions opts = null;
result.WithParsed(options => opts = options);
return opts;
}
}
public class StartupOptions
{
[Option("processname", Required = false, Default = "Ombi")]
public string ProcessName { get; set; }
[Option("applicationPath", Required = false)]
public string ApplicationPath { get; set; }
[Option("processId", Required = false)]
public int OmbiProcessId { get; set; }
[Option("startupArgs", Required = false)]
public string StartupArgs { get; set; }
[Option("windowsServiceName", Required = false)]
public string WindowsServiceName { get; set; }
public bool IsWindowsService => !string.IsNullOrEmpty(WindowsServiceName);
}
}

@ -2,7 +2,7 @@
"profiles": {
"Ombi.Updater": {
"commandName": "Project",
"commandLineArgs": "C:\\Users\\Jamie.Rees\\Source\\Repos\\PlexRequests.Net\\src\\Ombi\\bin\\Debug\\netcoreapp1.1 zip"
"commandLineArgs": "--applicationPath C:\\\\Users\\\\Jamie.Rees\\\\Source\\\\Repos\\\\test\\\\Ombi\\\\src\\\\Ombi\\\\bin\\\\Debug\\\\netcoreapp2.0 --processname Ombi --windowsServiceName \"World Wide Publishing Service\" --startupArgs http://*:5000"
}
}
}

@ -22,6 +22,9 @@ export interface IUpdateSettings extends ISettings {
processName: string;
useScript: boolean;
scriptLocation: string;
windowsService: boolean;
windowsServiceName: string;
isWindows: boolean;
}
export interface IEmbySettings extends ISettings {

@ -20,15 +20,31 @@
<label for="autoUpdateEnabled">Enable Automatic Update</label>
</div>
</div>
<div class="form-group" *ngIf="isWindows">
<div class="checkbox">
<input type="checkbox" id="windowsService" formControlName="windowsService">
<label for="windowsService">Running as a Windows Service</label>
</div>
</div>
<div class="form-group">
<div class="form-group" *ngIf="!form.value.windowsService">
<div class="checkbox">
<input type="checkbox" id="useScript" formControlName="useScript">
<label for="useScript">Use your own updater script</label>
</div>
</div>
<div [hidden]="!useScript">
<div *ngIf="form.value.windowsService">
<div class="form-group">
<label for="windowsServiceName" class="control-label">Windows Service Name</label>
<input type="text" class="form-control form-control-custom " id="windowsServiceName" name="windowsServiceName" formControlName="windowsServiceName">
</div>
</div>
<div [hidden]="!useScript || form.value.windowsService">
<small>For information how to use this, please press the wiki button at the top of the page</small>
<div class="form-group">
<label for="scriptLocation" class="control-label">Script Path</label>
@ -37,7 +53,7 @@
</div>
<div [hidden]="useScript">
<div [hidden]="useScript || form.value.windowsService">
<small >By default the process name is Ombi, but this could be different for your system. We need to know the process name so we can kill that process to update the files.</small>
<div class="form-group">
<label for="processName">Ombi Process Name</label>
@ -51,8 +67,8 @@
</div>
</div>
</div>
<div class="col-md-6" [hidden]="useScript">
<small>If you are getting any permissions issues, you can specify a user for the update process to run under (Only supported on Windows).</small>
<div class="col-md-6" [hidden]="useScript" *ngIf="isWindows">
<small>If you are getting any permissions issues, you can specify a user for the update process to run under.</small>
<div class="form-group">
<label for="username" class="control-label">Username</label>

@ -12,9 +12,9 @@ export class UpdateComponent implements OnInit {
public form: FormGroup;
public updateAvailable = false;
public enableUpdateButton = false;
public isWindows = false;
public get useScript() {
const control = this.form.get("useScript");
console.log(control);
return control!.value!;
}
@ -33,7 +33,10 @@ export class UpdateComponent implements OnInit {
processName: [x.processName],
useScript: [x.useScript],
scriptLocation: [x.scriptLocation],
windowsService: [x.windowsService],
windowsServiceName: [x.windowsServiceName],
});
this.isWindows = x.isWindows;
this.enableUpdateButton = x.autoUpdateEnabled;
});
}

@ -379,7 +379,9 @@ namespace Ombi.Controllers
[HttpGet("Update")]
public async Task<UpdateSettings> UpdateSettings()
{
return await Get<UpdateSettings>();
var settings = await Get<UpdateSettings>();
return Mapper.Map<UpdateSettingsViewModel>(settings);
}
/// <summary>

Loading…
Cancel
Save