def testExpandArg(self): dfobj = dockerfile.get_dockerfile_obj(self.buildpackarg) dockerfile.expand_arg(dfobj) replace_content = 'FROM debian:jessie\n' replace_value = 'debian:jessie' struct = dfobj.structure[1] self.assertEqual(struct['value'], replace_value) self.assertEqual(struct['content'], replace_content)
def testParseFromImage(self): dfobj = dockerfile.get_dockerfile_obj(self.buildpack) image_list = dockerfile.parse_from_image(dfobj) self.assertEqual(image_list, [{ 'name': 'debian', 'tag': 'jessie', 'digest_type': '', 'digest': '' }]) dfobj = dockerfile.get_dockerfile_obj(self.buildpackpinned) image_list = dockerfile.parse_from_image(dfobj) debian_digest = ('e25703ee6ab5b2fac31510323d959cdae31eebdf48e88891c54' '9e55b25ad7e94') self.assertEqual(image_list, [{ 'name': 'debian', 'tag': '', 'digest_type': 'sha256', 'digest': debian_digest }])
def testDockerfileParserWithoutEnv(self): dfobj = dockerfile.get_dockerfile_obj(self.buildpack) self.assertFalse(dfobj.is_none()) self.assertEqual(dfobj.parent_images, ['debian:jessie']) structure = [{ 'instruction': 'FROM', 'startline': 0, 'endline': 0, 'content': 'FROM debian:jessie\n', 'value': 'debian:jessie' }, { 'instruction': 'RUN', 'startline': 2, 'endline': 7, 'content': ('RUN apt-get update && apt-get install -y --' 'no-install-recommends \\\n\t\tca-certific' 'ates \\\n\t\tcurl \\\n\t\tnetbase \\\n\t\tw' 'get \\\n\t&& rm -rf /var/lib/apt/lists/*' '\n'), 'value': ('apt-get update && apt-get install -y --no-in' 'stall-recommends \t\tca-certificates \t\tcur' 'l \t\tnetbase \t\twget \t&& rm -rf /var/lib/' 'apt/lists/*') }, { 'instruction': 'RUN', 'startline': 9, 'endline': 17, 'content': ('RUN set -ex; \\\n\tif ! command -v gpg > /' 'dev/null; then \\\n\t\tapt-get update; \\' '\n\t\tapt-get install -y --no-install-reco' 'mmends \\\n\t\t\tgnupg \\\n\t\t\tdirmngr \\' '\n\t\t; \\\n\t\trm -rf /var/lib/apt/lists/' '*; \\\n\tfi\n'), 'value': ('set -ex; \tif ! command -v gpg > /dev/null; t' 'hen \t\tapt-get update; \t\tapt-get install -' 'y --no-install-recommends \t\t\tgnupg \t\t\td' 'irmngr \t\t; \t\trm -rf /var/lib/apt/lists/*' '; \tfi') }] self.assertEqual(dfobj.structure, structure) self.assertFalse(dfobj.envs)
def testReplaceEnv(self): dfobj = dockerfile.get_dockerfile_obj(self.golang) envs = { 'GOLANG_VERSION': '1.13.6', 'GOPATH': '/go', 'PATH': '/go/bin:/usr/local/go/bin:' } self.assertEqual(dfobj.envs, envs) struct = dfobj.structure[9] dockerfile.replace_env(dfobj.envs, struct) self.assertEqual(struct['content'], 'WORKDIR /go\n') self.assertEqual(struct['value'], '/go') replace_content = ('\n\turl="https://golang.org/dl/go1.13.6.' '${goRelArch}.tar.gz"; ') replace_value = (' \t\turl="https://golang.org/dl/go1.13.6' '.${goRelArch}.tar.gz"') struct = dfobj.structure[5] dockerfile.replace_env(dfobj.envs, struct) self.assertEqual(struct['content'].split('\\')[14], replace_content) self.assertEqual(struct['value'].split(';')[28], replace_value)
def execute_dockerfile(args): # noqa C901,R0912 '''Execution path if given a dockerfile''' container.check_docker_setup() logger.debug('Setting up...') dfile = '' dfile_lock = False if args.name == 'report': dfile = args.dockerfile else: dfile = args.lock dfile_lock = True dfobj = dockerfile.get_dockerfile_obj(dfile) # expand potential ARG values so base image tag is correct dockerfile.expand_arg(dfobj) dockerfile.expand_vars(dfobj) report.setup(dfobj=dfobj) # attempt to build the image logger.debug('Building Docker image...') # placeholder to check if we can analyze the full image completed = True build, _ = dhelper.is_build() if build: # attempt to get built image metadata image_tag_string = dhelper.get_dockerfile_image_tag() full_image = report.load_full_image(image_tag_string) if full_image.origins.is_empty(): # image loading was successful # Add an image origin here full_image.origins.add_notice_origin( formats.dockerfile_image.format(dockerfile=dfile)) # analyze image analyze(full_image, args, dfile_lock, dfobj) else: # we cannot load the full image logger.warning('Cannot retrieve full image metadata') completed = False # clean up image container.remove_image(full_image.repotag) if not args.keep_wd: report.clean_image_tars(full_image) else: # cannot build the image logger.warning('Cannot build image') completed = False # check if we have analyzed the full image or not if not completed: # get the base image logger.debug('Loading base image...') base_image = report.load_base_image() if base_image.origins.is_empty(): # image loading was successful # add a notice stating failure to build image base_image.origins.add_notice_to_origins( dfile, Notice(formats.image_build_failure, 'warning')) # analyze image analyze(base_image, args, dfile_lock, dfobj) else: # we cannot load the base image logger.warning('Cannot retrieve base image metadata') stub_image = get_dockerfile_packages() if args.name == 'report': if not args.keep_wd: report.clean_image_tars(base_image) # generate report based on what images were created if not dfile_lock: if completed: report.report_out(args, full_image) else: report.report_out(args, base_image, stub_image) else: logger.debug('Parsing Dockerfile to generate report...') output = dockerfile.create_locked_dockerfile(dfobj) dockerfile.write_locked_dockerfile(output, args.output_file) logger.debug('Teardown...') report.teardown() if args.name == 'report': if not args.keep_wd: report.clean_working_dir()
def testDockerfileParserWithEnv(self): dfobj = dockerfile.get_dockerfile_obj(self.buildpack, {'buildno': '123abc'}) self.assertFalse(dfobj.is_none()) self.assertEqual(dfobj.prev_env, {'buildno': '123abc'})
def execute_dockerfile(args): # noqa C901,R0912 '''Execution path if given a dockerfile''' dfile = '' dfile_lock = False if args.name == 'report': dfile = args.dockerfile else: dfile = args.lock dfile_lock = True logger.debug("Parsing Dockerfile...") dfobj = dockerfile.get_dockerfile_obj(dfile) # expand potential ARG values so base image tag is correct dockerfile.expand_arg(dfobj) dockerfile.expand_vars(dfobj) # Store dockerfile path and commands so we can access it during execution dhelper.load_docker_commands(dfobj) # attempt to build the image logger.debug('Building Docker image...') image_info = docker_api.build_and_dump(dfile) if image_info: # attempt to load the built image metadata full_image = report.load_full_image(dfile, '') if full_image.origins.is_empty(): # image loading was successful # Add an image origin here full_image.origins.add_notice_origin( formats.dockerfile_image.format(dockerfile=dfile)) # analyze image analyze(full_image, args, dfile_lock, dfobj) completed = True else: # we cannot analyze the full image, but maybe we can # analyze the base image logger.warning('Cannot retrieve full image metadata') # clean up image tarballs if not args.keep_wd: prep.clean_image_tars(full_image) else: # cannot build the image logger.warning('Cannot build image') # check if we have analyzed the full image or not if not completed: # Try to analyze the base image logger.debug('Analyzing base image...') base_image = report.load_base_image() if base_image.origins.is_empty(): # image loading was successful # add a notice stating failure to build image base_image.origins.add_notice_to_origins( dfile, Notice( formats.image_build_failure, 'warning')) # analyze image analyze(base_image, args, dfile_lock, dfobj) else: # we cannot load the base image logger.warning('Cannot retrieve base image metadata') stub_image = get_dockerfile_packages() if args.name == 'report': if not args.keep_wd: report.clean_image_tars(base_image) # generate report based on what images were created if not dfile_lock: if completed: report.report_out(args, full_image) else: report.report_out(args, base_image, stub_image) else: logger.debug('Parsing Dockerfile to generate report...') output = dockerfile.create_locked_dockerfile(dfobj) dockerfile.write_locked_dockerfile(output, args.output_file) # cleanup if not args.keep_wd: prep.clean_image_tars(full_image)