Skip to content

Commit

Permalink
Register WOL service in agent. Show toast after sending WOL commands.
Browse files Browse the repository at this point in the history
  • Loading branch information
bitbound committed Jun 22, 2023
1 parent db421ce commit e8b428e
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 25 deletions.
1 change: 1 addition & 0 deletions Agent/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ private static void RegisterServices(IServiceCollection services)
// TODO: All these should be registered as interfaces.
services.AddSingleton<IAgentHubConnection, AgentHubConnection>();
services.AddSingleton<ICpuUtilizationSampler, CpuUtilizationSampler>();
services.AddSingleton<IWakeOnLanService, WakeOnLanService>();
services.AddHostedService(services => services.GetRequiredService<ICpuUtilizationSampler>());
services.AddScoped<ChatClientService>();
services.AddTransient<PSCore>();
Expand Down
8 changes: 6 additions & 2 deletions Server/Components/Devices/DeviceCard.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -328,11 +328,15 @@ private async Task WakeDevice()
var result = await CircuitConnection.WakeDevice(Device);
if (result.IsSuccess)
{
ToastService.ShowToast2("Wake command sent.", ToastType.Success);
ToastService.ShowToast2(
$"Wake command sent to {result.Value} peer devices.",
ToastType.Success);
}
else
{
ToastService.ShowToast2($"Wake command failed. Reason: {result.Reason}", ToastType.Error);
ToastService.ShowToast2(
$"Wake command failed. Reason: {result.Reason}",
ToastType.Error);
}
}
}
Expand Down
25 changes: 14 additions & 11 deletions Server/Components/Devices/DevicesFrame.razor
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@
<div>
<div>
<div>Device Group</div>
<select class="form-control" style="width: 200px" @bind="_selectedGroupId">
<option value="@_deviceGroupAll">All</option>
<option value="@_deviceGroupNone">None</option>
@foreach (var group in _deviceGroups)
{
<option @key="group.ID" value="@group.ID">@group.Name</option>
}
</select>
<button class="btn btn-sm btn-secondary" title="Wake Devices" style="width: 40px; margin-left: 5px;" @onclick="WakeDevices">
<span class="oi oi-eye"></span>
</button>
<div class="text-nowrap">
<select class="form-control d-inline" style="width: 200px" @bind="_selectedGroupId">
<option value="@_deviceGroupAll">All</option>
<option value="@_deviceGroupNone">None</option>
@foreach (var group in _deviceGroups)
{
<option @key="group.ID" value="@group.ID">@group.Name</option>
}
</select>
<button class="btn btn-sm btn-secondary" title="Wake Devices in Group" style="width: 40px; margin-left: 5px;" @onclick="WakeDevices">
<span class="oi oi-eye"></span>
</button>

</div>
</div>

<div>
Expand Down
4 changes: 3 additions & 1 deletion Server/Components/Devices/DevicesFrame.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,9 @@ private async Task WakeDevices()

if (result.IsSuccess)
{
ToastService.ShowToast2("Wake commands sent.", ToastType.Success);
ToastService.ShowToast2(
$"Wake commands sent to {result.Value} peer devices.",
ToastType.Success);
}
else
{
Expand Down
44 changes: 33 additions & 11 deletions Server/Hubs/CircuitConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,22 @@ public interface ICircuitConnection
Task UninstallAgents(string[] deviceIDs);
Task UpdateTags(string deviceID, string tags);
Task UploadFiles(List<string> fileIDs, string transferID, string[] deviceIDs);
Task<Result> WakeDevice(Device device);
Task<Result> WakeDevices(Device[] deviceId);

/// <summary>
/// Sends a Wake-On-LAN request for the specified device to its peer devices.
/// Peer devices are those in the same group or the same public IP.
/// </summary>
/// <param name="device"></param>
/// <returns>The number of peer devices that broadcasted the WOL packet.</returns>
Task<Result<int>> WakeDevice(Device device);

/// <summary>
/// Sends a Wake-On-LAN request for the specified device to its peer devices.
/// Peer devices are those in the same group or the same public IP.
/// </summary>
/// <param name="devices"></param>
/// <returns>The number of peer devices that broadcasted the WOL packet.</returns>
Task<Result<int>> WakeDevices(Device[] devices);
}

public class CircuitConnection : CircuitHandler, ICircuitConnection
Expand Down Expand Up @@ -433,33 +447,34 @@ public Task UploadFiles(List<string> fileIDs, string transferID, string[] device
return Task.CompletedTask;
}

public async Task<Result> WakeDevice(Device device)
public async Task<Result<int>> WakeDevice(Device device)
{
try
{
if (!_dataService.DoesUserHaveAccessToDevice(device.ID, User.Id))
{
return Result.Fail("Unauthorized.") ;
return Result.Fail<int>("Unauthorized.") ;
}

var availableDevices = _serviceSessionCache
.GetAllDevices()
.Where(x =>
x.OrganizationID == User.OrganizationID &&
(x.DeviceGroup == device.DeviceGroup || x.PublicIP == device.PublicIP));
(x.DeviceGroup == device.DeviceGroup || x.PublicIP == device.PublicIP))
.ToArray();

await SendWakeCommand(device, availableDevices);

return Result.Ok();
return Result.Ok(availableDevices.Length);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error waking device {deviceId}.", device.ID);
return Result.Fail(ex);
return Result.Fail<int>(ex);
}
}

public async Task<Result> WakeDevices(Device[] devices)
public async Task<Result<int>> WakeDevices(Device[] devices)
{
try
{
Expand All @@ -483,6 +498,8 @@ public async Task<Result> WakeDevices(Device[] devices)
{
var group = devicesByGroupId.GetOrAdd(device.DeviceGroupID, key => new());
group.Add(device);
// We only need it added to one group.
continue;
}

if (!string.IsNullOrWhiteSpace(device.PublicIP))
Expand All @@ -492,27 +509,32 @@ public async Task<Result> WakeDevices(Device[] devices)
}
}


var peerCount = 0;

foreach (var deviceToWake in filteredDevices)
{
if (!string.IsNullOrWhiteSpace(deviceToWake.DeviceGroupID) &&
devicesByGroupId.TryGetValue(deviceToWake.DeviceGroupID, out var groupList))
{
await SendWakeCommand(deviceToWake, groupList);
peerCount += groupList.Count;
}

if (!string.IsNullOrWhiteSpace(deviceToWake.PublicIP) &&
devicesByGroupId.TryGetValue(deviceToWake.PublicIP, out var ipList))
devicesByPublicIp.TryGetValue(deviceToWake.PublicIP, out var ipList))
{
await SendWakeCommand(deviceToWake, ipList);
peerCount += ipList.Count;
}

}
return Result.Ok();
return Result.Ok(peerCount);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while waking devices.");
return Result.Fail(ex);
return Result.Fail<int>(ex);
}
}

Expand Down
2 changes: 2 additions & 0 deletions Server/Services/DataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ public async Task<Result<Device>> AddOrUpdateDevice(Device device)
using var dbContext = _appDbFactory.GetContext();

var resultDevice = await dbContext.Devices.FindAsync(device.ID);

if (resultDevice != null)
{
resultDevice.CurrentUser = device.CurrentUser;
Expand All @@ -346,6 +347,7 @@ public async Task<Result<Device>> AddOrUpdateDevice(Device device)
resultDevice.TotalMemory = device.TotalMemory;
resultDevice.TotalStorage = device.TotalStorage;
resultDevice.AgentVersion = device.AgentVersion;
resultDevice.MacAddresses = device.MacAddresses;
resultDevice.LastOnline = DateTimeOffset.Now;
}
else
Expand Down

0 comments on commit e8b428e

Please sign in to comment.