diff --git a/_modules/win_agent.py b/_modules/win_agent.py index 26f3ce29..7a11e9e5 100644 --- a/_modules/win_agent.py +++ b/_modules/win_agent.py @@ -44,8 +44,20 @@ def uninstall_agent(): def update_salt(): - __salt__["cmd.run_bg"]([TAC_RMM, "-m", "updatesalt"]) - return "ok" + from subprocess import Popen, PIPE + + CREATE_NEW_PROCESS_GROUP = 0x00000200 + DETACHED_PROCESS = 0x00000008 + cmd = [TAC_RMM, "-m", "updatesalt"] + p = Popen( + cmd, + stdin=PIPE, + stdout=PIPE, + stderr=PIPE, + close_fds=True, + creationflags=DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, + ) + return p.pid def run_manual_checks(): diff --git a/api/tacticalrmm/agents/migrations/0010_auto_20200809_0133.py b/api/tacticalrmm/agents/migrations/0010_auto_20200809_0133.py new file mode 100644 index 00000000..819cc25f --- /dev/null +++ b/api/tacticalrmm/agents/migrations/0010_auto_20200809_0133.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.8 on 2020-08-09 01:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('agents', '0009_agent_salt_id'), + ] + + operations = [ + migrations.AddField( + model_name='agent', + name='salt_update_pending', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='agent', + name='salt_ver', + field=models.CharField(default='1.0.3', max_length=255), + ), + ] diff --git a/api/tacticalrmm/agents/models.py b/api/tacticalrmm/agents/models.py index 3fe1978c..c325bfd6 100644 --- a/api/tacticalrmm/agents/models.py +++ b/api/tacticalrmm/agents/models.py @@ -25,6 +25,7 @@ logger.configure(**settings.LOG_CONFIG) class Agent(models.Model): version = models.CharField(default="0.1.0", max_length=255) + salt_ver = models.CharField(default="1.0.3", max_length=255) operating_system = models.CharField(null=True, max_length=255) plat = models.CharField(max_length=255, null=True) plat_release = models.CharField(max_length=255, null=True) @@ -53,6 +54,7 @@ class Agent(models.Model): needs_reboot = models.BooleanField(default=False) managed_by_wsus = models.BooleanField(default=False) update_pending = models.BooleanField(default=False) + salt_update_pending = models.BooleanField(default=False) choco_installed = models.BooleanField(default=False) wmi_detail = JSONField(null=True) time_zone = models.CharField( diff --git a/api/tacticalrmm/api/urls.py b/api/tacticalrmm/api/urls.py index 2948fc56..d9e174a4 100644 --- a/api/tacticalrmm/api/urls.py +++ b/api/tacticalrmm/api/urls.py @@ -12,4 +12,5 @@ urlpatterns = [ path("firstinstall/", views.on_agent_first_install), path("/checkrunner/", views.CheckRunner.as_view()), path("/taskrunner/", views.TaskRunner.as_view()), + path("/saltinfo/", views.SaltInfo.as_view()), ] diff --git a/api/tacticalrmm/api/views.py b/api/tacticalrmm/api/views.py index a6560cd6..6a750500 100644 --- a/api/tacticalrmm/api/views.py +++ b/api/tacticalrmm/api/views.py @@ -319,3 +319,24 @@ class TaskRunner(APIView): serializer.is_valid(raise_exception=True) serializer.save(last_run=djangotime.now()) return Response("ok") + + +class SaltInfo(APIView): + authentication_classes = [TokenAuthentication] + permission_classes = [IsAuthenticated] + + def get(self, request, pk): + agent = get_object_or_404(Agent, pk=pk) + ret = { + "latestVer": settings.LATEST_SALT_VER, + "currentVer": agent.salt_ver, + "salt_id": agent.salt_id, + } + return Response(ret) + + def patch(self, request, pk): + agent = get_object_or_404(Agent, pk=pk) + agent.salt_ver = request.data["ver"] + agent.salt_update_pending = False + agent.save(update_fields=["salt_ver", "salt_update_pending"]) + return Response("ok") diff --git a/api/tacticalrmm/tacticalrmm/settings.py b/api/tacticalrmm/tacticalrmm/settings.py index 57c872fc..65e4ccb3 100644 --- a/api/tacticalrmm/tacticalrmm/settings.py +++ b/api/tacticalrmm/tacticalrmm/settings.py @@ -13,6 +13,9 @@ AUTH_USER_MODEL = "accounts.User" # to alert user they need to manually refresh their browser APP_VER = "0.0.17" +# https://github.com/wh1te909/salt +LATEST_SALT_VER = "1.0.3" + try: from .local_settings import * except ImportError: