forked from wubbl0rz/VmChamp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHelper.cs
163 lines (132 loc) · 4.77 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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
using System.Diagnostics;
using System.IO.Pipes;
using System.Net.NetworkInformation;
using Spectre.Console;
using System.Text.RegularExpressions;
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();
public static string GetUserFromIso(string vmDir)
{
var isoPath = Path.Combine(vmDir, "cloudInit.iso");
if (!File.Exists(isoPath))
{
return "N/A";
}
try
{
var content = File.ReadAllText(isoPath);
var userPattern = new Regex(@"^\s*- name\s*:\s*(\w+)", RegexOptions.Multiline);
var match = userPattern.Match(content);
if (match.Success)
{
return match.Groups[1].Value;
}
return "N/A";
}
catch (Exception ex)
{
Console.WriteLine($"Error reading user from ISO: {ex.Message}");
return "N/A";
}
}
}