def testNotInRegistry(self): """No registry entry, no explicit skip files.""" source_files_util.GetSourceFiles(self.upload_dir, self.skip_files, False, 'fake-runtime', 'fake-env', self.source_dir) self.file_chooser_mock.assert_not_called() self.file_iterator_mock.assert_called_once_with( self.upload_dir, self.skip_files)
def testInRegistry(self): """In gcloudignore registry, writes .gcloudignore to disk.""" it = source_files_util.GetSourceFiles(self.upload_dir.path, self.skip_files, False, 'python37', env.STANDARD, self.source_dir.path) self.assertListEqual(sorted(it), ['main.py', 'main.pyc']) self.AssertFileContains('__pycache__', self.gcloudignore_path)
def testImplicitSkipFiles(self): """Not in gcloudignore registry, uses implicit skip_files.""" it = source_files_util.GetSourceFiles(self.upload_dir.path, self.skip_files, False, 'python27', env.STANDARD, self.source_dir.path) self.assertListEqual( sorted(it), [os.path.join('__pycache__', 'cached-file'), 'main.py']) self.AssertFileNotExists(self.gcloudignore_path)
def testNotInRegistry_GcloudignoreExists(self): """A gcloudignore is allowed opt-in if not in registry.""" exists = self.StartObjectPatch(os.path, 'exists', return_value=True) source_files_util.GetSourceFiles(self.upload_dir, self.skip_files, False, 'fake-runtime', 'fake-env', self.source_dir) exists.assert_called_once_with( os.path.join(self.source_dir, '.gcloudignore')) self.file_chooser_mock.assert_called_once_with(self.source_dir) self.file_iterator_mock.assert_not_called()
def testInRegistry_ExplicitSkipFiles(self): """Skip files not allowed when there's a registry entry.""" self.entry = 'gcloudignore-contents' with self.assertRaisesRegexp( source_files_util.SkipFilesError, r'cannot be used with the \[fake-runtime\] runtime'): source_files_util.GetSourceFiles(self.upload_dir, self.skip_files, True, 'fake-runtime', 'fake-env', self.source_dir) self.file_chooser_mock.assert_not_called() self.file_iterator_mock.assert_not_called()
def testNotInRegistry_IgnoreFileExists(self): """Skip files specified in ignore-file.""" exists = self.StartObjectPatch(os.path, 'exists', return_value=True) ignore_file = '.gcloudignore-testing-config1' source_files_util.GetSourceFiles(self.upload_dir, self.skip_files, False, 'fake-runtime', 'fake-env', self.source_dir, ignore_file) exists.assert_called_once_with( os.path.join(self.source_dir, ignore_file)) self.file_chooser_mock.assert_called_once_with(self.source_dir, ignore_file=ignore_file) self.file_iterator_mock.assert_not_called()
def testInRegistry(self): """Has registry entry for .gcloudignore, no explicit skip files.""" self.entry = 'gcloudignore-contents' source_files_util.GetSourceFiles(self.upload_dir, self.skip_files, False, 'fake-runtime', 'fake-env', self.source_dir) self.file_chooser_mock.assert_called_once_with( self.source_dir, default_ignore_file='gcloudignore-contents', include_gitignore=False, gcloud_ignore_creation_predicate=mock.ANY, write_on_disk=True) self.file_iterator_mock.assert_not_called()
def testNotInRegistry_ExplicitSkipFiles_GcloudignoreExists(self): """Skip files never allowed in conjunction with gcloudignore.""" exists = self.StartObjectPatch(os.path, 'exists', return_value=True) with self.assertRaisesRegexp( source_files_util.SkipFilesError, r'Cannot have both a \.gcloudignore file and skip_files'): source_files_util.GetSourceFiles(self.upload_dir, self.skip_files, True, 'fake-runtime', 'fake-env', self.source_dir) exists.assert_called_once_with( os.path.join(self.source_dir, '.gcloudignore')) self.file_chooser_mock.assert_not_called() self.file_iterator_mock.assert_not_called()
def testIgnorefileNotExist(self): """Raise error if user specified ignore-file does not exist.""" exists = self.StartObjectPatch(os.path, 'exists', return_value=False) ignore_file = '.gcloudignore-testing-config1' with self.assertRaisesRegexp( exceptions.FileNotFoundError, 'File {0} referenced by --ignore-file does not exist.'.format( ignore_file)): source_files_util.GetSourceFiles(self.upload_dir, self.skip_files, True, 'fake-runtime', 'fake-env', self.source_dir, ignore_file) exists.assert_called_once_with( os.path.join(self.source_dir, ignore_file)) self.file_chooser_mock.assert_not_called() self.file_iterator_mock.assert_not_called()
def testExistingIgnorefile(self): """Existing ignore-file overrides .gcloudignore. This is an imaginary scenario where the user wants to upload pre-compiled *.pyc files only, and hence ignores *.py files. This behavior is independent of whether there is a registry entry or not for the runtime. """ ignore_file = '.gcloudignore-testing-config1' self.Touch(self.source_dir.path, ignore_file, '*.py') it = source_files_util.GetSourceFiles(self.upload_dir.path, self.skip_files, False, 'python27', env.STANDARD, self.source_dir.path, ignore_file) self.assertListEqual( sorted(it), [os.path.join('__pycache__', 'cached-file'), 'main.pyc']) self.AssertFileEquals('*.py', self.ignore_file_path)
def testExistingGcloudignore(self, runtime): """Existing .gcloudignore overrides default .gcloudignore. This is an imaginary scenario where the user wants to upload pre-compiled *.pyc files only, and hence ignores *.py files. This behavior is independent of whether there is a .gcloudignore registry entry or not for the runtime. Args: runtime: str, runtime id. """ self.Touch(self.source_dir.path, '.gcloudignore', '*.py') it = source_files_util.GetSourceFiles(self.upload_dir.path, self.skip_files, False, runtime, env.STANDARD, self.source_dir.path) self.assertListEqual( sorted(it), [os.path.join('__pycache__', 'cached-file'), 'main.pyc']) self.AssertFileEquals('*.py', self.gcloudignore_path)
def Deploy(self, service, new_version, code_bucket_ref, image, all_services, gcr_domain, disable_build_cache, flex_image_build_option=FlexImageBuildOptions.ON_CLIENT, ignore_file=None): """Deploy the given service. Performs all deployment steps for the given service (if applicable): * Enable endpoints (for beta deployments) * Build and push the Docker image (Flex only, if image_url not provided) * Upload files (non-hermetic deployments and flex deployments with flex_image_build_option=FlexImageBuildOptions.ON_SERVER) * Create the new version * Promote the version to receive all traffic (if --promote given (default)) * Stop the previous version (if new version promoted and --stop-previous-version given (default)) Args: service: deployables.Service, service to be deployed. new_version: version_util.Version describing where to deploy the service code_bucket_ref: cloud_storage.BucketReference where the service's files will be uploaded image: str or None, the URL for the Docker image to be deployed (if image already exists). all_services: dict of service ID to service_util.Service objects corresponding to all pre-existing services (used to determine how to promote this version to receive all traffic, if applicable). gcr_domain: str, Cloud Registry domain, determines the physical location of the image. E.g. `us.gcr.io`. disable_build_cache: bool, disable the build cache. flex_image_build_option: FlexImageBuildOptions, whether a flex deployment should upload files so that the server can build the image or build the image on client. ignore_file: custom ignore_file name. Override .gcloudignore file to customize files to be skipped. """ log.status.Print( 'Beginning deployment of service [{service}]...'.format( service=new_version.service)) if (service.service_info.env == env.MANAGED_VMS and flex_image_build_option == FlexImageBuildOptions.ON_SERVER): # Server-side builds are not supported for Managed VMs. flex_image_build_option = FlexImageBuildOptions.ON_CLIENT service_info = service.service_info self._ValidateRuntime(service_info) source_files = source_files_util.GetSourceFiles( service.upload_dir, service_info.parsed.skip_files.regex, service_info.HasExplicitSkipFiles(), service_info.runtime, service_info.env, service.source, ignore_file=ignore_file) # Tar-based upload for flex build = self._PossiblyBuildAndPush(new_version, service_info, service.upload_dir, source_files, image, code_bucket_ref, gcr_domain, flex_image_build_option) # Manifest-based incremental source upload for all envs manifest = self._PossiblyUploadFiles(image, service_info, service.upload_dir, source_files, code_bucket_ref, flex_image_build_option) del source_files # Free some memory extra_config_settings = {} if disable_build_cache: extra_config_settings['no-cache'] = 'true' # Actually create the new version of the service. metrics.CustomTimedEvent(metric_names.DEPLOY_API_START) self.api_client.DeployService(new_version.service, new_version.id, service_info, manifest, build, extra_config_settings) metrics.CustomTimedEvent(metric_names.DEPLOY_API) self._PossiblyPromote(all_services, new_version)