refactor goinstaller to prepare for code signing

This commit is contained in:
wh1te909 2021-03-30 20:52:03 +00:00
parent 9af5c9ead9
commit 258261dc64
19 changed files with 79 additions and 514 deletions

View File

@ -1,7 +1,6 @@
FROM python:3.9.2-slim
ENV TACTICAL_DIR /opt/tactical
ENV TACTICAL_GO_DIR /usr/local/rmmgo
ENV TACTICAL_READY_FILE ${TACTICAL_DIR}/tmp/tactical.ready
ENV WORKSPACE_DIR /workspace
ENV TACTICAL_USER tactical
@ -14,9 +13,6 @@ EXPOSE 8000
RUN groupadd -g 1000 tactical && \
useradd -u 1000 -g 1000 tactical
# Copy Go Files
COPY --from=golang:1.16 /usr/local/go ${TACTICAL_GO_DIR}/go
# Copy Dev python reqs
COPY ./requirements.txt /

View File

@ -150,9 +150,6 @@ EOF
fi
if [ "$1" = 'tactical-api' ]; then
cp "${WORKSPACE_DIR}"/api/tacticalrmm/core/goinstaller/bin/goversioninfo /usr/local/bin/goversioninfo
chmod +x /usr/local/bin/goversioninfo
check_tactical_ready
"${VIRTUAL_ENV}"/bin/python manage.py runserver 0.0.0.0:"${API_PORT}"
fi

View File

@ -363,8 +363,7 @@ class TestAgentViews(TacticalTestCase):
self.check_not_authenticated("patch", url)
@patch("os.path.exists")
@patch("subprocess.run")
def test_install_agent(self, mock_subprocess, mock_file_exists):
def test_install_agent(self, mock_file_exists):
url = f"/agents/installagent/"
site = baker.make("clients.Site")
@ -382,29 +381,20 @@ class TestAgentViews(TacticalTestCase):
}
mock_file_exists.return_value = False
mock_subprocess.return_value.returncode = 0
r = self.client.post(url, data, format="json")
self.assertEqual(r.status_code, 406)
mock_file_exists.return_value = True
mock_subprocess.return_value.returncode = 1
r = self.client.post(url, data, format="json")
self.assertEqual(r.status_code, 413)
mock_file_exists.return_value = True
mock_subprocess.return_value.returncode = 0
r = self.client.post(url, data, format="json")
self.assertEqual(r.status_code, 200)
data["arch"] = "32"
mock_subprocess.return_value.returncode = 0
mock_file_exists.return_value = False
r = self.client.post(url, data, format="json")
self.assertEqual(r.status_code, 415)
data["installMethod"] = "manual"
data["arch"] = "64"
mock_subprocess.return_value.returncode = 0
mock_file_exists.return_value = True
r = self.client.post(url, data, format="json")
self.assertIn("rdp", r.json()["cmd"])

View File

@ -14,12 +14,11 @@ from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.views import APIView
from core.models import CoreSettings, CustomField
from core.models import CoreSettings
from logs.models import AuditLog, PendingAction
from scripts.models import Script
from scripts.tasks import handle_bulk_command_task, handle_bulk_script_task
from tacticalrmm.utils import (
generate_installer_exe,
get_default_timezone,
notify_error,
reload_nats,
@ -381,26 +380,21 @@ def install_agent(request):
f"winagent-v{version}.exe" if arch == "64" else f"winagent-v{version}-x86.exe"
)
download_url = settings.DL_64 if arch == "64" else settings.DL_32
goarch = "amd64" if arch == "64" else "386"
_, token = AuthToken.objects.create(
user=request.user, expiry=dt.timedelta(hours=request.data["expires"])
)
if request.data["installMethod"] == "exe":
return generate_installer_exe(
file_name="rmm-installer.exe",
goarch="amd64" if arch == "64" else "386",
inno=inno,
api=request.data["api"],
client_id=client_id,
site_id=site_id,
atype=request.data["agenttype"],
rdp=request.data["rdp"],
ping=request.data["ping"],
power=request.data["power"],
download_url=download_url,
token=token,
)
ret = {
"token": token,
"url": download_url,
"inno": inno,
"goarch": goarch,
"genurl": settings.EXE_GEN_URL,
}
return Response(ret)
elif request.data["installMethod"] == "manual":
cmd = [

View File

@ -11,8 +11,8 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from agents.models import Agent
from core.models import CoreSettings, CustomField
from tacticalrmm.utils import generate_installer_exe, notify_error
from core.models import CoreSettings
from tacticalrmm.utils import notify_error
from .models import Client, ClientCustomField, Deployment, Site, SiteCustomField
from .serializers import (
@ -278,6 +278,10 @@ class GenerateAgent(APIView):
permission_classes = (AllowAny,)
def get(self, request, uid):
import requests
import tempfile
from django.http import FileResponse
try:
_ = uuid.UUID(uid, version=4)
except ValueError:
@ -295,18 +299,36 @@ class GenerateAgent(APIView):
client = re.sub(r"([^a-zA-Z0-9]+)", "", client)
site = re.sub(r"([^a-zA-Z0-9]+)", "", site)
ext = ".exe" if d.arch == "64" else "-x86.exe"
file_name = f"rmm-{client}-{site}-{d.mon_type}{ext}"
return generate_installer_exe(
file_name=f"rmm-{client}-{site}-{d.mon_type}{ext}",
goarch="amd64" if d.arch == "64" else "386",
inno=inno,
api=f"https://{request.get_host()}",
client_id=d.client.pk,
site_id=d.site.pk,
atype=d.mon_type,
rdp=d.install_flags["rdp"],
ping=d.install_flags["ping"],
power=d.install_flags["power"],
download_url=settings.DL_64 if d.arch == "64" else settings.DL_32,
token=d.token_key,
)
data = {
"client": d.client.pk,
"site": d.site.pk,
"agenttype": d.mon_type,
"rdp": str(d.install_flags["rdp"]),
"ping": str(d.install_flags["ping"]),
"power": str(d.install_flags["power"]),
"goarch": "amd64" if d.arch == "64" else "386",
"token": d.token_key,
"inno": inno,
"url": settings.DL_64 if d.arch == "64" else settings.DL_32,
"api": f"https://{request.get_host()}",
}
headers = {"Content-type": "application/json"}
with tempfile.NamedTemporaryFile() as fp:
r = requests.post(
settings.EXE_GEN_URL,
json=data,
headers=headers,
stream=True,
)
with open(fp.name, "wb") as f:
for chunk in r.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
del r
response = FileResponse(
open(fp.name, "rb"), as_attachment=True, filename=file_name
)
return response

View File

@ -1,5 +0,0 @@
module github.com/wh1te909/goinstaller
go 1.16
require github.com/josephspurrier/goversioninfo v1.2.0 // indirect

View File

@ -1,10 +0,0 @@
github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw=
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/josephspurrier/goversioninfo v1.2.0 h1:tpLHXAxLHKHg/dCU2AAYx08A4m+v9/CWg6+WUvTF4uQ=
github.com/josephspurrier/goversioninfo v1.2.0/go.mod h1:AGP2a+Y/OVJZ+s6XM4IwFUpkETwvn0orYurY8qpw1+0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="TacticalRMMInstaller"
version="1.0.0.0"
processorArchitecture="*"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

View File

@ -1,186 +0,0 @@
//go:generate goversioninfo -icon=onit.ico -manifest=goversioninfo.exe.manifest -gofile=versioninfo.go
package main
import (
"bufio"
"flag"
"fmt"
"io"
"net"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
)
var (
Inno string
Api string
Client string
Site string
Atype string
Power string
Rdp string
Ping string
Token string
DownloadUrl string
)
var netTransport = &http.Transport{
Dial: (&net.Dialer{
Timeout: 5 * time.Second,
}).Dial,
TLSHandshakeTimeout: 5 * time.Second,
}
var netClient = &http.Client{
Timeout: time.Second * 900,
Transport: netTransport,
}
func downloadAgent(filepath string) (err error) {
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
resp, err := netClient.Get(DownloadUrl)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("Bad response: %s", resp.Status)
}
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}
func main() {
debugLog := flag.String("log", "", "Verbose output")
localMesh := flag.String("local-mesh", "", "Use local mesh agent")
silent := flag.Bool("silent", false, "Do not popup any message boxes during installation")
cert := flag.String("cert", "", "Path to ca.pem")
flag.Parse()
var debug bool = false
if strings.TrimSpace(strings.ToLower(*debugLog)) == "debug" {
debug = true
}
agentBinary := filepath.Join(os.Getenv("windir"), "Temp", Inno)
tacrmm := filepath.Join(os.Getenv("PROGRAMFILES"), "TacticalAgent", "tacticalrmm.exe")
cmdArgs := []string{
"-m", "install", "--api", Api, "--client-id",
Client, "--site-id", Site, "--agent-type", Atype,
"--auth", Token,
}
if debug {
cmdArgs = append(cmdArgs, "-log", "debug")
}
if *silent {
cmdArgs = append(cmdArgs, "-silent")
}
if len(strings.TrimSpace(*localMesh)) != 0 {
cmdArgs = append(cmdArgs, "-local-mesh", *localMesh)
}
if len(strings.TrimSpace(*cert)) != 0 {
cmdArgs = append(cmdArgs, "-cert", *cert)
}
if Rdp == "1" {
cmdArgs = append(cmdArgs, "-rdp")
}
if Ping == "1" {
cmdArgs = append(cmdArgs, "-ping")
}
if Power == "1" {
cmdArgs = append(cmdArgs, "-power")
}
if debug {
fmt.Println("Installer:", agentBinary)
fmt.Println("Tactical Agent:", tacrmm)
fmt.Println("Download URL:", DownloadUrl)
fmt.Println("Install command:", tacrmm, strings.Join(cmdArgs, " "))
}
fmt.Println("Downloading agent...")
dl := downloadAgent(agentBinary)
if dl != nil {
fmt.Println("ERROR: unable to download agent from", DownloadUrl)
fmt.Println(dl)
os.Exit(1)
}
defer os.Remove(agentBinary)
fmt.Println("Extracting files...")
winagentCmd := exec.Command(agentBinary, "/VERYSILENT", "/SUPPRESSMSGBOXES")
err := winagentCmd.Run()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
time.Sleep(5 * time.Second)
fmt.Println("Installation starting.")
cmd := exec.Command(tacrmm, cmdArgs...)
cmdReader, err := cmd.StdoutPipe()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
cmdErrReader, oerr := cmd.StderrPipe()
if oerr != nil {
fmt.Fprintln(os.Stderr, oerr)
return
}
scanner := bufio.NewScanner(cmdReader)
escanner := bufio.NewScanner(cmdErrReader)
go func() {
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}()
go func() {
for escanner.Scan() {
fmt.Println(escanner.Text())
}
}()
err = cmd.Start()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
err = cmd.Wait()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

View File

@ -1,43 +0,0 @@
{
"FixedFileInfo": {
"FileVersion": {
"Major": 1,
"Minor": 0,
"Patch": 0,
"Build": 0
},
"ProductVersion": {
"Major": 1,
"Minor": 0,
"Patch": 0,
"Build": 0
},
"FileFlagsMask": "3f",
"FileFlags ": "00",
"FileOS": "040004",
"FileType": "01",
"FileSubType": "00"
},
"StringFileInfo": {
"Comments": "",
"CompanyName": "Tactical Techs",
"FileDescription": "Tactical RMM Installer",
"FileVersion": "v1.0.0.0",
"InternalName": "rmm.exe",
"LegalCopyright": "Copyright (c) 2020 Tactical Techs",
"LegalTrademarks": "",
"OriginalFilename": "installer.go",
"PrivateBuild": "",
"ProductName": "Tactical RMM Installer",
"ProductVersion": "v1.0.0.0",
"SpecialBuild": ""
},
"VarFileInfo": {
"Translation": {
"LangID": "0409",
"CharsetID": "04B0"
}
},
"IconPath": "",
"ManifestPath": ""
}

View File

@ -33,6 +33,8 @@ NPM_VER = "11"
DL_64 = f"https://github.com/wh1te909/rmmagent/releases/download/v{LATEST_AGENT_VER}/winagent-v{LATEST_AGENT_VER}.exe"
DL_32 = f"https://github.com/wh1te909/rmmagent/releases/download/v{LATEST_AGENT_VER}/winagent-v{LATEST_AGENT_VER}-x86.exe"
EXE_GEN_URL = "https://exe.tacticalrmm.io/api/v1/exe"
try:
from .local_settings import *
except ImportError:

View File

@ -3,11 +3,9 @@ import os
import string
import subprocess
import time
from typing import Union
import pytz
from django.conf import settings
from django.http import HttpResponse
from loguru import logger
from rest_framework import status
from rest_framework.response import Response
@ -31,130 +29,6 @@ WEEK_DAYS = {
}
def generate_installer_exe(
file_name: str,
goarch: str,
inno: str,
api: str,
client_id: int,
site_id: int,
atype: str,
rdp: int,
ping: int,
power: int,
download_url: str,
token: str,
) -> Union[Response, HttpResponse]:
go_bin = "/usr/local/rmmgo/go/bin/go"
if not os.path.exists(go_bin):
return Response("nogolang", status=status.HTTP_409_CONFLICT)
exe = os.path.join(settings.EXE_DIR, file_name)
if os.path.exists(exe):
try:
os.remove(exe)
except Exception as e:
logger.error(str(e))
cmd = [
"env",
"CGO_ENABLED=0",
"GOOS=windows",
f"GOARCH={goarch}",
go_bin,
"build",
f"-ldflags=\"-s -w -X 'main.Inno={inno}'",
f"-X 'main.Api={api}'",
f"-X 'main.Client={client_id}'",
f"-X 'main.Site={site_id}'",
f"-X 'main.Atype={atype}'",
f"-X 'main.Rdp={rdp}'",
f"-X 'main.Ping={ping}'",
f"-X 'main.Power={power}'",
f"-X 'main.DownloadUrl={download_url}'",
f"-X 'main.Token={token}'\"",
"-o",
exe,
]
build_error = False
gen_error = False
gen = [
"env",
"GOOS=windows",
"CGO_ENABLED=0",
f"GOARCH={goarch}",
go_bin,
"generate",
]
try:
r1 = subprocess.run(
" ".join(gen),
capture_output=True,
shell=True,
cwd=os.path.join(settings.BASE_DIR, "core/goinstaller"),
)
except Exception as e:
gen_error = True
logger.error(str(e))
return Response("genfailed", status=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE)
if r1.returncode != 0:
gen_error = True
if r1.stdout:
logger.error(r1.stdout.decode("utf-8", errors="ignore"))
if r1.stderr:
logger.error(r1.stderr.decode("utf-8", errors="ignore"))
logger.error(f"Go build failed with return code {r1.returncode}")
if gen_error:
return Response("genfailed", status=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE)
try:
r = subprocess.run(
" ".join(cmd),
capture_output=True,
shell=True,
cwd=os.path.join(settings.BASE_DIR, "core/goinstaller"),
)
except Exception as e:
build_error = True
logger.error(str(e))
return Response("buildfailed", status=status.HTTP_412_PRECONDITION_FAILED)
if r.returncode != 0:
build_error = True
if r.stdout:
logger.error(r.stdout.decode("utf-8", errors="ignore"))
if r.stderr:
logger.error(r.stderr.decode("utf-8", errors="ignore"))
logger.error(f"Go build failed with return code {r.returncode}")
if build_error:
return Response("buildfailed", status=status.HTTP_412_PRECONDITION_FAILED)
if settings.DEBUG:
with open(exe, "rb") as f:
response = HttpResponse(
f.read(),
content_type="application/vnd.microsoft.portable-executable",
)
response["Content-Disposition"] = f"inline; filename={file_name}"
return response
else:
response = HttpResponse()
response["Content-Disposition"] = f"attachment; filename={file_name}"
response["X-Accel-Redirect"] = f"/private/exe/{file_name}"
return response
def get_default_timezone():
from core.models import CoreSettings

View File

@ -30,17 +30,15 @@ FROM python:3.9.2-slim
ENV VIRTUAL_ENV /opt/venv
ENV TACTICAL_DIR /opt/tactical
ENV TACTICAL_TMP_DIR /tmp/tactical
ENV TACTICAL_GO_DIR /usr/local/rmmgo
ENV TACTICAL_READY_FILE ${TACTICAL_DIR}/tmp/tactical.ready
ENV TACTICAL_USER tactical
ENV PATH "${VIRTUAL_ENV}/bin:${TACTICAL_GO_DIR}/go/bin:$PATH"
ENV PATH "${VIRTUAL_ENV}/bin:$PATH"
# copy files from repo
COPY api/tacticalrmm ${TACTICAL_TMP_DIR}/api
COPY scripts ${TACTICAL_TMP_DIR}/scripts
# copy go install from build stage
COPY --from=golang:1.16 /usr/local/go ${TACTICAL_GO_DIR}/go
COPY --from=CREATE_VENV_STAGE ${VIRTUAL_ENV} ${VIRTUAL_ENV}
# install deps
@ -48,16 +46,11 @@ RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends git rsync && \
rm -rf /var/lib/apt/lists/* && \
go get github.com/josephspurrier/goversioninfo/cmd/goversioninfo && \
groupadd -g 1000 "${TACTICAL_USER}" && \
useradd -M -d "${TACTICAL_DIR}" -s /bin/bash -u 1000 -g 1000 "${TACTICAL_USER}"
SHELL ["/bin/bash", "-e", "-o", "pipefail", "-c"]
# overwrite goversioninfo file
COPY api/tacticalrmm/core/goinstaller/bin/goversioninfo /usr/local/bin/goversioninfo
RUN chmod +x /usr/local/bin/goversioninfo
# copy nats-api file
COPY natsapi/bin/nats-api /usr/local/bin/
RUN chmod +x /usr/local/bin/nats-api

View File

@ -181,17 +181,6 @@ CERT_PUB_KEY=/etc/letsencrypt/live/${rootdomain}/fullchain.pem
sudo chown ${USER}:${USER} -R /etc/letsencrypt
sudo chmod 775 -R /etc/letsencrypt
print_green 'Installing golang'
sudo mkdir -p /usr/local/rmmgo
go_tmp=$(mktemp -d -t rmmgo-XXXXXXXXXX)
wget https://golang.org/dl/go1.16.2.linux-amd64.tar.gz -P ${go_tmp}
tar -xzf ${go_tmp}/go1.16.2.linux-amd64.tar.gz -C ${go_tmp}
sudo mv ${go_tmp}/go /usr/local/rmmgo/
rm -rf ${go_tmp}
print_green 'Downloading NATS'
nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX)
@ -376,11 +365,6 @@ EOF
)"
echo "${localvars}" > /rmm/api/tacticalrmm/tacticalrmm/local_settings.py
/usr/local/rmmgo/go/bin/go get github.com/josephspurrier/goversioninfo/cmd/goversioninfo
sudo cp /rmm/api/tacticalrmm/core/goinstaller/bin/goversioninfo /usr/local/bin/
sudo chown ${USER}:${USER} /usr/local/bin/goversioninfo
sudo chmod +x /usr/local/bin/goversioninfo
sudo cp /rmm/natsapi/bin/nats-api /usr/local/bin
sudo chown ${USER}:${USER} /usr/local/bin/nats-api
sudo chmod +x /usr/local/bin/nats-api

View File

@ -103,17 +103,7 @@ fi
# prevents logging issues with some VPS providers like Vultr if this is a freshly provisioned instance that hasn't been rebooted yet
sudo systemctl restart systemd-journald.service
print_green 'Installing golang'
sudo apt update
sudo mkdir -p /usr/local/rmmgo
go_tmp=$(mktemp -d -t rmmgo-XXXXXXXXXX)
wget https://golang.org/dl/go1.16.2.linux-amd64.tar.gz -P ${go_tmp}
tar -xzf ${go_tmp}/go1.16.2.linux-amd64.tar.gz -C ${go_tmp}
sudo mv ${go_tmp}/go /usr/local/rmmgo/
rm -rf ${go_tmp}
print_green 'Downloading NATS'
@ -276,11 +266,6 @@ gzip -d $tmp_dir/rmm/debug.log.gz
cp $tmp_dir/rmm/debug.log /rmm/api/tacticalrmm/tacticalrmm/private/log/
cp $tmp_dir/rmm/mesh*.exe /rmm/api/tacticalrmm/tacticalrmm/private/exe/
/usr/local/rmmgo/go/bin/go get github.com/josephspurrier/goversioninfo/cmd/goversioninfo
sudo cp /rmm/api/tacticalrmm/core/goinstaller/bin/goversioninfo /usr/local/bin/
sudo chown ${USER}:${USER} /usr/local/bin/goversioninfo
sudo chmod +x /usr/local/bin/goversioninfo
sudo cp /rmm/natsapi/bin/nats-api /usr/local/bin
sudo chown ${USER}:${USER} /usr/local/bin/nats-api
sudo chmod +x /usr/local/bin/nats-api

View File

@ -121,20 +121,6 @@ if ! [[ $CHECK_NGINX_WORKER_CONN ]]; then
sudo sed -i 's/worker_connections.*/worker_connections 2048;/g' /etc/nginx/nginx.conf
fi
CHECK_HAS_GO116=$(/usr/local/rmmgo/go/bin/go version | grep go1.16.2)
if ! [[ $CHECK_HAS_GO116 ]]; then
printf >&2 "${GREEN}Updating golang to version 1.16.2${NC}\n"
sudo rm -rf /home/${USER}/go/
sudo rm -rf /usr/local/rmmgo/
sudo mkdir -p /usr/local/rmmgo
go_tmp=$(mktemp -d -t rmmgo-XXXXXXXXXX)
wget https://golang.org/dl/go1.16.2.linux-amd64.tar.gz -P ${go_tmp}
tar -xzf ${go_tmp}/go1.16.2.linux-amd64.tar.gz -C ${go_tmp}
sudo mv ${go_tmp}/go /usr/local/rmmgo/
rm -rf ${go_tmp}
sudo chown -R $USER:$GROUP /home/${USER}/.cache
fi
HAS_PY39=$(which python3.9)
if ! [[ $HAS_PY39 ]]; then
printf >&2 "${GREEN}Updating to Python 3.9${NC}\n"
@ -212,11 +198,6 @@ EOF
echo "${adminenabled}" | tee --append /rmm/api/tacticalrmm/tacticalrmm/local_settings.py > /dev/null
fi
/usr/local/rmmgo/go/bin/go get github.com/josephspurrier/goversioninfo/cmd/goversioninfo
sudo cp /rmm/api/tacticalrmm/core/goinstaller/bin/goversioninfo /usr/local/bin/
sudo chown ${USER}:${USER} /usr/local/bin/goversioninfo
sudo chmod +x /usr/local/bin/goversioninfo
sudo cp /rmm/natsapi/bin/nats-api /usr/local/bin
sudo chown ${USER}:${USER} /usr/local/bin/nats-api
sudo chmod +x /usr/local/bin/nats-api

View File

@ -189,29 +189,38 @@ export default {
this.arch === "64"
? `rmm-${clientStripped}-${siteStripped}-${this.agenttype}.exe`
: `rmm-${clientStripped}-${siteStripped}-${this.agenttype}-x86.exe`;
this.$axios
.post("/agents/installagent/", data, { responseType: "blob" })
.post("/agents/installagent/", data)
.then(r => {
this.$q.loading.hide();
const blob = new Blob([r.data], { type: "application/vnd.microsoft.portable-executable" });
let link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
this.showDLMessage();
const newData = {
client: this.client.value,
site: this.site.value,
agenttype: this.agenttype,
power: this.power ? "1" : "0",
rdp: this.rdp ? "1" : "0",
ping: this.ping ? "1" : "0",
goarch: r.data.goarch,
token: r.data.token,
inno: r.data.inno,
url: r.data.url,
api,
};
this.$axios.post(r.data.genurl, newData, { responseType: "blob" }).then(r => {
this.$q.loading.hide();
const blob = new Blob([r.data], { type: "application/vnd.microsoft.portable-executable" });
let link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
this.showDLMessage();
});
})
.catch(e => {
this.$q.loading.hide();
let err;
switch (e.response.status) {
case 409:
err = "Golang is not installed";
break;
case 412:
err = "Golang build failed. Check debug log for the error message";
break;
case 413:
err = "Golang generate failed. Check debug log for the error message";
break;
case 406:
err = "Missing 64 bit meshagent.exe. Upload it from File > Upload Mesh Agent";
break;
@ -219,9 +228,8 @@ export default {
err = "Missing 32 bit meshagent-x86.exe. Upload it from File > Upload Mesh Agent";
break;
default:
err = "Something went wrong";
err = e.response.data;
}
this.$q.loading.hide();
this.notifyError(err, 4000);
});
} else if (this.installMethod === "powershell") {