wsp-10329 Adding hyper-v replica to HyperV Provider. Server Part.
This commit is contained in:
parent
414414b11d
commit
41fd1230bf
23 changed files with 5194 additions and 37 deletions
|
@ -56,7 +56,7 @@ using System.Configuration;
|
|||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public class HyperV2012R2 : HostingServiceProviderBase, IVirtualizationServer
|
||||
public class HyperV2012R2 : HostingServiceProviderBase, IVirtualizationServer2012
|
||||
{
|
||||
#region Provider Settings
|
||||
protected string ServerNameSettings
|
||||
|
@ -98,6 +98,20 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
{
|
||||
get { return ProviderSettings.GetInt("CpuWeight"); }
|
||||
}
|
||||
|
||||
|
||||
public ReplicaMode ReplicaMode
|
||||
{
|
||||
get { return (ReplicaMode) ProviderSettings.GetInt("ReplicaMode"); }
|
||||
}
|
||||
protected string ReplicaServerPath
|
||||
{
|
||||
get { return ProviderSettings["ReplicaServerPath"]; }
|
||||
}
|
||||
protected string ReplicaServerThumbprint
|
||||
{
|
||||
get { return ProviderSettings["ReplicaServerThumbprint"]; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
@ -157,12 +171,12 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
vm.RamSize = Convert.ToInt32(ConvertNullableToInt64(result[0].GetProperty("MemoryStartup")) / Constants.Size1M);
|
||||
vm.Uptime = Convert.ToInt64(result[0].GetProperty<TimeSpan>("UpTime").TotalMilliseconds);
|
||||
vm.Status = result[0].GetProperty("Status").ToString();
|
||||
vm.ReplicationState = result[0].GetProperty("ReplicationState").ToString();
|
||||
vm.Generation = result[0].GetInt("Generation");
|
||||
vm.ProcessorCount = result[0].GetInt("ProcessorCount");
|
||||
vm.ParentSnapshotId = result[0].GetString("ParentSnapshotId");
|
||||
vm.Heartbeat = VirtualMachineHelper.GetVMHeartBeatStatus(PowerShell, vm.Name);
|
||||
vm.CreatedDate = DateTime.Now;
|
||||
vm.ReplicationState = result[0].GetEnum<ReplicationState>("ReplicationState");
|
||||
|
||||
if (extendedInfo)
|
||||
{
|
||||
|
@ -222,9 +236,10 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
VirtualMachine vm = new VirtualMachine
|
||||
{
|
||||
VirtualMachineId = current.GetProperty("Id").ToString(),
|
||||
Name = current.GetProperty("Name").ToString(),
|
||||
State = (VirtualMachineState)Enum.Parse(typeof(VirtualMachineState), current.GetProperty("State").ToString()),
|
||||
Uptime = Convert.ToInt64(current.GetProperty<TimeSpan>("UpTime").TotalMilliseconds)
|
||||
Name = current.GetString("Name"),
|
||||
State = current.GetEnum<VirtualMachineState>("State"),
|
||||
Uptime = Convert.ToInt64(current.GetProperty<TimeSpan>("UpTime").TotalMilliseconds),
|
||||
ReplicationState = result[0].GetEnum<ReplicationState>("ReplicationState")
|
||||
};
|
||||
vmachines.Add(vm);
|
||||
}
|
||||
|
@ -443,30 +458,11 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
|
||||
public ReturnCode ShutDownVirtualMachine(string vmId, bool force, string reason)
|
||||
{
|
||||
HostedSolutionLog.LogStart("ShutDownVirtualMachine");
|
||||
ReturnCode returnCode = ReturnCode.OK;
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
try
|
||||
{
|
||||
Command cmd = new Command("Stop-VM");
|
||||
VirtualMachineHelper.Stop(PowerShell, vm.Name, force, ServerNameSettings);
|
||||
|
||||
cmd.Parameters.Add("Name", vm.Name);
|
||||
if (force) cmd.Parameters.Add("Force");
|
||||
//if (!string.IsNullOrEmpty(reason)) cmd.Parameters.Add("Reason", reason);
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HostedSolutionLog.LogError("ShutDownVirtualMachine", ex);
|
||||
throw;
|
||||
}
|
||||
|
||||
HostedSolutionLog.LogEnd("ShutDownVirtualMachine");
|
||||
|
||||
return returnCode;
|
||||
return ReturnCode.OK;
|
||||
}
|
||||
|
||||
public List<ConcreteJob> GetVirtualMachineJobs(string vmId)
|
||||
|
@ -517,10 +513,7 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
//DeleteSwitch(networkAdapter.SwitchName);
|
||||
}
|
||||
|
||||
Command cmdSet = new Command("Remove-VM");
|
||||
cmdSet.Parameters.Add("Name", vm.Name);
|
||||
cmdSet.Parameters.Add("Force");
|
||||
PowerShell.Execute(cmdSet, true, true);
|
||||
VirtualMachineHelper.Delete(PowerShell, vm.Name, ServerNameSettings);
|
||||
|
||||
return JobHelper.CreateSuccessResult(ReturnCode.JobStarted);
|
||||
}
|
||||
|
@ -1963,6 +1956,284 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
return !String.IsNullOrEmpty(connString);
|
||||
}
|
||||
#endregion Hyper-V Cloud
|
||||
|
||||
|
||||
#region Replication
|
||||
|
||||
public List<CertificateInfo> GetCertificates(string remoteServer)
|
||||
{
|
||||
// we cant get certificates from remote server
|
||||
if (string.IsNullOrEmpty(remoteServer))
|
||||
return null;
|
||||
|
||||
Command cmd = new Command("Get-ChildItem");
|
||||
cmd.Parameters.Add("Path", @"cert:\LocalMachine\My");
|
||||
|
||||
Collection<PSObject> result = PowerShell.Execute(cmd, true);
|
||||
|
||||
return result
|
||||
.Select(
|
||||
cert => new CertificateInfo
|
||||
{
|
||||
Subject = cert.GetString("Subject"),
|
||||
Thumbprint = cert.GetString("Thumbprint"),
|
||||
Title = string.Format("{0} ({1})", cert.GetString("Thumbprint"), cert.GetString("Subject")),
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public void SetReplicaServer(string remoteServer, string thumbprint, string storagePath)
|
||||
{
|
||||
// we cant enable firewall rules on remote server
|
||||
if (!string.IsNullOrEmpty(remoteServer))
|
||||
{
|
||||
ReplicaHelper.SetFirewallRule(PowerShell, true);
|
||||
}
|
||||
|
||||
ReplicaHelper.SetReplicaServer(PowerShell, true, remoteServer, thumbprint, storagePath);
|
||||
}
|
||||
|
||||
public void UnsetReplicaServer(string remoteServer)
|
||||
{
|
||||
ReplicaHelper.SetReplicaServer(PowerShell, false, remoteServer, null, null);
|
||||
}
|
||||
|
||||
public void EnableVmReplication(string vmId, string replicaServer, VmReplication replication)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachineEx(vmId);
|
||||
|
||||
Command cmd = new Command("Enable-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
cmd.Parameters.Add("ReplicaServerName", replicaServer);
|
||||
cmd.Parameters.Add("ReplicaServerPort", 443);
|
||||
cmd.Parameters.Add("AuthenticationType", "Cert");
|
||||
cmd.Parameters.Add("CertificateThumbprint", replication.Thumbprint);
|
||||
cmd.Parameters.Add("ReplicationFrequencySec", (int)replication.ReplicaFrequency);
|
||||
|
||||
var excludes = vm.Disks
|
||||
.Select(d => d.Path)
|
||||
.Where(p => !p.Equals(replication.VhdToReplicate, StringComparison.OrdinalIgnoreCase))
|
||||
.ToArray();
|
||||
if (excludes.Any())
|
||||
cmd.Parameters.Add("ExcludedVhdPath", excludes);
|
||||
|
||||
// recovery points
|
||||
if (replication.AdditionalRecoveryPoints > 0)
|
||||
{
|
||||
if (replication.AdditionalRecoveryPoints > 24)
|
||||
throw new Exception("AdditionalRecoveryPoints can not be greater than 24");
|
||||
|
||||
cmd.Parameters.Add("RecoveryHistory", replication.AdditionalRecoveryPoints);
|
||||
|
||||
if (replication.VSSSnapshotFrequencyHour > 0)
|
||||
{
|
||||
if (replication.VSSSnapshotFrequencyHour > 12)
|
||||
throw new Exception("VSSSnapshotFrequencyHour can not be greater than 12");
|
||||
|
||||
cmd.Parameters.Add("VSSSnapshotFrequencyHour", replication.VSSSnapshotFrequencyHour);
|
||||
}
|
||||
}
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
|
||||
// Initial Replication
|
||||
StartInitialReplication(vmId);
|
||||
}
|
||||
|
||||
public void SetVmReplication(string vmId, string replicaServer, VmReplication replication)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachineEx(vmId);
|
||||
|
||||
Command cmd = new Command("Set-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
cmd.Parameters.Add("ReplicaServerName", replicaServer);
|
||||
cmd.Parameters.Add("ReplicaServerPort", 443);
|
||||
cmd.Parameters.Add("AuthenticationType", "Cert");
|
||||
cmd.Parameters.Add("CertificateThumbprint", replication.Thumbprint);
|
||||
cmd.Parameters.Add("ReplicationFrequencySec", (int)replication.ReplicaFrequency);
|
||||
|
||||
var excludes = vm.Disks
|
||||
.Select(d => d.Path)
|
||||
.Where(p => !p.Equals(replication.VhdToReplicate, StringComparison.OrdinalIgnoreCase))
|
||||
.ToArray();
|
||||
if (excludes.Any())
|
||||
cmd.Parameters.Add("ExcludedVhdPath", excludes);
|
||||
|
||||
// recovery points
|
||||
if (replication.AdditionalRecoveryPoints > 0)
|
||||
{
|
||||
if (replication.AdditionalRecoveryPoints > 24)
|
||||
throw new Exception("AdditionalRecoveryPoints can not be greater than 24");
|
||||
|
||||
cmd.Parameters.Add("RecoveryHistory", replication.AdditionalRecoveryPoints);
|
||||
|
||||
if (replication.VSSSnapshotFrequencyHour > 0)
|
||||
{
|
||||
if (replication.VSSSnapshotFrequencyHour > 12)
|
||||
throw new Exception("VSSSnapshotFrequencyHour can not be greater than 12");
|
||||
|
||||
cmd.Parameters.Add("VSSSnapshotFrequencyHour", replication.VSSSnapshotFrequencyHour);
|
||||
}
|
||||
}
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
|
||||
public void TestReplicationServer(string vmId, string replicaServer, string localThumbprint)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
Command cmd = new Command("Test-VMReplicationConnection");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
cmd.Parameters.Add("ReplicaServerName", replicaServer);
|
||||
cmd.Parameters.Add("ReplicaServerPort", 443);
|
||||
cmd.Parameters.Add("AuthenticationType", "Cert");
|
||||
cmd.Parameters.Add("CertificateThumbprint", localThumbprint);
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
|
||||
public void StartInitialReplication(string vmId)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
Command cmd = new Command("Start-VMInitialReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
|
||||
public VmReplication GetReplication(string vmId)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
VmReplication replica = null;
|
||||
var vm = GetVirtualMachineEx(vmId);
|
||||
|
||||
Command cmd = new Command("Get-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
|
||||
Collection<PSObject> result = PowerShell.Execute(cmd, true);
|
||||
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
replica = new VmReplication();
|
||||
replica.ReplicaFrequency = result[0].GetEnum<ReplicaFrequency>("FrequencySec", ReplicaFrequency.Seconds30);
|
||||
replica.Thumbprint = result[0].GetString("CertificateThumbprint");
|
||||
replica.AdditionalRecoveryPoints = result[0].GetInt("RecoveryHistory");
|
||||
replica.VSSSnapshotFrequencyHour = result[0].GetInt("VSSSnapshotFrequencyHour");
|
||||
|
||||
List<string> excludes = new List<string>();
|
||||
foreach (dynamic item in (IEnumerable) result[0].GetProperty("ExcludedDisks"))
|
||||
excludes.Add(item.Path.ToString());
|
||||
replica.VhdToReplicate = vm.Disks
|
||||
.Select(d => d.Path)
|
||||
.FirstOrDefault(p => excludes.All(ep => !p.Equals(ep, StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
|
||||
return replica;
|
||||
}
|
||||
|
||||
public bool DisableVmReplication(string vmId, string replicaServer)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
ReplicaHelper.RemoveVmReplication(PowerShell, vm.Name, ServerNameSettings);
|
||||
|
||||
// move it to EnterpriseServer?
|
||||
// If we have access - delete garbage from replica server
|
||||
try
|
||||
{
|
||||
ReplicaHelper.RemoveVmReplication(PowerShell, vm.Name, replicaServer);
|
||||
// Delete replica vm
|
||||
VirtualMachineHelper.Stop(PowerShell, vm.Name, true, replicaServer);
|
||||
VirtualMachineHelper.Delete(PowerShell, vm.Name, replicaServer);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public ReplicationDetailInfo GetReplicationInfo(string vmId)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
ReplicationDetailInfo replica = null;
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
Command cmd = new Command("Measure-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
|
||||
Collection<PSObject> result = PowerShell.Execute(cmd, true);
|
||||
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
replica = new ReplicationDetailInfo();
|
||||
replica.AverageLatency = result[0].GetProperty<TimeSpan>("AverageReplicationLatency");
|
||||
replica.AverageSize = result[0].GetMb("AverageReplicationSize");
|
||||
replica.Errors = result[0].GetInt("ReplicationErrors");
|
||||
replica.FromTime = result[0].GetProperty<DateTime>("MonitoringStartTime");
|
||||
replica.Health = result[0].GetEnum<ReplicationHealth>("ReplicationHealth");
|
||||
replica.HealthDetails = result[0].GetString("ReplicationHealthDetails");
|
||||
replica.LastSynhronizedAt = result[0].GetProperty<DateTime>("LastReplicationTime");
|
||||
replica.MaximumSize = result[0].GetMb("MaximumReplicationSize");
|
||||
replica.Mode = result[0].GetEnum<VmReplicationMode>("ReplicationMode");
|
||||
replica.PendingSize = result[0].GetMb("PendingReplicationSize");
|
||||
replica.PrimaryServerName = result[0].GetString("PrimaryServerName");
|
||||
replica.ReplicaServerName = result[0].GetString("CurrentReplicaServerName");
|
||||
replica.State = result[0].GetEnum<ReplicationState>("ReplicationState");
|
||||
replica.SuccessfulReplications = result[0].GetInt("SuccessfulReplicationCount");
|
||||
replica.ToTime = result[0].GetProperty<DateTime>("MonitoringEndTime");
|
||||
}
|
||||
|
||||
return replica;
|
||||
}
|
||||
|
||||
public void PauseReplication(string vmId)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
Command cmd = new Command("Suspend-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
|
||||
public void ResumeReplication(string vmId)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
Command cmd = new Command("Resume-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue