-
Notifications
You must be signed in to change notification settings - Fork 10
/
Helper.cs
133 lines (107 loc) · 4.02 KB
/
Helper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using System.Diagnostics;
using System.IO.Pipes;
using System.Net.NetworkInformation;
using Spectre.Console;
namespace VmChamp;
public class Helper
{
public static Process? ConnectViaSsh(string user, string ip)
{
var startInfo = new ProcessStartInfo("ssh");
startInfo.Arguments = $"-Y -o StrictHostKeyChecking=off {user}@{ip}";
return Process.Start(startInfo);
}
public static void DeleteExistingDirectory(string directoryPath)
{
if (Directory.Exists(directoryPath))
{
Directory.Delete(directoryPath, true);
}
}
public static bool CheckDefaultNetwork()
{
var defaultBridge= NetworkInterface.GetAllNetworkInterfaces()
.FirstOrDefault(iface => iface.Name == "virbr0");
var defaultBridgeHasIp = defaultBridge?.GetIPProperties()
.UnicastAddresses
.Select(info => info.Address)
.Any();
var bridgeFileExists = File.Exists("/etc/qemu/bridge.conf");
if (defaultBridgeHasIp is true && bridgeFileExists)
return true;
var script = "";
if (defaultBridge == null || !bridgeFileExists)
{
AnsiConsole.MarkupLine("[red]Default network bridge: virbr0 missing configuration. " +
"Some distributions do not setup a bridge automatically.[/]");
var hasFreeNetwork = NetworkInterface.GetAllNetworkInterfaces()
.SelectMany(i => i.GetIPProperties().UnicastAddresses)
.Any(i => i.ToString()?.Contains("192.168.122.") is true);
var thirdOctet = hasFreeNetwork ? "122" : "22";
var bridgeName = $"virbr0";
var bridgeIp = $"192.168.{thirdOctet}.1";
var bridgeMask = "255.255.255.0";
var bridgeDhcpStart = $"192.168.{thirdOctet}.128";
var bridgeDhcpEnd = $"192.168.{thirdOctet}.254";
AnsiConsole.WriteLine("👉 The following default network can be created: ");
AnsiConsole.WriteLine($"Name: {bridgeName}");
AnsiConsole.WriteLine($"IP: {bridgeIp}");
AnsiConsole.WriteLine($"Mask: {bridgeMask}");
AnsiConsole.WriteLine();
if (AnsiConsole
.Ask<string>("Do you want to create it now and allow VMs to use it? (y/N)", "N")
.ToLower() != "y")
{
return false;
}
var bridgeXml = Interop.GenVirBridgeXml(bridgeName, bridgeIp, bridgeMask, bridgeDhcpStart, bridgeDhcpEnd);
script = $"""
if ! test -f /etc/qemu/bridge.conf; then
mkdir -p /etc/qemu &> /dev/null
echo \"allow virbr0\" > /etc/qemu/bridge.conf
chmod u+s /usr/lib/qemu/qemu-bridge-helper
fi
if ! virsh --connect qemu:///system net-start default &> /dev/null; then
virsh net-undefine default &> /dev/null
virsh --connect qemu:///system net-define <(echo \"{bridgeXml}\") &> /dev/null
virsh --connect qemu:///system net-destroy default &> /dev/null
fi
virsh --connect qemu:///system net-start default &> /dev/null
virsh --connect qemu:///system net-autostart default &> /dev/null
""";
}
else
{
script = $"""
IP=$(virsh net-dumpxml default | grep 'ip address' | cut -d \' -f 2)
MASK=$(virsh net-dumpxml default | grep 'ip address' | cut -d \' -f 4)
ip a add $IP/$MASK dev virbr0
ip link set dev virbr0 up
""";
AnsiConsole.MarkupLine("[red]Default network has no IP address or is down.[/]");
if (AnsiConsole.Ask<string>("Do you want to start it now? (y/N)", "N").ToLower() != "y")
{
return false;
}
}
var startInfo = new ProcessStartInfo("sudo")
{
Arguments = $"bash -c \"{script}\"",
};
Process.Start(startInfo)?.WaitForExit();
return true;
}
public static void ResizeImage(string file, double size)
{
var startInfo = new ProcessStartInfo("qemu-img")
{
Arguments = $"resize {file} {size}",
RedirectStandardOutput = true
};
Process.Start(startInfo)?.WaitForExit();
}
public static string?[] GetAllVmInDirectory(string path) =>
Directory.GetDirectories(path)
.Select(Path.GetFileName)
.ToArray();
}