Skip to content

Commit cfee3f3

Browse files
committed
fix(replay): require enterprise license for video worker
1 parent 4982adb commit cfee3f3

2 files changed

Lines changed: 67 additions & 15 deletions

File tree

‎pkg/tunnel/replay_part_upload.go‎

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -263,23 +263,33 @@ func (p *PartUploader) GetStorage() storage.ReplayStorage {
263263
const recordDirTimeFormat = "2006-01-02"
264264

265265
func (p *PartUploader) uploadToStorage(uploadPath string) {
266-
// check whether to use ENABLE_VIDEO_WORKER
267-
if videoWorkerClient := NewWorkerClient(*config.GlobalConfig); videoWorkerClient != nil {
268-
taskCfg := videoworker.TaskConfig{
269-
Width: p.Info.OptimalScreenWidth,
270-
Height: p.Info.OptimalScreenHeight,
271-
Bitrate: 1,
272-
}
273-
taskId, err := videoWorkerClient.CreateReplaySessionTask(p.SessionId, uploadPath, &taskCfg)
274-
if err == nil {
275-
logger.Infof("Create replay session VideoWorker task success, task id: %s", taskId)
276-
if err = os.RemoveAll(p.RootPath); err != nil {
277-
logger.Errorf("PartUploader %s remove root path %s error: %v", p.SessionId, p.RootPath, err)
266+
if p.TermCfg == nil {
267+
// Without Core's storage configuration there is no safe fallback target.
268+
// Leave local replay files intact for a later recovery attempt.
269+
logger.Errorf("PartUploader %s cannot upload replay without terminal config; retaining local files", p.SessionId)
270+
return
271+
}
272+
// An environment switch alone must not route Community Edition recordings
273+
// to Video Worker. Core supplies the license state in terminal configuration.
274+
if shouldUseVideoWorker(config.GlobalConfig.EnableVideoWorker, p.TermCfg) {
275+
videoWorkerClient := NewWorkerClient(*config.GlobalConfig)
276+
if videoWorkerClient != nil {
277+
taskCfg := videoworker.TaskConfig{
278+
Width: p.Info.OptimalScreenWidth,
279+
Height: p.Info.OptimalScreenHeight,
280+
Bitrate: 1,
278281
}
279-
return
282+
taskId, err := videoWorkerClient.CreateReplaySessionTask(p.SessionId, uploadPath, &taskCfg)
283+
if err == nil {
284+
logger.Infof("Create replay session VideoWorker task success, task id: %s", taskId)
285+
if err = os.RemoveAll(p.RootPath); err != nil {
286+
logger.Errorf("PartUploader %s remove root path %s error: %v", p.SessionId, p.RootPath, err)
287+
}
288+
return
289+
}
290+
// videoWorkerClient failed then try to use self storage to upload
291+
logger.Errorf("Create replay session task error: %v, try to use self storage", err)
280292
}
281-
// videoWorkerClient failed then try to use self storage to upload
282-
logger.Errorf("Create replay session task error: %v, try to use self storage", err)
283293
}
284294

285295
// 上传到存储
@@ -331,6 +341,10 @@ func (p *PartUploader) uploadToStorage(uploadPath string) {
331341

332342
}
333343

344+
func shouldUseVideoWorker(enabled bool, terminalCfg *model.TerminalConfig) bool {
345+
return enabled && terminalCfg != nil && terminalCfg.LicenseIsValid
346+
}
347+
334348
func (p *PartUploader) RecordLifecycleLog(event model.LifecycleEvent, logObj model.SessionLifecycleLog) {
335349
if err := p.ApiClient.RecordSessionLifecycleLog(p.SessionId, event, logObj); err != nil {
336350
logger.Errorf("Record session %s lifecycle %s log err: %s", p.SessionId, event, err)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package tunnel
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/jumpserver-dev/sdk-go/model"
8+
)
9+
10+
func TestVideoWorkerRequiresValidEnterpriseLicense(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
enabled bool
14+
terminal *model.TerminalConfig
15+
want bool
16+
}{
17+
{name: "switch off", terminal: &model.TerminalConfig{LicenseIsValid: true}},
18+
{name: "community edition", enabled: true, terminal: &model.TerminalConfig{}},
19+
{name: "missing terminal config", enabled: true},
20+
{name: "licensed and enabled", enabled: true, terminal: &model.TerminalConfig{LicenseIsValid: true}, want: true},
21+
}
22+
for _, test := range tests {
23+
t.Run(test.name, func(t *testing.T) {
24+
if got := shouldUseVideoWorker(test.enabled, test.terminal); got != test.want {
25+
t.Fatalf("shouldUseVideoWorker() = %t, want %t", got, test.want)
26+
}
27+
})
28+
}
29+
}
30+
31+
func TestMissingTerminalConfigRetainsReplay(t *testing.T) {
32+
root := t.TempDir()
33+
uploader := PartUploader{SessionId: "session-id", RootPath: root}
34+
uploader.uploadToStorage(root)
35+
if _, err := os.Stat(root); err != nil {
36+
t.Fatalf("source directory was not retained for recovery: %v", err)
37+
}
38+
}

0 commit comments

Comments
 (0)