def BuildLayer(self): """Override.""" is_gcp_build = False if self._ctx and self._ctx.Contains(constants.COMPOSER_JSON): is_gcp_build = ftl_util.is_gcp_build( json.loads(self._ctx.GetFile(constants.COMPOSER_JSON))) if is_gcp_build: ftl_util.gcp_build(self._directory, 'composer', 'run-script', flags=["--timeout=600", "--no-dev"]) self._cleanup_build_layer() cached_img = None key = self.GetCacheKey() if self._cache: with ftl_util.Timing('checking_cached_composer_json_layer'): cached_img = self._cache.Get(key) self._log_cache_result(False if cached_img is None else True, key) if cached_img: self.SetImage(cached_img) else: with ftl_util.Timing('building_composer_json_layer'): self._build_layer() self._cleanup_build_layer() if self._cache: with ftl_util.Timing('uploading_composer_json_layer'): self._cache.Set(key, self.GetImage())
def BuildLayer(self): """Override.""" cached_img = None is_gcp_build = False if self._ctx and self._ctx.Contains(constants.PACKAGE_JSON): is_gcp_build = self._is_gcp_build( json.loads(self._ctx.GetFile(constants.PACKAGE_JSON))) if is_gcp_build: if self._should_use_yarn: self._gcp_build(self._directory, 'yarn', 'run') self._cleanup_build_layer() else: self._gcp_build(self._directory, 'npm', 'run-script') self._cleanup_build_layer() key = self.GetCacheKey() if self._cache: with ftl_util.Timing('checking_cached_packages_json_layer'): cached_img = self._cache.Get(key) self._log_cache_result(False if cached_img is None else True, key) if cached_img: self.SetImage(cached_img) else: with ftl_util.Timing('building_packages_json_layer'): self._build_layer() self._cleanup_build_layer() if self._cache: with ftl_util.Timing('uploading_packages_json_layer'): self._cache.Set(key, self.GetImage())
def main(cli_args): builder_args = node_parser.parse_args(cli_args) logger.setup_logging(builder_args) with ftl_util.Timing("full build"): with ftl_util.Timing("builder initialization"): node_ftl = node_builder.Node( context.Workspace(builder_args.directory), builder_args, _NODE_CACHE_VERSION) with ftl_util.Timing("build process for FTL image"): node_ftl.Build()
def main(cli_args): builder_args = php_parser.parse_args(cli_args) logger.setup_logging(builder_args) logger.preamble("php", builder_args) with ftl_util.Timing("full build"): with ftl_util.Timing("builder initialization"): php_ftl = php_builder.PHP( context.Workspace(builder_args.directory), builder_args, _PHP_CACHE_VERSION) with ftl_util.Timing("build process for FTL image"): php_ftl.Build()
def main(cli_args): builder_args = python_parser.parse_args(cli_args) logger.setup_logging(builder_args) with ftl_util.Timing("full build"): with ftl_util.Timing("builder initialization"): python_ftl = python_builder.Python( context.Workspace(builder_args.directory), builder_args, _PYTHON_CACHE_VERSION, ) with ftl_util.Timing("build process for FTL image"): python_ftl.Build()
def BuildLayer(self): cached_img = None if self._cache: with ftl_util.Timing('checking_cached_interpreter_layer'): key = self.GetCacheKey() cached_img = self._cache.Get(key) self._log_cache_result(False if cached_img is None else True) if cached_img: self.SetImage(cached_img) else: with ftl_util.Timing('building_interpreter_layer'): self._build_layer() if self._cache: with ftl_util.Timing('uploading_interpreter_layer'): self._cache.Set(self.GetCacheKey(), self.GetImage())
def main(cli_args): try: builder_args = php_parser.parse_args(cli_args) logger.setup_logging(builder_args) logger.preamble("php", builder_args) with ftl_util.Timing("full build"): with ftl_util.Timing("builder initialization"): php_ftl = php_builder.PHP( context.Workspace(builder_args.directory), builder_args) with ftl_util.Timing("build process for FTL image"): php_ftl.Build() except ftl_error.UserError as e: ftl_error.UserErrorHandler(e, builder_args.builder_output_path) except ftl_error.InternalError as e: ftl_error.InternalErrorHandler(e, builder_args.builder_output_path)
def Build(self): lyr_imgs = [] lyr_imgs.append(self._base_image) interpreter_builder = package_builder.InterpreterLayerBuilder( venv_dir=self._venv_dir, python_cmd=self._python_cmd, venv_cmd=self._venv_cmd, cache=self._cache) interpreter_builder.BuildLayer() lyr_imgs.append(interpreter_builder.GetImage()) if ftl_util.has_pkg_descriptor(self._descriptor_files, self._ctx): # build interpreter layer if self._is_phase2: # do a phase 2 build of the package layers w/ Pipfile.lock # iterate over package/version Pipfile.lock python_util.setup_venv(self._venv_dir, self._venv_cmd, self._python_cmd) pkgs = self._parse_pipfile_pkgs() with ftl_util.Timing('uploading_all_package_layers'): with concurrent.futures.ThreadPoolExecutor( max_workers=constants.THREADS) as executor: future_to_params = {executor.submit( self._build_pkg, pkg, interpreter_builder, lyr_imgs): pkg for pkg in pkgs } for future in concurrent.futures.as_completed( future_to_params): future.result() else: # do a phase 1 build of the package layers w/ requirements.txt req_txt_builder = package_builder.RequirementsLayerBuilder( ctx=self._ctx, descriptor_files=self._descriptor_files, directory=self._args.directory, pkg_dir=None, wheel_dir=self._wheel_dir, venv_dir=self._venv_dir, python_cmd=self._python_cmd, pip_cmd=self._pip_cmd, venv_cmd=self._venv_cmd, dep_img_lyr=interpreter_builder, cache=self._cache) req_txt_builder.BuildLayer() if req_txt_builder.GetImage(): lyr_imgs.append(req_txt_builder.GetImage()) app = base_builder.AppLayerBuilder( directory=self._args.directory, destination_path=self._args.destination_path, entrypoint=self._args.entrypoint, exposed_ports=self._args.exposed_ports) app.BuildLayer() lyr_imgs.append(app.GetImage()) ftl_image = ftl_util.AppendLayersIntoImage(lyr_imgs) self.StoreImage(ftl_image)
def _gen_composer_install_tar(self, pkg_descriptor, destination_path): # Create temp directory to write package descriptor to pkg_dir = tempfile.mkdtemp() app_dir = os.path.join(pkg_dir, destination_path.strip("/")) print 'app_dir: %s' % app_dir os.makedirs(app_dir) # Copy out the relevant package descriptors to a tempdir. if pkg_descriptor is None: # phase 1 copy whole descriptor ftl_util.descriptor_copy(self._ctx, self._descriptor_files, app_dir) subprocess.check_call(['rm', '-rf', os.path.join(app_dir, 'vendor')]) with ftl_util.Timing("composer_install"): if pkg_descriptor is None: # phase 1 install entire descriptor subprocess.check_call( ['composer', 'install', '--no-dev', '--no-scripts'], cwd=app_dir) else: pkg, version = pkg_descriptor subprocess.check_call( ['composer', 'require', str(pkg), str(version)], cwd=app_dir) return ftl_util.zip_dir_to_layer_sha(pkg_dir)
def BuildLayer(self): """Override.""" with ftl_util.Timing('Building app layer'): buf = cStringIO.StringIO() logging.info('Starting to generate app layer \ tarfile from context...') with tarfile.open(fileobj=buf, mode='w') as out: for name in self._ctx.ListFiles(): content = self._ctx.GetFile(name) info = tarfile.TarInfo( os.path.join(self._destination_path.strip("/"), name)) info.size = len(content) out.addfile(info, fileobj=cStringIO.StringIO(content)) logging.info('Finished generating app layer tarfile from context.') tar = buf.getvalue() logging.info('Starting to gzip app layer tarfile...') gzip_process = subprocess.Popen(['gzip', '-f'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) gz = gzip_process.communicate(input=tar)[0] overrides_dct = { 'created': str(datetime.date.today()) + 'T00:00:00Z' } if self._entrypoint: overrides_dct['Entrypoint'] = self._entrypoint if self._exposed_ports: overrides_dct['ExposedPorts'] = self._exposed_ports if self._exposed_ports: overrides_dct['ExposedPorts'] = self._exposed_ports logging.info('Finished gzipping tarfile.') self._img = tar_to_dockerimage.FromFSImage([gz], [tar], overrides_dct)
def BuildLayer(self): """Override.""" cached_img = None if self._cache: with ftl_util.Timing('checking_cached_composer_json_layer'): key = self.GetCacheKey() cached_img = self._cache.Get(key) self._log_cache_result(False if cached_img is None else True) if cached_img: self.SetImage(cached_img) else: with ftl_util.Timing('building_composer_json_layer'): self._build_layer() self._cleanup_build_layer() if self._cache: with ftl_util.Timing('uploading_composer_json_layer'): self._cache.Set(self.GetCacheKey(), self.GetImage())
def main(cli_args): try: builder_args = node_parser.parse_args(cli_args) logger.setup_logging(builder_args) logger.preamble("node", builder_args) with ftl_util.Timing("full build"): with ftl_util.Timing("builder initialization"): node_ftl = node_builder.Node( context.Workspace(builder_args.directory), builder_args) with ftl_util.Timing("build process for FTL image"): node_ftl.Build() except ftl_error.UserError as u_err: ftl_error.UserErrorHandler(u_err, builder_args.log_path) except ftl_error.InternalError: ftl_error.InternalErrorHandler(builder_args.log_path) if builder_args.log_path: exit(0)
def main(cli_args): try: version.parse_known_args(cli_args) builder_args = node_parser.parse_args(cli_args) logger.setup_logging(builder_args) logger.preamble("node", builder_args) with ftl_util.Timing("full build"): with ftl_util.Timing("builder initialization"): node_ftl = node_builder.Node( context.Workspace(builder_args.directory), builder_args) with ftl_util.Timing("build process for FTL image"): node_ftl.Build() except ftl_error.UserError as e: ftl_error.UserErrorHandler(e, builder_args.builder_output_path, builder_args.fail_on_error) except ftl_error.InternalError as e: ftl_error.InternalErrorHandler(e, builder_args.builder_output_path, builder_args.fail_on_error)
def StoreImage(self, result_image): if self._args.output_path: with ftl_util.Timing("saving_tarball_image"): with tarfile.open(name=self._args.output_path, mode='w') as tar: save.tarball(self._target_image, result_image, tar) logging.info("{0} tarball located at {1}".format( str(self._target_image), self._args.output_path)) return if self._args.upload: with ftl_util.Timing("pushing_image_to_docker_registry"): with docker_session.Push(self._target_image, self._target_creds, self._transport, threads=_THREADS, mount=[self._base_name]) as session: logging.info('Pushing final image...') session.upload(result_image) return
def BuildLayer(self): cached_img = None if self._cache: with ftl_util.Timing('checking_cached_requirements.txt_layer'): key = self.GetCacheKey() cached_img = self._cache.Get(key) self._log_cache_result(False if cached_img is None else True) if cached_img: self.SetImage(cached_img) else: python_util.setup_venv(self._venv_dir, self._venv_cmd, self._python_cmd) pkg_descriptor = ftl_util.descriptor_parser( self._descriptor_files, self._ctx) self._pip_download_wheels(pkg_descriptor) whls = self._resolve_whls() pkg_dirs = [self._whl_to_fslayer(whl) for whl in whls] req_txt_imgs = [] with ftl_util.Timing('uploading_all_package_layers'): with concurrent.futures.ThreadPoolExecutor( max_workers=constants.THREADS) as executor: future_to_params = { executor.submit(self._build_pkg, whl_pkg_dir, req_txt_imgs): whl_pkg_dir for whl_pkg_dir in pkg_dirs } for future in concurrent.futures.as_completed( future_to_params): future.result() req_txt_image = ftl_util.AppendLayersIntoImage(req_txt_imgs) if req_txt_image: self.SetImage(req_txt_image) if self._cache: with ftl_util.Timing('uploading_requirements.txt_pkg_lyr'): self._cache.Set(self.GetCacheKey(), self.GetImage())
def _pip_install(self, pkg_txt): with ftl_util.Timing("pip_install_wheels"): args = ['pip', 'wheel', '-w', self._wheel_dir, '-r', "/dev/stdin"] pipe1 = subprocess.Popen( args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self._gen_pip_env(), ) pipe1.communicate(input=pkg_txt)[0]
def Build(self): lyr_imgs = [] lyr_imgs.append(self._base_image) if ftl_util.has_pkg_descriptor(self._descriptor_files, self._ctx): layer_builder = node_builder.LayerBuilder( ctx=self._ctx, descriptor_files=self._descriptor_files, destination_path=self._args.destination_path) cached_pkg_img = None if self._args.cache: with ftl_util.Timing("checking cached pkg layer"): key = layer_builder.GetCacheKey() cached_pkg_img = self._cache.Get(key) if cached_pkg_img is not None: layer_builder.SetImage(cached_pkg_img) else: with ftl_util.Timing("building pkg layer"): layer_builder.BuildLayer() if self._args.cache: with ftl_util.Timing("uploading pkg layer"): self._cache.Set(layer_builder.GetCacheKey(), layer_builder.GetImage()) lyr_imgs.append(layer_builder) app = base_builder.AppLayerBuilder(self._ctx, self._args.destination_path, self._args.entrypoint, self._args.exposed_ports) with ftl_util.Timing("builder app layer"): app.BuildLayer() lyr_imgs.append(app) with ftl_util.Timing("stitching lyrs into final image"): ftl_image = self.AppendLayersIntoImage(lyr_imgs) with ftl_util.Timing("uploading final image"): self.StoreImage(ftl_image)
def BuildLayer(self): cached_img = None if self._cache: with ftl_util.Timing('checking_cached_pipfile_pkg_layer'): key = self.GetCacheKey() cached_img = self._cache.Get(key) self._log_cache_result(False if cached_img is None else True) if cached_img: self.SetImage(cached_img) else: self._pip_download_wheels(' '.join(self._pkg_descriptor)) whls = self._resolve_whls() if len(whls) != 1: raise Exception("expected one whl for one installed pkg") pkg_dir = self._whl_to_fslayer(whls[0]) blob, u_blob = ftl_util.zip_dir_to_layer_sha(pkg_dir, "") overrides = ftl_util.generate_overrides(False, self._venv_dir) self._img = tar_to_dockerimage.FromFSImage([blob], [u_blob], overrides) if self._cache: with ftl_util.Timing('uploading_pipfile_pkg_layer'): self._cache.Set(self.GetCacheKey(), self.GetImage())
def BuildLayer(self): cached_img = None if self._cache: with ftl_util.Timing('checking_cached_requirements.txt_layer'): key = self.GetCacheKey() cached_img = self._cache.Get(key) self._log_cache_result(False if cached_img is None else True) if cached_img: self.SetImage(cached_img) else: self._setup_venv() pkg_descriptor = ftl_util.descriptor_parser( self._descriptor_files, self._ctx) self._pip_download_wheels(pkg_descriptor) whls = self._resolve_whls() pkg_dirs = [self._whl_to_fslayer(whl) for whl in whls] req_txt_imgs = [] for whl_pkg_dir in pkg_dirs: layer_builder = PackageLayerBuilder( ctx=self._ctx, descriptor_files=self._descriptor_files, pkg_dir=whl_pkg_dir, dep_img_lyr=self._dep_img_lyr, cache=self._cache) layer_builder.BuildLayer() req_txt_imgs.append(layer_builder.GetImage()) req_txt_image = ftl_util.AppendLayersIntoImage(req_txt_imgs) self.SetImage(req_txt_image) if self._cache: with ftl_util.Timing('uploading_requirements.txt_pkg_lyr'): self._cache.Set(self.GetCacheKey(), self.GetImage())
def BuildLayer(self): """Override.""" with ftl_util.Timing('Building app layer'): gz, tar = ftl_util.zip_dir_to_layer_sha(self._directory, self._destination_path) overrides_dct = { 'created': str(datetime.date.today()) + 'T00:00:00Z' } if self._entrypoint: overrides_dct['Entrypoint'] = self._entrypoint if self._exposed_ports: overrides_dct['ExposedPorts'] = self._exposed_ports if self._exposed_ports: overrides_dct['ExposedPorts'] = self._exposed_ports logging.info('Finished gzipping tarfile.') self._img = tar_to_dockerimage.FromFSImage([gz], [tar], overrides_dct)
def _python_version(self): with ftl_util.Timing('check python version'): python_version_cmd = list(self._python_cmd) python_version_cmd.append('--version') logging.info("`python version` full cmd:\n%s" % " ".join(python_version_cmd)) proc_pipe = subprocess.Popen( python_version_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout, stderr = proc_pipe.communicate() logging.info("`python version` stderr:\n%s" % stderr) if proc_pipe.returncode: raise Exception("error: `python version` returned code: %d" % proc_pipe.returncode) # up until Python 3.4 the version info gets written to stderr return stdout if len(stdout) >= len(stderr) else stderr
def Build(self): lyr_imgs = [] lyr_imgs.append(self._base_image) if ftl_util.has_pkg_descriptor(self._descriptor_files, self._ctx): if self._ctx.Contains(constants.COMPOSER_LOCK): pkgs = self._parse_composer_lock_pkgs() else: pkgs = self._parse_composer_pkgs() # due to image layers limits, we revert to using phase 1 if over # the threshold if len(pkgs) > 41: # phase 1 logging.info('Building package layer') layer_builder = php_builder.PhaseOneLayerBuilder( ctx=self._ctx, descriptor_files=self._descriptor_files, destination_path=self._args.destination_path, cache=self._cache) layer_builder.BuildLayer() lyr_imgs.append(layer_builder.GetImage()) else: # phase 2 with ftl_util.Timing('uploading_all_package_layers'): with concurrent.futures.ThreadPoolExecutor( max_workers=constants.THREADS) as executor: future_to_params = {executor.submit( self._build_pkg, pkg_txt, lyr_imgs): pkg_txt for pkg_txt in pkgs } for future in concurrent.futures.as_completed( future_to_params): future.result() app = base_builder.AppLayerBuilder( ctx=self._ctx, destination_path=self._args.destination_path, entrypoint=self._args.entrypoint, exposed_ports=self._args.exposed_ports) app.BuildLayer() lyr_imgs.append(app.GetImage()) ftl_image = ftl_util.AppendLayersIntoImage(lyr_imgs) self.StoreImage(ftl_image)
def _pip_install(self, pkg_txt): with ftl_util.Timing("pip_download_wheels"): pip_cmd_args = list(self._pip_cmd) pip_cmd_args.extend( ['wheel', '-w', self._wheel_dir, '-r', "/dev/stdin"]) proc_pipe = subprocess.Popen( pip_cmd_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=self._gen_pip_env(), ) stdout, stderr = proc_pipe.communicate(input=pkg_txt) logging.info("`pip wheel` stdout:\n%s" % stdout) if stderr: logging.error("`pip wheel` had error output:\n%s" % stderr) if proc_pipe.returncode: raise Exception("error: `pip wheel` returned code: %d" % proc_pipe.returncode)
def _gen_npm_install_tar(self, pkg_descriptor, destination_path): # Create temp directory to write package descriptor to pkg_dir = tempfile.mkdtemp() app_dir = os.path.join(pkg_dir, destination_path.strip("/")) os.makedirs(app_dir) # Copy out the relevant package descriptors to a tempdir. ftl_util.descriptor_copy(self._ctx, self._descriptor_files, app_dir) self._check_gcp_build( json.loads(self._ctx.GetFile(constants.PACKAGE_JSON)), app_dir) subprocess.check_call( ['rm', '-rf', os.path.join(app_dir, 'node_modules')]) with ftl_util.Timing("npm_install"): if pkg_descriptor is None: subprocess.check_call(['npm', 'install', '--production'], cwd=app_dir) else: subprocess.check_call( ['npm', 'install', '--production', pkg_descriptor], cwd=app_dir) return ftl_util.zip_dir_to_layer_sha(pkg_dir)
def Build(self): lyr_imgs = [] lyr_imgs.append(self._base_image) if ftl_util.has_pkg_descriptor(self._descriptor_files, self._ctx): pkgs = self._parse_composer_pkgs() # if there are 42 or more packages, revert to using phase 1 if len(pkgs) > 41: pkgs = [None] for pkg_txt in pkgs: logging.info('building package layer') logging.info(pkg_txt) layer_builder = php_builder.LayerBuilder( ctx=self._ctx, descriptor_files=self._descriptor_files, pkg_descriptor=pkg_txt, destination_path=self._args.destination_path) cached_pkg_img = None if self._args.cache: with ftl_util.Timing("checking cached pkg layer"): key = layer_builder.GetCacheKey() cached_pkg_img = self._cache.Get(key) if cached_pkg_img is not None: layer_builder.SetImage(cached_pkg_img) else: with ftl_util.Timing("building pkg layer"): layer_builder.BuildLayer() if self._args.cache: with ftl_util.Timing("uploading pkg layer"): self._cache.Set(layer_builder.GetCacheKey(), layer_builder.GetImage()) lyr_imgs.append(layer_builder) app = base_builder.AppLayerBuilder( ctx=self._ctx, destination_path=self._args.destination_path, entrypoint=self._args.entrypoint, exposed_ports=self._args.exposed_ports) with ftl_util.Timing("builder app layer"): app.BuildLayer() lyr_imgs.append(app) with ftl_util.Timing("stitching lyrs into final image"): ftl_image = self.AppendLayersIntoImage(lyr_imgs) with ftl_util.Timing("uploading final image"): self.StoreImage(ftl_image)
def _setup_venv(self): with ftl_util.Timing("create_virtualenv"): venv_cmd_args = list(self._venv_cmd) venv_cmd_args.extend([ '--no-download', self._venv_dir, '-p', ]) venv_cmd_args.extend(self._python_cmd) proc_pipe = subprocess.Popen( venv_cmd_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout, stderr = proc_pipe.communicate() logging.info("`virtualenv` stdout:\n%s" % stdout) if stderr: logging.error("`virtualenv` had error output:\n%s" % stderr) if proc_pipe.returncode: raise Exception("error: `virtualenv` returned code: %d" % proc_pipe.returncode) subprocess.check_call(venv_cmd_args)
def _resolve_whls(self): with ftl_util.Timing('resolving_whl_paths'): return [ os.path.join(self._wheel_dir, f) for f in os.listdir(self._wheel_dir) ]
def Build(self): lyr_imgs = [] lyr_imgs.append(self._base_image) if ftl_util.has_pkg_descriptor(self._descriptor_files, self._ctx): interpreter_builder = package_builder.InterpreterLayerBuilder( self._venv_dir, self._args.python_version) cached_int_img = None if self._args.cache: with ftl_util.Timing("checking cached int layer"): key = interpreter_builder.GetCacheKey() cached_int_img = self._cache.Get(key) if cached_int_img is not None: interpreter_builder.SetImage(cached_int_img) else: with ftl_util.Timing("building int layer"): interpreter_builder.BuildLayer() if self._args.cache: with ftl_util.Timing("uploading int layer"): self._cache.Set(interpreter_builder.GetCacheKey(), interpreter_builder.GetImage()) lyr_imgs.append(interpreter_builder) pkg_descriptor = ftl_util.descriptor_parser( self._descriptor_files, self._ctx) with ftl_util.Timing("installing pip packages"): self._pip_install(pkg_descriptor) with ftl_util.Timing("resolving whl paths"): whls = self._resolve_whls() pkg_dirs = [self._whl_to_fslayer(whl) for whl in whls] for whl_pkg_dir in pkg_dirs: layer_builder = package_builder.PackageLayerBuilder( self._ctx, self._descriptor_files, whl_pkg_dir, interpreter_builder) cached_pkg_img = None if self._args.cache: with ftl_util.Timing("checking cached pkg layer"): key = layer_builder.GetCacheKey() cached_pkg_img = self._cache.Get(key) if cached_pkg_img is not None: layer_builder.SetImage(cached_pkg_img) else: with ftl_util.Timing("building pkg layer"): layer_builder.BuildLayer() if self._args.cache: with ftl_util.Timing("uploading pkg layer"): self._cache.Set(layer_builder.GetCacheKey(), layer_builder.GetImage()) lyr_imgs.append(layer_builder) app = base_builder.AppLayerBuilder( ctx=self._ctx, destination_path=self._args.destination_path, entrypoint=self._args.entrypoint, exposed_ports=self._args.exposed_ports) with ftl_util.Timing("builder app layer"): app.BuildLayer() lyr_imgs.append(app) with ftl_util.Timing("stitching lyrs into final image"): ftl_image = self.AppendLayersIntoImage(lyr_imgs) with ftl_util.Timing("uploading final image"): self.StoreImage(ftl_image)
def BuildLayer(self): with ftl_util.Timing('building_python_pkg_layer'): self._build_layer() if self._cache: with ftl_util.Timing('uploading_python_pkg_layer'): self._cache.Set(self.GetCacheKey(), self.GetImage())
def _setup_venv(self, python_version): with ftl_util.Timing("create_virtualenv"): subprocess.check_call([ 'virtualenv', '--no-download', self._venv_dir, '-p', python_version ])