Release 0.15.0
This commit is contained in:
4
.github/FUNDING.yml
vendored
4
.github/FUNDING.yml
vendored
@@ -1,9 +1,9 @@
|
|||||||
# These are supported funding model platforms
|
# These are supported funding model platforms
|
||||||
|
|
||||||
github: wh1te909
|
github: amidaware
|
||||||
patreon: # Replace with a single Patreon username
|
patreon: # Replace with a single Patreon username
|
||||||
open_collective: # Replace with a single Open Collective username
|
open_collective: # Replace with a single Open Collective username
|
||||||
ko_fi: tacticalrmm
|
ko_fi: # tacticalrmm
|
||||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||||
liberapay: # Replace with a single Liberapay username
|
liberapay: # Replace with a single Liberapay username
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ Demo database resets every hour. A lot of features are disabled for obvious reas
|
|||||||
## Linux agent versions supported
|
## Linux agent versions supported
|
||||||
- Any distro with systemd which includes but is not limited to: Debian (10, 11), Ubuntu x86_64 (18.04, 20.04, 22.04), Synology 7, centos, freepbx and more!
|
- Any distro with systemd which includes but is not limited to: Debian (10, 11), Ubuntu x86_64 (18.04, 20.04, 22.04), Synology 7, centos, freepbx and more!
|
||||||
|
|
||||||
|
## Mac agent versions supported
|
||||||
|
- 64 bit Intel and Apple Silicon (M1, M2)
|
||||||
|
|
||||||
## Installation / Backup / Restore / Usage
|
## Installation / Backup / Restore / Usage
|
||||||
|
|
||||||
### Refer to the [documentation](https://docs.tacticalrmm.com)
|
### Refer to the [documentation](https://docs.tacticalrmm.com)
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ SECRET_KEY = "{{ django_secret }}"
|
|||||||
DEBUG = True
|
DEBUG = True
|
||||||
ALLOWED_HOSTS = ['{{ api }}']
|
ALLOWED_HOSTS = ['{{ api }}']
|
||||||
ADMIN_URL = "admin/"
|
ADMIN_URL = "admin/"
|
||||||
|
CORS_ORIGIN_WHITELIST = [
|
||||||
|
"http://{{ rmm }}:8080",
|
||||||
|
"https://{{ rmm }}:8080",
|
||||||
|
]
|
||||||
CORS_ORIGIN_ALLOW_ALL = True
|
CORS_ORIGIN_ALLOW_ALL = True
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
|
|||||||
@@ -835,9 +835,12 @@ class Agent(BaseAuditModel):
|
|||||||
Return type: tuple(message: str, error: bool)
|
Return type: tuple(message: str, error: bool)
|
||||||
"""
|
"""
|
||||||
if mode == "tacagent":
|
if mode == "tacagent":
|
||||||
if self.is_posix:
|
if self.plat == AgentPlat.LINUX:
|
||||||
cmd = "systemctl restart tacticalagent.service"
|
cmd = "systemctl restart tacticalagent.service"
|
||||||
shell = 3
|
shell = 3
|
||||||
|
elif self.plat == AgentPlat.DARWIN:
|
||||||
|
cmd = "launchctl kickstart -k system/tacticalagent"
|
||||||
|
shell = 3
|
||||||
else:
|
else:
|
||||||
cmd = "net stop tacticalrmm & taskkill /F /IM tacticalrmm.exe & net start tacticalrmm"
|
cmd = "net stop tacticalrmm & taskkill /F /IM tacticalrmm.exe & net start tacticalrmm"
|
||||||
shell = 1
|
shell = 1
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ from scripts.models import Script
|
|||||||
from scripts.tasks import handle_bulk_command_task, handle_bulk_script_task
|
from scripts.tasks import handle_bulk_command_task, handle_bulk_script_task
|
||||||
from tacticalrmm.constants import (
|
from tacticalrmm.constants import (
|
||||||
AGENT_DEFER,
|
AGENT_DEFER,
|
||||||
AGENT_TABLE_DEFER,
|
|
||||||
AGENT_STATUS_OFFLINE,
|
AGENT_STATUS_OFFLINE,
|
||||||
AGENT_STATUS_ONLINE,
|
AGENT_STATUS_ONLINE,
|
||||||
|
AGENT_TABLE_DEFER,
|
||||||
AgentHistoryType,
|
AgentHistoryType,
|
||||||
AgentMonType,
|
AgentMonType,
|
||||||
AgentPlat,
|
AgentPlat,
|
||||||
@@ -174,6 +174,7 @@ class GetUpdateDeleteAgent(APIView):
|
|||||||
fields = [
|
fields = [
|
||||||
"maintenance_mode", # TODO separate this
|
"maintenance_mode", # TODO separate this
|
||||||
"policy", # TODO separate this
|
"policy", # TODO separate this
|
||||||
|
"block_policy_inheritance", # TODO separate this
|
||||||
"monitoring_type",
|
"monitoring_type",
|
||||||
"description",
|
"description",
|
||||||
"overdue_email_alert",
|
"overdue_email_alert",
|
||||||
@@ -236,10 +237,13 @@ class GetUpdateDeleteAgent(APIView):
|
|||||||
def delete(self, request, agent_id):
|
def delete(self, request, agent_id):
|
||||||
agent = get_object_or_404(Agent, agent_id=agent_id)
|
agent = get_object_or_404(Agent, agent_id=agent_id)
|
||||||
|
|
||||||
code = "foo"
|
code = "foo" # stub for windows
|
||||||
if agent.plat == AgentPlat.LINUX:
|
if agent.plat == AgentPlat.LINUX:
|
||||||
with open(settings.LINUX_AGENT_SCRIPT, "r") as f:
|
with open(settings.LINUX_AGENT_SCRIPT, "r") as f:
|
||||||
code = f.read()
|
code = f.read()
|
||||||
|
elif agent.plat == AgentPlat.DARWIN:
|
||||||
|
with open(settings.MAC_UNINSTALL, "r") as f:
|
||||||
|
code = f.read()
|
||||||
|
|
||||||
asyncio.run(agent.nats_cmd({"func": "uninstall", "code": code}, wait=False))
|
asyncio.run(agent.nats_cmd({"func": "uninstall", "code": code}, wait=False))
|
||||||
name = agent.hostname
|
name = agent.hostname
|
||||||
@@ -550,7 +554,15 @@ def install_agent(request):
|
|||||||
|
|
||||||
codesign_token, is_valid = token_is_valid()
|
codesign_token, is_valid = token_is_valid()
|
||||||
|
|
||||||
inno = f"tacticalagent-v{version}-{plat}-{goarch}.exe"
|
if request.data["installMethod"] in {"bash", "mac"} and not is_valid:
|
||||||
|
return notify_error(
|
||||||
|
"Missing code signing token, or token is no longer valid. Please read the docs for more info."
|
||||||
|
)
|
||||||
|
|
||||||
|
inno = f"tacticalagent-v{version}-{plat}-{goarch}"
|
||||||
|
if plat == AgentPlat.WINDOWS:
|
||||||
|
inno += ".exe"
|
||||||
|
|
||||||
download_url = get_agent_url(goarch=goarch, plat=plat, token=codesign_token)
|
download_url = get_agent_url(goarch=goarch, plat=plat, token=codesign_token)
|
||||||
|
|
||||||
installer_user = User.objects.filter(is_installer_user=True).first()
|
installer_user = User.objects.filter(is_installer_user=True).first()
|
||||||
@@ -559,6 +571,21 @@ def install_agent(request):
|
|||||||
user=installer_user, expiry=dt.timedelta(hours=request.data["expires"])
|
user=installer_user, expiry=dt.timedelta(hours=request.data["expires"])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
install_flags = [
|
||||||
|
"-m",
|
||||||
|
"install",
|
||||||
|
"--api",
|
||||||
|
request.data["api"],
|
||||||
|
"--client-id",
|
||||||
|
client_id,
|
||||||
|
"--site-id",
|
||||||
|
site_id,
|
||||||
|
"--agent-type",
|
||||||
|
request.data["agenttype"],
|
||||||
|
"--auth",
|
||||||
|
token,
|
||||||
|
]
|
||||||
|
|
||||||
if request.data["installMethod"] == "exe":
|
if request.data["installMethod"] == "exe":
|
||||||
from tacticalrmm.utils import generate_winagent_exe
|
from tacticalrmm.utils import generate_winagent_exe
|
||||||
|
|
||||||
@@ -576,14 +603,6 @@ def install_agent(request):
|
|||||||
)
|
)
|
||||||
|
|
||||||
elif request.data["installMethod"] == "bash":
|
elif request.data["installMethod"] == "bash":
|
||||||
# TODO
|
|
||||||
# linux agents are in beta for now, only available for sponsors for testing
|
|
||||||
# remove this after it's out of beta
|
|
||||||
|
|
||||||
if not is_valid:
|
|
||||||
return notify_error(
|
|
||||||
"Missing code signing token, or token is no longer valid. Please read the docs for more info."
|
|
||||||
)
|
|
||||||
|
|
||||||
from agents.utils import generate_linux_install
|
from agents.utils import generate_linux_install
|
||||||
|
|
||||||
@@ -597,7 +616,9 @@ def install_agent(request):
|
|||||||
download_url=download_url,
|
download_url=download_url,
|
||||||
)
|
)
|
||||||
|
|
||||||
elif request.data["installMethod"] == "manual":
|
elif request.data["installMethod"] in {"manual", "mac"}:
|
||||||
|
resp = {}
|
||||||
|
if request.data["installMethod"] == "manual":
|
||||||
cmd = [
|
cmd = [
|
||||||
inno,
|
inno,
|
||||||
"/VERYSILENT",
|
"/VERYSILENT",
|
||||||
@@ -609,19 +630,7 @@ def install_agent(request):
|
|||||||
"5",
|
"5",
|
||||||
"&&",
|
"&&",
|
||||||
r'"C:\Program Files\TacticalAgent\tacticalrmm.exe"',
|
r'"C:\Program Files\TacticalAgent\tacticalrmm.exe"',
|
||||||
"-m",
|
] + install_flags
|
||||||
"install",
|
|
||||||
"--api",
|
|
||||||
request.data["api"],
|
|
||||||
"--client-id",
|
|
||||||
client_id,
|
|
||||||
"--site-id",
|
|
||||||
site_id,
|
|
||||||
"--agent-type",
|
|
||||||
request.data["agenttype"],
|
|
||||||
"--auth",
|
|
||||||
token,
|
|
||||||
]
|
|
||||||
|
|
||||||
if int(request.data["rdp"]):
|
if int(request.data["rdp"]):
|
||||||
cmd.append("--rdp")
|
cmd.append("--rdp")
|
||||||
@@ -630,10 +639,16 @@ def install_agent(request):
|
|||||||
if int(request.data["power"]):
|
if int(request.data["power"]):
|
||||||
cmd.append("--power")
|
cmd.append("--power")
|
||||||
|
|
||||||
resp = {
|
resp["cmd"] = " ".join(str(i) for i in cmd)
|
||||||
"cmd": " ".join(str(i) for i in cmd),
|
else:
|
||||||
"url": download_url,
|
install_flags.insert(0, f"sudo ./{inno}")
|
||||||
}
|
cmd = install_flags.copy()
|
||||||
|
dl = f"curl -L -o {inno} '{download_url}'"
|
||||||
|
resp["cmd"] = (
|
||||||
|
dl + f" && chmod +x {inno} && " + " ".join(str(i) for i in cmd)
|
||||||
|
)
|
||||||
|
|
||||||
|
resp["url"] = download_url
|
||||||
|
|
||||||
return Response(resp)
|
return Response(resp)
|
||||||
|
|
||||||
@@ -912,6 +927,8 @@ def bulk(request):
|
|||||||
q = q.filter(plat=AgentPlat.WINDOWS)
|
q = q.filter(plat=AgentPlat.WINDOWS)
|
||||||
elif request.data["osType"] == AgentPlat.LINUX:
|
elif request.data["osType"] == AgentPlat.LINUX:
|
||||||
q = q.filter(plat=AgentPlat.LINUX)
|
q = q.filter(plat=AgentPlat.LINUX)
|
||||||
|
elif request.data["osType"] == AgentPlat.DARWIN:
|
||||||
|
q = q.filter(plat=AgentPlat.DARWIN)
|
||||||
|
|
||||||
agents: list[int] = [agent.pk for agent in q]
|
agents: list[int] = [agent.pk for agent in q]
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from core.utils import (
|
|||||||
get_core_settings,
|
get_core_settings,
|
||||||
get_mesh_device_id,
|
get_mesh_device_id,
|
||||||
get_mesh_ws_url,
|
get_mesh_ws_url,
|
||||||
|
get_meshagent_url,
|
||||||
)
|
)
|
||||||
from logs.models import DebugLog, PendingAction
|
from logs.models import DebugLog, PendingAction
|
||||||
from software.models import InstalledSoftware
|
from software.models import InstalledSoftware
|
||||||
@@ -398,25 +399,32 @@ class MeshExe(APIView):
|
|||||||
def post(self, request):
|
def post(self, request):
|
||||||
match request.data:
|
match request.data:
|
||||||
case {"goarch": GoArch.AMD64, "plat": AgentPlat.WINDOWS}:
|
case {"goarch": GoArch.AMD64, "plat": AgentPlat.WINDOWS}:
|
||||||
arch = MeshAgentIdent.WIN64
|
ident = MeshAgentIdent.WIN64
|
||||||
case {"goarch": GoArch.i386, "plat": AgentPlat.WINDOWS}:
|
case {"goarch": GoArch.i386, "plat": AgentPlat.WINDOWS}:
|
||||||
arch = MeshAgentIdent.WIN32
|
ident = MeshAgentIdent.WIN32
|
||||||
|
case {"goarch": GoArch.AMD64, "plat": AgentPlat.DARWIN} | {
|
||||||
|
"goarch": GoArch.ARM64,
|
||||||
|
"plat": AgentPlat.DARWIN,
|
||||||
|
}:
|
||||||
|
ident = MeshAgentIdent.DARWIN_UNIVERSAL
|
||||||
case _:
|
case _:
|
||||||
return notify_error("Arch not specified")
|
return notify_error("Arch not supported")
|
||||||
|
|
||||||
core = get_core_settings()
|
core = get_core_settings()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
uri = get_mesh_ws_url()
|
uri = get_mesh_ws_url()
|
||||||
mesh_id = asyncio.run(get_mesh_device_id(uri, core.mesh_device_group))
|
mesh_device_id: str = asyncio.run(
|
||||||
|
get_mesh_device_id(uri, core.mesh_device_group)
|
||||||
|
)
|
||||||
except:
|
except:
|
||||||
return notify_error("Unable to connect to mesh to get group id information")
|
return notify_error("Unable to connect to mesh to get group id information")
|
||||||
|
|
||||||
if settings.DOCKER_BUILD:
|
dl_url = get_meshagent_url(
|
||||||
dl_url = f"{settings.MESH_WS_URL.replace('ws://', 'http://')}/meshagents?id={arch}&meshid={mesh_id}&installflags=0"
|
ident=ident,
|
||||||
else:
|
plat=request.data["plat"],
|
||||||
dl_url = (
|
mesh_site=core.mesh_site,
|
||||||
f"{core.mesh_site}/meshagents?id={arch}&meshid={mesh_id}&installflags=0"
|
mesh_device_id=mesh_device_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
8
api/tacticalrmm/core/mac_uninstall.sh
Executable file
8
api/tacticalrmm/core/mac_uninstall.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
/usr/local/mesh_services/meshagent/meshagent -fulluninstall
|
||||||
|
launchctl bootout system /Library/LaunchDaemons/tacticalagent.plist
|
||||||
|
rm -rf /usr/local/mesh_services
|
||||||
|
rm -f /etc/tacticalagent
|
||||||
|
rm -rf /opt/tacticalagent
|
||||||
|
rm -f /Library/LaunchDaemons/tacticalagent.plist
|
||||||
@@ -5,13 +5,20 @@ from channels.db import database_sync_to_async
|
|||||||
from channels.testing import WebsocketCommunicator
|
from channels.testing import WebsocketCommunicator
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
|
from django.test import override_settings
|
||||||
from model_bakery import baker
|
from model_bakery import baker
|
||||||
from rest_framework.authtoken.models import Token
|
from rest_framework.authtoken.models import Token
|
||||||
|
|
||||||
from agents.models import Agent
|
from agents.models import Agent
|
||||||
from core.utils import get_core_settings
|
from core.utils import get_core_settings, get_meshagent_url
|
||||||
from logs.models import PendingAction
|
from logs.models import PendingAction
|
||||||
from tacticalrmm.constants import CONFIG_MGMT_CMDS, CustomFieldModel, PAAction, PAStatus
|
from tacticalrmm.constants import (
|
||||||
|
CONFIG_MGMT_CMDS,
|
||||||
|
CustomFieldModel,
|
||||||
|
MeshAgentIdent,
|
||||||
|
PAAction,
|
||||||
|
PAStatus,
|
||||||
|
)
|
||||||
from tacticalrmm.test import TacticalTestCase
|
from tacticalrmm.test import TacticalTestCase
|
||||||
|
|
||||||
from .consumers import DashInfo
|
from .consumers import DashInfo
|
||||||
@@ -444,3 +451,58 @@ class TestCorePermissions(TacticalTestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.setup_client()
|
self.setup_client()
|
||||||
self.setup_coresettings()
|
self.setup_coresettings()
|
||||||
|
|
||||||
|
|
||||||
|
class TestCoreUtils(TacticalTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.setup_coresettings()
|
||||||
|
|
||||||
|
def test_get_meshagent_url_standard(self):
|
||||||
|
|
||||||
|
r = get_meshagent_url(
|
||||||
|
ident=MeshAgentIdent.DARWIN_UNIVERSAL,
|
||||||
|
plat="darwin",
|
||||||
|
mesh_site="https://mesh.example.com",
|
||||||
|
mesh_device_id="abc123",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
r,
|
||||||
|
"https://mesh.example.com/meshagents?id=abc123&installflags=2&meshinstall=10005",
|
||||||
|
)
|
||||||
|
|
||||||
|
r = get_meshagent_url(
|
||||||
|
ident=MeshAgentIdent.WIN64,
|
||||||
|
plat="windows",
|
||||||
|
mesh_site="https://mesh.example.com",
|
||||||
|
mesh_device_id="abc123",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
r,
|
||||||
|
"https://mesh.example.com/meshagents?id=4&meshid=abc123&installflags=0",
|
||||||
|
)
|
||||||
|
|
||||||
|
@override_settings(DOCKER_BUILD=True)
|
||||||
|
@override_settings(MESH_WS_URL="ws://tactical-meshcentral:4443")
|
||||||
|
def test_get_meshagent_url_docker(self):
|
||||||
|
|
||||||
|
r = get_meshagent_url(
|
||||||
|
ident=MeshAgentIdent.DARWIN_UNIVERSAL,
|
||||||
|
plat="darwin",
|
||||||
|
mesh_site="https://mesh.example.com",
|
||||||
|
mesh_device_id="abc123",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
r,
|
||||||
|
"http://tactical-meshcentral:4443/meshagents?id=abc123&installflags=2&meshinstall=10005",
|
||||||
|
)
|
||||||
|
|
||||||
|
r = get_meshagent_url(
|
||||||
|
ident=MeshAgentIdent.WIN64,
|
||||||
|
plat="windows",
|
||||||
|
mesh_site="https://mesh.example.com",
|
||||||
|
mesh_device_id="abc123",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
r,
|
||||||
|
"http://tactical-meshcentral:4443/meshagents?id=4&meshid=abc123&installflags=0",
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import urllib.parse
|
||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
from typing import TYPE_CHECKING, Optional, cast
|
from typing import TYPE_CHECKING, Optional, cast
|
||||||
|
|
||||||
@@ -11,7 +12,12 @@ from django.core.cache import cache
|
|||||||
from django.http import FileResponse
|
from django.http import FileResponse
|
||||||
from meshctrl.utils import get_auth_token
|
from meshctrl.utils import get_auth_token
|
||||||
|
|
||||||
from tacticalrmm.constants import CORESETTINGS_CACHE_KEY, ROLE_CACHE_PREFIX
|
from tacticalrmm.constants import (
|
||||||
|
CORESETTINGS_CACHE_KEY,
|
||||||
|
ROLE_CACHE_PREFIX,
|
||||||
|
AgentPlat,
|
||||||
|
MeshAgentIdent,
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from core.models import CodeSignToken, CoreSettings
|
from core.models import CodeSignToken, CoreSettings
|
||||||
@@ -142,3 +148,28 @@ def sysd_svc_is_running(svc: str) -> bool:
|
|||||||
cmd = ["systemctl", "is-active", "--quiet", svc]
|
cmd = ["systemctl", "is-active", "--quiet", svc]
|
||||||
r = subprocess.run(cmd, capture_output=True)
|
r = subprocess.run(cmd, capture_output=True)
|
||||||
return not r.returncode
|
return not r.returncode
|
||||||
|
|
||||||
|
|
||||||
|
def get_meshagent_url(
|
||||||
|
*, ident: "MeshAgentIdent", plat: str, mesh_site: str, mesh_device_id: str
|
||||||
|
) -> str:
|
||||||
|
|
||||||
|
if settings.DOCKER_BUILD:
|
||||||
|
base = settings.MESH_WS_URL.replace("ws://", "http://")
|
||||||
|
else:
|
||||||
|
base = mesh_site
|
||||||
|
|
||||||
|
if plat == AgentPlat.WINDOWS:
|
||||||
|
params = {
|
||||||
|
"id": ident,
|
||||||
|
"meshid": mesh_device_id,
|
||||||
|
"installflags": 0,
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
params = {
|
||||||
|
"id": mesh_device_id,
|
||||||
|
"installflags": 2,
|
||||||
|
"meshinstall": ident,
|
||||||
|
}
|
||||||
|
|
||||||
|
return base + "/meshagents?" + urllib.parse.urlencode(params)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
asgiref==3.5.2
|
asgiref==3.5.2
|
||||||
celery==5.2.7
|
celery==5.2.7
|
||||||
certifi==2022.6.15.1
|
certifi==2022.9.14
|
||||||
cffi==1.15.1
|
cffi==1.15.1
|
||||||
channels==3.0.5
|
channels==3.0.5
|
||||||
channels_redis==3.4.1
|
channels_redis==3.4.1
|
||||||
@@ -11,7 +11,8 @@ Django==4.1.1
|
|||||||
django-cors-headers==3.13.0
|
django-cors-headers==3.13.0
|
||||||
django-ipware==4.0.2
|
django-ipware==4.0.2
|
||||||
django-rest-knox==4.2.0
|
django-rest-knox==4.2.0
|
||||||
djangorestframework==3.13.1
|
djangorestframework==3.14.0
|
||||||
|
drf-spectacular==0.24.1
|
||||||
future==0.18.2
|
future==0.18.2
|
||||||
msgpack==1.0.4
|
msgpack==1.0.4
|
||||||
nats-py==2.1.7
|
nats-py==2.1.7
|
||||||
@@ -28,12 +29,11 @@ hiredis==2.0.0
|
|||||||
requests==2.28.1
|
requests==2.28.1
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
sqlparse==0.4.2
|
sqlparse==0.4.2
|
||||||
twilio==7.14.0
|
twilio==7.14.1
|
||||||
urllib3==1.26.12
|
urllib3==1.26.12
|
||||||
uWSGI==2.0.20
|
uWSGI==2.0.20
|
||||||
validators==0.20.0
|
validators==0.20.0
|
||||||
vine==5.0.0
|
vine==5.0.0
|
||||||
websockets==10.3
|
websockets==10.3
|
||||||
zipp==3.8.1
|
zipp==3.8.1
|
||||||
drf-spectacular==0.23.1
|
|
||||||
meshctrl==0.1.15
|
meshctrl==0.1.15
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class MeshAgentIdent(Enum):
|
|||||||
LINUX64 = 6
|
LINUX64 = 6
|
||||||
LINUX_ARM_64 = 26
|
LINUX_ARM_64 = 26
|
||||||
LINUX_ARM_HF = 25
|
LINUX_ARM_HF = 25
|
||||||
|
DARWIN_UNIVERSAL = 10005
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.value)
|
return str(self.value)
|
||||||
|
|||||||
@@ -14,24 +14,26 @@ EXE_DIR = os.path.join(BASE_DIR, "tacticalrmm/private/exe")
|
|||||||
|
|
||||||
LINUX_AGENT_SCRIPT = BASE_DIR / "core" / "agent_linux.sh"
|
LINUX_AGENT_SCRIPT = BASE_DIR / "core" / "agent_linux.sh"
|
||||||
|
|
||||||
|
MAC_UNINSTALL = BASE_DIR / "core" / "mac_uninstall.sh"
|
||||||
|
|
||||||
AUTH_USER_MODEL = "accounts.User"
|
AUTH_USER_MODEL = "accounts.User"
|
||||||
|
|
||||||
# latest release
|
# latest release
|
||||||
TRMM_VERSION = "0.14.8"
|
TRMM_VERSION = "0.15.0"
|
||||||
|
|
||||||
# https://github.com/amidaware/tacticalrmm-web
|
# https://github.com/amidaware/tacticalrmm-web
|
||||||
WEB_VERSION = "0.100.9"
|
WEB_VERSION = "0.101.0"
|
||||||
|
|
||||||
# bump this version everytime vue code is changed
|
# bump this version everytime vue code is changed
|
||||||
# to alert user they need to manually refresh their browser
|
# to alert user they need to manually refresh their browser
|
||||||
APP_VER = "0.0.170"
|
APP_VER = "0.0.171"
|
||||||
|
|
||||||
# https://github.com/amidaware/rmmagent
|
# https://github.com/amidaware/rmmagent
|
||||||
LATEST_AGENT_VER = "2.3.1"
|
LATEST_AGENT_VER = "2.4.0"
|
||||||
|
|
||||||
MESH_VER = "1.0.85"
|
MESH_VER = "1.0.85"
|
||||||
|
|
||||||
NATS_SERVER_VER = "2.9.0"
|
NATS_SERVER_VER = "2.9.1"
|
||||||
|
|
||||||
# for the update script, bump when need to recreate venv
|
# for the update script, bump when need to recreate venv
|
||||||
PIP_VER = "32"
|
PIP_VER = "32"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM nats:2.9.0-alpine
|
FROM nats:2.9.1-alpine
|
||||||
|
|
||||||
ENV TACTICAL_DIR /opt/tactical
|
ENV TACTICAL_DIR /opt/tactical
|
||||||
ENV TACTICAL_READY_FILE ${TACTICAL_DIR}/tmp/tactical.ready
|
ENV TACTICAL_READY_FILE ${TACTICAL_DIR}/tmp/tactical.ready
|
||||||
|
|||||||
Reference in New Issue
Block a user