Source code for dockerreg.models

import six
import abc
import traceback
import json

import dockerreg.exceptions as ex
from dockerreg.util.applicable import ApplicableClass,ApplicableMethod
from dockerreg.util import getgoarch, getgoos

@six.add_metaclass(abc.ABCMeta)
[docs]class Model(object):
[docs] def __init__(self,api,name,id=None): self._api = api self._name = name self._id = id if name is None: raise ex.IllegalArgumentError("modeled object must have a name")
@property def api(self): """ The :py:class:`dockerreg.api.BaseApiClient` corresponding to this :py:class:`.Model`. """ return self._api @property def name(self): """ The name (a :py:class:`str`) corresponding to this object. """ #if not self._name: # return self._id return self._name @property def id(self): """ The identifier (a :py:class:`str`) corresponding to this object, if any. """ return self._id @abc.abstractmethod
[docs] def refresh(self): """ Refreshes this object's content from the registry. :raises dockerreg.exceptions.ObjectNotFoundError: if the object no longer exists at the registry. """
@abc.abstractmethod def __eq__(self,other): pass def __ne__(self,other): return not self.__eq__(other) @abc.abstractmethod def __hash__(self,other): pass def __repr__(self): return "<%s %s>" % (self.__class__.__name__,self.name)
@six.add_metaclass(abc.ABCMeta) @ApplicableClass()
[docs]class Registry(Model):
[docs] def __init__(self,api,name): super(Registry,self).__init__(api,name,id=None) self._namespaces = None self._repositories = None
@property def namespaces(self): """ A :py:class:`list` of namespaces in this registry. """ if self._namespaces is None: self._namespaces = self.get_namespaces() return self._namespaces @property def repositories(self): """ A :py:class:`dict` of repositories in this registry, keyed by `<namespace>/<repository>` strings, with values :py:class:`dockerreg.models.Repository`. """ if self._repositories is None: self._repositories = self.get_repositories() return self._repositories @abc.abstractmethod @ApplicableMethod()
[docs] def get_namespaces(self,regexp=None): """ Return a list of namespaces in this registry, possibly filtered by regexp string. :param str regexp: a regexp to filter over :returns: a :py:class:`list` of namespaces in this registry, possibly filtered by `regexp`. :rtype: :py:class:`list` """
@abc.abstractmethod @ApplicableMethod()
[docs] def get_repositories(self,regexp=None,namespace_regexp=None): """ Return a dict of namespaces-to-repository lists in this registry. :param str regexp: a regexp to filter over :param str namespace_regexp: a regexp to filter over namespaces :returns: a :py:class:`dict` of namespaces, whose values are lists of repositories, in this registry, possibly filtered by `regexp`. :rtype: :py:class:`dict` """
[docs] def refresh(self): self.get_repositories() self.get_namespaces()
[docs] def ping(self): """ :returns: :py:data:`True` if the registry is responding; :py:data:`False` if not. :rtype: :py:class:`bool` """ try: self.api.ping() return True except: LOG.debug(traceback.format_exc()) return False
[docs] def authping(self): """ :returns: :py:data:`True` if the registry is responding and the user is authenticated and authorized to the `/` URL (i.e. version check); :py:data:`False` if not. :rtype: :py:class:`bool` """ try: self.api.authping() return True except: LOG.debug(traceback.format_exc()) return False
@abc.abstractmethod @ApplicableMethod()
[docs] def get_tags(self,repository,metadata=False): """ :param str repository: the full name of the image, including the namespace and repository. :param str metadata: a boolean specifying to return tag metadata (i.e. its digest, manifest length, etc). :returns: a :py:class:`list` of tags in this repository, or a list of tag metadata :py:class:`dict`s if :param metadata: is set to `True`. """
@abc.abstractmethod @ApplicableMethod()
[docs] def get_reference_metadata(self,repository,reference): """ :param str repository: the full name of the image, including the namespace and repository. :param str reference: a manifest id or digest. :returns: a tag metadata :py:class:`dict`. """
@abc.abstractmethod @ApplicableMethod()
[docs] def get_image_metadata(self,repository,tag,arch=getgoarch,oss=getgoos): """ :param str repository: the full name of the image, including the namespace and repository. :param str tag: the tag indicating the version of the image. :param str arch: a GOARCH architecture string (i.e. amd64); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str oss: a GOOS operating system string (i.e. linux); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :returns: an image metadata :py:class:`dict`. """
@abc.abstractmethod @ApplicableMethod()
[docs] def check_image(self,repository,tag,arch=getgoarch,oss=getgoos): """ Ensures that the image and its layers are all present in the named repository at the given tag. :param str repository: the full name of the image, including the namespace and repository. :param str tag: the tag indicating the version of the image. :param str arch: a GOARCH architecture string (i.e. amd64); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str oss: a GOOS operating system string (i.e. linux); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :returns: 0 if all layers are present in repository; non-zero otherwise. """
@abc.abstractmethod @ApplicableMethod()
[docs] def pull_image(self,repository,tag,arch=getgoarch,oss=getgoos, filebasename=None): """ Pulls the image descriptor and all layers, returning an :py:class:`Image`representing the downloaded image. If the `filebasename` parameter is set, the raw data will be cached in files instead of in memory. :param str repository: the full name of the image, including the namespace and repository. :param str tag: the tag indicating the version of the image. :param str arch: a GOARCH architecture string (i.e. amd64); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str oss: a GOOS operating system string (i.e. linux); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str filebasename: if set, the image manifest and layers will be cached in files named `filebasename`.manifest and `filebasename`.<layer_id>. :returns: a :py:class:`Image`. """
@abc.abstractmethod @ApplicableMethod()
[docs] def get_image_size(self,repository,tag,arch=getgoarch,oss=getgoos, filebasename=None): """ Pulls the image descriptor and enough layer content to determine the total size of all layers in the image, returning an :type:`int` specifying the total layer size in bytes. If the `filebasename` parameter is set, the raw data will be cached in files instead of in memory. :param str repository: the full name of the image, including the namespace and repository. :param str tag: the tag indicating the version of the image. :param str arch: a GOARCH architecture string (i.e. amd64); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str oss: a GOOS operating system string (i.e. linux); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str filebasename: if set, the image manifest (and any layers, if they are fully downloaded) will be cached in files named `filebasename`.manifest and `filebasename`.<layer_id>. :returns: a :py:class:`Image`. """
@abc.abstractmethod @ApplicableMethod()
[docs] def get_image_created(self,repository,tag,arch=getgoarch,oss=getgoos, filebasename=None): """ Pulls the image descriptor to determine the creation time of the most recent layer (which is effectively the image creation time), returning an :type:`str` specifying created time. If the `filebasename` parameter is set, the raw data will be cached in files instead of in memory. :param str repository: the full name of the image, including the namespace and repository. :param str tag: the tag indicating the version of the image. :param str arch: a GOARCH architecture string (i.e. amd64); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str oss: a GOOS operating system string (i.e. linux); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str filebasename: if set, the image manifest (and any layers, if they are fully downloaded) will be cached in files named `filebasename`.manifest and `filebasename`.<layer_id>. :returns: an :type:`str` specifying created time. """
@abc.abstractmethod @ApplicableMethod()
[docs] def push_image(self,repository,tag,filebasename): """ Pushes the image referenced by filebasename to the given repository and tag. :param str repository: the full name of the image, including the namespace and repository. :param str tag: the tag indicating the version of the image. :param str filebasename: if set, the image manifest and layers will be read from the cached copy in files named `filebasename`.manifest and `filebasename`.<layer_id>. """
@abc.abstractmethod @ApplicableMethod()
[docs] def tag_image(self,repository,tag,newtag,arch=getgoarch,oss=getgoos): """ Applies a new tag to an existing image referenced by its tag. :param str repository: the full name of the image, including the namespace and repository. :param str tag: the tag indicating the version of the image. :param str newtag: the new tag to be added. :param str arch: a GOARCH architecture string (i.e. amd64); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str oss: a GOOS operating system string (i.e. linux); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :returns: a :py:class:`Image`. """
@abc.abstractmethod @ApplicableMethod()
[docs] def pull_and_push_image(self,repository,tag,arch=getgoarch,oss=getgoos, filebasename=None,refresh=False, dst_registry=None,dst_repository=None,dst_tag=None, dst_username=None,dst_password=None, dst_no_verify=None,dst_cert=None,dst_ca_bundle=None, dst_skip_docker_config=False,dst_no_cache=False, dst_cache_file=None): """ Pulls the repository:tag image from this registry, and pushes it to dst_registry/dst_repository:dst_tag. If all dst* parameters are None, an IllegalArgumentError will be raised. If any of the dst* parameters are unspecified, their values will be taken from the current values of the specified image. This allows you to simply re-tag an image; copy it to another repository; or copy it to another repository. """
@abc.abstractmethod @ApplicableMethod( kwargs=[dict(name='layers',action='store_true',default=False)])
[docs] def delete_image(self,repository,tag,layers=False, arch=getgoarch,oss=getgoos): """ Deletes the image. :param str repository: the full name of the image, including the namespace and repository. :param str tag: the tag indicating the version of the image. :param bool layers: True if we should delete layers; defaults to False. :param str arch: a GOARCH architecture string (i.e. amd64); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str oss: a GOOS operating system string (i.e. linux); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :returns: `None`. """
@abc.abstractmethod @ApplicableMethod()
[docs] def delete_tag(self,repository,tag,arch=getgoarch,oss=getgoos): """ Deletes a tag. :param str repository: the full name of the image, including the namespace and repository. :param str tag: the tag indicating the version of the image. :param str arch: a GOARCH architecture string (i.e. amd64); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str oss: a GOOS operating system string (i.e. linux); defaults to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :returns: `None`. """
def __eq__(self,other): if self.__class__ == other.__class__ \ and self.name == other.name and self.id == other.id: return True return False def __hash__(self): return hash((self.__class__,self.name,self.id)) def __repr__(self): return "<%s %s>" % (self.__class__.__name__,self.name)
@six.add_metaclass(abc.ABCMeta)
[docs]class Repository(Model):
[docs] def __init__(self,api,repository,registry): super(Repository,self).__init__(api,repository,id=None) self.registry = registry self._tags = None
@abc.abstractmethod
[docs] def get_tags(self,metadata=False): """ :returns: a :py:class:`list` of tags in this repository, or a list of tag metadata :py:class:`dict`s if :param metadata: is set to `True`. """
@abc.abstractmethod
[docs] def get_reference_metadata(self,reference): """ :param str reference: a manifest id or digest. :returns: a tag metadata :py:class:`dict`. """
[docs] def get_image(self,tag,arch=None,oss=None,filebasename=None): """ Returns an :py:class:`Image`representing the requested image. If the `filebasename` parameter is set, any downloaded raw data will be cached in files instead of in memory. :param str tag: the tag indicating the version of the image. :param str filebasename: if set, the image manifest and layers will be cached in files named `filebasename`.manifest and `filebasename`.<layer_id>. :param str arch: either None or a GOARCH architecture string (i.e. amd64). Some Registry versions support multi-platform images; if there is a choice, and if you do not specify a value, it will default to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :param str oss: a GOOS operating system string (i.e. linux). Some Registry versions support multi-platform images; if there is a choice, and if you do not specify a value, it will default to the platform this library is running on; see https://golang.org/doc/install/source#environment for valid values. :returns: a :py:class:`Image`. """
def __eq__(self,other): if self.__class__ == other.__class__ \ and self.registry == other.registry \ and self.name == other.name and self.id == other.id: return True return False def __hash__(self): return hash((self.__class__,self.registry,self.name,self.id)) def __repr__(self): return "<%s %s:%s>" % (self.__class__.__name__,self.registry.name, self.name)
@six.add_metaclass(abc.ABCMeta)
[docs]class Image(Model):
[docs] def __init__(self,api,tag,repository,id=None): super(Image,self).__init__(api,tag,id=id) self.repository = repository self._deleted = False
@property def tag(self): return self.name @property def deleted(self): return self._deleted def __eq__(self,other): if self.__class__ == other.__class__ \ and self.repository == other.repository \ and self.name == other.name and self.id == other.id: return True return False @abc.abstractmethod
[docs] def size(self): """ :returns: the total size of the blobs/layers that make up the image. :rtype: :type:`int` """
def __hash__(self): return hash((self.__class__,self.repository,self.name,self.id)) def __repr__(self): return "<%s %s/%s:%s %s>" % ( self.__class__.__name__,self.repository.registry.name, self.repository.name,self.name,str(self.id))
@six.add_metaclass(abc.ABCMeta)
[docs]class Manifest(Model): _media_types = []
[docs] def __init__(self,api,blob={},raw=b'{}',media_type=None, repository=None,tag=None,id=None): name = None if repository and tag: name = "%s:%s" % (repository,tag) super(Manifest,self).__init__(api,name,id=id) self._attrs = blob self._raw = raw self._media_type = media_type self._repository = repository self._tag = tag self._version = None
def __eq__(self,other): if self.__class__ != other.__class__: return False if self.repository != other.repository or self.tag != other.tag \ or self.id != other.id: return False if self.raw != other.raw: return False return True def __hash__(self): return hash( (self.__class__.__name__,self.repository,self.tag,self.id, self.raw,self._attrs)) @abc.abstractmethod
[docs] def verify(self): """ :returns: `True` if verified; `None` if there is nothing to verify; or throws an Exception if verification fails. """
[docs] def modify(self,**kwargs): """ Modify this manifest. This could mean, for instance, for a v2-1 manifest, to change the repository and/or tag. It is manifest version-defined; but all Manifest subclasses should at least support the repository and tag modification keys. """ return
@property def raw(self): if not self._raw: self._raw = json.dumps( self._attrs,indent=3,separators=(',\n',': ')) return self._raw @property def valid_media_types(self): return self.__class__._media_types @property def version(self): return self._version @property def media_type(self): return self._media_type @property def repository(self): return self._repository @property def tag(self): return self._tag def __repr__(self): idstr = "" if self.id: idstr = " " + str(self.id) return "<%s %s:%s%s>" % ( self.__class__.__name__,self.repository,self.tag,idstr)
@six.add_metaclass(abc.ABCMeta)
[docs]class SignableMixin(object): @abc.abstractmethod
[docs] def sign(self): """ Updates the :py:class:`Manifest` in place (specifically, updates the `_raw` instance variable (the `raw` property) with a new, signed raw manifest string, based on the current manifest attributes. """