perf: 支持发布机卸载远程应用

pull/12869/head
Eric 2024-03-20 19:23:44 +08:00 committed by Bryan
parent a5e8792092
commit 0589f7fe33
6 changed files with 89 additions and 4 deletions

View File

@ -11,9 +11,14 @@ from common.permissions import IsServiceAccount
from orgs.utils import tmp_to_builtin_org
from terminal.models import AppletHost, AppletHostDeployment
from terminal.serializers import (
AppletHostSerializer, AppletHostDeploymentSerializer, AppletHostStartupSerializer
AppletHostSerializer, AppletHostDeploymentSerializer,
AppletHostStartupSerializer, AppletSetupSerializer
)
from terminal.tasks import (
run_applet_host_deployment,
run_applet_host_deployment_install_applet,
run_applet_host_deployment_uninstall_applet
)
from terminal.tasks import run_applet_host_deployment, run_applet_host_deployment_install_applet
__all__ = ['AppletHostViewSet', 'AppletHostDeploymentViewSet']
@ -56,6 +61,7 @@ class AppletHostDeploymentViewSet(viewsets.ModelViewSet):
filterset_fields = ['host', ]
rbac_perms = (
('applets', 'terminal.view_AppletHostDeployment'),
('uninstall', 'terminal.change_applethost'),
)
@staticmethod
@ -90,7 +96,29 @@ class AppletHostDeploymentViewSet(viewsets.ModelViewSet):
transaction.on_commit(lambda: self.start_install_applet(applet_host_deployment_ids, applet_id, task_id))
return Response({'task': task_id}, status=201)
@action(methods=['post'], detail=False)
def uninstall(self, request, *args, **kwargs):
serializer = AppletSetupSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
validated_data = serializer.validated_data
hosts = validated_data.pop('hosts', [])
applet_id = validated_data.pop('applet_id', '')
hosts_qs = AppletHost.objects.filter(id__in=hosts)
if not hosts_qs.exists():
return Response(status=status.HTTP_404_NOT_FOUND)
task_id = str(uuid.uuid4())
objs = [AppletHostDeployment(host=host, task=task_id) for host in hosts_qs]
applet_host_deployments = AppletHostDeployment.objects.bulk_create(objs)
applet_host_deployment_ids = [str(obj.id) for obj in applet_host_deployments]
transaction.on_commit(lambda: self.start_uninstall_applet(applet_host_deployment_ids, applet_id, task_id))
return Response({'task': task_id}, status=201)
@staticmethod
def start_install_applet(applet_host_deployment_ids, applet_id, task_id):
run_applet_host_deployment_install_applet.apply_async((applet_host_deployment_ids, applet_id),
task_id=str(task_id))
@staticmethod
def start_uninstall_applet(applet_host_deployment_ids, applet_id, task_id):
run_applet_host_deployment_uninstall_applet.apply_async((applet_host_deployment_ids, applet_id),
task_id=str(task_id))

View File

@ -36,6 +36,9 @@ class DeployAppletHostManager:
def install_applet(self, **kwargs):
self._run(self._run_install_applet, **kwargs)
def uninstall_applet(self, **kwargs):
self._run(self._run_uninstall_applet, **kwargs)
def _run_initial_deploy(self, **kwargs):
playbook = self.generate_initial_playbook
return self._run_playbook(playbook, **kwargs)
@ -47,6 +50,13 @@ class DeployAppletHostManager:
generate_playbook = self.generate_install_all_playbook
return self._run_playbook(generate_playbook, **kwargs)
def _run_uninstall_applet(self, **kwargs):
if self.applet:
generate_playbook = self.generate_uninstall_applet_playbook
else:
raise ValueError("applet is required for uninstall_applet")
return self._run_playbook(generate_playbook, **kwargs)
def generate_initial_playbook(self):
site_url = settings.SITE_URL
download_host = settings.APPLET_DOWNLOAD_HOST
@ -92,6 +102,16 @@ class DeployAppletHostManager:
return self._generate_playbook("install_applet.yml", handler)
def generate_uninstall_applet_playbook(self):
applet_name = self.applet.name
def handler(plays):
for play in plays:
play["vars"]["applet_name"] = applet_name
return plays
return self._generate_playbook("uninstall_applet.yml", handler)
def generate_inventory(self):
inventory = JMSInventory(
[self.deployment.host], account_policy="privileged_only"

View File

@ -0,0 +1,11 @@
---
- hosts: all
vars:
applet_name: chrome
tasks:
- name: uninstall applet
ansible.windows.win_powershell:
script: |
tinkerd uninstall --name {{ applet_name }}

View File

@ -168,6 +168,16 @@ class AppletHostDeployment(JMSBaseModel):
manager = DeployAppletHostManager(self, applet=applet)
manager.install_applet(**kwargs)
def uninstall_applet(self, applet_id, **kwargs):
from ...automations.deploy_applet_host import DeployAppletHostManager
from .applet import Applet
if applet_id:
applet = Applet.objects.get(id=applet_id)
else:
applet = None
manager = DeployAppletHostManager(self, applet=applet)
manager.uninstall_applet(**kwargs)
def save_task(self, task):
self.task = task
self.save(update_fields=['task'])

View File

@ -15,7 +15,7 @@ from ..models import AppletHost, AppletHostDeployment
__all__ = [
'AppletHostSerializer', 'AppletHostDeploymentSerializer',
'AppletHostAccountSerializer', 'AppletHostAppletReportSerializer',
'AppletHostStartupSerializer'
'AppletHostStartupSerializer', 'AppletSetupSerializer'
]
@ -143,7 +143,7 @@ class AppletHostDeploymentSerializer(serializers.ModelSerializer):
'status', 'date_created', 'date_updated',
'date_start', 'date_finished'
]
write_only_fields = ['install_applets',]
write_only_fields = ['install_applets', ]
fields = fields_mini + ['comment'] + read_only_fields + write_only_fields
@ -161,3 +161,8 @@ class AppletHostAppletReportSerializer(serializers.Serializer):
class AppletHostStartupSerializer(serializers.Serializer):
pass
class AppletSetupSerializer(serializers.Serializer):
hosts = serializers.ListField(child=serializers.UUIDField(label=_('Host ID')), label=_('Hosts'))
applet_id = serializers.UUIDField(label=_('Applet ID'))

View File

@ -108,6 +108,17 @@ def run_applet_host_deployment_install_applet(ids, applet_id):
deployment.install_applet(applet_id)
@shared_task(
verbose_name=_('Uninstall applet'),
activity_callback=lambda self, ids, applet_id, *args, **kwargs: (ids,)
)
def run_applet_host_deployment_uninstall_applet(ids, applet_id):
with tmp_to_builtin_org(system=1):
for did in ids:
deployment = AppletHostDeployment.objects.get(id=did)
deployment.uninstall_applet(applet_id)
@shared_task(
verbose_name=_('Generate applet host accounts'),
activity_callback=lambda self, host_id, *args, **kwargs: ([host_id],)