
    \i^                         S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKJ	r	J
r
Jr  SSKJrJr   SSKrSr " S S5      rg! \ a    Sr Nf = f)	uh   
简化版 Docker 执行服务
删除了所有 AI 相关功能，只保留核心的 Docker 部署功能
    N)DictListOptionaldatetime	timedeltaTFc            	       ^   \ rS rSrSrS#S jrS\4S jrS rS#S\	S	\
S
\4S jjrS\
S\\
\
4   4S jrS\\	   4S jrS\	4S jrS\	S\4S jrS\
S\	4S jrS\
S\
4S jrS\
S\
S\\
   4S jrS\
S\
S\4S jrS\
S\
S\4S jrS#S\
S\
S\	S\4S jjrS$S\
S\
S\	S\
4S  jjrS\
S\
S\4S! jrS"rg)%DockerExecutionService   uG   Docker执行服务，提供docker-compose命令的执行和管理功能Nc                 X   U=(       d    U R                  5       U l        U R                  R                  SS5      U l        U R                  R                  SS5      U l        U R                  R                  SS5      U l        [        R                  " U R                  SS9  0 U l        U R                  R                  S	S
5      U l	        U R                  R                  SS5      U l
        [        5       U l        [        R                  " 5       U l        [!        SU R                   35        g)u   初始化Docker执行服务deployment_root/tmp/ctf_deploymentscompose_commanddocker-composecommand_timeout,  T)exist_okport_range_start  port_range_endh  u5   Docker执行服务初始化完成，部署根目录: N)_get_default_configconfiggetr   r   r   osmakedirs_deployment_cacher   r   set_used_ports	threadingLock_lockprint)selfr   s     X   /Users/yu22x/Desktop/ddd_副本138/ctf/app/services/deployment/core/execution_service.py__init__DockerExecutionService.__init__   s    : 8 8 :#{{/@BXY#{{/@BRS#{{/@#F 	D((48 "$ !%0BE J"kkoo.>F5 ^^%
EdFZFZE[\]    returnc           	          SSSSSSSSS	.$ )
u   获取默认配置r   r   r   r   r   iQ Ti  )r   r   r   r   r   deployment_timeoutauto_cleanupcleanup_interval )r$   s    r%   r   *DockerExecutionService._get_default_config1   s&      6/" %#"'  $	
 		
r(   c                 <    UR                  S5      (       d  US-   $ U$ )u'   辅助函数：确保输出带换行符
)endswith)r$   messages     r%   _yield_line"DockerExecutionService._yield_line>   s"    %%T>!r(   challenge_idchallenge_diroptionsc           
   #      #    U=(       d    0 n[         R                  R                  U5      (       d  U R                  SU 35      v   gU R                  S5      v   U R	                  U5      nU(       d  Sv   gUR                  S5      nUR                  S5      nU(       a  SU 3v   OU(       a  SU 3v   OS	v   g[        [        R                  " 5       5      nS
U 3nUR                  SS5      SS n	U SU	 3n
SR                  S U
 5       5      n
SU 3v   SU
 3v   Sv    SSKJnJn  SSKJnJn  UR                   " 5       nX" UR                  SS5      S9-   nUUUR                  S5      U
SUUR#                  5       UR#                  5       S.nU" U5        U" USS5        U R                  S5      v   UR                  S5      nSn U(       a2  U R+                  U5      (       a  UnO)S U S!3v   U R-                  5       nOU R-                  5       nU(       d   S"v    SS#KJnJn  U" US$S%S&9  U" US$S%5        gS'U 3v   U(       GaU  S(v   [         R                  R1                  U5      nU R3                  UU5        S)U 3v   U R5                  XZ5        S*U
 3v   S+v   [         R                  R7                  U5      nS,S-US.US/S0/nS1S2R                  U5       3v   S3U 3v   [8        R:                  " U[8        R<                  [8        R>                  S4SUS59nUR@                   H  nURC                  5       v   M     URE                  5       nUS:w  a:  S6U 3v   U RG                  U5         SS#KJnJn  U" US$S7U 3S&9  U" US$S7U 35        gS8v   S9v   U RI                  UU5      nU(       d1  S:v   U RG                  U5         SS#KJnJn  U" US$S;S&9  U" US$S;5        gS<U 3v   UR                  S=5      =(       d     [         RJ                  R                  S>S?5      nS@U SAU 3nSBU 3v   SCv    SS#KJnJn  U" USDUUUUSE9  U" USDSFU SGU 35        U R                  SH5      v   U R                  SJ5      v   U R                  SKU SAU SAU SAU 35      v   gSLv   SMv   U RG                  U5        g! [$         a>  nU R                  S[        U5       35      v   SSKnUR)                  5          SnAGNESnAff = f!    g= f!    g= f!    g= f! [$         a=  nU R                  SI[        U5       35      v   SSKnUR)                  5          SnANSnAff = f! [$         a  nU(       a  U RG                  U5        SN[        U5       3v   SSKnSOURM                  5        3v    SS#KJnJn  U" US$SN[        U5       3S&9  U" US$SN[        U5       35         SnAg!     SnAg= fSnAff = f7f)Pu   执行部署操作（流式输出版本）

Args:
    challenge_id: 题目ID
    challenge_dir: 题目目录
    options: 部署选项

Yields:
    str: 部署过程的实时输出（每行带换行符）
u   错误: 题目目录不存在: Nu   查找Docker配置文件...uH   错误: 题目目录中没有发现Dockerfile或docker-compose.yml文件docker_compose
dockerfileu   找到docker-compose.yml: u   找到Dockerfile: u,   错误: 未找到有效的Docker配置文件
challenge_-    _c              3   R   #    U  H  oR                  5       (       a  UOS v   M     g7f)r@   N)isalnum).0cs     r%   	<genexpr>CDockerExecutionService.execute_deployment_stream.<locals>.<genexpr>p   s      SNqiikks!:Ns   %'u   生成部署ID: u   容器名称: u   创建部署记录...r   )create_deployment_recordadd_deployment_logr   timeout_days   )daysuser_idcreating)deployment_uuidr6   rL   container_namestatusworking_directory
created_at
expires_atu$   部署开始，正在准备环境...u   部署记录已创建u"   警告: 创建部署记录失败: portu   警告: 指定端口 u"    不可用，将自动分配端口u    错误: 无法分配可用端口)update_deployment_statusrH   erroru   无法分配可用端口)r3   u   分配端口: u   使用docker-compose.yml部署u    已更新外部端口映射为: u   已更新容器名称为: u&   开始执行docker-compose up命令...r   -pz-fupz-du   执行命令:  u   工作目录: T)stdoutstderrtextbufsizecwdu:   错误: docker-compose up 命令执行失败，返回码: u2   docker-compose up 命令执行失败，返回码: u$   docker-compose up 命令执行成功u   获取容器ID...u   错误: 无法获取容器IDu   无法获取容器IDu
   容器ID: host_addressHOST_ADDRESS	localhostzhttp://:u   访问地址: u   更新部署记录...running)container_idexternal_port
access_urlrQ   u   部署成功完成，容器ID: u
   , 端口: u   部署记录已更新u"   警告: 更新部署记录失败: u   部署成功完成！zDEPLOYMENT_SUCCESS:u   使用Dockerfile部署uA   注意: 此功能暂未实现，请使用docker-compose.yml配置u   部署过程中出错: u   错误详情:
)'r   pathexistsr4   _find_docker_filesr   struuiduuid4replacejoinapp.models.database.operationsrG   rH   r   r   now	isoformat	Exception	traceback	print_exc_check_port_available_allocate_portrU   dirname_update_compose_port_update_compose_container_namebasename
subprocessPopenPIPESTDOUTrZ   rstripwait_release_port_get_container_idenviron
format_exc) r$   r6   r7   r8   docker_filesdocker_compose_pathdockerfile_pathdeployment_idchallenge_name
uuid_shortrO   rG   rH   r   r   rR   rS   initial_deployment_recorders   rT   re   rU   
docker_dircompose_filecmdprocesslinereturn_coderd   r_   rf   s                                    r%   execute_deployment_stream0DockerExecutionService.execute_deployment_streamD   s     -Rww~~m,,""%D]O#TUU <==..}=\\*../?@&**<8./B.CDD&&788@@ DJJL) &l^4"**33BQ7
*+1ZL9 SN SS 00~.// &%	"c4 "J#iW[[QR5S&TTJ $1 ,";;y1"0$%2(224(224	)% %%>?}j:`a""#:;; {{6"X	--d33$(M1$7YZZ$($7$7$9M $ 3 3 5 88k,]GMgh&}g?YZ "=/22 #66  WW__-@A
 ))*=}M8HH 334GX2>2BCC ?>  "ww//0CD %-,$	 'sxx}o66&zl33 %**%??%,," $NND++-' + &lln!#VWbVcdd&&}5o0  TF  GR  FS  RT  U*='Ew  yD  xE  DF  G << *)#55mZP#88&&}5o0Qgh*='CYZ "<.11  '{{>:ibjjnn^]h>i&|nAm_E
&zl33 .-*k -%!%1&3#-*4 '}iCbcobppz  |I  {J  BK  L**+BCC &&'>??&&)<]O1\NZ[\i[jjklvkw'xyy /.YY""=1g  	"""%GAx#PQQ!!	"6x 2 ! ***-OPSTUPVx+XYY$''))*  	""=1+CF844#I$8$8$:#;<<g(KbcfghcibjIkl"='=TUXYZU[T\;]^^	s1  D%W>(BR> <W>AU( %T	 ?W> D4U( 5 T W>6U( T 'W>(AU( ;6T 12U( #W>$U( =W>>
T3T;W>TW>	TU( W>U( TU( W>U( TU( W>U( 
U%(3U U(  U%%U( (
W;2AW642W+&W>+W3-W6.W>3W66W;;W>	directoryc                     0 n[         R                  " U5       Hq  u  p4nU He  nUS:X  d  US:X  a$  [         R                  R                  X65      US'   M3  US:X  d  M;  SU;  d  MC  [         R                  R                  X65      US'   Mg     Ms     U$ )u   递归查找Docker配置文件zdocker-compose.ymlzdocker-compose.yamlr:   
Dockerfiler;   )r   walkrg   rn   )r$   r   resultrootr@   filesfiles          r%   ri   )DockerExecutionService._find_docker_files1  s     ggi0NDU//4;P3P/1ww||D/GF+,\)#61/1ww||D/G|,  1 r(   c                 <   U R                      [        U R                  U R                  5       HR  nXR                  ;  d  M  U R                  U5      (       d  M,  U R                  R                  U5        Us  sSSS5        $    SSS5        g! , (       d  f       g= f)u'   从端口池中分配一个可用端口N)r"   ranger   r   r   ru   addr$   rT   s     r%   rv   %DockerExecutionService._allocate_port?  sx    ZZd33T5H5HI///11$77((,,T2# ZI   Z s   1BBBB
BrT   c                     U R                      U R                  R                  U5        SSS5        g! , (       d  f       g= f)u   释放端口N)r"   r   discardr   s     r%   r   $DockerExecutionService._release_portI  s'    ZZ$$T* ZZs	   2
A c                     SSK n UR                  UR                  UR                  5       nUR                  SU45         SSS5        g! , (       d  f       g= f! [         a     gf = f)u   检查端口是否可用r   Nr>   TF)socketAF_INETSOCK_STREAMbindOSError)r$   rT   r   ss       r%   ru   ,DockerExecutionService._check_port_availableN  sW    	v~~v/A/ABaDz" CBB  		s.   &A A
A 

AA A 
A('A(compose_pathre   c                 x    [        US5       nUR                  5       nSSS5        SSKnSnSU S3nUR                  " XgWSS9n[        US	5       nUR	                  U5        SSS5        g! , (       d  f       NS= f! , (       d  f       g= f! [
         a!  n	[        S
[        U	5       35         Sn	A	gSn	A	ff = f)u   更新docker-compose.yml中的端口映射

支持多种端口映射格式：
- "10000:80"
- "10000:8080"
- "10000:3000"
- 0.0.0.0:10000:80
rNr   z8(\s+-\s+["\']?)(?:\d+\.\d+\.\d+\.\d+:)?(\d+)(:\d+["\']?)\g<1>\g<3>rJ   )countwu   更新端口映射失败: )openreadresubwriterr   r#   rj   )
r$   r   re   fcontentr   patternreplacementnew_contentr   s
             r%   rx   +DockerExecutionService._update_compose_portX  s    	9lC(A&&( )  RG"=/7K&&waHKlC(A$ )( )( )(  	9.s1vh788	9sK   B A,2B A=#B ,
A:6B =
BB B 
B9B44B9rO   c                     [        USSS9 nUR                  5       nSSS5        [        (       as   [        R                  " W5      nU(       aU  SU;   aO  US    H  nSUS   U   ;   d  M  X%S   U   S'   M     [        USSS9 n[        R
                  " XSSS	S
9  SSS5        gSnSU S3n	[        R                  " XW5      n
[        USSS9 nUR                  U
5        SSS5        g! , (       d  f       N= f! , (       d  f       Ne= f! [         a!  n[        S[        U5       35         SnANSnAff = f! , (       d  f       g= f! [         a!  n[        S[        U5       35         SnAgSnAff = f)uE   更新docker-compose.yml中的容器名称

避免容器名称冲突
r   zutf-8)encodingNservicesrO   r   FT)default_flow_styleallow_unicodeu*   YAML解析失败，使用正则表达式: z0(container_name\s*:\s*["\']?)([^"\'\n]+)(["\']?)r   r   u   更新容器名称失败: )r   r   HAS_YAMLyaml	safe_loaddumprr   r#   rj   r   r   r   )r$   r   rO   r   r   dataservice_namer   r   r   r   s              r%   ry   5DockerExecutionService._update_compose_container_names  s_   
	9lC':a&&( ; xQ>>'2D
d 2,0,<L/4
3CL3QQSaZ 0 >?O P -=
 ",gF! IId%W[\ G JG">"2%8K&&w?KlC':a$ ;:5 ;: GF ! QFs1vhOPPQ ;:  	9.s1vh788	9s   E
 C)E
 5D +D C:D $*E
 D9 E
 )
C73E
 :
DD 
D6D1,E
 1D66E
 9
EE
 E
 

E5E00E5r   r   c                 R    [         R                  " SSUSS/USSSS9nUR                  S:X  aK  UR                  R	                  5       (       a,  UR                  R	                  5       R                  S	5      S   $ g! [         a!  n[        S
[        U5       35         SnAgSnAff = f)u   获取容器IDr   rW   psz-qT   r^   capture_outputr\   timeoutr   r1   u   获取容器ID失败: N)	r{   run
returncoderZ   stripsplitrr   r#   rj   )r$   r   r   r   r   s        r%   r   (DockerExecutionService._get_container_id  s    	5^^!4dC#F   A%&--*=*=*?*?}}**,2248;;   	5*3q6(344	5s   A7A; ;
B&B!!B&rN   rQ   c                     [         R                  R                  U5      (       d  [         R                  R                  U5      n[         R                  R	                  U5      (       d  SSU 3S.$ [
        R                  " SSUS/USSSS	9nUR                  S
:X  a  SSS.$ SSUR                   3S.$ ! [         a  nSS[        U5       3S.s SnA$ SnAff = f)u   停止部署rV      工作目录不存在: rP   r3   r   rW   stopT<   r   r   successu   部署已停止u   停止失败: Nr   rg   isabsabspathrh   r{   r   r   r[   rr   rj   r$   rN   rQ   r   r   s        r%   stop_deployment&DockerExecutionService.stop_deployment  s    	M77==!233$&GGOO4E$F! 77>>"344")8OPaOb6cdd^^!4&A%#F   A%"+8IJJ")v}}o6VWW 	M%N3q6(2KLL	M*   A.B4 10B4 "B4 4
C>CCCc                     [         R                  R                  U5      (       d  [         R                  R                  U5      n[         R                  R	                  U5      (       d  SSU 3S.$ [
        R                  " SSUS/USSSS	9nUR                  S
:X  a  SSS.$ SSUR                   3S.$ ! [         a  nSS[        U5       3S.s SnA$ SnAff = f)u   启动部署rV   r   r   r   rW   startTr   r   r   r   u   部署已启动u   启动失败: Nr   r   s        r%   start_deployment'DockerExecutionService.start_deployment  s    	M77==!233$&GGOO4E$F! 77>>"344")8OPaOb6cdd^^!4'B%#F   A%"+8IJJ")v}}o6VWW 	M%N3q6(2KLL	Mr   c                 D    [         R                  R                  U5      (       d  [         R                  R                  U5      n[         R                  R	                  U5      (       dH  [        SU 35         [        R                  " SSUSS/SSSS9  U(       a  U R                  U5        SSS.$ [        R                  " SSUSS/USSSS9nU(       a  U R                  U5        [        SU 35        UR                  S:X  a  SSS.$ UR                  R                  5       nSU;   d  SU;   d  SU;   a  SSS.$ SSUR                   3S.$ ! [         a!  n[        S	[        U5       35         S
nANS
nAff = f! [         a  nSS[        U5       3S.s S
nA$ S
nAff = f)u   删除部署u   警告: 工作目录不存在: r   rW   downz-vTr   )r   r\   r   u   尝试停止容器失败: Nr   u<   部署已删除（工作目录不存在，已清理容器）r   r   u/   已停止并删除容器，保留工作目录: r   u<   部署已删除（容器已停止，题目文件已保留）zno such servicez	not foundzno resource foundu<   部署已删除（容器不存在，题目文件已保留）rV   u   删除失败: )r   rg   r   r   rh   r#   r{   r   rr   rj   r   r   r[   lower)r$   rN   rQ   re   r   r   r[   s          r%   delete_deployment(DockerExecutionService.delete_deployment  s   5	M77==!233$&GGOO4E$F! 77>>"34478I7JKLANN)4&$O'+! "	 !&&}5"+8vww  ^^!4&$G%#F ""=1 CDUCVWX  A%"+8vww  ,,.$.+2GK^bhKh&/<z{{")v}}o6VWWG ! A6s1vh?@@AH  	M%N3q6(2KLL	Ms[   A5E: 8E E: 1AE: 	0E: :E: 
E7E2-E: 2E77E: :
FFFFtailc                 ,    [         R                  R                  U5      (       d  [         R                  R                  [         R                  R                  [         R                  R                  [         R                  R                  [         R                  R                  [         R                  R	                  [
        5      5      5      5      5      5      n[         R                  R                  XB5      n[         R                  R                  U5      (       d  SU 3$ [        R                  " SSUSS[        U5      /USSSS9nUR                  S	:X  a  UR                  $ UR                  $ ! [         a  nS
[        U5       3s SnA$ SnAff = f)u   获取容器日志u*   获取日志失败: 工作目录不存在 r   rW   logsz--tailTr   r   r   u   获取日志失败: N)r   rg   r   rw   r   __file__rn   rh   r{   r   rj   r   rZ   r[   rr   )r$   rN   rQ   r   base_dirr   r   s          r%   get_container_logs)DockerExecutionService.get_container_logs  s:   	377==!23377??277??277??277??[][b[b[j[jkmkrkrkzkz  |D  lE  \F  LG  <H  ,I  J$&GGLL$M!77>>"344CDUCVWW^^!4&(CPTIV%#F %+$5$5$:6==MM 	3)#a&22	3s+   DE1 "AE1 %E1 1
F;FFFc                     [         R                  " SSUS/USSSS9nUR                  S:X  a'  UR                  nSU;   a  S	US
.$ SU;   a  SUS
.$ SUS
.$ SUR                  S
.$ ! [
         a  nS[        U5      S
.s SnA$ SnAff = f)u   获取容器状态r   rW   r   Tr   r   r   Uprc   )rP   detailsExitstoppedunknownrV   N)r{   r   r   rZ   r[   rr   rj   )r$   rN   rQ   r   outputr   s         r%   get_container_status+DockerExecutionService.get_container_status0  s    	:^^!4$?%#F   A%6>&/FCCv%&/FCC&/FCC")fmmDD 	:%#a&99	:s0   AA$ 
A$ A$ A$ $
B.B;BB)	r   r"   r   r   r   r   r   r   r   )N)d   )__name__
__module____qualname____firstlineno____doc__r&   r   r   r4   intrj   r   ri   r   rv   r   boolru   rx   ry   r   r   r   r   r   r   __static_attributes__r.   r(   r%   r
   r
      sq   Q^.
T 
kc k# kX\ kZC DcN  +# +
# $ 9 9S 96$93 $9PS $9Ls  QT $Ms Ms Mt M4M M MPT M47M 7M 7M]` 7Mlp 7Mr3# 3# 3UX 3cf 30:C :C :TX :r(   r
   )r  r   r{   shutiltimerk   r    r   typingr   r   r   r   r   r   r   ImportErrorr
   r.   r(   r%   <module>r
     sY    
      	 ' ' (H
p: p:	  Hs   A AA