-
Notifications
You must be signed in to change notification settings - Fork 3
Ze/labvm status job #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 17 commits
40c3859
8b7c2c5
f5a5353
67d7053
4e99555
695903e
3479d33
f36704c
1e3e2a5
9e2a103
3c8f762
34b4be4
354f071
f49158b
47acc84
77123c8
5b7dd18
952828b
4928be0
3c8328d
ce76973
820d90e
04050a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| using System; | ||
| using System.Threading.Tasks; | ||
| using CSLabs.Api.Models; | ||
| using CSLabs.Api.Services; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
|
|
||
| namespace CSLabs.Api.Jobs | ||
| { | ||
| public class VmStatusJob : AsyncJob | ||
| { | ||
| private readonly IServiceProvider _provider; | ||
| public VmStatusJob(IServiceProvider provider) | ||
| { | ||
| _provider = provider; | ||
| } | ||
|
|
||
| protected override async Task ExecuteAsync() | ||
| { | ||
| using var scope = _provider.CreateScope(); | ||
| using var context = scope.ServiceProvider.GetService<DefaultContext>(); | ||
|
|
||
| // Do job | ||
| var connectionService = new TestVmConnectionService(context); | ||
| await connectionService.TestLabVmConnection(); | ||
|
|
||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| using System.Threading.Tasks; | ||
| using CSLabs.Api.Models; | ||
| using CSLabs.Api.Models.HypervisorModels; | ||
|
|
||
| namespace CSLabs.Api.Proxmox | ||
| { | ||
| public class ProxmoxDBApi : ProxmoxApi | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You havent configured this ProxmoxDBApito be used anywhere but one place, it should be used instead of the Proxmox api since you want to track the start and stop states of the VM when initiated by the UI. |
||
| { | ||
| private DefaultContext _context; | ||
| public ProxmoxDBApi(HypervisorNode hypervisorNode, string password, DefaultContext context) : base(hypervisorNode, password) | ||
| { | ||
| _context = context; | ||
| } | ||
|
|
||
| public new async Task StartVM(int vmId, string targetNode = null) | ||
| { | ||
| await base.StartVM(vmId, targetNode); | ||
| // Save in the database that the VM is started | ||
| _context.UserLabVms.Find(vmId).Running = true; | ||
| } | ||
|
|
||
| public new async Task StopVM(int vmId) | ||
| { | ||
| await base.StopVM(vmId); | ||
| // Save in the database that the VM is stopped | ||
| _context.UserLabVms.Find(vmId).Running = false; | ||
jasekiw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| public new async Task ShutdownVm(int vmId, int timeout = 20) | ||
| { | ||
| await base.ShutdownVm(vmId, timeout); | ||
| // Save in the database that the VM is stopped | ||
| _context.UserLabVms.Find(vmId).Running = false; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The vm id here is the proxmox vmid so the .Find(vmId) will fail. |
||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| using System.Linq; | ||
| using System.Threading.Tasks; | ||
| using CSLabs.Api.Models; | ||
| using CSLabs.Api.Proxmox; | ||
| using Microsoft.AspNetCore.Mvc; | ||
| using Microsoft.EntityFrameworkCore; | ||
|
|
||
| namespace CSLabs.Api.Services | ||
| { | ||
| public class TestVmConnectionService | ||
| { | ||
| private DefaultContext Context { get; } | ||
|
|
||
| private ProxmoxManager ProxmoxManager; | ||
|
|
||
| public TestVmConnectionService(DefaultContext context) | ||
| { | ||
| Context = context; | ||
| } | ||
|
|
||
| // Recursive helper function | ||
| public async void AttemptStart(int attempt, int labId, ProxmoxApi api) | ||
| { | ||
| try | ||
| { | ||
| if (attempt != 3) // first or second attempt | ||
| { | ||
| await api.StartVM(labId); | ||
| } | ||
| else // third attempt | ||
| { | ||
| await api.StopVM(labId); | ||
| await api.StartVM(labId); | ||
| } | ||
|
|
||
| } | ||
| catch (ProxmoxRequestException) | ||
| { | ||
| if (attempt != 3) | ||
| { | ||
| AttemptStart(attempt + 1, labId, api); | ||
| } | ||
| else | ||
| { | ||
| // TODO | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ses sender is merged, so you should be able to continue with this. |
||
| // third attempt at restarting has failed. Something really bad has happened | ||
| // and the maintainers need to be emailed | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public async Task<IActionResult> TestLabVmConnection() | ||
| { | ||
| var hypervisors = await Context.Hypervisors | ||
| .Include(h => h.HypervisorNodes) | ||
| .ToListAsync(); | ||
|
|
||
| var labVms = await Context.LabVms | ||
| .Include(v => v.Id) | ||
| .ToListAsync(); | ||
|
|
||
| var userLabVms = await Context.UserLabVms | ||
| .Include(v => v.Id) | ||
| .ToListAsync(); | ||
|
|
||
| foreach (var hypervisor in hypervisors) | ||
| { | ||
| var api = ProxmoxManager.GetProxmoxDBApi(hypervisor.HypervisorNodes.First()); | ||
|
|
||
| foreach (var labVm in labVms) | ||
| { | ||
| try | ||
| { | ||
| //actual status of VM | ||
| var vmStatus = await api.GetVmStatus(labVm.Id); | ||
|
|
||
| //value stored in database | ||
| var userLab = userLabVms.Find(x => x.LabVmId.Equals(labVm.Id)); | ||
| var userLabStatus = userLab.Running; | ||
|
|
||
| // check if actual status is opposite what is stored in the database | ||
| if (vmStatus.IsStopped() != userLabStatus) | ||
| { | ||
| AttemptStart(1, labVm.Id, api); | ||
| } | ||
| } | ||
| catch (ProxmoxRequestException) | ||
| { | ||
| // something went wrong getting the vm status | ||
| } | ||
|
|
||
| } | ||
| } | ||
|
|
||
| return new OkObjectResult("All LabVMs are up and responding"); | ||
| } | ||
|
|
||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the following to the
ServiceProvider.ProvideAppServicesmethod:Then rewrite this section to handle the dependency injection:
Then anything in the constructor of the TestVmConnectionService will be automatically injected.