perf: add jms_ansible_ee CI workflow and refine EE build

This commit is contained in:
wangruidong
2026-06-04 14:53:51 +08:00
committed by 老广
parent c1a44cc202
commit a4ac6b72fc
6 changed files with 173 additions and 64 deletions

View File

@@ -0,0 +1,95 @@
name: Build and Push Ansible EE Image
on:
pull_request:
branches:
- 'dev'
- 'v*'
paths:
- utils/ansible_executor/**
- apps/libs/ansible/**
types:
- opened
- synchronize
- reopened
workflow_dispatch:
inputs:
branch:
description: '构建 Ansible EE 镜像所用的分支'
required: true
type: string
default: 'main'
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Lock Pull Request
if: github.event_name == 'push'
run: |
curl -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-d '{"state":"pending", "description":"Action running, merge disabled", "context":"Lock PR"}' \
"https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }}"
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.branch || github.ref }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract date
id: vars
run: echo "IMAGE_TAG=$(date +'%Y%m%d_%H%M%S')" >> $GITHUB_ENV
- name: Install ansible-builder
run: pip install 'ansible-builder>=3.1.1'
- name: Create EE build context
working-directory: utils/ansible_executor
run: |
ansible-builder create \
-f execution-environment.yml \
-c context \
--container-runtime docker
- name: Build and push multi-arch image
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
push: true
context: utils/ansible_executor/context
file: utils/ansible_executor/context/Dockerfile
tags: jumpserver/jms_ansible_ee:${{ env.IMAGE_TAG }}
- name: Update runner.py
run: |
sed -i "s|ANSIBLE_EE_IMAGE = .*|ANSIBLE_EE_IMAGE = 'jumpserver/jms_ansible_ee:${{ env.IMAGE_TAG }}'|" apps/ops/ansible/runner.py
- name: Commit changes
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git add apps/ops/ansible/runner.py
git commit -m "perf: Update Ansible EE image tag in runner.py"
git push
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Unlock Pull Request
if: github.event_name == 'push'
run: |
curl -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
-d '{"state":"success", "description":"Action running, merge disabled", "context":"Lock PR"}' \
"https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }}"

View File

@@ -13,9 +13,26 @@ from ..utils import get_ansible_log_verbosity
__all__ = ['AdHocRunner', 'PlaybookRunner', 'SuperPlaybookRunner', 'UploadFileRunner']
ANSIBLE_EE_IMAGE = 'jms_ansible_ee:latest'
def use_ansible_docker_isolation():
"""Production runs ansible in EE container; dev runs in celery worker."""
return not settings.DEBUG_DEV
def docker_isolation_kwargs():
return {
'process_isolation': True,
'process_isolation_executable': 'docker',
'container_image': ANSIBLE_EE_IMAGE,
}
def prepare_isolated_ansible_cfg(project_dir):
"""Copy ansible.cfg into job dir so the EE container picks up SSH settings."""
if not use_ansible_docker_isolation():
return
src = os.path.join(settings.APPS_DIR, 'libs', 'ansible', 'ansible.cfg')
dst = os.path.join(project_dir, 'ansible.cfg')
shutil.copyfile(src, dst)
@@ -69,23 +86,24 @@ class AdHocRunner:
prepare_isolated_ansible_cfg(self.project_dir)
interface.run(
process_isolation=True,
process_isolation_executable='docker',
container_image='company-ee:1.0',
timeout=self.timeout if self.timeout > 0 else None,
extravars=self.extra_vars,
envvars=self.envs,
host_pattern=self.pattern,
private_data_dir=self.project_dir,
inventory=self.inventory,
module=self.module,
module_args=self.module_args,
verbosity=verbosity,
event_handler=self.cb.event_handler,
status_handler=self.cb.status_handler,
**kwargs
)
run_kwargs = {
'timeout': self.timeout if self.timeout > 0 else None,
'extravars': self.extra_vars,
'envvars': self.envs,
'host_pattern': self.pattern,
'private_data_dir': self.project_dir,
'inventory': self.inventory,
'module': self.module,
'module_args': self.module_args,
'verbosity': verbosity,
'event_handler': self.cb.event_handler,
'status_handler': self.cb.status_handler,
**kwargs,
}
if use_ansible_docker_isolation():
run_kwargs.update(docker_isolation_kwargs())
interface.run(**run_kwargs)
return self.cb
@@ -123,10 +141,13 @@ class PlaybookRunner:
prepare_isolated_ansible_cfg(self.project_dir)
kwargs = dict(kwargs)
if use_ansible_docker_isolation():
kwargs.update(docker_isolation_kwargs())
elif self.isolate and not is_macos():
kwargs['process_isolation'] = True
kwargs['process_isolation_executable'] = 'bwrap'
interface.run(
process_isolation=True,
process_isolation_executable='docker',
container_image='company-ee:1.0',
private_data_dir=self.project_dir,
inventory=self.inventory,
playbook=self.playbook,
@@ -160,17 +181,21 @@ class UploadFileRunner:
def run(self, verbosity=0, **kwargs):
verbosity = get_ansible_log_verbosity(verbosity)
interface.run(
private_data_dir=self.project_dir,
host_pattern="*",
inventory=self.inventory,
module='copy',
module_args=f"src={self.src_paths}/ dest={self.dest_path}/",
verbosity=verbosity,
event_handler=self.cb.event_handler,
status_handler=self.cb.status_handler,
**kwargs
)
run_kwargs = {
'private_data_dir': self.project_dir,
'host_pattern': "*",
'inventory': self.inventory,
'module': 'copy',
'module_args': f"src={self.src_paths}/ dest={self.dest_path}/",
'verbosity': verbosity,
'event_handler': self.cb.event_handler,
'status_handler': self.cb.status_handler,
**kwargs,
}
if use_ansible_docker_isolation():
run_kwargs.update(docker_isolation_kwargs())
interface.run(**run_kwargs)
try:
shutil.rmtree(self.src_paths)
except OSError as e:

View File

@@ -1,20 +1,25 @@
# RPM packages for JumpServer ansible playbooks and custom modules.
# ansible-builder 只支持 dnf/microdnf不支持 Debian apt。
# [compile] 仅在 builder 阶段安装,不进入最终镜像(见 ansible-builder bindep 文档)。
# freetds-devel / sshpass 需配合 execution-environment.yml 中 EPEL 启用步骤。
gcc [platform:rpm]
pkgconf-pkg-config [platform:rpm]
python3.11-devel [platform:rpm]
gcc [compile platform:rpm]
pkgconf-pkg-config [compile platform:rpm]
python3.11-devel [compile platform:rpm]
mariadb-connector-c-devel [compile platform:rpm]
postgresql-devel [compile platform:rpm]
freetds-devel [compile platform:rpm]
krb5-devel [compile platform:rpm]
openldap-devel [compile platform:rpm]
cyrus-sasl-devel [compile platform:rpm]
libX11-devel [compile platform:rpm]
openssh-clients [platform:rpm]
sshpass [platform:rpm]
iputils [platform:rpm]
nmap [platform:rpm]
telnet [platform:rpm]
mariadb-connector-c-devel [platform:rpm]
postgresql-devel [platform:rpm]
freetds-devel [platform:rpm]
krb5-devel [platform:rpm]
openldap-devel [platform:rpm]
cyrus-sasl-devel [platform:rpm]
libX11-devel [platform:rpm]
mariadb-connector-c [platform:rpm]
libpq [platform:rpm]
freetds [platform:rpm]
libX11 [platform:rpm]
ca-certificates [platform:rpm]
glibc-langpack-en [platform:rpm]

View File

@@ -5,7 +5,7 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SCRIPT_DIR"
IMAGE_TAG="${IMAGE_TAG:-company-ee:1.0}"
IMAGE_TAG="${IMAGE_TAG:-jms_ansible_ee:latest}"
EE_FILE="${EE_FILE:-execution-environment.yml}"
GITHUB_MIRROR="${GITHUB_MIRROR:-https://ghfast.top/}"
USE_CHINA_MIRROR="${USE_CHINA_MIRROR:-1}"

View File

@@ -1,26 +1,7 @@
---
# JumpServer Ansible Execution Environment
#
# 国内加速构建(推荐):
# cd utils/ansible_executor
# chmod +x build.sh
# ./build.sh
#
# 手动构建:
# ansible-builder build -f execution-environment.yml -t company-ee:1.0 --container-runtime docker
#
# 加速要点:
# 1. pip: 清华源 (files/pip.conf)
# 2. dnf/epel: 阿里云 (files/use-china-mirrors.sh)
# 3. GitHub zip: build.sh 默认走 ghfast.top 镜像
# 4. 重复构建: PKGMGR_PRESERVE_CACHE=always 保留 dnf 缓存
# 5. Docker Desktop -> Settings -> Docker Engine 配置 registry-mirrors
version: 3
build_arg_defaults:
# 重复 build 时保留 dnf 缓存,显著加快二次构建
PKGMGR_PRESERVE_CACHE: always
images:
# ansible-builder 仅支持 RPM 系镜像 (dnf),不能用 python:3.11-slim 等 Debian 镜像
@@ -79,3 +60,6 @@ additional_build_steps:
- ENV ANSIBLE_FORCE_COLOR=True
- ENV LC_ALL=C.UTF-8
- ENV LANG=C.UTF-8
# bindep [compile] 已避免工具链进入最终层;此处仅清理 PKGMGR_PRESERVE_CACHE 写入的 dnf 缓存
- RUN $PKGMGR clean all && rm -rf /var/cache/dnf /var/cache/yum /root/.cache
- RUN pip cache purge

View File

@@ -2,7 +2,7 @@
paramiko==3.2.0
sshtunnel==0.4.0
pywinrm==0.4.3
python-nmap==0.7.1
telnetlib3==4.0.2
mysqlclient==2.2.4
pymssql==2.3.4
pymongo==4.6.3