@@ -711,6 +711,19 @@ <h2>Deploy a new instance</h2>
711
711
</ div >
712
712
</ div >
713
713
714
+ < div class ="form-group ">
715
+ < label for ="swapSize "> Swap (optional)</ label >
716
+ < div style ="display: flex; align-items: center; gap: 8px; ">
717
+ < input id ="swapSize " v-model.number ="vmForm.swapValue " type ="number " min ="0 "
718
+ step ="0.1 " placeholder ="Swap size " style ="flex: 1; ">
719
+ < select v-model ="vmForm.swapUnit " style ="width: 80px; ">
720
+ < option value ="MB "> MB</ option >
721
+ < option value ="GB "> GB</ option >
722
+ </ select >
723
+ </ div >
724
+ < small style ="color: #666; "> Leave as 0 to disable swap.</ small >
725
+ </ div >
726
+
714
727
< div class ="form-group ">
715
728
< label for ="diskSize "> Storage (GB)</ label >
716
729
< input id ="diskSize " v-model.number ="vmForm.disk_size " type ="number "
@@ -1009,6 +1022,10 @@ <h4 style="margin: 0 0 12px 0;">VM Configuration</h4>
1009
1022
< span class ="detail-value "> {{ formatMemory(vm.configuration?.memory)
1010
1023
}}</ span >
1011
1024
</ div >
1025
+ < div class ="detail-item " v-if ="vm.configuration?.swap_size ">
1026
+ < span class ="detail-label "> Swap:</ span >
1027
+ < span class ="detail-value "> {{ formatMemory(bytesToMB(vm.configuration.swap_size)) }}</ span >
1028
+ </ div >
1012
1029
< div class ="detail-item ">
1013
1030
< span class ="detail-label "> Disk Size:</ span >
1014
1031
< span class ="detail-value "> {{ vm.configuration?.disk_size }} GB</ span >
@@ -1136,6 +1153,21 @@ <h3>Update VM Config</h3>
1136
1153
</ div >
1137
1154
</ div >
1138
1155
1156
+ < div class ="form-group ">
1157
+ < label for ="upgradeSwap "> Swap (optional)</ label >
1158
+ < div style ="display: flex; align-items: center; gap: 8px; ">
1159
+ < input id ="upgradeSwap " v-model.number ="upgradeDialog.swapValue " type ="number " min ="0 "
1160
+ step ="0.1 " placeholder ="Swap size " style ="flex: 1; "
1161
+ :disabled ="!upgradeDialog.updateCompose ">
1162
+ < select v-model ="upgradeDialog.swapUnit " style ="width: 80px; "
1163
+ :disabled ="!upgradeDialog.updateCompose ">
1164
+ < option value ="MB "> MB</ option >
1165
+ < option value ="GB "> GB</ option >
1166
+ </ select >
1167
+ </ div >
1168
+ < small style ="color: #666; "> Enable "Update compose" to change swap size.</ small >
1169
+ </ div >
1170
+
1139
1171
< div class ="form-group ">
1140
1172
< label for ="diskSize "> Disk Size (GB)</ label >
1141
1173
< input id ="diskSize " v-model.number ="upgradeDialog.disk_size " type ="number "
@@ -1527,6 +1559,9 @@ <h3>Derive VM</h3>
1527
1559
memory : 2048 , // This will be computed from memoryValue and memoryUnit
1528
1560
memoryValue : 2 ,
1529
1561
memoryUnit : 'GB' ,
1562
+ swap_size : 0 ,
1563
+ swapValue : 0 ,
1564
+ swapUnit : 'GB' ,
1530
1565
disk_size : 20 ,
1531
1566
selectedGpus : [ ] ,
1532
1567
attachAllGpus : false ,
@@ -1566,6 +1601,9 @@ <h3>Derive VM</h3>
1566
1601
memory : 0 , // This will be computed from memoryValue and memoryUnit
1567
1602
memoryValue : 0 ,
1568
1603
memoryUnit : 'MB' ,
1604
+ swap_size : 0 ,
1605
+ swapValue : 0 ,
1606
+ swapUnit : 'GB' ,
1569
1607
disk_size : 0 ,
1570
1608
image : '' ,
1571
1609
ports : [ ] ,
@@ -1724,6 +1762,11 @@ <h3>Derive VM</h3>
1724
1762
app_compose . pre_launch_script = vmForm . value . preLaunchScript ;
1725
1763
}
1726
1764
1765
+ const swapBytes = Math . max ( 0 , Math . round ( vmForm . value . swap_size || 0 ) ) ;
1766
+ if ( swapBytes > 0 ) {
1767
+ app_compose . swap_size = swapBytes ;
1768
+ }
1769
+
1727
1770
// If APP_LAUNCH_TOKEN is set, add it's sha256 hash to the app compose file
1728
1771
const launchToken = vmForm . value . encryptedEnvs . find ( env => env . key === 'APP_LAUNCH_TOKEN' ) ;
1729
1772
if ( launchToken ) {
@@ -1831,15 +1874,39 @@ <h3>Derive VM</h3>
1831
1874
showCreateDialog . value = true ;
1832
1875
vmForm . value . encryptedEnvs = [ ] ;
1833
1876
vmForm . value . app_id = null ;
1877
+ vmForm . value . swapValue = 0 ;
1878
+ vmForm . value . swapUnit = 'GB' ;
1879
+ vmForm . value . swap_size = 0 ;
1834
1880
loadGpus ( ) ;
1835
1881
} ;
1836
1882
1837
1883
// Memory conversion functions
1838
1884
const convertMemoryToMB = ( value , unit ) => {
1885
+ const numericValue = Number ( value ) ;
1886
+ if ( ! Number . isFinite ( numericValue ) || numericValue < 0 ) {
1887
+ return 0 ;
1888
+ }
1839
1889
if ( unit === 'GB' ) {
1840
- return value * 1024 ;
1890
+ return numericValue * 1024 ;
1841
1891
}
1842
- return value ;
1892
+ return numericValue ;
1893
+ } ;
1894
+
1895
+ const BYTES_PER_MB = 1024 * 1024 ;
1896
+
1897
+ const convertSwapToBytes = ( value , unit ) => {
1898
+ const mb = convertMemoryToMB ( value , unit ) ;
1899
+ if ( ! Number . isFinite ( mb ) || mb <= 0 ) {
1900
+ return 0 ;
1901
+ }
1902
+ return Math . max ( 0 , Math . round ( mb * BYTES_PER_MB ) ) ;
1903
+ } ;
1904
+
1905
+ const bytesToMB = ( bytes ) => {
1906
+ if ( ! bytes ) {
1907
+ return 0 ;
1908
+ }
1909
+ return bytes / BYTES_PER_MB ;
1843
1910
} ;
1844
1911
1845
1912
const formatMemory = ( memoryMB ) => {
@@ -1862,6 +1929,14 @@ <h3>Derive VM</h3>
1862
1929
upgradeDialog . value . memory = convertMemoryToMB ( upgradeDialog . value . memoryValue , upgradeDialog . value . memoryUnit ) ;
1863
1930
} ) ;
1864
1931
1932
+ watch ( [ ( ) => vmForm . value . swapValue , ( ) => vmForm . value . swapUnit ] , ( ) => {
1933
+ vmForm . value . swap_size = convertSwapToBytes ( vmForm . value . swapValue , vmForm . value . swapUnit ) ;
1934
+ } ) ;
1935
+
1936
+ watch ( [ ( ) => upgradeDialog . value . swapValue , ( ) => upgradeDialog . value . swapUnit ] , ( ) => {
1937
+ upgradeDialog . value . swap_size = convertSwapToBytes ( upgradeDialog . value . swapValue , upgradeDialog . value . swapUnit ) ;
1938
+ } ) ;
1939
+
1865
1940
const createVm = async ( ) => {
1866
1941
try {
1867
1942
// Convert memory based on selected unit
@@ -1879,6 +1954,12 @@ <h3>Derive VM</h3>
1879
1954
user_config : vmForm . value . user_config ,
1880
1955
gpus : configGpu ( vmForm . value ) ,
1881
1956
} ;
1957
+ const swapBytes = Math . max ( 0 , Math . round ( form . swap_size || 0 ) ) ;
1958
+ if ( swapBytes > 0 ) {
1959
+ form . swap_size = swapBytes ;
1960
+ } else {
1961
+ delete form . swap_size ;
1962
+ }
1882
1963
const _response = await rpcCall ( 'CreateVm' , form ) ;
1883
1964
loadVMList ( ) ;
1884
1965
showCreateDialog . value = false ;
@@ -2054,6 +2135,10 @@ <h3>Derive VM</h3>
2054
2135
const selectedGpuSlots = currentGpuConfig . gpus ?. map ( gpu => gpu . slot ) || [ ] ;
2055
2136
const appCompose = JSON . parse ( updatedVM . configuration ?. compose_file || "{}" ) ;
2056
2137
2138
+ const swapBytes = Number ( appCompose . swap_size || 0 ) ;
2139
+ const swapMb = bytesToMB ( swapBytes ) ;
2140
+ const swapDisplay = autoMemoryDisplay ( swapMb ) ;
2141
+
2057
2142
upgradeDialog . value = {
2058
2143
show : true ,
2059
2144
vm : updatedVM ,
@@ -2066,6 +2151,9 @@ <h3>Derive VM</h3>
2066
2151
vcpu : updatedVM . configuration ?. vcpu || 1 ,
2067
2152
memory : updatedVM . configuration ?. memory || 1024 ,
2068
2153
...autoMemoryDisplay ( updatedVM . configuration ?. memory ) ,
2154
+ swap_size : swapBytes ,
2155
+ swapValue : Number ( swapDisplay . memoryValue ) ,
2156
+ swapUnit : swapDisplay . memoryUnit ,
2069
2157
disk_size : updatedVM . configuration ?. disk_size || 10 ,
2070
2158
image : updatedVM . configuration ?. image || '' ,
2071
2159
ports : updatedVM . configuration ?. ports ?. map ( port => ( { ...port } ) ) || [ ] ,
@@ -2100,6 +2188,13 @@ <h3>Derive VM</h3>
2100
2188
}
2101
2189
}
2102
2190
app_compose . pre_launch_script = upgradeDialog . value . preLaunchScript ?. trim ( ) ;
2191
+
2192
+ const swapBytes = Math . max ( 0 , Math . round ( upgradeDialog . value . swap_size || 0 ) ) ;
2193
+ if ( swapBytes > 0 ) {
2194
+ app_compose . swap_size = swapBytes ;
2195
+ } else {
2196
+ delete app_compose . swap_size ;
2197
+ }
2103
2198
return JSON . stringify ( app_compose ) ;
2104
2199
}
2105
2200
@@ -2493,6 +2588,7 @@ <h3>Derive VM</h3>
2493
2588
composeHashPreview,
2494
2589
upgradeComposeHashPreview,
2495
2590
formatMemory,
2591
+ bytesToMB,
2496
2592
// Pagination and search variables
2497
2593
searchQuery,
2498
2594
currentPage,
@@ -2514,4 +2610,4 @@ <h3>Derive VM</h3>
2514
2610
</ script >
2515
2611
</ body >
2516
2612
2517
- </ html >
2613
+ </ html >
0 commit comments