mirror of
https://github.com/jumpserver/jumpserver.git
synced 2026-07-02 07:01:30 +00:00
perf: add jms_ansible_ee CI workflow and refine EE build
This commit is contained in:
95
.github/workflows/build-jms-ansible-ee.yml
vendored
Normal file
95
.github/workflows/build-jms-ansible-ee.yml
vendored
Normal 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 }}"
|
||||
@@ -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:
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user