def publish(self, source_version='latest'): if self.build is None: raise EnvironmentError( 'No build associated with this release to publish') source_tag = 'git-{}'.format( self.build.sha) if self.build.sha else source_version source_image = '{}:{}'.format(self.build.image, source_tag) # IOW, this image did not come from the builder # FIXME: remove check for mock registry module if not self.build.sha and 'mock' not in settings.REGISTRY_MODULE: # we assume that the image is not present on our registry, # so shell out a task to pull in the repository data = {'src': self.build.image} requests.post( '{}/v1/repositories/{}/tags'.format(settings.REGISTRY_URL, self.app.id), data=data, ) # update the source image to the repository we just imported source_image = self.app.id # if the image imported had a tag specified, use that tag as the source if ':' in self.build.image: if '/' not in self.build.image[self.build.image.rfind(':') + 1:]: source_image += self.build.image[self.build.image.rfind(':' ):] publish_release(source_image, self.config.values, self.image)
def new(self, user, config=None, build=None, summary=None, source_version='latest'): """ Create a new application release using the provided Build and Config on behalf of a user. Releases start at v1 and auto-increment. """ if not config: config = self.config if not build: build = self.build # always create a release off the latest image source_image = '{}:{}'.format(build.image, source_version) # construct fully-qualified target image new_version = self.version + 1 tag = 'v{}'.format(new_version) release_image = '{}:{}'.format(self.app.id, tag) target_image = '{}:{}/{}'.format( settings.REGISTRY_HOST, settings.REGISTRY_PORT, self.app.id) # create new release and auto-increment version release = Release.objects.create( owner=user, app=self.app, config=config, build=build, version=new_version, image=target_image, summary=summary) # IOW, this image did not come from the builder if not build.sha: # we assume that the image is not present on our registry, # so shell out a task to pull in the repository tasks.import_repository.delay(build.image, self.app.id).get() # update the source image to the repository we just imported source_image = self.app.id publish_release(source_image, config.values, release_image,) return release
def publish(self, source_version='latest'): if self.build is None: raise EnvironmentError('No build associated with this release to publish') source_tag = 'git-{}'.format(self.build.sha) if self.build.sha else source_version source_image = '{}:{}'.format(self.build.image, source_tag) # IOW, this image did not come from the builder # FIXME: remove check for mock registry module if not self.build.sha and 'mock' not in settings.REGISTRY_MODULE: # we assume that the image is not present on our registry, # so shell out a task to pull in the repository data = { 'src': self.build.image } requests.post( '{}/v1/repositories/{}/tags'.format(settings.REGISTRY_URL, self.app.id), data=data, ) # update the source image to the repository we just imported source_image = self.app.id # if the image imported had a tag specified, use that tag as the source if ':' in self.build.image: if '/' not in self.build.image[self.build.image.rfind(':') + 1:]: source_image += self.build.image[self.build.image.rfind(':'):] publish_release(source_image, self.config.values, self.image)
def new(self, user, config=None, build=None, summary=None): """ Create a new application release using the provided Build and Config on behalf of a user. Releases start at v1 and auto-increment. """ if not config: config = self.config if not build: build = self.build # prepare release tag new_version = self.version + 1 tag = 'v{}'.format(new_version) image = build.image + ':{tag}'.format(**locals()) # create new release and auto-increment version release = Release.objects.create(owner=user, app=self.app, config=config, build=build, version=new_version, image=image, summary=summary) # publish release to registry as new docker image repository_path = "{}/{}".format(user.username, self.app.id) publish_release(repository_path, config.values, tag) return release
def new(self, user, config=None, build=None, summary=None, source_version=None): """ Create a new application release using the provided Build and Config on behalf of a user. Releases start at v1 and auto-increment. """ if not config: config = self.config if not build: build = self.build if not source_version: source_version = 'latest' else: source_version = 'v{}'.format(source_version) # prepare release tag new_version = self.version + 1 tag = 'v{}'.format(new_version) image = build.image + ':{tag}'.format(**locals()) # create new release and auto-increment version release = Release.objects.create( owner=user, app=self.app, config=config, build=build, version=new_version, image=image, summary=summary) # publish release to registry as new docker image repository_path = self.app.id publish_release(repository_path, config.values, tag, source_tag=source_version) return release
def publish(self, source_version='latest'): if self.build is None: raise EnvironmentError('No build associated with this release to publish') source_image = self.build.image if ':' not in source_image: source_tag = 'git-{}'.format(self.build.sha) if self.build.sha else source_version source_image = "{}:{}".format(source_image, source_tag) # If the build has a SHA, assume it's from deis-builder and in the deis-registry already deis_registry = bool(self.build.sha) publish_release(source_image, self.config.values, self.image, deis_registry)
def new(self, user, config=None, build=None, summary=None, source_version='latest'): """ Create a new application release using the provided Build and Config on behalf of a user. Releases start at v1 and auto-increment. """ if not config: config = self.config if not build: build = self.build # always create a release off the latest image source_image = '{}:{}'.format(build.image, source_version) # construct fully-qualified target image new_version = self.version + 1 tag = 'v{}'.format(new_version) release_image = '{}:{}'.format(self.app.id, tag) target_image = '{}'.format(self.app.id) # create new release and auto-increment version release = Release.objects.create(owner=user, app=self.app, config=config, build=build, version=new_version, image=target_image, summary=summary) # IOW, this image did not come from the builder # FIXME: remove check for mock registry module if not build.sha and 'mock' not in settings.REGISTRY_MODULE: # we assume that the image is not present on our registry, # so shell out a task to pull in the repository data = {'src': build.image} requests.post( '{}/v1/repositories/{}/tags'.format(settings.REGISTRY_URL, self.app.id), data=data, ) # update the source image to the repository we just imported source_image = self.app.id # if the image imported had a tag specified, use that tag as the source if ':' in build.image: if '/' not in build.image[build.image.rfind(':') + 1:]: source_image += build.image[build.image.rfind(':'):] publish_release( source_image, config.values, release_image, ) return release
def new(self, user, config=None, build=None, summary=None, source_version='latest'): """ Create a new application release using the provided Build and Config on behalf of a user. Releases start at v1 and auto-increment. """ if not config: config = self.config if not build: build = self.build # always create a release off the latest image source_tag = 'git-{}'.format(build.sha) if build.sha else source_version source_image = '{}:{}'.format(build.image, source_tag) # construct fully-qualified target image new_version = self.version + 1 tag = 'v{}'.format(new_version) release_image = '{}:{}'.format(self.app.id, tag) target_image = '{}'.format(self.app.id) # create new release and auto-increment version release = Release.objects.create( owner=user, app=self.app, config=config, build=build, version=new_version, image=target_image, summary=summary) # IOW, this image did not come from the builder # FIXME: remove check for mock registry module if not build.sha and 'mock' not in settings.REGISTRY_MODULE: # we assume that the image is not present on our registry, # so shell out a task to pull in the repository data = { 'src': build.image } requests.post( '{}/v1/repositories/{}/tags'.format(settings.REGISTRY_URL, self.app.id), data=data, ) # update the source image to the repository we just imported source_image = self.app.id # if the image imported had a tag specified, use that tag as the source if ':' in build.image: if '/' not in build.image[build.image.rfind(':') + 1:]: source_image += build.image[build.image.rfind(':'):] publish_release(source_image, config.values, release_image,) return release
def publish(self): if self.build is None: raise DeisException("No build associated with this release to publish") # If the build has a SHA, assume it's from deis-builder and in the deis-registry already if self.build.source_based: return # Builder pushes to internal registry, exclude SHA based images from being returned early registry = self.config.registry if ( registry.get("username", None) and registry.get("password", None) and # SHA means it came from a git push (builder) not self.build.sha and # hostname tells Builder where to push images not registry.get("hostname", None) ) or (settings.REGISTRY_LOCATION != "on-cluster"): self.app.log( "{} exists in the target registry. Using image for release {} of app {}".format( self.build.image, self.version, self.app ) ) # noqa return # return image if it is already in the registry, test host and then host + port if self.build.image.startswith(settings.REGISTRY_HOST) or self.build.image.startswith(settings.REGISTRY_URL): self.app.log( "{} exists in the target registry. Using image for release {} of app {}".format( self.build.image, self.version, self.app ) ) # noqa return # add tag if it was not provided source_image = self.build.image if ":" not in source_image: source_image = "{}:{}".format(source_image, self.build.version) # if build is source based then it was pushed into the deis registry deis_registry = bool(self.build.source_based) publish_release(source_image, self.image, deis_registry, self.get_registry_auth())
def publish(self): if self.build is None: raise DeisException( 'No build associated with this release to publish') # If the build has a SHA, assume it's from deis-builder and in the deis-registry already if self.build.source_based: return # Builder pushes to internal registry, exclude SHA based images from being returned early registry = self.config.registry if (registry.get('username', None) and registry.get('password', None) and # SHA means it came from a git push (builder) not self.build.sha and # hostname tells Builder where to push images not registry.get('hostname', None)) or ( settings.REGISTRY_LOCATION != 'on-cluster'): self.app.log( '{} exists in the target registry. Using image for release {} of app {}' .format(self.build.image, self.version, self.app)) # noqa return # return image if it is already in the registry, test host and then host + port if (self.build.image.startswith(settings.REGISTRY_HOST) or self.build.image.startswith(settings.REGISTRY_URL)): self.app.log( '{} exists in the target registry. Using image for release {} of app {}' .format(self.build.image, self.version, self.app)) # noqa return # add tag if it was not provided source_image = self.build.image if ':' not in source_image: source_image = "{}:{}".format(source_image, self.build.version) # if build is source based then it was pushed into the deis registry deis_registry = bool(self.build.source_based) publish_release(source_image, self.image, deis_registry, self.get_registry_auth())
def test_publish_release(self, mock_client): self.client = DockerClient() # Make sure login is not called when there are no creds publish_release('ozzy/embryo:git-f2a8020', 'ozzy/embryo:v4', False) self.assertFalse(self.client.client.login.called) creds = { 'username': '******', 'password': '******', 'email': 'fake', 'registry': 'quay.io' } client = {} client['Status'] = 'Login Succeeded' self.client.client.login.return_value = client publish_release('ozzy/embryo:git-f2a8020', 'ozzy/embryo:v4', False, creds) self.assertTrue(self.client.client.login.called) self.assertTrue(self.client.client.pull.called) self.assertTrue(self.client.client.tag.called) self.assertTrue(self.client.client.push.called) publish_release('ozzy/embryo:git-f2a8020', 'ozzy/embryo:v4', True) self.assertTrue(self.client.client.pull.called) self.assertTrue(self.client.client.tag.called) self.assertTrue(self.client.client.push.called) # Test that a registry host prefix is replaced with deis-registry for the target publish_release('ozzy/embryo:git-f2a8020', 'quay.io/ozzy/embryo:v4', True) docker_push = self.client.client.push docker_push.assert_called_with( 'localhost:5000/ozzy/embryo', tag='v4', insecure_registry=True, decode=True, stream=True) # Test that blacklisted image names can't be published with self.assertRaises(PermissionDenied): publish_release( 'deis/controller:v1.11.1', 'deis/controller:v1.11.1', True) with self.assertRaises(PermissionDenied): publish_release( 'localhost:5000/deis/controller:v1.11.1', 'deis/controller:v1.11.1', True)
def test_publish_release(self, mock_client): self.client = DockerClient() # Make sure login is not called when there are no creds publish_release('ozzy/embryo:git-f2a8020', 'ozzy/embryo:v4', False) self.assertFalse(self.client.client.login.called) creds = { 'username': '******', 'password': '******', 'email': 'fake', 'registry': 'quay.io' } client = {} client['Status'] = 'Login Succeeded' self.client.client.login.return_value = client publish_release('ozzy/embryo:git-f2a8020', 'ozzy/embryo:v4', False, creds) self.assertTrue(self.client.client.login.called) self.assertTrue(self.client.client.pull.called) self.assertTrue(self.client.client.tag.called) self.assertTrue(self.client.client.push.called) publish_release('ozzy/embryo:git-f2a8020', 'ozzy/embryo:v4', True) self.assertTrue(self.client.client.pull.called) self.assertTrue(self.client.client.tag.called) self.assertTrue(self.client.client.push.called) # Test that a registry host prefix is replaced with deis-registry for the target publish_release('ozzy/embryo:git-f2a8020', 'quay.io/ozzy/embryo:v4', True) docker_push = self.client.client.push docker_push.assert_called_with('localhost:5000/ozzy/embryo', tag='v4', decode=True, stream=True) # Test that blacklisted image names can't be published with self.assertRaises(PermissionDenied): publish_release('deis/controller:v1.11.1', 'deis/controller:v1.11.1', True) with self.assertRaises(PermissionDenied): publish_release('localhost:5000/deis/controller:v1.11.1', 'deis/controller:v1.11.1', True)