Skip to content

Commit d53708e

Browse files
committed
feat(caller): support install ffmpeg for linux(arm64,x86_64)
1 parent 86b8bc7 commit d53708e

File tree

15 files changed

+140
-22
lines changed

15 files changed

+140
-22
lines changed

.golangci.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ run:
55
linters:
66
default: all
77
disable:
8+
- noinlineerr
89
- canonicalheader
910
- containedctx
1011
- contextcheck

cmd/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ func main() {
4141
Action: start,
4242
}
4343

44-
if err := app.Run(context.Background(), os.Args); err != nil {
44+
err := app.Run(context.Background(), os.Args)
45+
if err != nil {
4546
logrus.Fatal(err)
4647
}
4748
}
@@ -59,8 +60,10 @@ func start(ctx context.Context, command *cli.Command) error {
5960

6061
g.Go(func() error {
6162
errChan := make(chan error, 1)
63+
6264
go func() {
6365
logrus.Infof("Start ssh server on %q", command.String(listen))
66+
6467
errChan <- ssh.ListenAndServe(command.String(listen), nil, handler.WithMiddleware(
6568
ffmpeg.Run,
6669
ffmpeg.Install,

pkg/archiver/tarxz.go

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,35 +26,37 @@ func Unarchive(tarball, dst string) error {
2626
}
2727
defer archiveFile.Close()
2828

29-
format, input, identifyErr := archives.Identify(context.Background(), tarball, archiveFile)
30-
if identifyErr != nil {
31-
return fmt.Errorf("identify format: %w", identifyErr)
29+
format, input, err := archives.Identify(context.Background(), tarball, archiveFile)
30+
if err != nil {
31+
return fmt.Errorf("identify format: %w", err)
3232
}
3333

3434
extractor, ok := format.(archives.Extractor)
3535
if !ok {
3636
return fmt.Errorf("unsupported format for extraction")
3737
}
3838

39-
if dirErr := createDirWithPermissions(dst, dirPermissions); dirErr != nil {
40-
return fmt.Errorf("creating destination directory: %w", dirErr)
39+
if err := createDirWithPermissions(dst, dirPermissions); err != nil {
40+
return fmt.Errorf("creating destination directory: %w", err)
4141
}
4242

4343
handler := func(ctx context.Context, f archives.FileInfo) error {
4444
return handleFile(f, dst)
4545
}
4646

47-
if extractErr := extractor.Extract(context.Background(), input, handler); extractErr != nil {
48-
return fmt.Errorf("extracting files: %w", extractErr)
47+
if err := extractor.Extract(context.Background(), input, handler); err != nil {
48+
return fmt.Errorf("extracting files: %w", err)
4949
}
5050

5151
return nil
5252
}
5353

5454
func createDirWithPermissions(path string, mode os.FileMode) error {
55-
if err := os.MkdirAll(path, mode); err != nil {
55+
err := os.MkdirAll(path, mode)
56+
if err != nil {
5657
return fmt.Errorf("mkdir: %w", err)
5758
}
59+
5860
return nil
5961
}
6062

@@ -68,6 +70,7 @@ func securePath(basePath, relativePath string) (string, error) {
6870
if !strings.HasPrefix(filepath.Clean(dstPath)+string(os.PathSeparator), filepath.Clean(basePath)+string(os.PathSeparator)) {
6971
return "", fmt.Errorf("illegal file path: %s", dstPath)
7072
}
73+
7174
return dstPath, nil
7275
}
7376

@@ -80,16 +83,20 @@ func handleFile(f archives.FileInfo, dst string) error {
8083

8184
// Ensure the parent directory exists
8285
parentDir := filepath.Dir(dstPath)
83-
if dirErr := createDirWithPermissions(parentDir, dirPermissions); dirErr != nil {
86+
87+
dirErr := createDirWithPermissions(parentDir, dirPermissions)
88+
if dirErr != nil {
8489
return dirErr
8590
}
8691

8792
// Handle directories
8893
if f.IsDir() {
8994
// Create the directory with permissions from the archive
90-
if dirErr := createDirWithPermissions(dstPath, f.Mode()); dirErr != nil {
95+
dirErr := createDirWithPermissions(dstPath, f.Mode())
96+
if dirErr != nil {
9197
return fmt.Errorf("creating directory: %w", dirErr)
9298
}
99+
93100
return nil
94101
}
95102

@@ -99,7 +106,9 @@ func handleFile(f archives.FileInfo, dst string) error {
99106
logrus.Warnf("Ignoring symlink: %s -> %s", f.NameInArchive, f.LinkTarget)
100107
return nil
101108
}
102-
if linkErr := os.Symlink(f.LinkTarget, dstPath); linkErr != nil {
109+
110+
linkErr := os.Symlink(f.LinkTarget, dstPath)
111+
if linkErr != nil {
103112
return fmt.Errorf("creating symlink: %w", linkErr)
104113
}
105114
}
@@ -112,12 +121,15 @@ func handleFile(f archives.FileInfo, dst string) error {
112121

113122
// If parent directory is read-only, temporarily make it writable
114123
if originalMode.Mode().Perm()&0o200 == 0 {
115-
if chmodErr := os.Chmod(parentDir, originalMode.Mode()|0o200); chmodErr != nil {
124+
chmodErr := os.Chmod(parentDir, originalMode.Mode()|0o200)
125+
if chmodErr != nil {
116126
return fmt.Errorf("chmod parent directory: %w", chmodErr)
117127
}
128+
118129
defer func() {
119130
// Restore the original permissions after writing
120-
if chmodErr := os.Chmod(parentDir, originalMode.Mode()); chmodErr != nil {
131+
chmodErr := os.Chmod(parentDir, originalMode.Mode())
132+
if chmodErr != nil {
121133
logrus.Warnf("Failed to restore original permissions for %s: %v", parentDir, chmodErr)
122134
}
123135
}()

pkg/define/whitelist.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ func IsWhitelisted(command string) bool {
1313
return true
1414
}
1515
}
16+
1617
return false
1718
}

pkg/exec/exec_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,25 @@ const MyJSONData = `
2828

2929
func TestExecPathCover(t *testing.T) {
3030
p := filepath.Join("/tmp", "mount-point.json")
31+
3132
jsonFile, err := os.Create(p)
3233
if err != nil {
3334
logrus.Fatalf("Failed to create json file: %v", err)
3435
}
36+
3537
_, _ = jsonFile.WriteString(MyJSONData)
3638
MyJSONFile = p
3739

3840
homeDir, err := os.UserHomeDir()
3941
if err != nil {
4042
t.Fatalf("Failed to get user home dir: %v", err)
4143
}
44+
4245
path, err := ContainerPath2HostPath("test")
4346
if err != nil {
4447
t.Fatalf("ContainerPath2HostPath failed: %v", err)
4548
}
49+
4650
if path != "test" {
4751
t.Error("ContainerPath2HostPath failed")
4852
}
@@ -51,6 +55,7 @@ func TestExecPathCover(t *testing.T) {
5155
if err != nil {
5256
t.Errorf("ContainerPath2HostPath failed: %v", err)
5357
}
58+
5459
if path != filepath.Join(homeDir, ooStorage) {
5560
t.Error("ContainerPath2HostPath failed")
5661
}
@@ -59,6 +64,7 @@ func TestExecPathCover(t *testing.T) {
5964
if err != nil {
6065
t.Errorf("ContainerPath2HostPath failed: %v", err)
6166
}
67+
6268
if path != filepath.Join(homeDir, ooHomePrefix, ooSessions) {
6369
t.Error("ContainerPath2HostPath failed")
6470
}
@@ -67,6 +73,7 @@ func TestExecPathCover(t *testing.T) {
6773
if err != nil {
6874
t.Errorf("ContainerPath2HostPath failed: %v", err)
6975
}
76+
7077
if path != "/Users/localuser/Desktop" {
7178
t.Error("ContainerPath2HostPath failed")
7279
}
@@ -75,17 +82,20 @@ func TestExecPathCover(t *testing.T) {
7582
if err != nil {
7683
t.Errorf("ContainerPath2HostPath failed: %v", err)
7784
}
85+
7886
if path != "/Users/localuser/Downloads" {
7987
t.Error("ContainerPath2HostPath failed")
8088
}
8189
}
8290

8391
func TestExecPathCover2(t *testing.T) {
8492
p := filepath.Join("/tmp", "mount-point.json")
93+
8594
jsonFile, err := os.Create(p)
8695
if err != nil {
8796
logrus.Fatalf("Failed to create json file: %v", err)
8897
}
98+
8999
_, _ = jsonFile.WriteString(MyJSONData)
90100
MyJSONFile = p
91101

@@ -101,5 +111,6 @@ func TestExecPathCover2(t *testing.T) {
101111
if err != nil {
102112
return
103113
}
114+
104115
t.Log(sanitizers)
105116
}

pkg/exec/sanitizers.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ func loadJSON(path string) (*DataStruct, error) {
4141
defer file.Close()
4242

4343
var data DataStruct
44+
4445
decoder := json.NewDecoder(file)
4546
if err = decoder.Decode(&data); err != nil {
4647
return nil, err
4748
}
49+
4850
return &data, nil
4951
}
5052

@@ -75,6 +77,7 @@ func ContainerPath2HostPath(arg string) (string, error) {
7577
path := filepath.Join(homeDir, ooHomePrefix, ooSessions)
7678
newArg := strings.Replace(arg, oomolSessions, path, 1)
7779
logrus.Warnf("%q --> %q", arg, newArg)
80+
7881
return newArg, nil
7982
}
8083

@@ -83,10 +86,12 @@ func ContainerPath2HostPath(arg string) (string, error) {
8386
path := filepath.Join(homeDir, ooStorage)
8487
newArg := strings.Replace(arg, oomolStorage, path, 1)
8588
logrus.Warnf("%q --> %q", arg, newArg)
89+
8690
return newArg, nil
8791
}
8892

8993
logrus.Infof("Load MountPoint json file: %q", MyJSONFile)
94+
9095
jsonData, err := loadJSON(MyJSONFile)
9196
if err != nil {
9297
return "", fmt.Errorf("failed to load json file: %v", err)
@@ -99,21 +104,26 @@ func ContainerPath2HostPath(arg string) (string, error) {
99104
if strings.Contains(arg, mountPoint.ContainerPath) {
100105
newArg := strings.Replace(arg, mountPoint.ContainerPath, mountPoint.HostPath, 1)
101106
logrus.Warnf("%q --> %q", arg, newArg)
107+
102108
return newArg, nil
103109
}
104110
}
105111
}
112+
106113
return arg, nil
107114
}
108115

109116
func DoArgsSanitizers(args []string) ([]string, error) {
110117
newArgs := make([]string, 0)
118+
111119
for _, arg := range args {
112120
singleArg, err := ContainerPath2HostPath(arg)
113121
if err != nil {
114122
return nil, fmt.Errorf("failed to convert container path to host path: %v", err)
115123
}
124+
116125
newArgs = append(newArgs, singleArg)
117126
}
127+
118128
return newArgs, nil
119129
}

pkg/handler/ffmpeg/handler.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ func Run(next ssh.Handler) ssh.Handler {
1818
targetBin := s.Command()[0]
1919
if targetBin == define.FFPROBEBin || targetBin == define.FFMPEGBin {
2020
logrus.Infof("run middleware: %q\n", RunFFMPEGStage)
21+
2122
stubber := ffmpeg.NewVersion6(s)
23+
2224
args, err := exec.DoArgsSanitizers(s.Command()[1:])
2325
if err != nil {
2426
slog.Fatalf(s, "DoArgsSanitizers error: %v\r\n", err)
@@ -51,7 +53,8 @@ func Install(next ssh.Handler) ssh.Handler {
5153
stubber := ffmpeg.NewVersion6(s)
5254

5355
// we first test the ffmpeg call be called, if ffmpeg can be called without error, just return
54-
if err := stubber.Test(s.Context()); err == nil {
56+
err := stubber.Test(s.Context())
57+
if err == nil {
5558
slog.Infof(s, "ffmpeg package installed before\r\n")
5659
return
5760
}
@@ -60,31 +63,37 @@ func Install(next ssh.Handler) ssh.Handler {
6063
slog.Fatalf(s, "Download ffmpeg error: %v\r\n", err)
6164
return
6265
}
66+
6367
slog.Infof(s, "Download ffmpeg success\r\n")
6468

6569
if err := stubber.Unpack(s.Context()); err != nil {
6670
slog.Fatalf(s, "Unpack ffmpeg error: %v\r\n", err)
6771
return
6872
}
73+
6974
slog.Infof(s, "Unpack ffmpeg success\r\n")
7075

7176
if err := stubber.Setup(s.Context()); err != nil {
7277
slog.Fatalf(s, "Setup ffmpeg error: %v", err)
7378
return
7479
}
80+
7581
slog.Infof(s, "Setup ffmpeg success\r\n")
7682

7783
if err := stubber.Test(s.Context()); err != nil {
7884
slog.Fatalf(s, "Test ffmpeg package error: %v\r\n", err)
7985
return
8086
}
87+
8188
slog.Infof(s, "Test ffmpeg package success\r\n")
8289

8390
if err := stubber.CleanUp(s.Context()); err != nil {
8491
slog.Fatalf(s, "Clean up ffmpeg error: %v\r\n", err)
8592
return
8693
}
94+
8795
slog.Infof(s, "Clean up ffmpeg success\r\n")
96+
8897
return
8998
}
9099

pkg/handler/handler.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ func WithMiddleware(mw ...Middleware) ssh.Option {
2222
for _, m := range mw {
2323
h = m(h)
2424
}
25+
2526
s.Handler = h
27+
2628
return nil
2729
}
2830
}
@@ -33,6 +35,7 @@ func ValidateCmdline(next ssh.Handler) ssh.Handler {
3335
// Parameter parsing follows the openssh standard implementation
3436
// https://stackoverflow.com/questions/53465980/how-to-keep-parameter-with-spaces-when-running-remote-script-file-with-ssh
3537
logrus.Infof("Validate string: %q\n", s.Command())
38+
3639
str := s.Command()
3740
if len(str) == 0 {
3841
slog.Fatalf(s, "Empty command, Support commands: %q \r\n", define.Whitelist)
@@ -55,6 +58,7 @@ func ShowVersion(next ssh.Handler) ssh.Handler {
5558
slog.Printf(s, "%s\r\n", define.CurrentVersion)
5659
return
5760
}
61+
5862
next(s)
5963
}
6064
}

pkg/logger/log.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func SetupLogger() error {
4141
DisableColors: false,
4242
TimestampFormat: "2006-01-02 15:04:05.000",
4343
})
44+
4445
homeDir, err := os.UserHomeDir()
4546
if err != nil {
4647
return fmt.Errorf("failed to get user home directory: %w", err)
@@ -55,17 +56,20 @@ func SetupLogger() error {
5556
logDir := filepath.Dir(logFile)
5657

5758
logrus.Infof("Try to make logDir dir: %q", logDir)
59+
5860
if err = os.MkdirAll(logDir, 0755); err != nil {
5961
return fmt.Errorf("failed to create log directory %q: %v", logDir, err)
6062
}
6163

6264
logrus.Infof("Try to open log file: %q", logFile)
65+
6366
fd, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm)
6467
if err != nil {
6568
return fmt.Errorf("failed to open log file %q: %v", logFile, err)
6669
}
6770

6871
logrus.SetOutput(fd)
6972
logrus.SetLevel(logrus.InfoLevel)
73+
7074
return nil
7175
}

0 commit comments

Comments
 (0)