Skip to content

Commit

Permalink
feat: 沙箱回收 command (#1710)
Browse files Browse the repository at this point in the history
  • Loading branch information
SheepSheepChen authored Nov 11, 2024
1 parent e892c22 commit b8f2080
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 11 deletions.
4 changes: 3 additions & 1 deletion apiserver/paasng/paas_wl/bk_app/dev_sandbox/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,15 @@ class DevSandboxWithCodeEditorUrls:
app_url: str
devserver_url: str
code_editor_url: str
code_editor_health_url: str

def __init__(self, base_url: str, dev_sandbox_code: str):
self.app_url = f"{base_url}/dev_sandbox/{dev_sandbox_code}/app/"
self.devserver_url = f"{base_url}/dev_sandbox/{dev_sandbox_code}/devserver/"
self.code_editor_url = (
f"{base_url}/dev_sandbox/{dev_sandbox_code}/code-editor/?folder={settings.CODE_EDITOR_START_DIR}"
)
self.code_editor_health_url = f"{base_url}/dev_sandbox/{dev_sandbox_code}/code-editor/healthz"


@dataclass
Expand All @@ -138,7 +140,7 @@ class DevSandboxWithCodeEditorDetail:
code_editor_env_vars: Dict[str, str]
dev_sandbox_status: str
code_editor_status: str
urls: Optional[DevSandboxWithCodeEditorUrls] = None
urls: DevSandboxWithCodeEditorUrls


@dataclass
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# TencentBlueKing is pleased to support the open source community by making
# 蓝鲸智云 - PaaS 平台 (BlueKing - PaaS System) available.
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
# Licensed under the MIT License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://opensource.org/licenses/MIT
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions and
# limitations under the License.
#
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# TencentBlueKing is pleased to support the open source community by making
# 蓝鲸智云 - PaaS 平台 (BlueKing - PaaS System) available.
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
# Licensed under the MIT License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://opensource.org/licenses/MIT
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions and
# limitations under the License.
#
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# -*- coding: utf-8 -*-
# TencentBlueKing is pleased to support the open source community by making
# 蓝鲸智云 - PaaS 平台 (BlueKing - PaaS System) available.
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
# Licensed under the MIT License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://opensource.org/licenses/MIT
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions and
# limitations under the License.
#
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.

"""Recycle dev sandbox.
By default, only expired sandboxes are recycled. Use the --all flag to recycle all sandboxes.
Examples:
# 仅回收过期沙箱
python manage.py recycle_dev_sandbox
# 全量回收沙箱
python manage.py recycle_dev_sandbox --all
"""

from django.core.management.base import BaseCommand

from paas_wl.bk_app.dev_sandbox.controller import DevSandboxWithCodeEditorController
from paasng.accessories.dev_sandbox.models import DevSandbox


class Command(BaseCommand):
help = "回收沙箱"

def add_arguments(self, parser):
parser.add_argument(
"--all",
dest="all",
action="store_true",
help="recycle all dev sandboxes",
)

def handle(self, all, *args, **options):
for dev_sandbox in DevSandbox.objects.all():
controller = DevSandboxWithCodeEditorController(
app=dev_sandbox.module.application,
module_name=dev_sandbox.module.name,
dev_sandbox_code=dev_sandbox.code,
owner=dev_sandbox.owner,
)
if all or dev_sandbox.is_expired():
controller.delete()
dev_sandbox.delete()
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# TencentBlueKing is pleased to support the open source community by making
# 蓝鲸智云 - PaaS 平台 (BlueKing - PaaS System) available.
# Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
# Licensed under the MIT License (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://opensource.org/licenses/MIT
#
# Unless required by applicable law or agreed to in writing, software distributed under
# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific language governing permissions and
# limitations under the License.
#
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.

import logging

import requests
from django.core.management.base import BaseCommand

from paas_wl.bk_app.dev_sandbox.controller import DevSandboxWithCodeEditorController
from paasng.accessories.dev_sandbox.models import DevSandbox

logger = logging.getLogger(__name__)


class Command(BaseCommand):
help = "更新沙箱状态"

def handle(self, *args, **options):
for dev_sandbox in DevSandbox.objects.all():
controller = DevSandboxWithCodeEditorController(
app=dev_sandbox.module.application,
module_name=dev_sandbox.module.name,
dev_sandbox_code=dev_sandbox.code,
owner=dev_sandbox.owner,
)
try:
detail = controller.get_detail()
except Exception as e:
# 防止沙箱资源被管理员删除等导致的报错
logger.warning("Failed to get detail of dev sandbox: %s. Error: %s", dev_sandbox.code, e)
continue

url = detail.urls.code_editor_health_url
# 沙箱相关域名无法确定协议,因此全部遍历 http 和 https
if check_alive(f"http://{url}") or check_alive(f"https://{url}"):
dev_sandbox.renew_expire_at()


# 通过 code_editor_health_url 检查沙箱是否存活
def check_alive(url: str) -> bool:
try:
resp = requests.get(url)
return resp.status_code == 200 and resp.json().get("status") == "alive"
except Exception as e:
logger.warning("Dev sandbox status check failed for URL: %s. Error: %s", url, e)
return False
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.16 on 2024-11-11 07:49

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('dev_sandbox', '0001_initial'),
]

operations = [
migrations.RenameField(
model_name='devsandbox',
old_name='expire_at',
new_name='expired_at',
),
]
16 changes: 6 additions & 10 deletions apiserver/paasng/paasng/accessories/dev_sandbox/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
#
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.
import datetime
import string

from blue_krill.models.fields import EncryptField
from django.db import models
from django.utils import timezone
from django.utils.crypto import get_random_string

from paas_wl.bk_app.dev_sandbox.constants import DevSandboxStatus
Expand All @@ -45,21 +45,17 @@ class DevSandbox(OwnerTimestampedModel):
code = models.CharField(max_length=8, help_text="沙箱标识", unique=True)
module = models.ForeignKey(Module, on_delete=models.CASCADE, db_constraint=False)
status = models.CharField(max_length=32, verbose_name="沙箱状态", choices=DevSandboxStatus.get_choices())
expire_at = models.DateTimeField(null=True, help_text="到期时间")
expired_at = models.DateTimeField(null=True, help_text="到期时间")
version_info = VersionInfoField(help_text="代码版本信息", default=None, null=True)

def renew_expire_at(self):
# 如果状态不是ALIVE, 则设置两小时后过期
if self.status != DevSandboxStatus.ACTIVE.value:
self.expire_at = datetime.datetime.now() + datetime.timedelta(hours=2)
else:
self.expire_at = None
def renew_expired_at(self):
self.expired_at = timezone.now() + timezone.timedelta(hours=2)
self.save(update_fields=["expire_at"])

def should_recycle(self) -> bool:
"""检查是否应该被回收"""
if self.expire_at:
return self.expire_at <= datetime.datetime.now()
if self.expired_at:
return self.expired_at <= timezone.now()
return False

class Meta:
Expand Down
2 changes: 2 additions & 0 deletions apiserver/paasng/paasng/accessories/dev_sandbox/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ def deploy(self, request, code, module_name):
version_info=version_info,
code=dev_sandbox_code,
)
# 更新过期时间
dev_sandbox.renew_expire_at()

# 生成代码编辑器密码
password = generate_password()
Expand Down

0 comments on commit b8f2080

Please sign in to comment.