unit1.pas 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, EditBtn,
  6. ComCtrls, Buttons, ExtCtrls, Process, Math;
  7. type
  8. { TForm1 }
  9. TForm1 = class(TForm)
  10. btnCreateHD: TBitBtn;
  11. btnStart: TBitBtn;
  12. btnStop: TBitBtn;
  13. chkKVM: TCheckBox;
  14. edtCustom: TEdit;
  15. edtImageFile: TFileNameEdit;
  16. edtHarddiskFile: TFileNameEdit;
  17. GroupBox1: TGroupBox;
  18. GroupBox2: TGroupBox;
  19. Image1: TImage;
  20. Label1: TLabel;
  21. Label2: TLabel;
  22. Label3: TLabel;
  23. Label4: TLabel;
  24. Label5: TLabel;
  25. lblCores: TLabel;
  26. lblRAM: TLabel;
  27. trkCores: TTrackBar;
  28. trkRAM: TTrackBar;
  29. procedure btnCreateHDClick(Sender: TObject);
  30. procedure btnStartClick(Sender: TObject);
  31. procedure btnStopClick(Sender: TObject);
  32. procedure FormCreate(Sender: TObject);
  33. procedure FormDestroy(Sender: TObject);
  34. procedure trkCoresChange(Sender: TObject);
  35. procedure trkRAMChange(Sender: TObject);
  36. private
  37. public
  38. function ConvertBytes(Bytes: Int64): string;
  39. function GetCommandOutput(command: string): string;
  40. end;
  41. var
  42. Form1: TForm1;
  43. //
  44. AProcess: TProcess;
  45. implementation
  46. uses
  47. unit_createhd;
  48. {$R *.lfm}
  49. { TForm1 }
  50. procedure TForm1.btnStartClick(Sender: TObject);
  51. var
  52. SystemArchitecture: string;
  53. Params: TStringArray;
  54. Param, s: string;
  55. begin
  56. // If already running then don't start vm
  57. if (AProcess <> nil) and (AProcess.Running = true) then Exit;
  58. if AProcess = nil then
  59. AProcess := TProcess.Create(nil);
  60. // TODO: Add specific qemu executable
  61. SystemArchitecture:=GetCommandOutput('uname -m');
  62. // It becomes something like: qemu-system-x86_64
  63. AProcess.Executable:= 'qemu-system-'+SystemArchitecture;
  64. AProcess.Parameters.Clear;
  65. // ISO image
  66. AProcess.Parameters.Add('--cdrom');
  67. AProcess.Parameters.Add(edtImageFile.FileName);
  68. // Hard Disk image
  69. if FileExists(edtHarddiskFile.FileName) then begin
  70. AProcess.Parameters.Add('--hda');
  71. AProcess.Parameters.Add(edtHarddiskFile.FileName);
  72. end;
  73. // CPU Cores
  74. AProcess.Parameters.Add('-smp');
  75. AProcess.Parameters.Add(inttostr(trkCores.Position));
  76. // Memory
  77. AProcess.Parameters.Add('-m');
  78. AProcess.Parameters.Add(inttostr(trkRAM.Position));
  79. // KVM
  80. if chkKVM.Checked then
  81. AProcess.Parameters.Add('-enable-kvm');
  82. // Custom parameters
  83. Params := string(edtCustom.Text).Split(' ');
  84. for Param in Params do
  85. AProcess.Parameters.Add(Param);
  86. AProcess.Options := AProcess.Options + [poUsePipes];
  87. AProcess.Execute;
  88. end;
  89. procedure TForm1.btnCreateHDClick(Sender: TObject);
  90. begin
  91. if frmCreateHD.ShowModal = mrOK then begin
  92. edtHarddiskFile.Text:=frmCreateHD.edtHDFile.Text;
  93. end;
  94. end;
  95. procedure TForm1.btnStopClick(Sender: TObject);
  96. begin
  97. AProcess.Terminate(0);
  98. end;
  99. procedure TForm1.FormCreate(Sender: TObject);
  100. var
  101. TotalMemory: longint;
  102. begin
  103. // RAM
  104. TotalMemory := StrToInt( GetCommandOutput('cat /proc/meminfo | head -n 1 | awk "{print \$2}"') ) div 1024;
  105. trkRAM.Max:=TotalMemory;
  106. trkRAM.Position:=TotalMemory div 4;
  107. // CPU Cores
  108. trkCores.Max:=StrToInt( GetCommandOutput('grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu || echo "$NUMBER_OF_PROCESSOR"') );
  109. trkCores.Position:=trkCores.Max;
  110. end;
  111. procedure TForm1.FormDestroy(Sender: TObject);
  112. begin
  113. AProcess.Free;
  114. end;
  115. procedure TForm1.trkCoresChange(Sender: TObject);
  116. begin
  117. lblCores.Caption:=inttostr( trkCores.Position );
  118. end;
  119. procedure TForm1.trkRAMChange(Sender: TObject);
  120. begin
  121. lblRAM.Caption:= ConvertBytes(trkRAM.Position*1024*1024);
  122. end;
  123. // Source: https://stackoverflow.com/a/30549584
  124. function TForm1.ConvertBytes(Bytes: Int64): string;
  125. const
  126. Description: Array [0 .. 8] of string = ('Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
  127. var
  128. i: Integer;
  129. begin
  130. i := 0;
  131. while Bytes > Power(1024, i + 1) do
  132. Inc(i);
  133. Result := FormatFloat('###0.##', Bytes / IntPower(1024, i)) + ' ' + Description[i];
  134. end;
  135. function TForm1.GetCommandOutput(Command:string):string;
  136. var
  137. s: ansistring;
  138. begin
  139. if RunCommand('/bin/sh', ['-c', Command], s) then
  140. Result := Trim(s);
  141. // We use Trim() to cut off access carriage return at the end
  142. end;
  143. end.