Guest User

Untitled

a guest
Dec 23rd, 2023
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.32 KB | None | 0 0
  1.  
  2.  
  3. Config.cs
  4.  
  5. using Newtonsoft.Json;
  6.  
  7. class Config
  8. {
  9. public static Configuration ReadConfig(string jsonFilePath)
  10. {
  11. try
  12. {
  13. string jsonContent = System.IO.File.ReadAllText(jsonFilePath);
  14. return JsonConvert.DeserializeObject<Configuration>(jsonContent);
  15. }
  16. catch (Exception ex)
  17. {
  18. Console.WriteLine(ex.Message);
  19. return null;
  20. }
  21. }
  22.  
  23. public static void WriteConfig(Configuration config)
  24. {
  25. if (config == null)
  26. {
  27. return;
  28. }
  29.  
  30. bool swap = config.Partitioning.SwapPartition != null;
  31.  
  32. Console.WriteLine($"Bootloader: {config.Bootloader}");
  33. Console.WriteLine($"Hostname: {config.Hostname}");
  34.  
  35. Console.WriteLine($"Type: {config.Partitioning.Type}");
  36. Console.WriteLine($"Swap: {swap}");
  37. Console.WriteLine($"System Partition: {config.Partitioning.SystemPartition}");
  38. Console.WriteLine($"EFI Partition: {config.Partitioning.EFIPartition}");
  39. Console.WriteLine($"Swap Partition: {config.Partitioning.SwapPartition}");
  40. Console.WriteLine($"System Partition Size: {config.Partitioning.PartitionSizes.System}");
  41. Console.WriteLine($"EFI Partition Size: {config.Partitioning.PartitionSizes.EFI}");
  42. Console.WriteLine($"Swap Partition Size: {config.Partitioning.PartitionSizes.Swap}");
  43.  
  44. Console.WriteLine($"Lang: {config.Locales.Lang}");
  45. Console.WriteLine($"Keyboard Layout: {config.Locales.KeyboardLayout}");
  46.  
  47. Console.WriteLine("Users:");
  48. foreach (var user in config.Users.UserList)
  49. {
  50. Console.WriteLine($" Username: {user.Username}");
  51. Console.WriteLine($" Display Name: {user.DisplayName}");
  52. Console.WriteLine($" Password: {user.Password}\n");
  53. }
  54.  
  55. Console.WriteLine("Packages:");
  56. foreach (var package in config.Pacman.Packages)
  57. {
  58. Console.WriteLine($" {package}");
  59. }
  60. }
  61.  
  62. public static Configuration CreateConfig(string bootloader, string hostname, string partitioningType, string diskToPartition, string filesystem, Dictionary<string, Program.User> users, List<string> packages, string SystemPartition, string EFIPartition, string SwapPartition, Dictionary<string, Program.PartitionSizes> partitionSizes)
  63. {
  64. Configuration config = new Configuration
  65. {
  66. Bootloader = bootloader,
  67. Hostname = hostname,
  68. Partitioning = new Partitioning
  69. {
  70. Type = partitioningType,
  71. PartitionSizes = new PartitionSizes
  72. {
  73. System = partitionSizes[diskToPartition].System,
  74. EFI = partitionSizes[diskToPartition].EFI,
  75. Swap = partitionSizes[diskToPartition].Swap
  76. },
  77. SystemPartition = SystemPartition,
  78. EFIPartition = EFIPartition,
  79. SwapPartition = SwapPartition
  80. },
  81. Locales = new Locales
  82. {
  83. // Not finished
  84. },
  85. Users = new Users
  86. {
  87. UserList = new List<User>(users.Values)
  88. },
  89. Pacman = new Pacman
  90. {
  91. Packages = packages
  92. }
  93. };
  94.  
  95. return config;
  96. }
  97.  
  98. }
  99.  
  100. class Configuration
  101. {
  102. public string Bootloader { get; set; }
  103. public string Hostname { get; set; }
  104. public Partitioning Partitioning { get; set; }
  105. public Locales Locales { get; set; }
  106. public Users Users { get; set; }
  107. public Pacman Pacman { get; set; }
  108. }
  109.  
  110. class Partitioning
  111. {
  112. public string Type { get; set; }
  113. public bool Swap { get; set; }
  114. public string SystemPartition { get; set; }
  115. public string EFIPartition { get; set; }
  116. public string SwapPartition { get; set; }
  117. public PartitionSizes PartitionSizes { get; set; }
  118. }
  119.  
  120. class PartitionSizes
  121. {
  122. public string System { get; set; }
  123. public string EFI { get; set; }
  124. public string Swap { get; set; }
  125. }
  126.  
  127. class Locales
  128. {
  129. public string Lang { get; set; }
  130. public string KeyboardLayout { get; set; }
  131. }
  132.  
  133. class Pacman
  134. {
  135. public List<string> Packages { get; set; }
  136. }
  137.  
  138. class User
  139. {
  140. public string Username { get; set; }
  141. public string DisplayName { get; set; }
  142. public string Password { get; set; }
  143. }
  144.  
  145. class Users
  146. {
  147. public List<User> UserList { get; set; }
  148. }
  149.  
  150. Program.cs:
  151.  
  152. using Newtonsoft.Json;
  153. using System.Diagnostics;
  154.  
  155. class Program
  156. {
  157. static string selectedBootloader;
  158. static string hostname;
  159. static string partitioningType;
  160. static string diskToPartition;
  161. static string filesystem;
  162. static string SystemPartition;
  163. static string EFIPartition;
  164. static string SwapPartition;
  165.  
  166. static Dictionary<string, PartitionSizes> partitionSizes = new Dictionary<string, PartitionSizes>();
  167. static Dictionary<string, User> users = new Dictionary<string, User>();
  168. static List<string> Packages { get; set; } = new List<string>();
  169. static bool swap;
  170.  
  171. public static void Main()
  172. {
  173. MainMenu();
  174. }
  175.  
  176. static void MainMenu()
  177. {
  178. string[] options = {"Partitioning", "Pacman configuration", "Bootloader", "Hostname", "Users", "Save configuration", "Developer mode", "Install", "Exit"};
  179. Menu mainMenu = new Menu("Feather installer\n", options);
  180. int selectedIndex = mainMenu.Run();
  181.  
  182. switch (selectedIndex)
  183. {
  184. // Partitioning
  185. case 0:
  186. PartitioningMenu();
  187. break;
  188. // Pacman configuration
  189. case 1:
  190. PacmanConfigMenu();
  191. break;
  192. // Bootloader
  193. case 2:
  194. SelectBootloader();
  195. break;
  196. // Hostname
  197. case 3:
  198. SetHostname();
  199. break;
  200. // Users
  201. case 4:
  202. ManageUsers();
  203. break;
  204. // Save Configuration
  205. case 5:
  206. var config = Config.CreateConfig(selectedBootloader,hostname,partitioningType,diskToPartition,filesystem,users,Packages,SystemPartition,EFIPartition,SwapPartition, partitionSizes);
  207. Console.Write("Config save path: ");
  208. string configPath = Console.ReadLine();
  209. break;
  210. // Developer Mode
  211. case 6:
  212. DeveloperMode();
  213. break;
  214. // Exit
  215. case 7:
  216. break;
  217. }
  218.  
  219. }
  220.  
  221. static void PacmanConfigMenu()
  222. {
  223. string[] options = {"Repositories", "Mirrors", "Packages", "Back"};
  224. Menu pacmanConfigurationMenu = new Menu("Pacman configuration\n", options);
  225. int selectedIndex = pacmanConfigurationMenu.Run();
  226.  
  227. switch (selectedIndex)
  228. {
  229. // Repositories
  230. case 0:
  231. break;
  232. // Mirrors
  233. case 1:
  234. break;
  235. // Packages
  236. case 2:
  237. while (true)
  238. {
  239. string[] packagesOptions = {"Add package", "Remove package", "Back"};
  240. Menu packagesMenu = new Menu("Packages\n", packagesOptions);
  241. int packagesIndex = packagesMenu.Run();
  242.  
  243. switch (packagesIndex)
  244. {
  245. // Add package
  246. case 0:
  247. Console.Write("Package name: ");
  248. string packageToAdd = Console.ReadLine();
  249. Packages.Add(packageToAdd);
  250. break;
  251. // Remove package
  252. case 1:
  253. Console.Write("Package name: ");
  254. string packageToRemove = Console.ReadLine();
  255. Packages.Remove(packageToRemove);
  256. break;
  257. // Back
  258. case 2:
  259. PacmanConfigMenu();
  260. return;
  261. }
  262. }
  263. // Back
  264. case 3:
  265. MainMenu();
  266. break;
  267. }
  268. }
  269. static List<string> ListDevices()
  270. {
  271. List<string> deviceList = new List<string>();
  272.  
  273. try
  274. {
  275. string blockDevicesPath = "/sys/block";
  276.  
  277. if (Directory.Exists(blockDevicesPath))
  278. {
  279. string[] devices = Directory.GetDirectories(blockDevicesPath);
  280.  
  281. foreach (string device in devices)
  282. {
  283. string deviceName = Path.GetFileName(device);
  284.  
  285. if (!deviceName.StartsWith("loop") && !deviceName.StartsWith("ram"))
  286. {
  287. deviceList.Add($"/dev/{deviceName}");
  288. }
  289. }
  290. }
  291. }
  292. catch (Exception ex)
  293. {
  294. Console.WriteLine($"Error listing devices: {ex.Message}");
  295. }
  296.  
  297. return deviceList;
  298. }
  299.  
  300. static void PartitioningMenu()
  301. {
  302. while (true)
  303. {
  304. List<string> options = ListDevices();
  305. options.Add("Back");
  306.  
  307. Menu diskSelectionMenu = new Menu("Select disk to partition\n", options.ToArray());
  308. int diskIndex = diskSelectionMenu.Run();
  309.  
  310. if (diskIndex == options.Count - 1)
  311. {
  312. MainMenu();
  313. return;
  314. }
  315.  
  316. diskToPartition = options[diskIndex];
  317. string[] filesystemOptions = { "ext4", "btrfs", "zfs", "Back" };
  318. Menu filesystemSelectionMenu = new Menu("Select filesystem\n", filesystemOptions);
  319. int filesystemIndex = filesystemSelectionMenu.Run();
  320.  
  321. if (filesystemIndex == 3)
  322. {
  323. continue;
  324. }
  325.  
  326. filesystem = filesystemOptions[filesystemIndex];
  327.  
  328. string[] swapOptions = { "Yes", "No", "Back" };
  329. Menu swapYesNoMenu = new Menu("Do you want to use swap?\n", swapOptions);
  330. int swapYesNoSelectedIndex = swapYesNoMenu.Run();
  331.  
  332. // Yes
  333. if (swapYesNoSelectedIndex == 0)
  334. {
  335. swap = true;
  336. // No
  337. } else if (swapYesNoSelectedIndex == 1)
  338. {
  339. swap = false;
  340. }
  341.  
  342. // Back
  343. else if (swapYesNoSelectedIndex == 2)
  344. {
  345. filesystemSelectionMenu.Run();
  346. }
  347.  
  348. string[] partitioningTypes = { "Erase Disk", "Manual Partitioning", "Back" };
  349. Menu partitioningTypeSelectionMenu = new Menu($"Selected Disk: {diskToPartition}\nFilesystem: {filesystem}\n", partitioningTypes);
  350. int partitioningTypeIndex = partitioningTypeSelectionMenu.Run();
  351.  
  352. // Erase disk
  353. if (partitioningTypeIndex == 0)
  354. {
  355. string[] confirmationOptions = { "Yes", "No" };
  356. Menu eraseConfirmationMenu = new Menu($"Warning: All data on {diskToPartition} will be lost! Do you want to continue?\n", confirmationOptions);
  357. int confirmationMenuIndex = eraseConfirmationMenu.Run();
  358.  
  359. if (confirmationMenuIndex == 0)
  360. {
  361. partitioningType = "erase";
  362. Console.Write("Enter EFI partition size (in MB): ");
  363. int efiPartitionSize = int.Parse(Console.ReadLine());
  364. EFIPartition = $"{diskToPartition}1";
  365. partitionSizes[diskToPartition] = new PartitionSizes { EFI = efiPartitionSize };
  366.  
  367. if (swap)
  368. {
  369. Console.Write("Enter Swap partition size (in MB): ");
  370. int swapPartitionSize = int.Parse(Console.ReadLine());
  371. SwapPartition = $"{diskToPartition}2";
  372. partitionSizes[diskToPartition].Swap = swapPartitionSize;
  373. partitionSizes[diskToPartition].System = GetDiskSize(diskToPartition) - efiPartitionSize - swapPartitionSize;
  374. }
  375. else
  376. {
  377. partitionSizes[diskToPartition].System = GetDiskSize(diskToPartition) - efiPartitionSize;
  378. }
  379.  
  380. MainMenu();
  381. return;
  382. }
  383. // Manual partitioning
  384. } else if (partitioningTypeIndex == 1)
  385. {
  386. partitioningType = "manual";
  387. // Not implemented
  388. MainMenu();
  389. return;
  390. }
  391. }
  392. }
  393.  
  394.  
  395.  
  396. static void SetHostname()
  397. {
  398. Console.Write("Hostname: ");
  399. hostname = Console.ReadLine();
  400. MainMenu();
  401. }
  402.  
  403. static void ManageUsers()
  404. {
  405. string[] options = { "Add user", "Remove user", "Back" };
  406. Menu manageUsersMenu = new Menu("Manage Users\n", options);
  407. int selectedIndex = manageUsersMenu.Run();
  408.  
  409. switch (selectedIndex)
  410. {
  411. case 0:
  412. Console.Write("Username: ");
  413. string username = Console.ReadLine();
  414.  
  415. if (users.ContainsKey(username))
  416. {
  417. Console.WriteLine($"User '{username}' already exists. Please choose a different username.");
  418. ManageUsers();
  419. return;
  420. }
  421.  
  422. Console.Write("Display name: ");
  423. string displayName = Console.ReadLine();
  424. Console.Write("Password: ");
  425. string password = Console.ReadLine();
  426.  
  427. User newUser = new User(username, displayName, password);
  428.  
  429. users.Add(username, newUser);
  430.  
  431. Console.WriteLine($"User '{username}' added successfully.");
  432.  
  433. ManageUsers();
  434. break;
  435.  
  436. case 1:
  437. Console.Write("Username: ");
  438. string userToRemove = Console.ReadLine();
  439.  
  440. // Check if the user exists before removing
  441. if (users.ContainsKey(userToRemove))
  442. {
  443. users.Remove(userToRemove);
  444. Console.WriteLine($"User '{userToRemove}' removed successfully.");
  445. }
  446. else
  447. {
  448. Console.WriteLine($"User '{userToRemove}' not found. Please enter a valid username.");
  449. }
  450.  
  451. ManageUsers();
  452. break;
  453.  
  454. case 2:
  455. MainMenu();
  456. break;
  457. }
  458. }
  459.  
  460. static long GetDiskSize(string diskToPartition)
  461. {
  462. try
  463. {
  464. Process process = new Process();
  465. ProcessStartInfo startInfo = new ProcessStartInfo
  466. {
  467. FileName = "lsblk",
  468. Arguments = $"-b -o SIZE --noheadings {diskToPartition}",
  469. RedirectStandardOutput = true,
  470. UseShellExecute = false,
  471. CreateNoWindow = true
  472. };
  473.  
  474. process.StartInfo = startInfo;
  475. process.Start();
  476.  
  477. string output = process.StandardOutput.ReadToEnd().Trim();
  478. process.WaitForExit();
  479.  
  480. if (long.TryParse(output, out long diskSizeBytes))
  481. {
  482. long diskSizeMB = diskSizeBytes / (1024 * 1024);
  483. return diskSizeMB;
  484. }
  485. else
  486. {
  487. Console.WriteLine($"Error parsing lsblk output: {output}");
  488. return -1;
  489. }
  490. }
  491. catch (Exception ex)
  492. {
  493. Console.WriteLine($"Error getting disk size: {ex.Message}");
  494. return -1;
  495. }
  496. }
  497.  
  498.  
  499. static void SelectBootloader()
  500. {
  501. string[] options = {"Grub", "Back"};
  502. Menu bootloaderSelectionMenu = new Menu("Select bootloader\n", options);
  503. int selectedIndex = bootloaderSelectionMenu.Run();
  504.  
  505. switch (selectedIndex)
  506. {
  507. // Grub
  508. case 0:
  509. selectedBootloader = "grub";
  510. MainMenu();
  511. break;
  512. // Back
  513. case 1:
  514. MainMenu();
  515. break;
  516. }
  517. }
  518.  
  519. static void DeveloperMode()
  520. {
  521. string[] options = {"Read Configuration","Write Variables", "Back"};
  522. Menu developerMenu = new Menu("Developer Mode/Menu (for testing)\n", options);
  523. int selectedIndex = developerMenu.Run();
  524. switch (selectedIndex)
  525. {
  526. // Read config
  527. case 0:
  528. Console.Write("Config path: ");
  529. string configPath = Console.ReadLine();
  530. if (File.Exists(configPath))
  531. {
  532. var config = Config.ReadConfig(configPath);;
  533. Config.WriteConfig(config);
  534. }else
  535. {
  536. Console.WriteLine("Configuration file does not exist.");
  537. }
  538. break;
  539. // Write Variables
  540. case 1:
  541. Console.WriteLine($"Selected bootloader: {selectedBootloader}");
  542. Console.WriteLine($"Hostname: {hostname}");
  543. Console.WriteLine($"Partitioning Type: {partitioningType}");
  544. Console.WriteLine($"Disk to partition: {diskToPartition}");
  545. Console.WriteLine($"Overall disk size: {GetDiskSize(diskToPartition)}MB");
  546. Console.WriteLine($"Filesystem: {filesystem}");
  547. Console.WriteLine($"Swap: {swap}");
  548. Console.WriteLine($"System partition size: {partitionSizes[diskToPartition].System}MB");
  549. Console.WriteLine($"EFI partition size: {partitionSizes[diskToPartition].EFI}MB");
  550. if (swap)
  551. {
  552. Console.WriteLine($"Swap partition size: {partitionSizes[diskToPartition].Swap}MB");
  553. }
  554. Console.WriteLine("Users:");
  555. foreach (var user in users.Values)
  556. {
  557. Console.WriteLine($"Username: {user.Username}\n Display Name: {user.DisplayName}\n Password: {user.Password}");
  558. }
  559. Console.WriteLine("Packages:");
  560. foreach (var package in Packages)
  561. {
  562. Console.Write($"{package}, ");
  563. }
  564. Console.WriteLine("");
  565. break;
  566. // Back
  567. case 2:
  568. MainMenu();
  569. break;
  570. }
  571. }
  572.  
  573. public class User
  574. {
  575. public string Username { get; set; }
  576. public string DisplayName { get; set; }
  577. public string Password { get; set; }
  578.  
  579. public User(string username, string displayName, string password)
  580. {
  581. Username = username;
  582. DisplayName = displayName;
  583. Password = password;
  584. }
  585. }
  586. public class PartitionSizes
  587. {
  588. public long System { get; set; }
  589. public long EFI { get; set; }
  590. public long Swap { get; set; }
  591. }
  592.  
  593. }
  594.  
  595. Error:
  596. [{
  597. "resource": "/home/natesworks/featherinstaller/Config.cs",
  598. "owner": "_generated_diagnostic_collection_name_#1",
  599. "code": {
  600. "value": "CS0029",
  601. "target": {
  602. "$mid": 1,
  603. "external": "https://msdn.microsoft.com/query/roslyn.query?appId%3Droslyn%26k%3Dk%28CS0029%29",
  604. "path": "/query/roslyn.query",
  605. "scheme": "https",
  606. "authority": "msdn.microsoft.com",
  607. "query": "appId=roslyn&k=k(CS0029)"
  608. }
  609. },
  610. "severity": 8,
  611. "message": "Cannot implicitly convert type 'long' to 'string'",
  612. "startLineNumber": 69,
  613. "startColumn": 30,
  614. "endLineNumber": 69,
  615. "endColumn": 68
  616. },{
  617. "resource": "/home/natesworks/featherinstaller/Config.cs",
  618. "owner": "_generated_diagnostic_collection_name_#1",
  619. "code": {
  620. "value": "CS0029",
  621. "target": {
  622. "$mid": 1,
  623. "external": "https://msdn.microsoft.com/query/roslyn.query?appId%3Droslyn%26k%3Dk%28CS0029%29",
  624. "path": "/query/roslyn.query",
  625. "scheme": "https",
  626. "authority": "msdn.microsoft.com",
  627. "query": "appId=roslyn&k=k(CS0029)"
  628. }
  629. },
  630. "severity": 8,
  631. "message": "Cannot implicitly convert type 'long' to 'string'",
  632. "startLineNumber": 70,
  633. "startColumn": 27,
  634. "endLineNumber": 70,
  635. "endColumn": 62
  636. },{
  637. "resource": "/home/natesworks/featherinstaller/Config.cs",
  638. "owner": "_generated_diagnostic_collection_name_#1",
  639. "code": {
  640. "value": "CS0029",
  641. "target": {
  642. "$mid": 1,
  643. "external": "https://msdn.microsoft.com/query/roslyn.query?appId%3Droslyn%26k%3Dk%28CS0029%29",
  644. "path": "/query/roslyn.query",
  645. "scheme": "https",
  646. "authority": "msdn.microsoft.com",
  647. "query": "appId=roslyn&k=k(CS0029)"
  648. }
  649. },
  650. "severity": 8,
  651. "message": "Cannot implicitly convert type 'long' to 'string'",
  652. "startLineNumber": 71,
  653. "startColumn": 28,
  654. "endLineNumber": 71,
  655. "endColumn": 64
  656. },{
  657. "resource": "/home/natesworks/featherinstaller/Config.cs",
  658. "owner": "_generated_diagnostic_collection_name_#1",
  659. "code": {
  660. "value": "CS1503",
  661. "target": {
  662. "$mid": 1,
  663. "path": "/query/roslyn.query",
  664. "scheme": "https",
  665. "authority": "msdn.microsoft.com",
  666. "query": "appId=roslyn&k=k(CS1503)"
  667. }
  668. },
  669. "severity": 8,
  670. "message": "Argument 1: cannot convert from 'System.Collections.Generic.Dictionary<string, Program.User>.ValueCollection' to 'System.Collections.Generic.IEnumerable<User>'",
  671. "startLineNumber": 83,
  672. "startColumn": 43,
  673. "endLineNumber": 83,
  674. "endColumn": 55
  675. }]
Advertisement
Add Comment
Please, Sign In to add comment