o
    i::                     @   s  d dl Z d dlmZ d dlmZ d dlZd dlmZ d dlm	Z	 d dl
mZ d dlmZmZ d dlmZ ejd	d
ddZG dd deeZdd ZdJdededee defddZdedefddZdJdefddZ	dKdee dedededef
dd Z	dJd!ed"ed#ed$ee def
d%d&Zejd'd(d)e	jeej ddd*ej!dd+d,d-ej dd.d/d0d1d2ej dd3d4d5d1d2ej dd6d7d1d2ej dd8d9d:d;d2ej d,d<d=d;d2ej d,d>d?d;d2fd#ed@edAed$edBedCedDefdEdFZ"dGejfdHdIZ#dS )L    N)Enum)Optional)Panel)synchronizer)console)DeployConfigParamswith_deploy_config)PIPECAT_CLI_NAMEdockerzDocker build and push utilitiesT)namehelpno_args_is_helpc                   @   s   e Zd ZdZdZdS )RegistryType	dockerhubcustomN)__name__
__module____qualname__	DOCKERHUBCUSTOM r   r   T/home/ubuntu/.local/lib/python3.10/site-packages/pipecatcloud/cli/commands/docker.pyr      s    r   c                  C   s   t d t d t d t d t d tjdddrHt d	 g d
} t| dddr7t d dS t d t d t d dS t d t d dS )zMSuggest and optionally install binfmt_misc support for cross-platform builds.u>   
[yellow]⚠️  Cross-platform build support missing[/yellow]zZ[yellow]   Building ARM64 images on x86_64 requires QEMU and binfmt_misc support.[/yellow]zS
[yellow]   This is a one-time setup that persists across Docker restarts.[/yellow]zU
[dim]   The following command will be run (requires Docker --privileged flag):[/dim]zJ[dim]   docker run --privileged --rm tonistiigi/binfmt --install all[/dim]z.
Would you like to install binfmt support now?Tdefaultz*
[cyan]Installing binfmt support...[/cyan])r
   runz--privilegedz--rmztonistiigi/binfmtz	--installallz'Setting up cross-platform build supportFstream_outputu;   ✓ binfmt support installed! You can now retry your build.z!Failed to install binfmt support.z9
[yellow]You can install it manually by running:[/yellow]zP[yellow]   docker run --privileged --rm tonistiigi/binfmt --install all[/yellow]zB
[yellow]Skipping installation. To install manually, run:[/yellow]N)r   printtyperconfirmrun_docker_commandsuccesserror)install_cmdr   r   r   _suggest_and_install_binfmt   s6   


	


r%   stderrstdoutcommandregistry_infoc                 C   sb   |   }|  }| d| }d|v sd|v rt  dS t|r-dd|v r/t| dS dS dS )zJProvide helpful error hints only when Docker's message isn't clear enough. zexec format errorzexec /bin/sh: exec format errorNpush)lowerr%   _is_auth_errorjoin_suggest_docker_login)r&   r'   r(   r)   stderr_lowerstdout_lowercombined_outputr   r   r   _provide_error_hintsG   s   r3   r0   returnc                    s   g d}t  fdd|D S )z-Check if the error is authentication related.)unauthorizedzaccess denieddeniedc                 3   s    | ]}| v V  qd S Nr   ).0keywordr0   r   r   	<genexpr>]   s    z!_is_auth_error.<locals>.<genexpr>)any)r0   auth_keywordsr   r:   r   r-   Z   s   r-   c                 C   sN   t d | r | ddkr | dr t d| d  d dS t d dS )	z-Suggest the appropriate docker login command.uA   
[yellow]💡 You need to authenticate with the registry[/yellow]typer   urlz[yellow]   docker login z	[/yellow]z [yellow]   docker login[/yellow]N)r   r   get)r)   r   r   r   r/   `   s   
r/   descriptionr   c              
   C   s  zot d| d |rSg }tj| tjtjdddd}|jD ]}|| t d|  d q|	  |j
dkrPt|j
| }d||_|j|_d|_|W dS tj| dddd	}|j rmt d|j  d W dS  tjy }	 zEt d
d|   t|	ddpt|	ddpd}
t|	ddpd}|
rt d|
 d |rt d| d t||
| | W Y d}	~	dS d}	~	w ty   t d Y dS w )z.Run a docker command and handle output/errors.z[dim]z	...[/dim]T   )r'   r&   textbufsizeuniversal_newlinesz[/dim]r    )capture_outputrC   checkzDocker command failed: r*   r'   outputr&   z[red]stdout: z[/red]z[red]stderr: NFzEDocker not found. Please ensure Docker is installed and in your PATH.)r   r   
subprocessPopenPIPESTDOUTr'   appendrstripwait
returncodeCalledProcessErrorr.   rI   r&   r   stripr#   getattrr3   FileNotFoundError)r(   rA   r   r)   output_linesprocessliner#   resulter'   r&   r   r   r   r!   j   sT   





r!   registry_typeusername
agent_nameregistry_urlc                 C   sP   | t jkr| d| S | t jkr!|std| d| d| S td|  )z1Build the full image name based on registry type./z.registry_url is required for custom registrieszUnsupported registry type: )r   r   r   
ValueError)r[   r\   r]   r^   r   r   r   _build_image_name   s   

ra   z
build-pushz!Build, tag, and push Docker image)r   r   )hiddenz4Name of the agent to build image for e.g. 'my-agent'F)r   show_defaultz
--registryz-rzRegistry type to push tozRegistry Configuration)r   rich_help_panelz
--usernamez-uzRegistry usernamez--registry-urlz4Custom registry URL (required for custom registries)z	--versionz-vzVersion tag for the imagezBuild Configurationz	--no-pushz+Build and tag only, do not push to registryz--no-latestzDo not tag as 'latest'registryregistry_usernameversionno_push	no_latestc           !         s  | pt  }t|di }	d}
d}d}d}d}|jrY|jd}t|dkr0d}
|d }|d }nt|dkrEd	}
|d }|d }|d }n|j}d
|v rU|d
d\}}n|}d}|p_|p_|j}|ph|
ph|	d}|pq|pq|	d}|pz|pz|	d}|p|pd}|p|	dd }|std t	
dS |s|std t	
dS |std t	
dS |tjkr|std t	
dS |r|}n*ztt||||}W n ty } ztt| t	
dW  Y d}~S d}~ww | d
| }| d}d|g}|s
|d|g dddddg|d}|g}|s || ttd| dd| d |r2d!nd"| d# d$d%d&d' t	jd(dd)sPt  t	
 S td* t|d+| dd,set	
dS td-d|  |std.| d/ ||d	kr|ndd0}tdd1|gd2| d3|d4st	
dS |stdd1|gd2| d3|d4st	
dS |g}|s|| td5d|  ntd6 |std7 |D ]} td8|  d9 qtd: td;| d< td= td8t d> dS dS )?z>Build, tag, and optionally push a Docker image for your agent.docker_configNr_      r   r   rB      r   :latestre   rf   r^   auto_latestTz?Agent name is required. Provide via argument or pcc-deploy.tomlzVRegistry type is required when pushing. Use --registry or configure in pcc-deploy.tomlzZRegistry username is required when pushing. Use --username or configure in pcc-deploy.tomlzbRegistry URL is required for custom registries. Use --registry-url or configure in pcc-deploy.tomlz:latestz-tr
   buildxbuildz--platform=linux/arm64z--load.z'[bold white]Agent:[/bold white] [green]zm[/green]
[bold white]Platform:[/bold white] [green]linux/arm64[/green]
[bold white]Tags:[/bold white] [green]z, z([/green]
[bold white]Push:[/bold white] z[red]No[/red]z[green]Yes (z	)[/green]zDocker Build Configurationleftyellow)titletitle_alignborder_stylez&Do you want to proceed with the build?r   z0
[bold cyan]Building Docker image...[/bold cyan]z	Building r   zSuccessfully built image(s): z
[bold cyan]Pushing to z...[/bold cyan])r>   r?   r+   zPushing F)r   r)   zSuccessfully pushed: z5
[yellow]Skipping push (--no-push specified)[/yellow]z+
[dim]Your image is now available at:[/dim]z  [bold]z[/bold]z>
[dim]To deploy this image, update your pcc-deploy.toml:[/dim]z  [bold]image = "z"[/bold]z
[dim]Then run:[/dim]z deploy[/bold])r   rT   imagesplitlenr]   r@   r   r#   r   Exitr   r   ra   r`   strextendrN   r   r   r.   r    cancelr!   r"   r	   )!deploy_configr]   re   rf   r^   rg   rh   ri   partial_configrj   parsed_registryparsed_usernameparsed_agent_nameparsed_versionparsed_registry_urlimage_partsrepo_and_tagfinal_agent_namefinal_registryfinal_usernamefinal_registry_urlfinal_versionfinal_no_latestbase_image_namerZ   version_tag
latest_tag
build_tagsbuild_commandtags_displayr)   pushed_tagstagr   r   r   
build_push   s  
3

















r   appc                 C   s   | j tdd dS )z'Add docker command to the main CLI app.Commands)rd   N)	add_typer
docker_cli)r   r   r   r   create_docker_command  s   r   r7   )TN)$rJ   enumr   typingr   r   
rich.panelr   pipecatcloud._utils.async_utilsr   !pipecatcloud._utils.console_utilsr    pipecatcloud._utils.deploy_utilsr   r   pipecatcloud.clir	   Typerr   r|   r   r%   listdictr3   boolr-   r/   r!   ra   r(   create_blockingOptionArgumentr   r   r   r   r   r   <module>   s    *
;
 & b