waveterm/wavesrv/pkg/sstore/fileops.go

188 lines
4.4 KiB
Go
Raw Normal View History

2023-10-17 06:31:13 +02:00
// Copyright 2023, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
package sstore
import (
"context"
"encoding/base64"
2023-07-31 02:16:43 +02:00
"errors"
"fmt"
2023-07-31 02:16:43 +02:00
"io/fs"
2023-03-26 22:21:58 +02:00
"log"
2022-09-20 23:15:20 +02:00
"os"
"path"
2023-10-16 22:30:10 +02:00
"github.com/wavetermdev/waveterm/waveshell/pkg/cirfile"
"github.com/wavetermdev/waveterm/wavesrv/pkg/scbase"
2023-07-31 02:16:43 +02:00
"github.com/google/uuid"
)
2023-07-31 02:16:43 +02:00
func CreateCmdPtyFile(ctx context.Context, screenId string, lineId string, maxSize int64) error {
ptyOutFileName, err := scbase.PtyOutFile(screenId, lineId)
if err != nil {
return err
}
f, err := cirfile.CreateCirFile(ptyOutFileName, maxSize)
if err != nil {
return err
}
return f.Close()
}
2023-07-31 02:16:43 +02:00
func StatCmdPtyFile(ctx context.Context, screenId string, lineId string) (*cirfile.Stat, error) {
ptyOutFileName, err := scbase.PtyOutFile(screenId, lineId)
2023-02-06 09:30:23 +01:00
if err != nil {
return nil, err
}
return cirfile.StatCirFile(ctx, ptyOutFileName)
}
2023-07-31 02:16:43 +02:00
func AppendToCmdPtyBlob(ctx context.Context, screenId string, lineId string, data []byte, pos int64) (*PtyDataUpdate, error) {
if screenId == "" {
return nil, fmt.Errorf("cannot append to PtyBlob, screenid is not set")
}
if pos < 0 {
return nil, fmt.Errorf("invalid seek pos '%d' in AppendToCmdPtyBlob", pos)
}
2023-07-31 02:16:43 +02:00
ptyOutFileName, err := scbase.PtyOutFile(screenId, lineId)
if err != nil {
return nil, err
}
f, err := cirfile.OpenCirFile(ptyOutFileName)
if err != nil {
return nil, err
}
defer f.Close()
err = f.WriteAt(ctx, data, pos)
if err != nil {
return nil, err
}
data64 := base64.StdEncoding.EncodeToString(data)
update := &PtyDataUpdate{
ScreenId: screenId,
2023-07-31 02:16:43 +02:00
LineId: lineId,
PtyPos: pos,
PtyData64: data64,
PtyDataLen: int64(len(data)),
}
2023-07-31 02:16:43 +02:00
err = MaybeInsertPtyPosUpdate(ctx, screenId, lineId)
2023-03-26 22:21:58 +02:00
if err != nil {
// just log
2023-07-31 02:16:43 +02:00
log.Printf("error inserting ptypos update %s/%s: %v\n", screenId, lineId, err)
2023-03-26 22:21:58 +02:00
}
return update, nil
}
2023-03-26 22:21:58 +02:00
// returns (real-offset, data, err)
2023-07-31 02:16:43 +02:00
func ReadFullPtyOutFile(ctx context.Context, screenId string, lineId string) (int64, []byte, error) {
ptyOutFileName, err := scbase.PtyOutFile(screenId, lineId)
if err != nil {
return 0, nil, err
}
f, err := cirfile.OpenCirFile(ptyOutFileName)
if err != nil {
return 0, nil, err
}
defer f.Close()
return f.ReadAll(ctx)
}
2022-09-20 23:15:20 +02:00
2023-03-26 22:21:58 +02:00
// returns (real-offset, data, err)
2023-07-31 02:16:43 +02:00
func ReadPtyOutFile(ctx context.Context, screenId string, lineId string, offset int64, maxSize int64) (int64, []byte, error) {
ptyOutFileName, err := scbase.PtyOutFile(screenId, lineId)
2023-03-26 22:21:58 +02:00
if err != nil {
return 0, nil, err
}
f, err := cirfile.OpenCirFile(ptyOutFileName)
if err != nil {
return 0, nil, err
}
defer f.Close()
return f.ReadAtWithMax(ctx, offset, maxSize)
}
2022-09-20 23:15:20 +02:00
type SessionDiskSizeType struct {
NumFiles int
TotalSize int64
ErrorCount int
2022-12-27 04:06:46 +01:00
Location string
2022-09-20 23:15:20 +02:00
}
func directorySize(dirName string) (SessionDiskSizeType, error) {
var rtn SessionDiskSizeType
2022-12-27 04:06:46 +01:00
rtn.Location = dirName
2022-09-20 23:15:20 +02:00
entries, err := os.ReadDir(dirName)
if err != nil {
return rtn, err
}
for _, entry := range entries {
if entry.IsDir() {
rtn.ErrorCount++
continue
}
finfo, err := entry.Info()
if err != nil {
rtn.ErrorCount++
continue
}
rtn.NumFiles++
rtn.TotalSize += finfo.Size()
}
return rtn, nil
}
func SessionDiskSize(sessionId string) (SessionDiskSizeType, error) {
2022-12-27 03:49:45 +01:00
sessionDir, err := scbase.EnsureSessionDir(sessionId)
2022-09-20 23:15:20 +02:00
if err != nil {
return SessionDiskSizeType{}, err
}
return directorySize(sessionDir)
}
func FullSessionDiskSize() (map[string]SessionDiskSizeType, error) {
2022-12-27 03:49:45 +01:00
sdir := scbase.GetSessionsDir()
2022-09-20 23:15:20 +02:00
entries, err := os.ReadDir(sdir)
if err != nil {
return nil, err
}
rtn := make(map[string]SessionDiskSizeType)
for _, entry := range entries {
if !entry.IsDir() {
continue
}
name := entry.Name()
_, err = uuid.Parse(name)
if err != nil {
continue
}
diskSize, err := directorySize(path.Join(sdir, name))
if err != nil {
continue
}
rtn[name] = diskSize
}
return rtn, nil
}
2023-07-31 02:16:43 +02:00
func DeletePtyOutFile(ctx context.Context, screenId string, lineId string) error {
ptyOutFileName, err := scbase.PtyOutFile(screenId, lineId)
if err != nil {
return err
}
2023-07-31 02:16:43 +02:00
err = os.Remove(ptyOutFileName)
if errors.Is(err, fs.ErrNotExist) {
return nil
}
return err
}
2022-12-27 01:09:21 +01:00
2023-03-21 03:20:57 +01:00
func DeleteScreenDir(ctx context.Context, screenId string) error {
screenDir, err := scbase.EnsureScreenDir(screenId)
if err != nil {
return fmt.Errorf("error getting screendir: %w", err)
}
log.Printf("remove-all %s\n", screenDir)
2023-03-21 03:20:57 +01:00
return os.RemoveAll(screenDir)
}