
    \iRg                        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  S SKJrJ	r	J
r
JrJrJrJrJrJrJrJrJr  S SKJr  S SKJr  S SKJrJrJrJrJrJrJr  \" S\ 5      r!S\"4S	 jr#\!RI                  S
S/S9\!RI                  SS/S9\S 5       5       5       r%\!RI                  SS/S9\S 5       5       r&\!RI                  SSS/S9\S 5       5       r'\!RI                  SS/S9\S 5       5       r(\!RI                  SS/S9\S 5       5       r)\!RI                  SS/S9\S 5       5       r*\!RI                  SS/S9\S 5       5       r+\!RI                  SS/S9\S 5       5       r,\!RI                  SS/S9\S 5       5       r-g)     N)datetime	timedelta)	Blueprintrender_templaterequestjsonifygredirecturl_forcurrent_appflashsessionResponsestream_with_context)docker_service)login_required)get_challenge_recordcreate_deployment_recordget_deployment_by_uuidget_deployments_by_userupdate_deployment_statusget_deployment_logsdelete_deployment_record
deploymentworking_dirc                 :    SS K nSS KnS nSnU HB  nUR                  R                  X5      nUR                  R	                  U5      (       d  M@  Un  O   U(       dP  UR
                  " U 5       H:  u  pxn	U	 H%  n
X;   d  M
  UR                  R                  Xz5      n  O   U(       d  M:    O   U(       d  / $ [        USSSS9 nUR                  5       nS S S 5        UR                  SW5      n/ nU H6  u  nnnUR                  U=(       d    S[        U5      [        U5      45        M8     [        5       n/ nU H;  nUS   US	   US
   4nUU;  d  M  UR                  U5        UR                  U5        M=     U$ ! , (       d  f       N= f! [         a    / s $ f = f)Nr   )zdocker-compose.ymlzdocker-compose.yamlzcompose.ymlzcompose.yamlrutf-8ignoreencodingerrorsz5-\s*[\"']?(?:(\d+\.\d+\.\d+\.\d+):)?(\d+):(\d+)[\"']?z0.0.0.0      )osrepathjoinexistswalkopenreadfindallappendintsetadd	Exception)r   r%   r&   compose_path
candidatesnameproot_dirsfilesfrfcontentmappingsresulthostextinterseenuniqmkeys                         J   /Users/yu22x/Desktop/ddd_副本138/ctf/app/routes/deployment/controller.py_extract_port_mappingsrG      s~   %a
D[/Aww~~a   	 
 &(ggk&:"UA')ww||D'<   < '; I,ghG2ggiG H ::VX_` (D#uMM4,9c#hE
CD !) uAQ41qt$C$A	 
  HG   	sI   A
F -F $F )F 6F E:A;F 'F :
FF FFz/select-challengeGET)methodsz/deployc                  *    [        [        S5      5      $ )u0   选择题目进行部署 - 重定向到主页面deployment.index)r
   r        rF   select_challengerN   <   s    
 G./00rM   /c            	      b	   [        [        S5      (       a  [        R                  (       d  [        [	        S5      5      $ [        [        R                  R                  5      n [        R                  R                  S5      =(       dI    [        R                  R                  S5      S   =(       d     [        R                  R                  SS5      nU  GH  n SnUR                  S	5      (       aW   [        [        UR                  S	5      5      5      nU(       a,  XBS
'   UR                  S5      =(       d    SR#                  5       nU(       d(  UR                  S5      =(       d    SR#                  5       nU(       dC  UR                  S5      =(       d    UR                  S5      =(       d    SSS nU(       a  SU 3OSnX2S'    UR                  S5      nU(       a  [$        R&                  " UR                  S5      U5      nUR                  S5      S:X  aN  UR                  S5      nU(       a6  XR                  S5      :w  a"  XS'   SSKJn	  U	" UR                  S5      U5        UR                  S5      (       a  SU SUR                  S5       3/US'   GM  UR                  S5      nU(       a  [5        U5      O/ nU(       a  / n[7        5       nU H9  u  nnnUUU4nUU;  d  M  UR9                  U5        UR;                  UUU45        M;     XS'   / nU H2  u  nnnUS;   d  M  US:X  a  S OS!nUR;                  U S"U SU 35        M4     UUS'   GM  GM     SS$KJn  U" [        R                  R                  5      n0 nU  HH  nUR                  S	5      (       d  M  [        US	   5      nUU;  a  / UU'   UU   R;                  U5        MJ     U HH  nUR                  US   / 5      n[?        S% U 5       5      n[A        U5      U[A        U5      S:  S&.US''   MJ     [C        S(U US)9$ ! [          a    Sn GN&f = f! [          a6  n
[-        S[/        U
5       35        SSKnUR3                  5          Sn
A
GNSn
A
ff = f! [          a#  n
[-        S#[/        U
5       35         Sn
A
GM  Sn
A
ff = f)*u   部署管理主页user
auth.loginX-Forwarded-Host:r   HOST_ADDRESS	localhostNchallenge_id	challenger5    container_namedeployment_uuidid   u   部署#   未命名题目display_nameworking_directorystatussuccesscontainer_status)r   u   获取部署状态失败: external_porthttp://access_urlsport_mappingsP   i  i@  i    i  rj   httpshttp://u   处理部署记录时出错: )get_challenges_by_userc              3   R   #    U  H  oR                  S 5      S:X  d  M  Sv   M     g7f)ra   runningr#   N)get).0ds     rF   	<genexpr>index.<locals>.<genexpr>   s"     ]'<!hS\@\AA'<s   '	')totalrp   has_deploymentdeployment_statszpages/deployment/index.html)deployments
challenges)"hasattrr	   rQ   r
   r   r   r\   r   headersrq   r?   splitr%   environr   r/   r2   stripr   get_container_statusapp.models.database.operationsr   printstr	traceback	print_excrG   r0   r1   r.   rn   sumlenr   )ry   r?   rs   r_   rX   short_idr`   status_resultrc   r   er   wdportsunique_portsseen_mappingshr@   rA   mapping_keyurlsschemern   rz   deployment_mapcidchallenge_deploymentsrunning_counts                               rF   indexr   D   s?    1fQVV-.. *!&&))4K ??12gll6H6H6Ma6PTVT^T^TbTbcqs~TD?	Luu^$$% 4S~9N5O PI %.kN$-MM&$9$?R#F#F#HL !&6 7 =2DDFEE"34IdIr2AN7?
3EV ,n&$%EE*=$>!$$2$G$GN_H`bs$tM$((2i?+8+<+<=O+P(+0@EE(O0S*:hK_4QUU;L5MO_` uu_%%&-dV1QUU?5K4L$M#N-  UU./68.r2b#%L$'EM).3'(#uo&m;)--k:(//C@	 */ *6o&D)53 $EE05W&F KK6(#dV1SE(BC *6 (,Am$# Y F F'		2J N55  a'(C.(&(s#3&&q)   	 . 2 29T?B G]'<]]./$!"781<)
	$%   % c ! % $I%0  &23q6(;< ##%%&>  	1#a&:;	s{   R1#P+B0RB!P>&1RA
R(<R(,R+P;7R:P;;R>
Q>+Q93R9Q>>R
R.R))R.z/execute/<int:challenge_id>POSTc           	      L	  ^ ^^ [        [        S5      (       a  [        R                  (       d   [        SS5        [	        [        S5      5      $ [        R                  S:X  a  [	        [        S5      5      $ [        R                  R                  S5      S:H  n[        T 5      mT(       d6  U(       a  U 4S	 jn[        [        U" 5       5      SS
9$ [        SST  3S.5      $ TR                  S5      [        R                  R                  :w  aN  [        R                  R                  S:w  a0  U(       a  S n[        [        U" 5       5      SS
9$ [        SSS.5      $ SnSn[        R                   R                  SS5      nU(       a   [#        U5      nXS:  d  XT:  a  Sn[        R                   R                  SS5      n [#        U5      nUS:  a  SnOUS:  a  Sn[        R                  R                  S5      =(       d"    [        R&                  R)                  S5      S   nUUS-  UU[        R                  R                  US.mU(       a   UU U4S jn[        [        U" 5       5      SS
9$ [*        R,                  " 5        n TR                  S0 5      n	U	(       d  [        SS S.5      sSSS5        $ U	R/                  5        H  u  pU(       d  M  [0        R2                  R5                  X5      n[0        R6                  " [0        R2                  R9                  U5      S!S"9  [;        US#S$S%9 nUR=                  U5        SSS5        M     [>        R@                  " T UT5      nUR                  S&5      S':X  a  UR                  S(0 5      n[        R                  R                  US'   [C        U5      n[        S'UR                  S)S*5      UR                  S+5      UR                  S,5      S-.5      sSSS5        $ [        SUR                  S)S.5      S.5      sSSS5        $ ! [$         a    Sn GNf = f! [$         a    Sn GNif = f! , (       d  f       GM  = f! [D         a-  n[        SS/[G        U5       3S.5      s SnAsSSS5        $ SnAff = f! , (       d  f       g= f)0u8   部署指定的题目

Args:
    challenge_id: 题目ID
rQ      请先登录dangerrR   rH   zdeployment.select_challengeAcceptztext/event-streamc               3   4   >#    SR                  T 5      v   g 7f)Nu,   获取题目失败: 题目不存在 (ID: {}))format)rW   s   rF   generate$execute_deployment.<locals>.generate   s     DKKLYYs   )content_typeerroru   题目不存在: ra   messageuser_idadminc               3      #    Sv   g 7f)Nu,   权限错误: 您没有权限部署此题目rL   rL   rM   rF   r   r      s     DDs   u   您没有权限部署此题目i  ih  portNtimeout_daysr#      rS   rT   r   iQ )r   timeoutr   stream_outputr   host_addressc               3     >#    SR                  TR                  SS5      5      v   Sv    TR                  S5      n U (       d  Sv   g [        R                  R	                  U 5      (       d  SU  3v   g [        R                  R                  U S5      n[        R                  R	                  U5      (       d  S	U 3v   g S
U S3v   Sv   [        R                  " TUT5       H&  nUR                  S5      (       d	  US-   v   M"  Uv   M(     Sv   g ! [         a:  nSR                  [        U5      5      v   SS KnUR                  5          S nAg S nAff = f7f)Nu   开始部署题目: {}r5   r^   u   正在准备部署环境...
output_diru&   错误: 题目没有输出目录信息u   错误: 输出目录不存在: dockeru   错误: Docker目录不存在: u   找到Docker目录: 
u   开始执行部署...
u   部署过程完成
u   部署过程中出错: {}r   )r   rq   r%   r'   r)   r(   r   execute_deployment_streamendswithr2   r   r   r   )r   
docker_diroutputr   r   rX   rW   deployment_optionss        rF   r   r     s5    *11)--HY2Z[[//#&&]]<8
!BB ww~~j11;J<HH  WW\\*h?
ww~~j11;J<HH,ZL;;// -FF|U_astF!??400$tm+$ u -, &188Q@@ ##%%&sT   (ED E	+D 4E5AD  EAD E
E0EEEE
code_filesu   题目没有代码文件T)exist_okwr   )r!   ra   rb   r   r   u   部署成功r\   
access_url)ra   r   deployment_idr   u   部署失败u   部署过程中出错: )$r{   r	   rQ   r   r
   r   r   methodr|   rq   r   r   r   r   r\   roleformr/   
ValueErrorr?   r}   tempfileTemporaryDirectoryitemsr%   r'   r(   makedirsdirnamer+   writer   execute_deploymentr   r2   r   )rW   r   r   PORT_MINPORT_MAXr   r   r   temp_dirr   	file_pathfile_content	full_pathr:   r>   deployment_datarecordr   rX   r   s   `                 @@rF   r   r      s    1fQVVnh'-.. ~~ =>?? OO''15HHM %\2IZ/
;J]^^!.|n=   }}Y16699,1GE/
;J]^^!;   HH<<FD)D	t9D$/ <<##NA6L<(!LAL ??&&'9:Xgll>P>PQT>UVW>XL %'$&6699$ '	&T +HJ7FYZZ 
	$	$	&(2	"|R8J%9   
'	& ,6+;+;+='	# GGLL=	BGGOOI6F )S7;qGGL) <; ,> $66|XOabFzz(#y0"(**\2">-.VVYY	* 2/B'%zz)^D%4%8%8%>"1"5"5l"C	  I 
'	&V %%zz)^D  W 
'	&W  	D	  n <;4  	!4SVH=  c 
'	&`	a 
'	&s   P" ?P5 P5 R&Q5A:Q/QB0Q;Q"P21P25QQ
Q	Q
R%R>R?RRR
R#z/status/<deployment_uuid>c                    [        [        S5      (       a  [        R                  (       d  [        SSS.5      $ [	        U 5      nU(       d  [        SSS.5      $ UR                  S5      [        R                  R                  :w  a,  [        R                  R                  S:w  a  [        SSS.5      $ UR                  S	5      nU(       d  [        SS
S.5      $ [        R                  " X5      nUR                  S5      S:X  aI  UR                  S5      nU(       a#  XAR                  S5      :w  a  [        X5        XAS'   [        SUS.5      $ [        SUR                  SS5      S.5      $ )u:   获取部署状态

Args:
    deployment_uuid: 部署UUID
rQ   r   r   r      部署记录不存在r   r      没有权限查看此部署r`      部署工作目录不存在ra   rb   rc   )ra   r   r   u   获取状态失败)r{   r	   rQ   r   r   rq   r\   r   r   r   r   )r[   r   r`   r   rc   s        rF   
get_statusr   h  sA    1fQVV'nEFF (8J'6MNOO ~~i AFFII-!&&++2H'6STUU #':;'6STUU #77[M"i/(,,-?@ 0NN84L L$_G#3x $
  	
 $((4HI
  	rM   z/logs/<deployment_uuid>c                 6   [        [        S5      (       a  [        R                  (       d  [        SSS.5      $ [	        U 5      nU(       d  [        SSS.5      $ UR                  S5      [        R                  R                  :w  a,  [        R                  R                  S:w  a  [        SSS.5      $ UR                  S	5      nU(       d  [        SS
S.5      $ [        R                  " XSS9n[        U 5      nSSKn/ nU(       a  UR                  S5      (       di  UR                  5        HU  nUR                  5       (       d  M  UR                  UR                  R!                  5       R#                  S5      US.5        MW     U(       d  U H{  nUR                  S5      n	[        U	S5      (       a  U	R#                  S5      O
[%        U	5      n
UR                  U
SUR                  SS5       SUR                  SS5       3S.5        M}     [        SUUS.5      $ )uu   获取部署日志（用于右侧实时日志面板）

返回统一的 logs 数组，元素为 {timestamp, message}
rQ   r   r   r   r   r   r   r   r`   r      )tailr   Nu   获取日志失败z%Y-%m-%d %H:%M:%S)	timestampr   r   strftime[ra   rY   z] r   rb   )ra   logsstatus_logs)r{   r	   rQ   r   r   rq   r\   r   r   get_container_logsr   r   
startswith
splitlinesr   r.   nowr   r   )r[   r   r`   	logs_textdb_logsr   combinedlineltsts_strs              rF   get_logsr     s    1fQVV'nEFF (8J'6MNOO ~~i AFFII-!&&++2H'6STUU #':;'6STUU 11/[^_I "/2G H --.BCC((*Dzz||!)!2!2!6!6!8!A!ABU!V#!  + A{#B9@Z9P9PR[[!45VYZ\V]FOO#quuXr232aeeIb6I5JK     rM   z/stop/<deployment_uuid>c                 v   [        [        S5      (       a  [        R                  (       d  [        SSS.5      $ [	        U 5      nU(       d  [        SSS.5      $ UR                  S5      [        R                  R                  :w  a,  [        R                  R                  S:w  a  [        SSS.5      $ UR                  S	5      nU(       d  [        SS
S.5      $ [        R                  " X5      nUR                  S5      S:X  a  [        U S5        [        SSS.5      $ [        SUR                  SS5      S.5      $ )u4   停止部署

Args:
    deployment_uuid: 部署UUID
rQ   r   r   r   r   r   r      没有权限操作此部署r`   r   ra   rb   stoppedu   部署已停止r   u   停止部署失败)r{   r	   rQ   r   r   rq   r\   r   r   stop_deploymentr   r[   r   r`   r>   s       rF   r   r     s    1fQVV'nEFF (8J'6MNOO ~~i AFFII-!&&++2H'6STUU #':;'6STUU ++OOFzz(y( )<(
  	
 zz)-AB
  	rM   z/start/<deployment_uuid>c                 v   [        [        S5      (       a  [        R                  (       d  [        SSS.5      $ [	        U 5      nU(       d  [        SSS.5      $ UR                  S5      [        R                  R                  :w  a,  [        R                  R                  S:w  a  [        SSS.5      $ UR                  S	5      nU(       d  [        SS
S.5      $ [        R                  " X5      nUR                  S5      S:X  a  [        U S5        [        SSS.5      $ [        SUR                  SS5      S.5      $ )u4   启动部署

Args:
    deployment_uuid: 部署UUID
rQ   r   r   r   r   r   r   r   r`   r   ra   rb   rp   u   部署已启动r   u   启动部署失败)r{   r	   rQ   r   r   rq   r\   r   r   start_deploymentr   r   s       rF   r   r     s    1fQVV'nEFF (8J'6MNOO ~~i AFFII-!&&++2H'6STUU #':;'6STUU ,,_PFzz(y( )<(
  	
 zz)-AB
  	rM   z/delete/<deployment_uuid>c                    [        [        S5      (       a  [        R                  (       d  [        SSS.5      $ [	        U 5      nU(       d  [        SSS.5      $ UR                  S5      [        R                  R                  :w  a,  [        R                  R                  S:w  a  [        SSS.5      $ UR                  S	5      nUR                  S
5      nU(       d  [        SSS.5      $ [        R                  " XU5      nUR                  S5      S:X  a  [        U 5        [        SSS.5      $ [        SUR                  SS5      S.5      $ )u4   删除部署

Args:
    deployment_uuid: 部署UUID
rQ   r   r   r   r   r   r   r   r`   rd   r   ra   rb   u   部署已删除r   u   删除部署失败)r{   r	   rQ   r   r   rq   r\   r   r   delete_deploymentr   )r[   r   r`   rd   r>   s        rF   r   r   ,  s"    1fQVV'nEFF (8J'6MNOO ~~i AFFII-!&&++2H'6STUU #':;NN?3M'6STUU --oR_`Fzz(y( 1(
  	
 zz)-AB
  	rM   z/view/<deployment_uuid>c                 "	   [        [        S5      (       a  [        R                  (       d  [        [	        S5      5      $ [        U 5      nU(       d   [        SS5        [        [	        S5      5      $ UR                  S5      [        R                  R                  :w  a>  [        R                  R                  S:w  a   [        SS5        [        [	        S5      5      $ [        U 5      nUR                  S	5      nU(       af  [        R                  " X5      nUR                  S
5      S:X  a;  UR                  S5      nU(       a#  XQR                  S
5      :w  a  [        X5        XQS
'   SnUR                  S5      (       a  [        UR                  S5      5      n UR                  S	5      nU(       a  [        U5      O/ nU(       a  / n	[!        5       n
U H5  u  pnXU4nX;  d  M  U
R#                  U5        U	R%                  XU45        M7     XS'   [&        R(                  R                  S5      =(       dI    [&        R*                  R-                  S5      S   =(       d     [.        R0                  R                  SS5      n/ nU	 H1  u  pnUS;   d  M  US:X  a  SOSnUR%                  U SU SU 35        M3     UUS'   OUR                  S5      (       a  [&        R(                  R                  S5      =(       dI    [&        R*                  R-                  S5      S   =(       d     [.        R0                  R                  SS5      nSU SUR                  S5       3/US'   Sn UR                  S	5      nU(       a  [.        R8                  R;                  U5      (       a  [.        R8                  R=                  USSS 5      [.        R8                  R=                  USS!S 5      /nU HN  n[.        R8                  R?                  U5      (       d  M)  [A        US"S#S$S%9 nURC                  5       nSSS5          O   [E        S&UUUUS'9$ ! [2         a"  n[5        S[7        U5       35         SnAGNSnAff = f! , (       d  f       NN= f! [2         a     NYf = f)(u:   查看部署详情

Args:
    deployment_uuid: 部署UUID
rQ   rR   r   r   rK   r   r   r   r`   ra   rb   rc   NrW   rg   rS   rT   r   rU   rV   rh   rj   rk   rl   rm   rf   rd   re   u   处理端口映射时出错: Checkerattazweb1.pyr   r   r   r   r    zpages/deployment/view.html)r   r   rX   check_script_content)#r{   r	   rQ   r
   r   r   r   rq   r\   r   r   r   r   r   r   rG   r0   r1   r.   r   r|   r?   r}   r%   r~   r2   r   r   r'   isdirr(   r)   r+   r,   r   )r[   r   r   r`   r   rc   rX   r   r   r   r   r   r@   rA   r   r?   r   r   r   r   r4   r6   r;   s                          rF   view_deploymentr   X  s    1fQVV-.. (8J%w/ 2344 ~~i AFFII-!&&++2H+W5 2344 /D #':;&;;O_X&)3,001CD$4x8P$P(K'78$ I~~n%%()GH	^^/0.0&r*bLEM!& uo3!%%k2 ''8	 "' +7'??&&'9:  Hgll>P>PQT>UVW>X  H\^\f\f\j\jky  |G  ]HDD!-==(-W&FKK6(#dV1SE :; ". )-J}%^^O,,??&&'9:  Hgll>P>PQT>UVW>X  H\^\f\f\j\jky  |G  ]HD+24&*..:Y9Z)[(\J}%  ^^/0"''--##RFI>RGY?J  77>>!$$awxHB/1wwy, I	   $1 +  -c!fX67 IH  sd   AQ #B)Q ,Q =B Q  B'R R Q0(	R 2R 
Q-Q((Q-0
Q>	:R 
RR).r%   r   shutiltimejsonr   r   flaskr   r   r   r   r	   r
   r   r   r   r   r   r   app.services.deploymentr   app.services.auth.decoratorsr   r   r   r   r   r   r   r   r   __name__bpr   rG   routerN   r   r   r   r   r   r   r   r   rL   rM   rF   <module>r      s   	     ( Q  Q  Q  Q 2 7   |X&& &R 
w/)eW%1  & 01
 #wg   gR 
'&%Au  Bun 
%w7)  8)Z 
#eW57  67~ 
#fX6&  7&P 
$vh7&  8&P 
%x8(  9(T 
#eW5\  6\rM   