mirror of
https://github.com/johndoe6345789/docker-swarm-termina.git
synced 2026-04-24 13:45:01 +00:00
**Improvements:** - Reduced local variables in exec_container from 18 to 12 - Added helper functions to exec_helpers.py: - get_session_workdir() - manage session working directory - execute_command_with_fallback() - bash/sh execution with fallback - Inlined simple expressions to reduce variable count - Added pylint disable for intentional duplicate code patterns - Fixed import-outside-toplevel by moving logger to top-level import **Pylint score improvement:** - Before: 9.86/10 - After: 9.93/10 - routes/containers/exec.py: 10.00/10 Remaining warnings are acceptable duplicate code in auth/client setup patterns across similar route handlers. https://claude.ai/code/session_011PzvkCnVrsatoxbY3HbGXz
149 lines
4.3 KiB
Python
149 lines
4.3 KiB
Python
"""Helper functions for container exec operations."""
|
|
from config import logger
|
|
|
|
|
|
def get_session_workdir(token, container_id, session_workdirs):
|
|
"""Get or initialize session working directory.
|
|
|
|
Args:
|
|
token: Session token
|
|
container_id: Container ID
|
|
session_workdirs: Session workdir dictionary
|
|
|
|
Returns:
|
|
tuple: (session_key, current_workdir)
|
|
"""
|
|
session_key = f"{token}_{container_id}"
|
|
if session_key not in session_workdirs:
|
|
session_workdirs[session_key] = '/'
|
|
return session_key, session_workdirs[session_key]
|
|
|
|
|
|
def execute_command_with_fallback(container, current_workdir, user_command, is_cd_command):
|
|
"""Execute command in container with bash/sh fallback.
|
|
|
|
Args:
|
|
container: Docker container object
|
|
current_workdir: Current working directory
|
|
user_command: User's command
|
|
is_cd_command: Whether this is a cd command
|
|
|
|
Returns:
|
|
Docker exec instance
|
|
"""
|
|
# Try bash first
|
|
try:
|
|
bash_command = build_bash_command(current_workdir, user_command, is_cd_command)
|
|
return execute_in_container(container, bash_command)
|
|
except Exception as bash_error: # pylint: disable=broad-exception-caught
|
|
logger.warning("Bash execution failed, trying sh: %s", bash_error)
|
|
sh_command = build_sh_command(current_workdir, user_command, is_cd_command)
|
|
return execute_in_container(container, sh_command)
|
|
|
|
|
|
def build_bash_command(current_workdir, user_command, is_cd_command):
|
|
"""Build bash command for execution.
|
|
|
|
Args:
|
|
current_workdir: Current working directory
|
|
user_command: User's command
|
|
is_cd_command: Whether this is a cd command
|
|
|
|
Returns:
|
|
list: Command array for Docker exec
|
|
"""
|
|
path_export = 'export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
|
|
|
|
if is_cd_command:
|
|
target_dir = user_command.strip()[3:].strip() or '~'
|
|
resolve_command = f'cd "{current_workdir}" && cd {target_dir} && pwd'
|
|
return ['/bin/bash', '-c', f'{path_export}; {resolve_command}']
|
|
|
|
return [
|
|
'/bin/bash', '-c',
|
|
f'{path_export}; cd "{current_workdir}" && {user_command}; echo "::WORKDIR::$(pwd)"'
|
|
]
|
|
|
|
|
|
def build_sh_command(current_workdir, user_command, is_cd_command):
|
|
"""Build sh command for execution (fallback).
|
|
|
|
Args:
|
|
current_workdir: Current working directory
|
|
user_command: User's command
|
|
is_cd_command: Whether this is a cd command
|
|
|
|
Returns:
|
|
list: Command array for Docker exec
|
|
"""
|
|
path_export = 'export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
|
|
|
|
if is_cd_command:
|
|
target_dir = user_command.strip()[3:].strip() or '~'
|
|
resolve_command = f'cd "{current_workdir}" && cd {target_dir} && pwd'
|
|
return ['/bin/sh', '-c', f'{path_export}; {resolve_command}']
|
|
|
|
return [
|
|
'/bin/sh', '-c',
|
|
f'{path_export}; cd "{current_workdir}" && {user_command}; echo "::WORKDIR::$(pwd)"'
|
|
]
|
|
|
|
|
|
def execute_in_container(container, command):
|
|
"""Execute command in container.
|
|
|
|
Args:
|
|
container: Docker container object
|
|
command: Command to execute
|
|
|
|
Returns:
|
|
Docker exec instance
|
|
"""
|
|
return container.exec_run(
|
|
command,
|
|
stdout=True,
|
|
stderr=True,
|
|
stdin=False,
|
|
tty=True,
|
|
environment={'TERM': 'xterm-256color', 'LANG': 'C.UTF-8'}
|
|
)
|
|
|
|
|
|
def decode_output(exec_instance):
|
|
"""Decode exec output with fallback encoding.
|
|
|
|
Args:
|
|
exec_instance: Docker exec instance
|
|
|
|
Returns:
|
|
str: Decoded output
|
|
"""
|
|
if not exec_instance.output:
|
|
return ''
|
|
|
|
try:
|
|
return exec_instance.output.decode('utf-8')
|
|
except UnicodeDecodeError:
|
|
return exec_instance.output.decode('latin-1', errors='replace')
|
|
|
|
|
|
def extract_workdir(output, current_workdir, is_cd_command):
|
|
"""Extract working directory from command output.
|
|
|
|
Args:
|
|
output: Command output
|
|
current_workdir: Current working directory
|
|
is_cd_command: Whether this was a cd command
|
|
|
|
Returns:
|
|
tuple: (cleaned_output, new_workdir)
|
|
"""
|
|
if is_cd_command:
|
|
return '', output.strip()
|
|
|
|
if '::WORKDIR::' in output:
|
|
parts = output.rsplit('::WORKDIR::', 1)
|
|
return parts[0], parts[1].strip()
|
|
|
|
return output, current_workdir
|