o
    2.a`D                     @   s   d dl Z d dlZd dlZddlmZ ddlmZ ddlmZm	Z	m
Z
 ddlmZ ddlmZ dd	lmZmZ G d
d deZG dd deZG dd deZdd ZdS )    N   )	APIClient)DEFAULT_DATA_CHUNK_SIZE)
BuildErrorImageLoadErrorInvalidArgument)parse_repository_tag)json_stream   )
CollectionModelc                   @   s\   e Zd ZdZdd Zedd Zedd Zedd	 Zd
d Z	e
dfddZdddZdS )Imagez!
    An image on the server.
    c                 C   s   d | jjd| jS )Nz
<{}: '{}'>z', ')format	__class____name__jointagsself r   6/usr/lib/python3/dist-packages/docker/models/images.py__repr__      zImage.__repr__c                 C   s   | j d d}|pi S )z7
        The labels of an image as dictionary.
        ZConfigZLabelsattrsget)r   resultr   r   r   labels   s   zImage.labelsc                 C   s(   | j dr| j dd S | j dd S )f
        The ID of the image truncated to 10 characters, plus the ``sha256:``
        prefix.
        sha256:N   
   )id
startswithr   r   r   r   short_id   s   zImage.short_idc                 C   s&   | j d}|du rg }dd |D S )z#
        The image's tags.
        ZRepoTagsNc                 S   s   g | ]}|d kr|qS )z<none>:<none>r   ).0tagr   r   r   
<listcomp>.   s    zImage.tags.<locals>.<listcomp>r   )r   r   r   r   r   r   &   s   z
Image.tagsc                 C   s   | j j| jS )z
        Show the history of an image.

        Returns:
            (str): The history of the image.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        )clientapihistoryr"   r   r   r   r   r*   0   s   zImage.historyFc                 C   sT   | j }|r"| jr| jd n|}t|tr"|| jvr t| d|}| jj||S )a  
        Get a tarball of an image. Similar to the ``docker save`` command.

        Args:
            chunk_size (int): The generator will return up to that much data
                per iteration, but may return less. If ``None``, data will be
                streamed as it is received. Default: 2 MB
            named (str or bool): If ``False`` (default), the tarball will not
                retain repository and tag information for this image. If set
                to ``True``, the first tag in the :py:attr:`~tags` list will
                be used to identify the image. Alternatively, any element of
                the :py:attr:`~tags` list can be used as an argument to use
                that specific tag as the saved identifier.

        Returns:
            (generator): A stream of raw archive data.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.

        Example:

            >>> image = cli.images.get("busybox:latest")
            >>> f = open('/tmp/busybox-latest.tar', 'wb')
            >>> for chunk in image.save():
            >>>   f.write(chunk)
            >>> f.close()
        r   z" is not a valid tag for this image)r"   r   
isinstancestrr   r(   r)   Z	get_image)r   Z
chunk_sizeZnamedZimgr   r   r   save=   s   

z
Image.saveNc                 K   s   | j jj| j|fd|i|S )a  
        Tag this image into a repository. Similar to the ``docker tag``
        command.

        Args:
            repository (str): The repository to set for the tag
            tag (str): The tag name
            force (bool): Force

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.

        Returns:
            (bool): ``True`` if successful
        r&   )r(   r)   r&   r"   r   
repositoryr&   kwargsr   r   r   r&   g   s   z	Image.tagN)r   
__module____qualname____doc__r   propertyr   r$   r   r*   r   r-   r&   r   r   r   r   r      s    

	
	*r   c                       s\   e Zd ZdZ fddZedd Zedd Zdd	d
Zdd Z	dd Z
ej
je
_  ZS )RegistryDatazO
    Image metadata stored on the registry, including available platforms.
    c                    s   t  j|i | || _d S r1   )super__init__
image_name)r   r9   argsr0   r   r   r   r8      s   
zRegistryData.__init__c                 C   s   | j d d S )z'
        The ID of the object.
        Z
DescriptorZdigest)r   r   r   r   r   r"      s   zRegistryData.idc                 C   s   | j dd S )r   Nr    )r"   r   r   r   r   r$      s   zRegistryData.short_idNc                 C   s"   t | j\}}| jj|| j|dS )z
        Pull the image digest.

        Args:
            platform (str): The platform to pull the image for.
            Default: ``None``

        Returns:
            (:py:class:`Image`): A reference to the pulled image.
        )r&   platform)r   r9   
collectionpullr"   )r   r<   r/   _r   r   r   r>      s   zRegistryData.pullc                 C   s   |r>t |ts>|d}t|dkst|dk r td| dd|d i}t|dkr2|d |d	< t|dkr>|d |d
< t|| j | jd v S )a  
        Check whether the given platform identifier is available for this
        digest.

        Args:
            platform (str or dict): A string using the ``os[/arch[/variant]]``
                format, or a platform dictionary.

        Returns:
            (bool): ``True`` if the platform is recognized as available,
            ``False`` otherwise.

        Raises:
            :py:class:`docker.errors.InvalidArgument`
                If the platform argument is not a valid descriptor.
        /   r
   "z$" is not a valid platform descriptorosr   r   ZvariantarchitectureZ	Platforms)	r+   dictsplitlenr   normalize_platformr(   versionr   )r   r<   partsr   r   r   has_platform   s    


zRegistryData.has_platformc                 C   s   | j j| j| _d S r1   )r(   r)   inspect_distributionr9   r   r   r   r   r   reload   s   zRegistryData.reloadr1   )r   r2   r3   r4   r8   r5   r"   r$   r>   rK   rM   r   __classcell__r   r   r;   r   r6   {   s    


 r6   c                   @   s   e Zd ZeZdd Zdd ZdddZdd	d
Zdd Z	dddZ
dddZejje_dd Zejje_dd Zejje_dddZejje_dd Zejje_dS )ImageCollectionc           	      K   s   | j jjdi |}t|tr| |S d}d}tt|\}}|D ]"}d|v r0t	|d |d|v rCt
d|d }|rC|d}|}q#|rO| ||fS t	|pSd|)a  
        Build an image and return it. Similar to the ``docker build``
        command. Either ``path`` or ``fileobj`` must be set.

        If you have a tar file for the Docker build context (including a
        Dockerfile) already, pass a readable file-like object to ``fileobj``
        and also pass ``custom_context=True``. If the stream is compressed
        also, set ``encoding`` to the correct value (e.g ``gzip``).

        If you want to get the raw output of the build, use the
        :py:meth:`~docker.api.build.BuildApiMixin.build` method in the
        low-level API.

        Args:
            path (str): Path to the directory containing the Dockerfile
            fileobj: A file object to use as the Dockerfile. (Or a file-like
                object)
            tag (str): A tag to add to the final image
            quiet (bool): Whether to return the status
            nocache (bool): Don't use the cache when set to ``True``
            rm (bool): Remove intermediate containers. The ``docker build``
                command now defaults to ``--rm=true``, but we have kept the old
                default of `False` to preserve backward compatibility
            timeout (int): HTTP timeout
            custom_context (bool): Optional if using ``fileobj``
            encoding (str): The encoding for a stream. Set to ``gzip`` for
                compressing
            pull (bool): Downloads any updates to the FROM image in Dockerfiles
            forcerm (bool): Always remove intermediate containers, even after
                unsuccessful builds
            dockerfile (str): path within the build context to the Dockerfile
            buildargs (dict): A dictionary of build arguments
            container_limits (dict): A dictionary of limits applied to each
                container created by the build process. Valid keys:

                - memory (int): set memory limit for build
                - memswap (int): Total memory (memory + swap), -1 to disable
                    swap
                - cpushares (int): CPU shares (relative weight)
                - cpusetcpus (str): CPUs in which to allow execution, e.g.,
                    ``"0-3"``, ``"0,1"``
            shmsize (int): Size of `/dev/shm` in bytes. The size must be
                greater than 0. If omitted the system uses 64MB
            labels (dict): A dictionary of labels to set on the image
            cache_from (list): A list of images used for build cache
                resolution
            target (str): Name of the build-stage to build in a multi-stage
                Dockerfile
            network_mode (str): networking mode for the run commands during
                build
            squash (bool): Squash the resulting images layers into a
                single layer.
            extra_hosts (dict): Extra hosts to add to /etc/hosts in building
                containers, as a mapping of hostname to IP address.
            platform (str): Platform in the format ``os[/arch[/variant]]``.
            isolation (str): Isolation technology used during build.
                Default: `None`.
            use_config_proxy (bool): If ``True``, and if the docker client
                configuration file (``~/.docker/config.json`` by default)
                contains a proxy configuration, the corresponding environment
                variables will be set in the container being built.

        Returns:
            (tuple): The first item is the :py:class:`Image` object for the
                image that was build. The second item is a generator of the
                build logs as JSON-decoded objects.

        Raises:
            :py:class:`docker.errors.BuildError`
                If there is an error during the build.
            :py:class:`docker.errors.APIError`
                If the server returns any other error.
            ``TypeError``
                If neither ``path`` nor ``fileobj`` is specified.
        Nerrorstreamz*(^Successfully built |sha256:)([0-9a-f]+)$r   ZUnknownr   )r(   r)   buildr+   r,   r   	itertoolsteer	   r   researchgroup)	r   r0   respZ
last_eventimage_idZresult_streamZinternal_streamchunkmatchr   r   r   rR      s(   L


zImageCollection.buildc                 C   s   |  | jj|S )am  
        Gets an image.

        Args:
            name (str): The name of the image.

        Returns:
            (:py:class:`Image`): The image.

        Raises:
            :py:class:`docker.errors.ImageNotFound`
                If the image does not exist.
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        )Zprepare_modelr(   r)   Zinspect_image)r   namer   r   r   r   *  s   zImageCollection.getNc                 C   s   t || jj||| j| dS )a  
        Gets the registry data for an image.

        Args:
            name (str): The name of the image.
            auth_config (dict): Override the credentials that are found in the
                config for this request.  ``auth_config`` should contain the
                ``username`` and ``password`` keys to be valid.

        Returns:
            (:py:class:`RegistryData`): The data object.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        )r9   r   r(   r=   )r6   r(   r)   rL   )r   r\   Zauth_configr   r   r   get_registry_data<  s   z!ImageCollection.get_registry_dataFc                    s&    j jj|||d} fdd|D S )a  
        List images on the server.

        Args:
            name (str): Only show images belonging to the repository ``name``
            all (bool): Show intermediate image layers. By default, these are
                filtered out.
            filters (dict): Filters to be processed on the image list.
                Available filters:
                - ``dangling`` (bool)
                - `label` (str|list): format either ``"key"``, ``"key=value"``
                    or a list of such.

        Returns:
            (list of :py:class:`Image`): The images.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        )r\   allfiltersc                    s   g | ]	}  |d  qS )ZIdr   )r%   rr   r   r   r'   j  s    z(ImageCollection.list.<locals>.<listcomp>)r(   r)   images)r   r\   r^   r_   rX   r   r   r   listT  s   zImageCollection.listc                    sr    j j|}g }|D ]$}d|v r%td|d }|r%|d}|| d|v r/t|d q fdd|D S )a  
        Load an image that was previously saved using
        :py:meth:`~docker.models.images.Image.save` (or ``docker save``).
        Similar to ``docker load``.

        Args:
            data (binary): Image data to be loaded.

        Returns:
            (list of :py:class:`Image`): The images.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.
        rQ   z)(^Loaded image ID: |^Loaded image: )(.+)$r   rP   c                    s   g | ]}  |qS r   r`   )r%   ir   r   r   r'     s    z(ImageCollection.load.<locals>.<listcomp>)r(   r)   Z
load_imagerU   rV   rW   appendr   )r   datarX   rb   rZ   r[   rY   r   r   r   loadl  s   

zImageCollection.loadc              	   K   s   t |\}}|p|pd}d|v rtd |d= | jjj|f|d|d|}|D ]}q)|sA| d|||dr=dS d	S | 	|S )
a  
        Pull an image of the given name and return it. Similar to the
        ``docker pull`` command.
        If ``tag`` is ``None`` or empty, it is set to ``latest``.
        If ``all_tags`` is set, the ``tag`` parameter is ignored and all image
        tags will be pulled.

        If you want to get the raw pull output, use the
        :py:meth:`~docker.api.image.ImageApiMixin.pull` method in the
        low-level API.

        Args:
            repository (str): The repository to pull
            tag (str): The tag to pull
            auth_config (dict): Override the credentials that are found in the
                config for this request.  ``auth_config`` should contain the
                ``username`` and ``password`` keys to be valid.
            platform (str): Platform in the format ``os[/arch[/variant]]``
            all_tags (bool): Pull all image tags

        Returns:
            (:py:class:`Image` or list): The image that has been pulled.
                If ``all_tags`` is True, the method will return a list
                of :py:class:`Image` objects belonging to this repository.

        Raises:
            :py:class:`docker.errors.APIError`
                If the server returns an error.

        Example:

            >>> # Pull the image tagged `latest` in the busybox repo
            >>> image = client.images.pull('busybox')

            >>> # Pull all tags in the busybox repo
            >>> images = client.images.pull('busybox', all_tags=True)
        ZlatestrQ   zH`stream` is not a valid parameter for this method and will be overriddenT)r&   rQ   all_tagsz	{0}{2}{1}r   @:)
r   warningswarnr(   r)   r>   r   r   r#   rc   )r   r/   r&   rh   r0   Z	image_tagZpull_logr?   r   r   r   r>     s.   &
zImageCollection.pullc                 K   s   | j jj|fd|i|S )Nr&   )r(   r)   pushr.   r   r   r   rm     s   zImageCollection.pushc                 O   s   | j jj|i | d S r1   )r(   r)   remove_imager   r:   r0   r   r   r   remove  r   zImageCollection.removec                 O      | j jj|i |S r1   )r(   r)   rV   ro   r   r   r   rV        zImageCollection.searchc                 C   s   | j jj|dS )N)r_   )r(   r)   prune_images)r   r_   r   r   r   prune  s   zImageCollection.prunec                 O   rq   r1   )r(   r)   prune_buildsro   r   r   r   ru     rr   zImageCollection.prune_buildsr1   )NFN)NF)r   r2   r3   r   ZmodelrR   r   r]   rc   rg   r>   rm   r   r4   rp   rn   rV   rt   rs   ru   r   r   r   r   rO      s$    a


 
>




rO   c                 C   s8   | d u ri } d| vr|d | d< d| vr|d | d< | S )NrC   ZOsrD   ZArchr   )r<   Zengine_infor   r   r   rH     s   rH   )rS   rU   rk   r)   r   Z	constantsr   errorsr   r   r   Zutilsr   Zutils.json_streamr	   Zresourcer   r   r   r6   rO   rH   r   r   r   r   <module>   s    nK  