6
6
"fmt"
7
7
"net"
8
8
"os"
9
+ "path"
10
+ "strconv"
9
11
"strings"
10
12
"time"
11
13
@@ -14,10 +16,12 @@ import (
14
16
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
15
17
"github.com/1Panel-dev/1Panel/backend/utils/common"
16
18
"github.com/1Panel-dev/1Panel/backend/utils/ntp"
19
+ "github.com/shirou/gopsutil/v3/mem"
17
20
)
18
21
19
22
const defaultDNSPath = "/etc/resolv.conf"
20
23
const defaultHostPath = "/etc/hosts"
24
+ const defaultFstab = "/etc/fstab"
21
25
22
26
type DeviceService struct {}
23
27
@@ -26,6 +30,7 @@ type IDeviceService interface {
26
30
Update (key , value string ) error
27
31
UpdateHosts (req []dto.HostHelper ) error
28
32
UpdatePasswd (req dto.ChangePasswd ) error
33
+ UpdateSwap (req dto.SwapHelper ) error
29
34
UpdateByConf (req dto.UpdateByNameAndFile ) error
30
35
LoadTimeZone () ([]string , error )
31
36
CheckDNS (key , value string ) (bool , error )
@@ -47,6 +52,14 @@ func (u *DeviceService) LoadBaseInfo() (dto.DeviceBaseInfo, error) {
47
52
ntp , _ := settingRepo .Get (settingRepo .WithByKey ("NtpSite" ))
48
53
baseInfo .Ntp = ntp .Value
49
54
55
+ swapInfo , _ := mem .SwapMemory ()
56
+ baseInfo .SwapMemoryTotal = swapInfo .Total
57
+ baseInfo .SwapMemoryAvailable = swapInfo .Free
58
+ baseInfo .SwapMemoryUsed = swapInfo .Used
59
+ if baseInfo .SwapMemoryTotal != 0 {
60
+ baseInfo .SwapDetails = loadSwap ()
61
+ }
62
+
50
63
return baseInfo , nil
51
64
}
52
65
@@ -104,11 +117,20 @@ func (u *DeviceService) Update(key, value string) error {
104
117
if err != nil {
105
118
return errors .New (std )
106
119
}
107
- case "LocalTime" :
108
- if err := settingRepo .Update ("NtpSite" , value ); err != nil {
109
- return err
120
+ case "Ntp" , "LocalTime" :
121
+ ntpValue := value
122
+ if key == "LocalTime" {
123
+ ntpItem , err := settingRepo .Get (settingRepo .WithByKey ("NtpSite" ))
124
+ if err != nil {
125
+ return err
126
+ }
127
+ ntpValue = ntpItem .Value
128
+ } else {
129
+ if err := settingRepo .Update ("NtpSite" , ntpValue ); err != nil {
130
+ return err
131
+ }
110
132
}
111
- ntime , err := ntp .GetRemoteTime (value )
133
+ ntime , err := ntp .GetRemoteTime (ntpValue )
112
134
if err != nil {
113
135
return err
114
136
}
@@ -168,6 +190,35 @@ func (u *DeviceService) UpdatePasswd(req dto.ChangePasswd) error {
168
190
return nil
169
191
}
170
192
193
+ func (u * DeviceService ) UpdateSwap (req dto.SwapHelper ) error {
194
+ if ! req .IsNew {
195
+ std , err := cmd .Execf ("%s swapoff %s" , cmd .SudoHandleCmd (), req .Path )
196
+ if err != nil {
197
+ return fmt .Errorf ("handle swapoff %s failed, err: %s" , req .Path , std )
198
+ }
199
+ }
200
+ if req .Size == 0 {
201
+ if req .Path == path .Join (global .CONF .System .BaseDir , ".1panel_swap" ) {
202
+ _ = os .Remove (path .Join (global .CONF .System .BaseDir , ".1panel_swap" ))
203
+ }
204
+ return operateSwapWithFile (true , req )
205
+ }
206
+ std1 , err := cmd .Execf ("%s dd if=/dev/zero of=%s bs=1024 count=%d" , cmd .SudoHandleCmd (), req .Path , req .Size )
207
+ if err != nil {
208
+ return fmt .Errorf ("handle dd path %s failed, err: %s" , req .Path , std1 )
209
+ }
210
+ std2 , err := cmd .Execf ("%s mkswap -f %s" , cmd .SudoHandleCmd (), req .Path )
211
+ if err != nil {
212
+ return fmt .Errorf ("handle dd path %s failed, err: %s" , req .Path , std2 )
213
+ }
214
+ std3 , err := cmd .Execf ("%s swapon %s" , cmd .SudoHandleCmd (), req .Path )
215
+ if err != nil {
216
+ _ , _ = cmd .Execf ("%s swapoff %s" , cmd .SudoHandleCmd (), req .Path )
217
+ return fmt .Errorf ("handle dd path %s failed, err: %s" , req .Path , std3 )
218
+ }
219
+ return operateSwapWithFile (false , req )
220
+ }
221
+
171
222
func (u * DeviceService ) LoadConf (name string ) (string , error ) {
172
223
pathItem := ""
173
224
switch name {
@@ -291,3 +342,55 @@ func loadUser() string {
291
342
}
292
343
return strings .ReplaceAll (std , "\n " , "" )
293
344
}
345
+
346
+ func loadSwap () []dto.SwapHelper {
347
+ var data []dto.SwapHelper
348
+ std , err := cmd .Execf ("%s swapon --show --summary" , cmd .SudoHandleCmd ())
349
+ if err != nil {
350
+ return data
351
+ }
352
+ lines := strings .Split (std , "\n " )
353
+ for index , line := range lines {
354
+ if index == 0 {
355
+ continue
356
+ }
357
+ parts := strings .Fields (line )
358
+ if len (parts ) < 5 {
359
+ continue
360
+ }
361
+ sizeItem , _ := strconv .Atoi (parts [2 ])
362
+ data = append (data , dto.SwapHelper {Path : parts [0 ], Size : uint64 (sizeItem ), Used : parts [3 ]})
363
+ }
364
+ return data
365
+ }
366
+
367
+ func operateSwapWithFile (delete bool , req dto.SwapHelper ) error {
368
+ conf , err := os .ReadFile (defaultFstab )
369
+ if err != nil {
370
+ return fmt .Errorf ("read file %s failed, err: %v" , defaultFstab , err )
371
+ }
372
+ lines := strings .Split (string (conf ), "\n " )
373
+ newFile := ""
374
+ for _ , line := range lines {
375
+ if len (line ) == 0 {
376
+ continue
377
+ }
378
+ parts := strings .Fields (line )
379
+ if len (parts ) == 6 && parts [0 ] == req .Path {
380
+ continue
381
+ }
382
+ newFile += line + "\n "
383
+ }
384
+ if ! delete {
385
+ newFile += fmt .Sprintf ("%s swap swap defaults 0 0\n " , req .Path )
386
+ }
387
+ file , err := os .OpenFile (defaultFstab , os .O_WRONLY | os .O_TRUNC , 0640 )
388
+ if err != nil {
389
+ return err
390
+ }
391
+ defer file .Close ()
392
+ write := bufio .NewWriter (file )
393
+ _ , _ = write .WriteString (newFile )
394
+ write .Flush ()
395
+ return nil
396
+ }
0 commit comments