Add: Server variables are opt-out by default
- Pull the Nushell and Deno versions from the server. - Support downloading Nushell and Deno from a url (not GitHUb). - Add support for nu config.nu and env.nu files. - Add support for default Deno permissions.
This commit is contained in:
parent
87e1b29ef6
commit
2afdfd7ab8
@ -89,12 +89,11 @@ const (
|
|||||||
nixMeshDir = "/opt/tacticalmesh"
|
nixMeshDir = "/opt/tacticalmesh"
|
||||||
nixAgentBin = nixAgentDir + "/tacticalagent"
|
nixAgentBin = nixAgentDir + "/tacticalagent"
|
||||||
nixAgentBinDir = nixAgentDir + "/bin"
|
nixAgentBinDir = nixAgentDir + "/bin"
|
||||||
|
nixAgentEtcDir = nixAgentDir + "/etc"
|
||||||
nixMeshAgentBin = nixMeshDir + "/meshagent"
|
nixMeshAgentBin = nixMeshDir + "/meshagent"
|
||||||
macPlistPath = "/Library/LaunchDaemons/tacticalagent.plist"
|
macPlistPath = "/Library/LaunchDaemons/tacticalagent.plist"
|
||||||
macPlistName = "tacticalagent"
|
macPlistName = "tacticalagent"
|
||||||
defaultMacMeshSvcDir = "/usr/local/mesh_services"
|
defaultMacMeshSvcDir = "/usr/local/mesh_services"
|
||||||
nuVersion = "0.87.0"
|
|
||||||
denoVersion = "v1.38.2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var defaultWinTmpDir = filepath.Join(os.Getenv("PROGRAMDATA"), "TacticalRMM")
|
var defaultWinTmpDir = filepath.Join(os.Getenv("PROGRAMDATA"), "TacticalRMM")
|
||||||
|
@ -167,7 +167,7 @@ func NewAgentConfig() *rmm.AgentConfig {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) RunScript(code string, shell string, args []string, timeout int, runasuser bool, envVars []string) (stdout, stderr string, exitcode int, e error) {
|
func (a *Agent) RunScript(code string, shell string, args []string, timeout int, runasuser bool, envVars []string, nushellEnableConfig bool, denoDefaultPermissions string) (stdout, stderr string, exitcode int, e error) {
|
||||||
code = removeWinNewLines(code)
|
code = removeWinNewLines(code)
|
||||||
content := []byte(code)
|
content := []byte(code)
|
||||||
|
|
||||||
@ -197,12 +197,21 @@ func (a *Agent) RunScript(code string, shell string, args []string, timeout int,
|
|||||||
opts.IsScript = true
|
opts.IsScript = true
|
||||||
switch shell {
|
switch shell {
|
||||||
case "nushell":
|
case "nushell":
|
||||||
|
var nushellArgs []string
|
||||||
|
if nushellEnableConfig {
|
||||||
|
nushellArgs = []string{
|
||||||
|
"--config",
|
||||||
|
path.Join(nixAgentEtcDir, "nushell", "config.nu"),
|
||||||
|
"--env-config",
|
||||||
|
path.Join(nixAgentEtcDir, "nushell", "env.nu"),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nushellArgs = []string{"--no-config-file"}
|
||||||
|
}
|
||||||
opts.Shell = a.NuBin
|
opts.Shell = a.NuBin
|
||||||
opts.Args = append([]string{
|
opts.Args = nushellArgs
|
||||||
"--no-config-file",
|
opts.Args = append(opts.Args, f.Name())
|
||||||
f.Name(),
|
opts.Args = append(opts.Args, args...)
|
||||||
},
|
|
||||||
args...)
|
|
||||||
if !trmm.FileExists(a.NuBin) {
|
if !trmm.FileExists(a.NuBin) {
|
||||||
a.Logger.Errorln("RunScript(): Executable does not exist. Install Nu and try again:", a.NuBin)
|
a.Logger.Errorln("RunScript(): Executable does not exist. Install Nu and try again:", a.NuBin)
|
||||||
err := errors.New("File Not Found: " + a.NuBin)
|
err := errors.New("File Not Found: " + a.NuBin)
|
||||||
@ -225,6 +234,8 @@ func (a *Agent) RunScript(code string, shell string, args []string, timeout int,
|
|||||||
// https://docs.deno.com/runtime/manual/basics/permissions#permissions-list
|
// https://docs.deno.com/runtime/manual/basics/permissions#permissions-list
|
||||||
// DENO_PERMISSIONS is not an official environment variable.
|
// DENO_PERMISSIONS is not an official environment variable.
|
||||||
// https://docs.deno.com/runtime/manual/basics/env_variables
|
// https://docs.deno.com/runtime/manual/basics/env_variables
|
||||||
|
// DENO_DEFAULT_PERMISSIONS is used if not found in the environment variables.
|
||||||
|
found := false
|
||||||
for i, v := range envVars {
|
for i, v := range envVars {
|
||||||
if strings.HasPrefix(v, "DENO_PERMISSIONS=") {
|
if strings.HasPrefix(v, "DENO_PERMISSIONS=") {
|
||||||
permissions := strings.Split(v, "=")[1]
|
permissions := strings.Split(v, "=")[1]
|
||||||
@ -232,9 +243,13 @@ func (a *Agent) RunScript(code string, shell string, args []string, timeout int,
|
|||||||
// Remove the DENO_PERMISSIONS variable from the environment variables slice.
|
// Remove the DENO_PERMISSIONS variable from the environment variables slice.
|
||||||
// It's possible more variables may exist with the same prefix.
|
// It's possible more variables may exist with the same prefix.
|
||||||
envVars = append(envVars[:i], envVars[i+1:]...)
|
envVars = append(envVars[:i], envVars[i+1:]...)
|
||||||
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !found && denoDefaultPermissions != "" {
|
||||||
|
opts.Args = append(opts.Args, strings.Split(denoDefaultPermissions, " ")...)
|
||||||
|
}
|
||||||
|
|
||||||
// Can't append a variadic slice after a string arg.
|
// Can't append a variadic slice after a string arg.
|
||||||
// https://pkg.go.dev/builtin#append
|
// https://pkg.go.dev/builtin#append
|
||||||
@ -536,11 +551,321 @@ func (a *Agent) GetWMIInfo() map[string]interface{} {
|
|||||||
return wmiInfo
|
return wmiInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// windows only below TODO add into stub file
|
// InstallNushell will download nushell from GitHub and install (copy) it to nixAgentBinDir
|
||||||
|
func (a *Agent) InstallNushell(force bool) {
|
||||||
|
conf := a.GetAgentCheckInConfig(a.GetCheckInConfFromAPI())
|
||||||
|
if !conf.InstallNushell {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if trmm.FileExists(a.NuBin) {
|
||||||
|
if force {
|
||||||
|
a.Logger.Debugln(a.NuBin, "InstallNushell(): Forced install. Removing nu binary.")
|
||||||
|
err := os.Remove(a.NuBin)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error removing nu binary:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !trmm.FileExists(nixAgentBinDir) {
|
||||||
|
err := os.MkdirAll(nixAgentBinDir, 0755)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error creating nixAgentBinDir:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if conf.NushellEnableConfig {
|
||||||
|
// Create 0-byte config files for Nushell
|
||||||
|
nushellPath := path.Join(nixAgentEtcDir, "nushell")
|
||||||
|
nushellConfig := path.Join(nushellPath, "config.nu")
|
||||||
|
nushellEnv := path.Join(nushellPath, "env.nu")
|
||||||
|
if !trmm.FileExists(nushellPath) {
|
||||||
|
err := os.MkdirAll(nushellPath, 0755)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error creating nixAgentEtcDir/nushell:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !trmm.FileExists(nushellConfig) {
|
||||||
|
_, err := os.Create(nushellConfig)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error creating nushell config.nu:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = os.Chmod(nushellConfig, 0744)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error changing permissions for nushell config.nu:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !trmm.FileExists(nushellEnv) {
|
||||||
|
_, err := os.Create(nushellEnv)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error creating nushell env.nu:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = os.Chmod(nushellEnv, 0744)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error changing permissions for nushell env.nu:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
assetName string
|
||||||
|
url string
|
||||||
|
targzDirName string
|
||||||
|
)
|
||||||
|
|
||||||
|
if conf.InstallNushellUrl != "" {
|
||||||
|
url = conf.InstallNushellUrl
|
||||||
|
url = strings.Replace(url, "{OS}", runtime.GOOS, -1)
|
||||||
|
url = strings.Replace(url, "{ARCH}", runtime.GOARCH, -1)
|
||||||
|
url = strings.Replace(url, "{VERSION}", conf.InstallNushellVersion, -1)
|
||||||
|
} else {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "darwin":
|
||||||
|
switch runtime.GOARCH {
|
||||||
|
case "arm64":
|
||||||
|
// https://github.com/nushell/nushell/releases/download/0.87.0/nu-0.87.0-aarch64-darwin-full.tar.gz
|
||||||
|
assetName = fmt.Sprintf("nu-%s-aarch64-darwin-full.tar.gz", conf.InstallNushellVersion)
|
||||||
|
default:
|
||||||
|
a.Logger.Debugln("InstallNushell(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case "linux":
|
||||||
|
switch runtime.GOARCH {
|
||||||
|
case "amd64":
|
||||||
|
// https://github.com/nushell/nushell/releases/download/0.87.0/nu-0.87.0-x86_64-linux-musl-full.tar.gz
|
||||||
|
assetName = fmt.Sprintf("nu-%s-x86_64-linux-musl-full.tar.gz", conf.InstallNushellVersion)
|
||||||
|
case "arm64":
|
||||||
|
// https://github.com/nushell/nushell/releases/download/0.87.0/nu-0.87.0-aarch64-linux-gnu-full.tar.gz
|
||||||
|
assetName = fmt.Sprintf("nu-%s-aarch64-linux-gnu-full.tar.gz", conf.InstallNushellVersion)
|
||||||
|
default:
|
||||||
|
a.Logger.Debugln("InstallNushell(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
a.Logger.Debugln("InstallNushell(): Unsupported OS:", runtime.GOOS)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
url = fmt.Sprintf("https://github.com/nushell/nushell/releases/download/%s/%s", conf.InstallNushellVersion, assetName)
|
||||||
|
}
|
||||||
|
a.Logger.Debugln("InstallNushell(): Nu download url:", url)
|
||||||
|
|
||||||
|
tmpDir, err := os.MkdirTemp("", "trmm")
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error creating temp directory:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func(path string) {
|
||||||
|
err := os.RemoveAll(path)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error removing temp directory:", err)
|
||||||
|
}
|
||||||
|
}(tmpDir)
|
||||||
|
|
||||||
|
tmpAssetName := filepath.Join(tmpDir, assetName)
|
||||||
|
a.Logger.Debugln("InstallNushell(): tmpAssetName:", tmpAssetName)
|
||||||
|
|
||||||
|
rClient := resty.New()
|
||||||
|
rClient.SetTimeout(20 * time.Minute)
|
||||||
|
rClient.SetRetryCount(10)
|
||||||
|
rClient.SetRetryWaitTime(1 * time.Minute)
|
||||||
|
rClient.SetRetryMaxWaitTime(15 * time.Minute)
|
||||||
|
if len(a.Proxy) > 0 {
|
||||||
|
rClient.SetProxy(a.Proxy)
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := rClient.R().SetOutput(tmpAssetName).Get(url)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Unable to download nu:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.IsError() {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Unable to download nu. Status code:", r.StatusCode())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if conf.InstallNushellUrl != "" {
|
||||||
|
// InstallNushellUrl is not compressed.
|
||||||
|
err = copyFile(path.Join(tmpDir, tmpAssetName), a.NuBin)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Failed to copy nu file to install dir:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// GitHub asset is tar.gz compressed.
|
||||||
|
targzDirName, err = a.ExtractTarGz(tmpAssetName, tmpDir)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Failed to extract downloaded tar.gz file:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = copyFile(path.Join(tmpDir, targzDirName, "nu"), a.NuBin)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Failed to copy nu file to install dir:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Chmod(a.NuBin, 0755)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Failed to chmod nu binary:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstallDeno will download deno from GitHub and install (copy) it to nixAgentBinDir
|
||||||
|
func (a *Agent) InstallDeno(force bool) {
|
||||||
|
conf := a.GetAgentCheckInConfig(a.GetCheckInConfFromAPI())
|
||||||
|
if !conf.InstallDeno {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if trmm.FileExists(a.DenoBin) {
|
||||||
|
if force {
|
||||||
|
a.Logger.Debugln(a.NuBin, "InstallDeno(): Forced install. Removing deno binary.")
|
||||||
|
err := os.Remove(a.DenoBin)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallDeno(): Error removing deno binary:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !trmm.FileExists(nixAgentBinDir) {
|
||||||
|
err := os.MkdirAll(nixAgentBinDir, 0755)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallDeno(): Error creating nixAgentBinDir:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
assetName string
|
||||||
|
url string
|
||||||
|
)
|
||||||
|
|
||||||
|
if conf.InstallDenoUrl != "" {
|
||||||
|
url = conf.InstallDenoUrl
|
||||||
|
url = strings.Replace(url, "{OS}", runtime.GOOS, -1)
|
||||||
|
url = strings.Replace(url, "{ARCH}", runtime.GOARCH, -1)
|
||||||
|
url = strings.Replace(url, "{VERSION}", conf.InstallDenoVersion, -1)
|
||||||
|
} else {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "darwin":
|
||||||
|
switch runtime.GOARCH {
|
||||||
|
case "arm64":
|
||||||
|
// https://github.com/denoland/deno/releases/download/v1.38.2/deno-aarch64-apple-darwin.zip
|
||||||
|
assetName = fmt.Sprintf("deno-aarch64-apple-darwin.zip")
|
||||||
|
case "amd64":
|
||||||
|
// https://github.com/denoland/deno/releases/download/v1.38.2/deno-x86_64-apple-darwin.zip
|
||||||
|
assetName = fmt.Sprintf("deno-x86_64-apple-darwin.zip")
|
||||||
|
default:
|
||||||
|
a.Logger.Debugln("InstallDeno(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case "linux":
|
||||||
|
switch runtime.GOARCH {
|
||||||
|
case "amd64":
|
||||||
|
// https://github.com/denoland/deno/releases/download/v1.38.2/deno-x86_64-unknown-linux-gnu.zip
|
||||||
|
assetName = fmt.Sprintf("deno-x86_64-unknown-linux-gnu.zip")
|
||||||
|
default:
|
||||||
|
a.Logger.Debugln("InstallDeno(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
a.Logger.Debugln("InstallDeno(): Unsupported OS:", runtime.GOOS)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
url = fmt.Sprintf("https://github.com/denoland/deno/releases/download/%s/%s", conf.InstallDenoVersion, assetName)
|
||||||
|
}
|
||||||
|
a.Logger.Debugln("InstallDeno(): Deno download url:", url)
|
||||||
|
|
||||||
|
tmpDir, err := os.MkdirTemp("", "trmm")
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallDeno(): Error creating temp directory:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func(path string) {
|
||||||
|
err := os.RemoveAll(path)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallDeno(): Error removing temp directory:", err)
|
||||||
|
}
|
||||||
|
}(tmpDir)
|
||||||
|
|
||||||
|
tmpAssetName := filepath.Join(tmpDir, assetName)
|
||||||
|
a.Logger.Debugln("InstallDeno(): tmpAssetName:", tmpAssetName)
|
||||||
|
|
||||||
|
rClient := resty.New()
|
||||||
|
rClient.SetTimeout(20 * time.Minute)
|
||||||
|
rClient.SetRetryCount(10)
|
||||||
|
rClient.SetRetryWaitTime(1 * time.Minute)
|
||||||
|
rClient.SetRetryMaxWaitTime(15 * time.Minute)
|
||||||
|
if len(a.Proxy) > 0 {
|
||||||
|
rClient.SetProxy(a.Proxy)
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := rClient.R().SetOutput(tmpAssetName).Get(url)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallDeno(): Unable to download deno:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.IsError() {
|
||||||
|
a.Logger.Errorln("InstallDeno(): Unable to download deno. Status code:", r.StatusCode())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if conf.InstallDenoUrl != "" {
|
||||||
|
// InstallDenoUrl is not compressed.
|
||||||
|
err = copyFile(path.Join(tmpDir, tmpAssetName), a.DenoBin)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallDeno(): Failed to copy deno file to install dir:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// GitHub asset is zip compressed.
|
||||||
|
err = Unzip(tmpAssetName, tmpDir)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallDeno(): Failed to unzip downloaded zip file:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = copyFile(path.Join(tmpDir, "deno"), a.DenoBin)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallDeno(): Failed to copy deno file to install dir:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Chmod(a.DenoBin, 0755)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallDeno(): Failed to chmod deno binary:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAgentCheckInConfig will get the agent configuration from the server.
|
||||||
|
// The Windows agent stores the configuration in the registry. The UNIX agent does not store the config.
|
||||||
|
// @return AgentCheckInConfig
|
||||||
func (a *Agent) GetAgentCheckInConfig(ret AgentCheckInConfig) AgentCheckInConfig {
|
func (a *Agent) GetAgentCheckInConfig(ret AgentCheckInConfig) AgentCheckInConfig {
|
||||||
|
// TODO: Persist the config to disk.
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// windows only below TODO add into stub file
|
||||||
func (a *Agent) PlatVer() (string, error) { return "", nil }
|
func (a *Agent) PlatVer() (string, error) { return "", nil }
|
||||||
|
|
||||||
func (a *Agent) SendSoftware() {}
|
func (a *Agent) SendSoftware() {}
|
||||||
@ -553,235 +878,6 @@ func GetServiceStatus(name string) (string, error) { return "", nil }
|
|||||||
|
|
||||||
func (a *Agent) GetPython(force bool) {}
|
func (a *Agent) GetPython(force bool) {}
|
||||||
|
|
||||||
// GetNushell will download nushell from GitHub and install (copy) it to nixAgentBinDir
|
|
||||||
func (a *Agent) GetNushell(force bool) {
|
|
||||||
if trmm.FileExists(a.NuBin) {
|
|
||||||
if force {
|
|
||||||
err := os.Remove(a.NuBin)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetNushell(): Error removing nu binary:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !trmm.FileExists(nixAgentBinDir) {
|
|
||||||
err := os.MkdirAll(nixAgentBinDir, 0755)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetNushell(): Error creating nixAgentBinDir:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
assetName string
|
|
||||||
url string
|
|
||||||
targzDirName string
|
|
||||||
)
|
|
||||||
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin":
|
|
||||||
switch runtime.GOARCH {
|
|
||||||
case "arm64":
|
|
||||||
// https://github.com/nushell/nushell/releases/download/0.87.0/nu-0.87.0-aarch64-darwin-full.tar.gz
|
|
||||||
assetName = fmt.Sprintf("nu-%s-aarch64-darwin-full.tar.gz", nuVersion)
|
|
||||||
default:
|
|
||||||
a.Logger.Debugln("GetNushell(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "linux":
|
|
||||||
switch runtime.GOARCH {
|
|
||||||
case "amd64":
|
|
||||||
// https://github.com/nushell/nushell/releases/download/0.87.0/nu-0.87.0-x86_64-linux-musl-full.tar.gz
|
|
||||||
assetName = fmt.Sprintf("nu-%s-x86_64-linux-musl-full.tar.gz", nuVersion)
|
|
||||||
case "arm64":
|
|
||||||
// https://github.com/nushell/nushell/releases/download/0.87.0/nu-0.87.0-aarch64-linux-gnu-full.tar.gz
|
|
||||||
assetName = fmt.Sprintf("nu-%s-aarch64-linux-gnu-full.tar.gz", nuVersion)
|
|
||||||
default:
|
|
||||||
a.Logger.Debugln("GetNushell(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
a.Logger.Debugln("GetNushell(): Unsupported OS:", runtime.GOOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
url = fmt.Sprintf("https://github.com/nushell/nushell/releases/download/%s/%s", nuVersion, assetName)
|
|
||||||
a.Logger.Debugln("GetNushell(): Nu download url:", url)
|
|
||||||
|
|
||||||
tmpDir, err := os.MkdirTemp("", "trmm")
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetNushell(): Error creating temp directory:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer func(path string) {
|
|
||||||
err := os.RemoveAll(path)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetNushell(): Error removing temp directory:", err)
|
|
||||||
}
|
|
||||||
}(tmpDir)
|
|
||||||
|
|
||||||
tmpAssetName := filepath.Join(tmpDir, assetName)
|
|
||||||
a.Logger.Debugln("GetNushell(): tmpAssetName:", tmpAssetName)
|
|
||||||
|
|
||||||
rClient := resty.New()
|
|
||||||
rClient.SetTimeout(20 * time.Minute)
|
|
||||||
rClient.SetRetryCount(10)
|
|
||||||
rClient.SetRetryWaitTime(1 * time.Minute)
|
|
||||||
rClient.SetRetryMaxWaitTime(15 * time.Minute)
|
|
||||||
if len(a.Proxy) > 0 {
|
|
||||||
rClient.SetProxy(a.Proxy)
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := rClient.R().SetOutput(tmpAssetName).Get(url)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetNushell(): Unable to download nu from github.", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if r.IsError() {
|
|
||||||
a.Logger.Errorln("GetNushell(): Unable to download nu from github. Status code", r.StatusCode())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
targzDirName, err = a.ExtractTarGz(tmpAssetName, tmpDir)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetNushell(): Failed to extract downloaded tar.gz file:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = copyFile(path.Join(tmpDir, targzDirName, "nu"), a.NuBin)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetNushell(): Failed to copy nu file to install dir:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.Chmod(a.NuBin, 0755)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetNushell(): Failed to chmod nu binary:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDeno will download deno from GitHub and install (copy) it to nixAgentBinDir
|
|
||||||
func (a *Agent) GetDeno(force bool) {
|
|
||||||
if trmm.FileExists(a.DenoBin) {
|
|
||||||
if force {
|
|
||||||
err := os.Remove(a.DenoBin)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetDeno(): Error removing deno binary:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !trmm.FileExists(nixAgentBinDir) {
|
|
||||||
err := os.MkdirAll(nixAgentBinDir, 0755)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetDeno(): Error creating nixAgentBinDir:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
assetName string
|
|
||||||
url string
|
|
||||||
)
|
|
||||||
|
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin":
|
|
||||||
switch runtime.GOARCH {
|
|
||||||
case "arm64":
|
|
||||||
// https://github.com/denoland/deno/releases/download/v1.38.2/deno-aarch64-apple-darwin.zip
|
|
||||||
assetName = fmt.Sprintf("deno-aarch64-apple-darwin.zip")
|
|
||||||
case "amd64":
|
|
||||||
// https://github.com/denoland/deno/releases/download/v1.38.2/deno-x86_64-apple-darwin.zip
|
|
||||||
assetName = fmt.Sprintf("deno-x86_64-apple-darwin.zip")
|
|
||||||
default:
|
|
||||||
a.Logger.Debugln("GetDeno(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case "linux":
|
|
||||||
switch runtime.GOARCH {
|
|
||||||
case "amd64":
|
|
||||||
// https://github.com/denoland/deno/releases/download/v1.38.2/deno-x86_64-unknown-linux-gnu.zip
|
|
||||||
assetName = fmt.Sprintf("deno-x86_64-unknown-linux-gnu.zip")
|
|
||||||
default:
|
|
||||||
a.Logger.Debugln("GetDeno(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
a.Logger.Debugln("GetDeno(): Unsupported OS:", runtime.GOOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
url = fmt.Sprintf("https://github.com/denoland/deno/releases/download/%s/%s", denoVersion, assetName)
|
|
||||||
a.Logger.Debugln("GetDeno(): Deno download url:", url)
|
|
||||||
|
|
||||||
tmpDir, err := os.MkdirTemp("", "trmm")
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetDeno(): Error creating temp directory:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer func(path string) {
|
|
||||||
err := os.RemoveAll(path)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetDeno(): Error removing temp directory:", err)
|
|
||||||
}
|
|
||||||
}(tmpDir)
|
|
||||||
|
|
||||||
tmpAssetName := filepath.Join(tmpDir, assetName)
|
|
||||||
a.Logger.Debugln("GetDeno(): tmpAssetName:", tmpAssetName)
|
|
||||||
|
|
||||||
if !trmm.FileExists(nixAgentBinDir) {
|
|
||||||
err = os.MkdirAll(nixAgentBinDir, 0755)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetDeno(): Error creating nixAgentBinDir:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rClient := resty.New()
|
|
||||||
rClient.SetTimeout(20 * time.Minute)
|
|
||||||
rClient.SetRetryCount(10)
|
|
||||||
rClient.SetRetryWaitTime(1 * time.Minute)
|
|
||||||
rClient.SetRetryMaxWaitTime(15 * time.Minute)
|
|
||||||
if len(a.Proxy) > 0 {
|
|
||||||
rClient.SetProxy(a.Proxy)
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := rClient.R().SetOutput(tmpAssetName).Get(url)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetDeno(): Unable to download deno from github.", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if r.IsError() {
|
|
||||||
a.Logger.Errorln("GetDeno(): Unable to download deno from github. Status code", r.StatusCode())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = Unzip(tmpAssetName, tmpDir)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetDeno(): Failed to unzip downloaded zip file:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = copyFile(path.Join(tmpDir, "deno"), a.DenoBin)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetDeno(): Failed to copy deno file to install dir:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.Chmod(a.DenoBin, 0755)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetDeno(): Failed to chmod deno binary:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type SchedTask struct{ Name string }
|
type SchedTask struct{ Name string }
|
||||||
|
|
||||||
func (a *Agent) PatchMgmnt(enable bool) error { return nil }
|
func (a *Agent) PatchMgmnt(enable bool) error { return nil }
|
||||||
|
@ -92,7 +92,7 @@ func NewAgentConfig() *rmm.AgentConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) RunScript(code string, shell string, args []string, timeout int, runasuser bool, envVars []string) (stdout, stderr string, exitcode int, e error) {
|
func (a *Agent) RunScript(code string, shell string, args []string, timeout int, runasuser bool, envVars []string, nushellEnableConfig bool, denoDefaultPermissions string) (stdout, stderr string, exitcode int, e error) {
|
||||||
|
|
||||||
content := []byte(code)
|
content := []byte(code)
|
||||||
|
|
||||||
@ -158,7 +158,18 @@ func (a *Agent) RunScript(code string, shell string, args []string, timeout int,
|
|||||||
exe = tmpfn.Name()
|
exe = tmpfn.Name()
|
||||||
case "nushell":
|
case "nushell":
|
||||||
exe = a.NuBin
|
exe = a.NuBin
|
||||||
cmdArgs = []string{"--no-config-file", tmpfn.Name()}
|
var nushellArgs []string
|
||||||
|
if nushellEnableConfig {
|
||||||
|
nushellArgs = []string{
|
||||||
|
"--config",
|
||||||
|
path.Join(a.ProgramDir, "etc", "nushell", "config.nu"),
|
||||||
|
"--env-config",
|
||||||
|
path.Join(a.ProgramDir, "etc", "nushell", "env.nu"),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nushellArgs = []string{"--no-config-file"}
|
||||||
|
}
|
||||||
|
cmdArgs = append(nushellArgs, tmpfn.Name())
|
||||||
if !trmm.FileExists(a.NuBin) {
|
if !trmm.FileExists(a.NuBin) {
|
||||||
a.Logger.Errorln("RunScript(): Executable does not exist. Install Nu and try again:", a.NuBin)
|
a.Logger.Errorln("RunScript(): Executable does not exist. Install Nu and try again:", a.NuBin)
|
||||||
err := errors.New("File Not Found: " + a.NuBin)
|
err := errors.New("File Not Found: " + a.NuBin)
|
||||||
@ -177,6 +188,8 @@ func (a *Agent) RunScript(code string, shell string, args []string, timeout int,
|
|||||||
// https://docs.deno.com/runtime/manual/basics/permissions#permissions-list
|
// https://docs.deno.com/runtime/manual/basics/permissions#permissions-list
|
||||||
// DENO_PERMISSIONS is not an official environment variable.
|
// DENO_PERMISSIONS is not an official environment variable.
|
||||||
// https://docs.deno.com/runtime/manual/basics/env_variables
|
// https://docs.deno.com/runtime/manual/basics/env_variables
|
||||||
|
// DENO_DEFAULT_PERMISSIONS is used if not found in the environment variables.
|
||||||
|
found := false
|
||||||
for i, v := range envVars {
|
for i, v := range envVars {
|
||||||
if strings.HasPrefix(v, "DENO_PERMISSIONS=") {
|
if strings.HasPrefix(v, "DENO_PERMISSIONS=") {
|
||||||
permissions := strings.Split(v, "=")[1]
|
permissions := strings.Split(v, "=")[1]
|
||||||
@ -184,12 +197,13 @@ func (a *Agent) RunScript(code string, shell string, args []string, timeout int,
|
|||||||
// Remove the DENO_PERMISSIONS variable from the environment variables slice.
|
// Remove the DENO_PERMISSIONS variable from the environment variables slice.
|
||||||
// It's possible more variables may exist with the same prefix.
|
// It's possible more variables may exist with the same prefix.
|
||||||
envVars = append(envVars[:i], envVars[i+1:]...)
|
envVars = append(envVars[:i], envVars[i+1:]...)
|
||||||
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !found && denoDefaultPermissions != "" {
|
||||||
// Can't append a variadic slice after a string arg.
|
cmdArgs = append(cmdArgs, strings.Split(denoDefaultPermissions, " ")...)
|
||||||
// https://pkg.go.dev/builtin#append
|
}
|
||||||
cmdArgs = append(cmdArgs, tmpfn.Name())
|
cmdArgs = append(cmdArgs, tmpfn.Name())
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -879,14 +893,20 @@ func (a *Agent) GetPython(force bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNushell will download nushell from GitHub and install (copy) it to ProgramDir\bin, where ProgramDir is
|
// InstallNushell will download nushell from GitHub and install (copy) it to ProgramDir\bin, where ProgramDir is
|
||||||
// initialized to C:\Program Files\TacticalAgent
|
// initialized to C:\Program Files\TacticalAgent
|
||||||
func (a *Agent) GetNushell(force bool) {
|
func (a *Agent) InstallNushell(force bool) {
|
||||||
|
conf := a.GetAgentCheckInConfig(a.GetCheckInConfFromAPI())
|
||||||
|
if !conf.InstallNushell {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if trmm.FileExists(a.NuBin) {
|
if trmm.FileExists(a.NuBin) {
|
||||||
if force {
|
if force {
|
||||||
|
a.Logger.Debugln(a.NuBin, "InstallNushell(): Forced install. Removing nu.exe binary.")
|
||||||
err := os.Remove(a.NuBin)
|
err := os.Remove(a.NuBin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetNushell(): Error removing nu binary:", err)
|
a.Logger.Errorln("InstallNushell(): Error removing nu.exe binary:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -898,50 +918,96 @@ func (a *Agent) GetNushell(force bool) {
|
|||||||
if !trmm.FileExists(programBinDir) {
|
if !trmm.FileExists(programBinDir) {
|
||||||
err := os.MkdirAll(programBinDir, 0755)
|
err := os.MkdirAll(programBinDir, 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetNushell(): Error creating Program Files bin folder:", err)
|
a.Logger.Errorln("InstallNushell(): Error creating Program Files bin folder:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if conf.NushellEnableConfig {
|
||||||
|
// Create 0-byte config files for Nushell
|
||||||
|
nushellPath := path.Join(a.ProgramDir, "etc", "nushell")
|
||||||
|
nushellConfig := path.Join(nushellPath, "config.nu")
|
||||||
|
nushellEnv := path.Join(nushellPath, "env.nu")
|
||||||
|
if !trmm.FileExists(nushellPath) {
|
||||||
|
err := os.MkdirAll(nushellPath, 0755)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error creating Program Files/nushell:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !trmm.FileExists(nushellConfig) {
|
||||||
|
_, err := os.Create(nushellConfig)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error creating nushell config.nu:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = os.Chmod(nushellConfig, 0744)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error changing permissions for nushell config.nu:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !trmm.FileExists(nushellEnv) {
|
||||||
|
_, err := os.Create(nushellEnv)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error creating nushell env.nu:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = os.Chmod(nushellEnv, 0744)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Error changing permissions for nushell env.nu:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
assetName string
|
assetName string
|
||||||
url string
|
url string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if conf.InstallNushellUrl != "" {
|
||||||
|
url = conf.InstallNushellUrl
|
||||||
|
url = strings.Replace(url, "{OS}", runtime.GOOS, -1)
|
||||||
|
url = strings.Replace(url, "{ARCH}", runtime.GOARCH, -1)
|
||||||
|
url = strings.Replace(url, "{VERSION}", conf.InstallNushellVersion, -1)
|
||||||
|
} else {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "windows":
|
case "windows":
|
||||||
switch runtime.GOARCH {
|
switch runtime.GOARCH {
|
||||||
case "amd64":
|
case "amd64":
|
||||||
// https://github.com/nushell/nushell/releases/download/0.87.0/nu-0.87.0-x86_64-windows-msvc-full.zip
|
// https://github.com/nushell/nushell/releases/download/0.87.0/nu-0.87.0-x86_64-windows-msvc-full.zip
|
||||||
assetName = fmt.Sprintf("nu-%s-x86_64-windows-msvc-full.zip", nuVersion)
|
assetName = fmt.Sprintf("nu-%s-x86_64-windows-msvc-full.zip", conf.InstallNushellVersion)
|
||||||
case "arm64":
|
case "arm64":
|
||||||
// https://github.com/nushell/nushell/releases/download/0.87.0/nu-0.87.0-aarch64-windows-msvc-full.zip
|
// https://github.com/nushell/nushell/releases/download/0.87.0/nu-0.87.0-aarch64-windows-msvc-full.zip
|
||||||
assetName = fmt.Sprintf("nu-%s-aarch64-windows-msvc-full.zip", nuVersion)
|
assetName = fmt.Sprintf("nu-%s-aarch64-windows-msvc-full.zip", conf.InstallNushellVersion)
|
||||||
default:
|
default:
|
||||||
a.Logger.Debugln("GetNushell(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
a.Logger.Debugln("InstallNushell(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
a.Logger.Debugln("GetNushell(): Unsupported OS:", runtime.GOOS)
|
a.Logger.Debugln("InstallNushell(): Unsupported OS:", runtime.GOOS)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
url = fmt.Sprintf("https://github.com/nushell/nushell/releases/download/%s/%s", nuVersion, assetName)
|
url = fmt.Sprintf("https://github.com/nushell/nushell/releases/download/%s/%s", conf.InstallNushellVersion, assetName)
|
||||||
a.Logger.Debugln("GetNushell(): Nu download url:", url)
|
}
|
||||||
|
a.Logger.Debugln("InstallNushell(): Nu download url:", url)
|
||||||
|
|
||||||
tmpDir, err := os.MkdirTemp("", "trmm")
|
tmpDir, err := os.MkdirTemp("", "trmm")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetNushell(): Error creating temp directory:", err)
|
a.Logger.Errorln("InstallNushell(): Error creating temp directory:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer func(path string) {
|
defer func(path string) {
|
||||||
err := os.RemoveAll(path)
|
err := os.RemoveAll(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetNushell(): Error removing temp directory:", err)
|
a.Logger.Errorln("InstallNushell(): Error removing temp directory:", err)
|
||||||
}
|
}
|
||||||
}(tmpDir)
|
}(tmpDir)
|
||||||
|
|
||||||
tmpAssetName := filepath.Join(tmpDir, assetName)
|
tmpAssetName := filepath.Join(tmpDir, assetName)
|
||||||
a.Logger.Debugln("GetNushell(): tmpAssetName:", tmpAssetName)
|
a.Logger.Debugln("InstallNushell(): tmpAssetName:", tmpAssetName)
|
||||||
|
|
||||||
rClient := resty.New()
|
rClient := resty.New()
|
||||||
rClient.SetTimeout(20 * time.Minute)
|
rClient.SetTimeout(20 * time.Minute)
|
||||||
@ -954,35 +1020,50 @@ func (a *Agent) GetNushell(force bool) {
|
|||||||
|
|
||||||
r, err := rClient.R().SetOutput(tmpAssetName).Get(url)
|
r, err := rClient.R().SetOutput(tmpAssetName).Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetNushell(): Unable to download nu from github.", err)
|
a.Logger.Errorln("InstallNushell(): Unable to download nu:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if r.IsError() {
|
if r.IsError() {
|
||||||
a.Logger.Errorln("GetNushell(): Unable to download nu from github. Status code", r.StatusCode())
|
a.Logger.Errorln("InstallNushell(): Unable to download nu. Status code:", r.StatusCode())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if conf.InstallNushellUrl != "" {
|
||||||
|
// InstallNushellUrl is not compressed.
|
||||||
|
err = copyFile(path.Join(tmpDir, tmpAssetName), a.NuBin)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallNushell(): Failed to copy nu file to install dir:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
err = Unzip(tmpAssetName, tmpDir)
|
err = Unzip(tmpAssetName, tmpDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetNushell(): Failed to unzip downloaded zip file:", err)
|
a.Logger.Errorln("InstallNushell(): Failed to unzip downloaded zip file:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = copyFile(path.Join(tmpDir, "nu.exe"), a.NuBin)
|
err = copyFile(path.Join(tmpDir, "nu.exe"), a.NuBin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetNushell(): Failed to copy nu.exe file to install dir:", err)
|
a.Logger.Errorln("InstallNushell(): Failed to copy nu.exe file to install dir:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstallDeno will download deno from GitHub and install (copy) it to ProgramDir\bin, where ProgramDir is
|
||||||
|
// initialized to C:\Program Files\TacticalAgent
|
||||||
|
func (a *Agent) InstallDeno(force bool) {
|
||||||
|
conf := a.GetAgentCheckInConfig(a.GetCheckInConfFromAPI())
|
||||||
|
if !conf.InstallDeno {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDeno will download deno from GitHub and install (copy) it to nixAgentBinDir
|
|
||||||
func (a *Agent) GetDeno(force bool) {
|
|
||||||
if trmm.FileExists(a.DenoBin) {
|
if trmm.FileExists(a.DenoBin) {
|
||||||
if force {
|
if force {
|
||||||
err := os.Remove(a.DenoBin)
|
err := os.Remove(a.DenoBin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetDeno(): Error removing deno binary:", err)
|
a.Logger.Errorln("InstallDeno(): Error removing deno binary:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -994,7 +1075,7 @@ func (a *Agent) GetDeno(force bool) {
|
|||||||
if !trmm.FileExists(programBinDir) {
|
if !trmm.FileExists(programBinDir) {
|
||||||
err := os.MkdirAll(programBinDir, 0755)
|
err := os.MkdirAll(programBinDir, 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetDeno(): Error creating Program Files bin folder:", err)
|
a.Logger.Errorln("InstallDeno(): Error creating Program Files bin folder:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1004,6 +1085,12 @@ func (a *Agent) GetDeno(force bool) {
|
|||||||
url string
|
url string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if conf.InstallDenoUrl != "" {
|
||||||
|
url = conf.InstallDenoUrl
|
||||||
|
url = strings.Replace(url, "{OS}", runtime.GOOS, -1)
|
||||||
|
url = strings.Replace(url, "{ARCH}", runtime.GOARCH, -1)
|
||||||
|
url = strings.Replace(url, "{VERSION}", conf.InstallDenoVersion, -1)
|
||||||
|
} else {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "windows":
|
case "windows":
|
||||||
switch runtime.GOARCH {
|
switch runtime.GOARCH {
|
||||||
@ -1011,38 +1098,31 @@ func (a *Agent) GetDeno(force bool) {
|
|||||||
// https://github.com/denoland/deno/releases/download/v1.38.2/deno-x86_64-pc-windows-msvc.zip
|
// https://github.com/denoland/deno/releases/download/v1.38.2/deno-x86_64-pc-windows-msvc.zip
|
||||||
assetName = fmt.Sprintf("deno-x86_64-pc-windows-msvc.zip")
|
assetName = fmt.Sprintf("deno-x86_64-pc-windows-msvc.zip")
|
||||||
default:
|
default:
|
||||||
a.Logger.Debugln("GetDeno(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
a.Logger.Debugln("InstallDeno(): Unsupported architecture and OS:", runtime.GOARCH, runtime.GOOS)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
a.Logger.Debugln("GetDeno(): Unsupported OS:", runtime.GOOS)
|
a.Logger.Debugln("InstallDeno(): Unsupported OS:", runtime.GOOS)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
url = fmt.Sprintf("https://github.com/denoland/deno/releases/download/%s/%s", denoVersion, assetName)
|
url = fmt.Sprintf("https://github.com/denoland/deno/releases/download/%s/%s", conf.InstallDenoVersion, assetName)
|
||||||
a.Logger.Debugln("GetDeno(): Deno download url:", url)
|
}
|
||||||
|
a.Logger.Debugln("InstallDeno(): Deno download url:", url)
|
||||||
|
|
||||||
tmpDir, err := os.MkdirTemp("", "trmm")
|
tmpDir, err := os.MkdirTemp("", "trmm")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetDeno(): Error creating temp directory:", err)
|
a.Logger.Errorln("InstallDeno(): Error creating temp directory:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer func(path string) {
|
defer func(path string) {
|
||||||
err := os.RemoveAll(path)
|
err := os.RemoveAll(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetDeno(): Error removing temp directory:", err)
|
a.Logger.Errorln("InstallDeno(): Error removing temp directory:", err)
|
||||||
}
|
}
|
||||||
}(tmpDir)
|
}(tmpDir)
|
||||||
|
|
||||||
tmpAssetName := filepath.Join(tmpDir, assetName)
|
tmpAssetName := filepath.Join(tmpDir, assetName)
|
||||||
a.Logger.Debugln("GetDeno(): tmpAssetName:", tmpAssetName)
|
a.Logger.Debugln("InstallDeno(): tmpAssetName:", tmpAssetName)
|
||||||
|
|
||||||
if !trmm.FileExists(nixAgentBinDir) {
|
|
||||||
err = os.MkdirAll(nixAgentBinDir, 0755)
|
|
||||||
if err != nil {
|
|
||||||
a.Logger.Errorln("GetDeno(): Error creating nixAgentBinDir:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rClient := resty.New()
|
rClient := resty.New()
|
||||||
rClient.SetTimeout(20 * time.Minute)
|
rClient.SetTimeout(20 * time.Minute)
|
||||||
@ -1055,25 +1135,35 @@ func (a *Agent) GetDeno(force bool) {
|
|||||||
|
|
||||||
r, err := rClient.R().SetOutput(tmpAssetName).Get(url)
|
r, err := rClient.R().SetOutput(tmpAssetName).Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetDeno(): Unable to download deno from github.", err)
|
a.Logger.Errorln("InstallDeno(): Unable to download deno:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if r.IsError() {
|
if r.IsError() {
|
||||||
a.Logger.Errorln("GetDeno(): Unable to download deno from github. Status code", r.StatusCode())
|
a.Logger.Errorln("InstallDeno(): Unable to download deno. Status code:", r.StatusCode())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if conf.InstallDenoUrl != "" {
|
||||||
|
// InstallDenoUrl is not compressed.
|
||||||
|
err = copyFile(path.Join(tmpDir, tmpAssetName), a.DenoBin)
|
||||||
|
if err != nil {
|
||||||
|
a.Logger.Errorln("InstallDeno(): Failed to copy deno file to install dir:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// GitHub asset is zip compressed.
|
||||||
err = Unzip(tmpAssetName, tmpDir)
|
err = Unzip(tmpAssetName, tmpDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetDeno(): Failed to unzip downloaded zip file:", err)
|
a.Logger.Errorln("InstallDeno(): Failed to unzip downloaded zip file:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = copyFile(path.Join(tmpDir, "deno.exe"), a.DenoBin)
|
err = copyFile(path.Join(tmpDir, "deno.exe"), a.DenoBin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Errorln("GetDeno(): Failed to copy deno.exe file to install dir:", err)
|
a.Logger.Errorln("InstallDeno(): Failed to copy deno.exe file to install dir:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ type ScriptCheckResult struct {
|
|||||||
// ScriptCheck runs either bat, powershell or python script
|
// ScriptCheck runs either bat, powershell or python script
|
||||||
func (a *Agent) ScriptCheck(data rmm.Check, r *resty.Client) {
|
func (a *Agent) ScriptCheck(data rmm.Check, r *resty.Client) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
stdout, stderr, retcode, _ := a.RunScript(data.Script.Code, data.Script.Shell, data.ScriptArgs, data.Timeout, data.Script.RunAsUser, data.EnvVars)
|
stdout, stderr, retcode, _ := a.RunScript(data.Script.Code, data.Script.Shell, data.ScriptArgs, data.Timeout, data.Script.RunAsUser, data.EnvVars, data.NushellEnableConfig, data.DenoDefaultPermissions)
|
||||||
|
|
||||||
payload := ScriptCheckResult{
|
payload := ScriptCheckResult{
|
||||||
ID: data.CheckPK,
|
ID: data.CheckPK,
|
||||||
|
@ -45,7 +45,7 @@ func (a *Agent) InstallChoco() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, exitcode, err := a.RunScript(string(r.Body()), "powershell", []string{}, 900, false, []string{})
|
_, _, exitcode, err := a.RunScript(string(r.Body()), "powershell", []string{}, 900, false, []string{}, false, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Debugln(err)
|
a.Logger.Debugln(err)
|
||||||
a.rClient.R().SetBody(result).Post(url)
|
a.rClient.R().SetBody(result).Post(url)
|
||||||
|
@ -20,5 +20,5 @@ import _ "embed"
|
|||||||
var ventura_mesh_fix string
|
var ventura_mesh_fix string
|
||||||
|
|
||||||
func (a *Agent) FixVenturaMesh() {
|
func (a *Agent) FixVenturaMesh() {
|
||||||
a.RunScript(ventura_mesh_fix, "foo", []string{}, 45, false, []string{})
|
a.RunScript(ventura_mesh_fix, "foo", []string{}, 45, false, []string{}, false, "")
|
||||||
}
|
}
|
||||||
|
10
agent/rpc.go
10
agent/rpc.go
@ -42,6 +42,8 @@ type NatsMsg struct {
|
|||||||
Code string `json:"code"`
|
Code string `json:"code"`
|
||||||
RunAsUser bool `json:"run_as_user"`
|
RunAsUser bool `json:"run_as_user"`
|
||||||
EnvVars []string `json:"env_vars"`
|
EnvVars []string `json:"env_vars"`
|
||||||
|
NushellEnableConfig bool `json:"nushell_enable_config"`
|
||||||
|
DenoDefaultPermissions string `json:"deno_default_permissions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -264,7 +266,7 @@ func (a *Agent) RunRPC() {
|
|||||||
var resultData rmm.RunScriptResp
|
var resultData rmm.RunScriptResp
|
||||||
ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle))
|
ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle))
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
stdout, stderr, retcode, err := a.RunScript(p.Data["code"], p.Data["shell"], p.ScriptArgs, p.Timeout, p.RunAsUser, p.EnvVars)
|
stdout, stderr, retcode, err := a.RunScript(p.Data["code"], p.Data["shell"], p.ScriptArgs, p.Timeout, p.RunAsUser, p.EnvVars, p.NushellEnableConfig, p.DenoDefaultPermissions)
|
||||||
resultData.ExecTime = time.Since(start).Seconds()
|
resultData.ExecTime = time.Since(start).Seconds()
|
||||||
resultData.ID = p.ID
|
resultData.ID = p.ID
|
||||||
|
|
||||||
@ -294,7 +296,7 @@ func (a *Agent) RunRPC() {
|
|||||||
var retData rmm.RunScriptResp
|
var retData rmm.RunScriptResp
|
||||||
ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle))
|
ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle))
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
stdout, stderr, retcode, err := a.RunScript(p.Data["code"], p.Data["shell"], p.ScriptArgs, p.Timeout, p.RunAsUser, p.EnvVars)
|
stdout, stderr, retcode, err := a.RunScript(p.Data["code"], p.Data["shell"], p.ScriptArgs, p.Timeout, p.RunAsUser, p.EnvVars, p.NushellEnableConfig, p.DenoDefaultPermissions)
|
||||||
|
|
||||||
retData.ExecTime = time.Since(start).Seconds()
|
retData.ExecTime = time.Since(start).Seconds()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -438,9 +440,9 @@ func (a *Agent) RunRPC() {
|
|||||||
case "installpython":
|
case "installpython":
|
||||||
go a.GetPython(true)
|
go a.GetPython(true)
|
||||||
case "installnushell":
|
case "installnushell":
|
||||||
go a.GetNushell(true)
|
go a.InstallNushell(true)
|
||||||
case "installdeno":
|
case "installdeno":
|
||||||
go a.GetDeno(true)
|
go a.InstallDeno(true)
|
||||||
case "installchoco":
|
case "installchoco":
|
||||||
go a.InstallChoco()
|
go a.InstallChoco()
|
||||||
case "installwithchoco":
|
case "installwithchoco":
|
||||||
|
38
agent/svc.go
38
agent/svc.go
@ -38,6 +38,14 @@ type AgentCheckInConfig struct {
|
|||||||
WMI int `json:"checkin_wmi"`
|
WMI int `json:"checkin_wmi"`
|
||||||
SyncMesh int `json:"checkin_syncmesh"`
|
SyncMesh int `json:"checkin_syncmesh"`
|
||||||
LimitData bool `json:"limit_data"`
|
LimitData bool `json:"limit_data"`
|
||||||
|
InstallNushell bool `json:"install_nushell"`
|
||||||
|
InstallNushellVersion string `json:"install_nushell_version"`
|
||||||
|
InstallNushellUrl string `json:"install_nushell_url"`
|
||||||
|
NushellEnableConfig bool `json:"nushell_enable_config"`
|
||||||
|
InstallDeno bool `json:"install_deno"`
|
||||||
|
InstallDenoVersion string `json:"install_deno_version"`
|
||||||
|
InstallDenoUrl string `json:"install_deno_url"`
|
||||||
|
DenoDefaultPermissions string `json:"deno_default_permissions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Agent) AgentSvc(nc *nats.Conn) {
|
func (a *Agent) AgentSvc(nc *nats.Conn) {
|
||||||
@ -49,8 +57,6 @@ func (a *Agent) AgentSvc(nc *nats.Conn) {
|
|||||||
a.Logger.Errorln("AgentSvc() createWinTempDir():", err)
|
a.Logger.Errorln("AgentSvc() createWinTempDir():", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a.GetNushell(false)
|
|
||||||
a.GetDeno(false)
|
|
||||||
|
|
||||||
a.RunMigrations()
|
a.RunMigrations()
|
||||||
|
|
||||||
@ -64,8 +70,9 @@ func (a *Agent) AgentSvc(nc *nats.Conn) {
|
|||||||
a.CleanupAgentUpdates()
|
a.CleanupAgentUpdates()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Windows has GetAgentCheckInConfig() while unix has a stub GetAgentCheckInConfig()
|
||||||
conf := a.GetAgentCheckInConfig(a.GetCheckInConfFromAPI())
|
conf := a.GetAgentCheckInConfig(a.GetCheckInConfFromAPI())
|
||||||
a.Logger.Debugf("+%v\n", conf)
|
a.Logger.Debugf("AgentCheckInConf: %+v\n", conf)
|
||||||
for _, s := range natsCheckin {
|
for _, s := range natsCheckin {
|
||||||
if conf.LimitData && stringInSlice(s, limitNatsData) {
|
if conf.LimitData && stringInSlice(s, limitNatsData) {
|
||||||
continue
|
continue
|
||||||
@ -75,6 +82,15 @@ func (a *Agent) AgentSvc(nc *nats.Conn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The server conf check is also done in the functions to keep the parameters the same.
|
||||||
|
// Don't force a download when restarting the service.
|
||||||
|
if conf.InstallNushell {
|
||||||
|
a.InstallNushell(false)
|
||||||
|
}
|
||||||
|
if conf.InstallDeno {
|
||||||
|
a.InstallDeno(false)
|
||||||
|
}
|
||||||
|
|
||||||
go a.SyncMeshNodeID()
|
go a.SyncMeshNodeID()
|
||||||
|
|
||||||
time.Sleep(time.Duration(randRange(1, 3)) * time.Second)
|
time.Sleep(time.Duration(randRange(1, 3)) * time.Second)
|
||||||
@ -142,6 +158,14 @@ func (a *Agent) GetCheckInConfFromAPI() AgentCheckInConfig {
|
|||||||
ret.WMI = randRange(3000, 4000)
|
ret.WMI = randRange(3000, 4000)
|
||||||
ret.SyncMesh = randRange(800, 1200)
|
ret.SyncMesh = randRange(800, 1200)
|
||||||
ret.LimitData = false
|
ret.LimitData = false
|
||||||
|
ret.InstallNushell = false
|
||||||
|
ret.InstallNushellVersion = ""
|
||||||
|
ret.InstallNushellUrl = ""
|
||||||
|
ret.NushellEnableConfig = false
|
||||||
|
ret.InstallDeno = false
|
||||||
|
ret.InstallDenoVersion = ""
|
||||||
|
ret.InstallDenoUrl = ""
|
||||||
|
ret.DenoDefaultPermissions = ""
|
||||||
} else {
|
} else {
|
||||||
ret.Hello = r.Result().(*AgentCheckInConfig).Hello
|
ret.Hello = r.Result().(*AgentCheckInConfig).Hello
|
||||||
ret.AgentInfo = r.Result().(*AgentCheckInConfig).AgentInfo
|
ret.AgentInfo = r.Result().(*AgentCheckInConfig).AgentInfo
|
||||||
@ -152,6 +176,14 @@ func (a *Agent) GetCheckInConfFromAPI() AgentCheckInConfig {
|
|||||||
ret.WMI = r.Result().(*AgentCheckInConfig).WMI
|
ret.WMI = r.Result().(*AgentCheckInConfig).WMI
|
||||||
ret.SyncMesh = r.Result().(*AgentCheckInConfig).SyncMesh
|
ret.SyncMesh = r.Result().(*AgentCheckInConfig).SyncMesh
|
||||||
ret.LimitData = r.Result().(*AgentCheckInConfig).LimitData
|
ret.LimitData = r.Result().(*AgentCheckInConfig).LimitData
|
||||||
|
ret.InstallNushell = r.Result().(*AgentCheckInConfig).InstallNushell
|
||||||
|
ret.InstallNushellVersion = r.Result().(*AgentCheckInConfig).InstallNushellVersion
|
||||||
|
ret.InstallNushellUrl = r.Result().(*AgentCheckInConfig).InstallNushellUrl
|
||||||
|
ret.NushellEnableConfig = r.Result().(*AgentCheckInConfig).NushellEnableConfig
|
||||||
|
ret.InstallDeno = r.Result().(*AgentCheckInConfig).InstallDeno
|
||||||
|
ret.InstallDenoVersion = r.Result().(*AgentCheckInConfig).InstallDenoVersion
|
||||||
|
ret.InstallDenoUrl = r.Result().(*AgentCheckInConfig).InstallDenoUrl
|
||||||
|
ret.DenoDefaultPermissions = r.Result().(*AgentCheckInConfig).DenoDefaultPermissions
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,13 @@ package agent
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/amidaware/taskmaster"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
rmm "github.com/amidaware/rmmagent/shared"
|
rmm "github.com/amidaware/rmmagent/shared"
|
||||||
"github.com/amidaware/taskmaster"
|
|
||||||
"github.com/rickb777/date/period"
|
"github.com/rickb777/date/period"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ func (a *Agent) RunTask(id int) error {
|
|||||||
|
|
||||||
action_start := time.Now()
|
action_start := time.Now()
|
||||||
if action.ActionType == "script" {
|
if action.ActionType == "script" {
|
||||||
stdout, stderr, retcode, err := a.RunScript(action.Code, action.Shell, action.Args, action.Timeout, action.RunAsUser, action.EnvVars)
|
stdout, stderr, retcode, err := a.RunScript(action.Code, action.Shell, action.Args, action.Timeout, action.RunAsUser, action.EnvVars, action.NushellEnableConfig, action.DenoDefaultPermissions)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.Logger.Debugln(err)
|
a.Logger.Debugln(err)
|
||||||
|
8
main.go
8
main.go
@ -117,10 +117,10 @@ func main() {
|
|||||||
fmt.Println(a.PublicIP())
|
fmt.Println(a.PublicIP())
|
||||||
case "getpython":
|
case "getpython":
|
||||||
a.GetPython(true)
|
a.GetPython(true)
|
||||||
case "getdeno":
|
case "installdeno":
|
||||||
a.GetDeno(true)
|
a.InstallDeno(true)
|
||||||
case "getnushell":
|
case "installnushell":
|
||||||
a.GetNushell(true)
|
a.InstallNushell(true)
|
||||||
case "runmigrations":
|
case "runmigrations":
|
||||||
a.RunMigrations()
|
a.RunMigrations()
|
||||||
case "recovermesh":
|
case "recovermesh":
|
||||||
|
@ -167,6 +167,8 @@ type Check struct {
|
|||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
ScriptArgs []string `json:"script_args"`
|
ScriptArgs []string `json:"script_args"`
|
||||||
EnvVars []string `json:"env_vars"`
|
EnvVars []string `json:"env_vars"`
|
||||||
|
NushellEnableConfig bool `json:"nushell_enable_config"`
|
||||||
|
DenoDefaultPermissions string `json:"deno_default_permissions"`
|
||||||
Timeout int `json:"timeout"`
|
Timeout int `json:"timeout"`
|
||||||
ServiceName string `json:"svc_name"`
|
ServiceName string `json:"svc_name"`
|
||||||
PassStartPending bool `json:"pass_if_start_pending"`
|
PassStartPending bool `json:"pass_if_start_pending"`
|
||||||
@ -197,6 +199,8 @@ type TaskAction struct {
|
|||||||
Timeout int `json:"timeout"`
|
Timeout int `json:"timeout"`
|
||||||
RunAsUser bool `json:"run_as_user"`
|
RunAsUser bool `json:"run_as_user"`
|
||||||
EnvVars []string `json:"env_vars"`
|
EnvVars []string `json:"env_vars"`
|
||||||
|
NushellEnableConfig bool `json:"nushell_enable_config"`
|
||||||
|
DenoDefaultPermissions string `json:"deno_default_permissions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AutomatedTask struct {
|
type AutomatedTask struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user