Browse Source

add logic to run scripts under `/etc/casaos/start.d` when starting (#756)

Tiger Wang 2 years ago
parent
commit
4b26631374
4 changed files with 89 additions and 0 deletions
  1. 1 0
      go.mod
  2. 6 0
      main.go
  3. 53 0
      pkg/utils/command/command_helper.go
  4. 29 0
      pkg/utils/command/command_helper_test.go

+ 1 - 0
go.mod

@@ -39,4 +39,5 @@ require (
 	golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
 	golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
 	golang.org/x/tools v0.1.7 // indirect
 	golang.org/x/tools v0.1.7 // indirect
 	gorm.io/gorm v1.24.0
 	gorm.io/gorm v1.24.0
+	gotest.tools v2.2.0+incompatible
 )
 )

+ 6 - 0
main.go

@@ -9,11 +9,13 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/IceWhaleTech/CasaOS-Common/model"
 	"github.com/IceWhaleTech/CasaOS-Common/model"
+	"github.com/IceWhaleTech/CasaOS-Common/utils/constants"
 	"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
 	"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
 	"github.com/IceWhaleTech/CasaOS/model/notify"
 	"github.com/IceWhaleTech/CasaOS/model/notify"
 	"github.com/IceWhaleTech/CasaOS/pkg/cache"
 	"github.com/IceWhaleTech/CasaOS/pkg/cache"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/sqlite"
 	"github.com/IceWhaleTech/CasaOS/pkg/sqlite"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
 	"github.com/IceWhaleTech/CasaOS/route"
 	"github.com/IceWhaleTech/CasaOS/route"
 	"github.com/IceWhaleTech/CasaOS/service"
 	"github.com/IceWhaleTech/CasaOS/service"
@@ -140,6 +142,10 @@ func main() {
 		)
 		)
 	}
 	}
 
 
+	// run any script that needs to be executed
+	scriptDirectory := filepath.Join(constants.DefaultConfigPath, "start.d")
+	command.ExecuteScripts(scriptDirectory)
+
 	if supported, err := daemon.SdNotify(false, daemon.SdNotifyReady); err != nil {
 	if supported, err := daemon.SdNotify(false, daemon.SdNotifyReady); err != nil {
 		logger.Error("Failed to notify systemd that casaos main service is ready", zap.Any("error", err))
 		logger.Error("Failed to notify systemd that casaos main service is ready", zap.Any("error", err))
 	} else if supported {
 	} else if supported {

+ 53 - 0
pkg/utils/command/command_helper.go

@@ -5,7 +5,10 @@ import (
 	"context"
 	"context"
 	"fmt"
 	"fmt"
 	"io/ioutil"
 	"io/ioutil"
+	"os"
 	"os/exec"
 	"os/exec"
+	"path/filepath"
+	"strings"
 	"time"
 	"time"
 )
 )
 
 
@@ -111,3 +114,53 @@ func ExecSmartCTLByPath(path string) []byte {
 func ExecEnabledSMART(path string) {
 func ExecEnabledSMART(path string) {
 	exec.Command("smartctl", "-s on", path).Output()
 	exec.Command("smartctl", "-s on", path).Output()
 }
 }
+
+func ExecuteScripts(scriptDirectory string) {
+	if _, err := os.Stat(scriptDirectory); os.IsNotExist(err) {
+		fmt.Printf("No post-start scripts at %s\n", scriptDirectory)
+		return
+	}
+
+	files, err := os.ReadDir(scriptDirectory)
+	if err != nil {
+		fmt.Printf("Failed to read from script directory %s: %s\n", scriptDirectory, err.Error())
+		return
+	}
+
+	for _, file := range files {
+		if file.IsDir() {
+			continue
+		}
+
+		scriptFilepath := filepath.Join(scriptDirectory, file.Name())
+
+		f, err := os.Open(scriptFilepath)
+		if err != nil {
+			fmt.Printf("Failed to open script file %s: %s\n", scriptFilepath, err.Error())
+			continue
+		}
+		f.Close()
+
+		scanner := bufio.NewScanner(f)
+		scanner.Scan()
+		shebang := scanner.Text()
+
+		interpreter := "/bin/sh"
+		if strings.HasPrefix(shebang, "#!") {
+			interpreter = shebang[2:]
+		}
+
+		cmd := exec.Command(interpreter, scriptFilepath)
+
+		fmt.Printf("Executing post-start script %s using %s\n", scriptFilepath, interpreter)
+
+		cmd.Stdout = os.Stdout
+		cmd.Stderr = os.Stderr
+
+		err = cmd.Run()
+		if err != nil {
+			fmt.Printf("Failed to execute post-start script %s: %s\n", scriptFilepath, err.Error())
+		}
+	}
+	fmt.Println("Finished executing post-start scripts.")
+}

+ 29 - 0
pkg/utils/command/command_helper_test.go

@@ -0,0 +1,29 @@
+package command
+
+import (
+	"os"
+	"testing"
+
+	"gotest.tools/assert"
+)
+
+func TestExecuteScripts(t *testing.T) {
+	// make a temp directory
+	tmpDir, err := os.MkdirTemp("", "casaos-test-*")
+	assert.NilError(t, err)
+	defer os.RemoveAll(tmpDir)
+
+	ExecuteScripts(tmpDir)
+
+	// create a sample script under tmpDir
+	script := tmpDir + "/test.sh"
+	f, err := os.Create(script)
+	assert.NilError(t, err)
+	defer f.Close()
+
+	// write a sample script
+	_, err = f.WriteString("#!/bin/bash\necho 123")
+	assert.NilError(t, err)
+
+	ExecuteScripts(tmpDir)
+}