Skip to content

Commit

Permalink
Draft version of analyze multistage dockerfile
Browse files Browse the repository at this point in the history
1. In tern\analyze\docker\dockerfile.py, add function
split_multistage_dockerfile_by_stage() to split by stage.

2. In tern\analyze\docker\run.py, add function
build_multistage(), this is a draft version for building and analyzing
multistage dockerfile.

Works towards tern-tools#612.

Signed-off-by: WangJL <hazard15020@gmail.com>
  • Loading branch information
ForgetMe17 committed Aug 21, 2020
1 parent 888fb74 commit a01d0b8
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
32 changes: 32 additions & 0 deletions tern/analyze/docker/dockerfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,38 @@ def get_multistage_image_dockerfiles(dfobj_multi):
return file_path_list


def split_multistage_dockerfile_by_stage(dfobj_multi):
file_path_list = []
structure = []
file_idx = 0
from_lines = check_multistage_dockerfile(dfobj_multi)
# Pop the first FROM
from_lines.pop(0)
for idx in range(len(dfobj_multi.structure)):
if idx in from_lines:
if structure:
file_path = dfobj_multi.filepath + '_stage_%d' % (file_idx)
# we make a new dir for the dockerfile of each stage.
if not os.path.isdir(file_path):
os.mkdir(file_path)
file_path += '/Dockerfile'
file_idx += 1
write_dockerfile_by_structure(file_path, structure)
file_path_list.append(file_path)
structure.clear()
structure.append(dfobj_multi.structure[idx])
if structure:
file_path = dfobj_multi.filepath + '_stage_%d' % (file_idx)
# we make a new dir for the dockerfile of each stage.
if not os.path.isdir(file_path):
os.mkdir(file_path)
file_path += '/Dockerfile'
file_idx += 1
write_dockerfile_by_structure(file_path, structure)
file_path_list.append(file_path)
return file_path_list


def write_dockerfile_by_structure(file_name, structure):
"""Given a dockerfile name and its structure, write the content into the
dockerfile."""
Expand Down
35 changes: 35 additions & 0 deletions tern/analyze/docker/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,38 @@ def execute_dockerfile(args): # noqa C901,R0912
if args.name == 'report':
if not args.keep_wd:
report.clean_working_dir()


def build_multistage(dockerfile_path, args):
"""Given a multistage dockerfile, first get the dockerfiles for each
stage and then build the dockerfiles.
TO DO:
1. Add image analyze
2. Clean the temp dockerfiles"""
dfobj_multi = dockerfile.get_dockerfile_obj(dockerfile_path)
file_path_list = dockerfile.get_multistage_image_dockerfiles(dfobj_multi)
stage_list = dockerfile.split_multistage_dockerfile_by_stage(dfobj_multi)
print(file_path_list)
print(stage_list)
for idx, dfile in enumerate(file_path_list):
args.output_file = '/home/vagrant/output_%d.html' % (idx)
dfobj = dockerfile.get_dockerfile_obj(dfile)
stageobj = dockerfile.get_dockerfile_obj(stage_list[idx])
# 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
build, _ = dhelper.is_build()
print(build)
# TO DO: Add image analyze here to analyze each image.
if build:
# attempt to get built image metadata
image_tag_string = dhelper.get_dockerfile_image_tag()
print(image_tag_string)
full_image = report.load_full_image(image_tag_string)
analyze(full_image, args, False, stageobj)
container.remove_image(full_image.repotag)
report.report_out(args, full_image)

0 comments on commit a01d0b8

Please sign in to comment.