mirror of
https://github.com/jumpserver/jumpserver.git
synced 2026-07-01 22:49:06 +00:00
feat: ansible use Docker for process isolation
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -49,3 +49,4 @@ apps.iml
|
||||
*.db
|
||||
*.mmdb
|
||||
*.ipdb
|
||||
context
|
||||
|
||||
@@ -7,6 +7,10 @@ timeout = 65
|
||||
[privilege_escalation]
|
||||
[paramiko_connection]
|
||||
[ssh_connection]
|
||||
# Docker 隔离下 ControlMaster 在 bind mount 上无法创建 mux socket(macOS 尤其明显)
|
||||
ssh_args = -o ControlMaster=no -o ControlPersist=no
|
||||
pipelining = True
|
||||
|
||||
[persistent_connection]
|
||||
[accelerate]
|
||||
[selinux]
|
||||
|
||||
@@ -14,6 +14,13 @@ from ..utils import get_ansible_log_verbosity
|
||||
__all__ = ['AdHocRunner', 'PlaybookRunner', 'SuperPlaybookRunner', 'UploadFileRunner']
|
||||
|
||||
|
||||
def prepare_isolated_ansible_cfg(project_dir):
|
||||
"""Copy ansible.cfg into job dir so the EE container picks up SSH settings."""
|
||||
src = os.path.join(settings.APPS_DIR, 'libs', 'ansible', 'ansible.cfg')
|
||||
dst = os.path.join(project_dir, 'ansible.cfg')
|
||||
shutil.copyfile(src, dst)
|
||||
|
||||
|
||||
class AdHocRunner:
|
||||
cmd_modules_choices = ('shell', 'raw', 'command', 'script', 'win_shell')
|
||||
need_local_connection_modules_choices = ("mysql", "postgresql", "sqlserver", "huawei")
|
||||
@@ -60,7 +67,12 @@ class AdHocRunner:
|
||||
if os.path.exists(private_env):
|
||||
shutil.rmtree(private_env)
|
||||
|
||||
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,
|
||||
@@ -108,12 +120,13 @@ class PlaybookRunner:
|
||||
if os.path.exists(private_env):
|
||||
shutil.rmtree(private_env)
|
||||
|
||||
kwargs = dict(kwargs)
|
||||
if self.isolate and not is_macos():
|
||||
kwargs['process_isolation'] = True
|
||||
kwargs['process_isolation_executable'] = 'bwrap'
|
||||
prepare_isolated_ansible_cfg(self.project_dir)
|
||||
|
||||
kwargs = dict(kwargs)
|
||||
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,
|
||||
|
||||
@@ -152,6 +152,7 @@ dependencies = [
|
||||
"pyhttpsig==1.3.0",
|
||||
"telnetlib3==4.0.2",
|
||||
"defusedxml>=0.7.1",
|
||||
"ansible-builder>=3.1.1",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
||||
8
utils/ansible_executor/ansible.cfg
Normal file
8
utils/ansible_executor/ansible.cfg
Normal file
@@ -0,0 +1,8 @@
|
||||
[defaults]
|
||||
forks = 10
|
||||
host_key_checking = False
|
||||
library = /opt/jumpserver/apps/libs/ansible/modules:./modules
|
||||
timeout = 65
|
||||
[ssh_connection]
|
||||
ssh_args = -o ControlMaster=no -o ControlPersist=no
|
||||
pipelining = True
|
||||
20
utils/ansible_executor/bindep.txt
Normal file
20
utils/ansible_executor/bindep.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
# RPM packages for JumpServer ansible playbooks and custom modules.
|
||||
# ansible-builder 只支持 dnf/microdnf,不支持 Debian apt。
|
||||
# freetds-devel / sshpass 需配合 execution-environment.yml 中 EPEL 启用步骤。
|
||||
gcc [platform:rpm]
|
||||
pkgconf-pkg-config [platform:rpm]
|
||||
python3.11-devel [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]
|
||||
ca-certificates [platform:rpm]
|
||||
glibc-langpack-en [platform:rpm]
|
||||
40
utils/ansible_executor/build.sh
Executable file
40
utils/ansible_executor/build.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
# Build EE image with China-friendly defaults (mirrors + cache).
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
IMAGE_TAG="${IMAGE_TAG:-company-ee:1.0}"
|
||||
EE_FILE="${EE_FILE:-execution-environment.yml}"
|
||||
GITHUB_MIRROR="${GITHUB_MIRROR:-https://ghfast.top/}"
|
||||
USE_CHINA_MIRROR="${USE_CHINA_MIRROR:-1}"
|
||||
|
||||
if ! command -v ansible-builder >/dev/null 2>&1; then
|
||||
echo "ansible-builder not found. Install: pip install ansible-builder" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Optional: rewrite GitHub zip URLs via mirror (speed up ansible-core / ansible-runner download).
|
||||
# 临时 EE 必须放在 SCRIPT_DIR:ansible-builder 按 EE 文件所在目录解析 requirements-python.txt 等相对路径。
|
||||
WORK_EE="$EE_FILE"
|
||||
if [ "$USE_CHINA_MIRROR" = "1" ] && [ -n "$GITHUB_MIRROR" ]; then
|
||||
WORK_EE="$(mktemp "${SCRIPT_DIR}/.execution-environment.XXXXXX.yml")"
|
||||
sed \
|
||||
-e "s|https://github.com/|${GITHUB_MIRROR}https://github.com/|g" \
|
||||
"$EE_FILE" > "$WORK_EE"
|
||||
trap 'rm -f "$WORK_EE"' EXIT
|
||||
fi
|
||||
|
||||
export DOCKER_BUILDKIT=1
|
||||
|
||||
echo "==> image: $IMAGE_TAG"
|
||||
echo "==> ee file: $WORK_EE"
|
||||
echo "==> github mirror: ${GITHUB_MIRROR:-disabled}"
|
||||
echo "==> tip: configure Docker Desktop registry mirrors for quay.io / docker.io"
|
||||
|
||||
ansible-builder build \
|
||||
-f "$WORK_EE" \
|
||||
-t "$IMAGE_TAG" \
|
||||
--container-runtime docker \
|
||||
"$@"
|
||||
81
utils/ansible_executor/execution-environment.yml
Normal file
81
utils/ansible_executor/execution-environment.yml
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
# 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 镜像
|
||||
base_image:
|
||||
name: quay.io/centos/centos:stream9
|
||||
|
||||
dependencies:
|
||||
python_interpreter:
|
||||
package_system: python3.11
|
||||
python_path: /usr/bin/python3.11
|
||||
|
||||
# 与 pyproject.toml [tool.uv.sources] 保持一致,不要用 PyPI 官方包
|
||||
ansible_core:
|
||||
package_pip: https://github.com/jumpserver-dev/ansible/archive/refs/tags/v2.14.1.7.zip
|
||||
ansible_runner:
|
||||
package_pip: https://github.com/jumpserver-dev/ansible-runner/archive/refs/tags/2.4.0.1.zip
|
||||
|
||||
galaxy:
|
||||
collections:
|
||||
- name: community.postgresql
|
||||
version: "2.4.0"
|
||||
- name: community.mysql
|
||||
- name: community.mongodb
|
||||
- name: community.windows
|
||||
- name: ansible.windows
|
||||
|
||||
python: requirements-python.txt
|
||||
system: bindep.txt
|
||||
|
||||
additional_build_files:
|
||||
- src: files/pip.conf
|
||||
dest: configs/
|
||||
- src: files/use-china-mirrors.sh
|
||||
dest: scripts/
|
||||
- src: ../../apps/libs/ansible/
|
||||
dest: jumpserver-ansible/
|
||||
- src: ansible.cfg
|
||||
dest: configs/
|
||||
|
||||
additional_build_steps:
|
||||
prepend_base:
|
||||
# pip 镜像需在 base 阶段最早注入,后续各 stage 的 pip install 都会走国内源
|
||||
- COPY _build/configs/pip.conf /etc/pip.conf
|
||||
- COPY _build/scripts/use-china-mirrors.sh /tmp/use-china-mirrors.sh
|
||||
- RUN chmod +x /tmp/use-china-mirrors.sh && /tmp/use-china-mirrors.sh centos
|
||||
# freetds-devel、sshpass 等在 EPEL;postgresql-devel 等开发包常需 CRB
|
||||
- RUN $PKGMGR config-manager --set-enabled crb
|
||||
- RUN $PKGMGR install -y epel-release
|
||||
- RUN /tmp/use-china-mirrors.sh epel && $PKGMGR makecache -y
|
||||
append_final:
|
||||
- RUN mkdir -p /opt/jumpserver/apps
|
||||
- COPY _build/jumpserver-ansible/ /opt/jumpserver/apps/libs/ansible/
|
||||
- COPY _build/configs/ansible.cfg /etc/ansible/ansible.cfg
|
||||
- ENV PYTHONPATH=/opt/jumpserver/apps
|
||||
- ENV ANSIBLE_LIBRARY=/opt/jumpserver/apps/libs/ansible/modules
|
||||
- ENV ANSIBLE_FORCE_COLOR=True
|
||||
- ENV LC_ALL=C.UTF-8
|
||||
- ENV LANG=C.UTF-8
|
||||
7
utils/ansible_executor/files/pip.conf
Normal file
7
utils/ansible_executor/files/pip.conf
Normal file
@@ -0,0 +1,7 @@
|
||||
[global]
|
||||
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
trusted-host = pypi.tuna.tsinghua.edu.cn
|
||||
timeout = 120
|
||||
|
||||
[install]
|
||||
trusted-host = pypi.tuna.tsinghua.edu.cn
|
||||
67
utils/ansible_executor/files/use-china-mirrors.sh
Executable file
67
utils/ansible_executor/files/use-china-mirrors.sh
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/bin/bash
|
||||
# Switch CentOS Stream / EPEL repos to Aliyun mirrors (for builds in China).
|
||||
set -euo pipefail
|
||||
|
||||
mirror_centos() {
|
||||
for f in /etc/yum.repos.d/centos*.repo; do
|
||||
[ -f "$f" ] || continue
|
||||
sed -i \
|
||||
-e 's|^mirrorlist=|#mirrorlist=|g' \
|
||||
-e 's|^#baseurl=http://mirror.centos.org|baseurl=https://mirrors.aliyun.com|g' \
|
||||
-e 's|^#baseurl=https://mirror.centos.org|baseurl=https://mirrors.aliyun.com|g' \
|
||||
"$f"
|
||||
done
|
||||
}
|
||||
|
||||
mirror_epel() {
|
||||
# epel-release 默认只有 metalink,sed 改 baseurl 会失效;直接覆盖为阿里云固定地址
|
||||
cat > /etc/yum.repos.d/epel.repo <<'EOF'
|
||||
[epel]
|
||||
name=Extra Packages for Enterprise Linux 9 - $basearch
|
||||
baseurl=https://mirrors.aliyun.com/epel/9/Everything/$basearch
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
countme=0
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9
|
||||
|
||||
[epel-debuginfo]
|
||||
name=Extra Packages for Enterprise Linux 9 - $basearch - Debug
|
||||
baseurl=https://mirrors.aliyun.com/epel/9/Everything/$basearch/debug
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9
|
||||
|
||||
[epel-source]
|
||||
name=Extra Packages for Enterprise Linux 9 - $basearch - Source
|
||||
baseurl=https://mirrors.aliyun.com/epel/9/Everything/source/tree
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-9
|
||||
EOF
|
||||
|
||||
# epel-next 在阿里云 aarch64 上常 404,且 freetds-devel/sshpass 在 epel 主仓库即可
|
||||
rm -f /etc/yum.repos.d/epel-next.repo
|
||||
|
||||
# 禁用可能仍指向官方源的其他 epel 附属 repo
|
||||
for f in /etc/yum.repos.d/epel*.repo; do
|
||||
case "$(basename "$f")" in
|
||||
epel.repo) ;;
|
||||
*)
|
||||
sed -i 's/^enabled=1/enabled=0/g' "$f" || true
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
case "${1:-all}" in
|
||||
centos) mirror_centos ;;
|
||||
epel) mirror_epel ;;
|
||||
all)
|
||||
mirror_centos
|
||||
mirror_epel
|
||||
;;
|
||||
*)
|
||||
echo "usage: $0 [centos|epel|all]" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
10
utils/ansible_executor/requirements-python.txt
Normal file
10
utils/ansible_executor/requirements-python.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
# Aligned with JumpServer pyproject.toml ansible-related Python deps.
|
||||
paramiko==3.2.0
|
||||
sshtunnel==0.4.0
|
||||
pywinrm==0.4.3
|
||||
python-nmap==0.7.1
|
||||
mysqlclient==2.2.4
|
||||
pymssql==2.3.4
|
||||
pymongo==4.6.3
|
||||
oracledb==1.4.0
|
||||
pyfreerdp==0.0.2
|
||||
Reference in New Issue
Block a user