1
0
mirror of https://github.com/garraflavatra/rolens.git synced 2025-06-28 05:25:11 +00:00

Shell feature (#44)

Resolves #37: adds a shell tab where the user can write mongo shell
scripts and execute them.
This commit is contained in:
2023-07-01 21:34:32 +02:00
committed by GitHub
parent 62f4b88ea6
commit 61142844fa
12 changed files with 375 additions and 59 deletions

View File

@ -25,6 +25,7 @@ type EnvironmentInfo struct {
HasMongoExport bool `json:"hasMongoExport"`
HasMongoDump bool `json:"hasMongoDump"`
HasMongoShell bool `json:"hasMongoShell"`
HomeDirectory string `json:"homeDirectory"`
DataDirectory string `json:"dataDirectory"`
@ -49,6 +50,9 @@ func NewApp(version string) *App {
_, err = exec.LookPath("mongoexport")
a.Env.HasMongoExport = err == nil
_, err = exec.LookPath("mongosh")
a.Env.HasMongoShell = err == nil
a.Env.HomeDirectory, err = os.UserHomeDir()
if err != nil {
panic(errors.New("encountered an error while getting home directory"))

105
internal/app/host_shell.go Normal file
View File

@ -0,0 +1,105 @@
package app
import (
"fmt"
"net/url"
"os"
"os/exec"
"path"
"github.com/google/uuid"
"github.com/wailsapp/wails/v2/pkg/runtime"
)
type ExecuteShellScriptResult struct {
Output string `json:"output"`
Status int `json:"status"`
ErrorTitle string `json:"errorTitle"`
ErrorDescription string `json:"errorDescription"`
}
func (a *App) ExecuteShellScript(hostKey, dbKey, collKey, script string) (result ExecuteShellScriptResult) {
if !a.Env.HasMongoShell {
result.ErrorTitle = "mongosh not found"
result.ErrorDescription = "The mongosh executable is required to run a shell script. Please see https://www.mongodb.com/docs/mongodb-shell/install/"
return
}
hosts, err := a.Hosts()
if err != nil {
result.ErrorTitle = "Could not get hosts"
result.ErrorDescription = err.Error()
return
}
host, hostFound := hosts[hostKey]
if !hostFound {
result.ErrorTitle = "The specified host does not seem to exist"
return
}
id, err := uuid.NewRandom()
if err != nil {
runtime.LogErrorf(a.ctx, "Shell: failed to generate a UUID: %s", err.Error())
result.ErrorTitle = "Could not generate UUID"
result.ErrorDescription = err.Error()
return
}
dirname := path.Join(a.Env.DataDirectory, "Shell Scripts")
fname := path.Join(dirname, fmt.Sprintf("%s.mongosh.js", id.String()))
if err := os.MkdirAll(dirname, os.ModePerm); err != nil {
runtime.LogWarningf(a.ctx, "Shell: failed to mkdir %s", err.Error())
result.ErrorTitle = "Could not create temporary directory"
result.ErrorDescription = err.Error()
return
}
scriptHeader := fmt.Sprintf("// Namespace: %s.%s\n", dbKey, collKey)
if dbKey != "" {
url, err := url.Parse(host.URI)
if err != nil {
runtime.LogWarningf(a.ctx, "Shell: failed to parse host URI %s: %s", host.URI, err.Error())
result.ErrorTitle = "Could parse host URI"
result.ErrorDescription = err.Error()
return
}
url.Path = "/" + dbKey
scriptHeader = scriptHeader + fmt.Sprintf("db = connect('%s');\n", url.String())
}
if collKey != "" {
scriptHeader = scriptHeader + fmt.Sprintf("coll = db.getCollection('%s');\n", collKey)
}
scriptHeader = scriptHeader + "\n// Start of user script\n"
script = scriptHeader + script
if err := os.WriteFile(fname, []byte(script), os.ModePerm); err != nil {
runtime.LogWarningf(a.ctx, "Shell: failed to write script to %s", err.Error())
result.ErrorTitle = "Could not create temporary script file"
result.ErrorDescription = err.Error()
return
}
cmd := exec.Command("mongosh", "--file", fname, host.URI)
stdout, err := cmd.Output()
if exiterr, ok := err.(*exec.ExitError); ok {
result.Status = exiterr.ExitCode()
} else if err != nil {
runtime.LogWarningf(a.ctx, "Shell: failed to execute: mongosh --file %s: %s", fname, err.Error())
result.ErrorTitle = "Could not execute script"
result.ErrorDescription = err.Error()
return
} else {
result.Status = 0
}
os.Remove(fname)
result.Output = string(stdout)
return
}