def get_dockerfile_packages(): '''Given a Dockerfile return an approximate image object. This is mosty guess work and shouldn't be relied on for accurate information. Add Notice messages indicating as such: 1. Create an image with a placeholder repotag 2. For each RUN command, create a package list 3. Create layer objects with incremental integers and add the package list to that layer with a Notice about parsing 4. Return stub image''' stub_image = Image('easteregg:cookie') layer_count = 0 for inst in docker.docker_commands: if inst[0] == 'RUN': layer_count = layer_count + 1 layer = ImageLayer(layer_count) install_commands, msg = common.filter_install_commands(inst[1]) if msg: layer.origins.add_notice_to_origins( inst[1], Notice(msg, 'info')) pkg_names = [] for command in install_commands: pkg_names.append(common.get_installed_package_names(command)) for pkg_name in pkg_names: pkg = Package(pkg_name) # shell parser does not parse version pins yet # when that is enabled, Notices for no versions need to be # added here layer.add_package(pkg) return stub_image
def add_packages_from_history(image_obj, shell): '''Given a DockerImage object, get package objects installed in each layer Assume that the imported images have already gone through this process and have their layer's packages populated. So collecting package object occurs from the last linked layer: 1. For each layer get a list of package names 2. For each package name get a list of dependencies 3. Create a list of package objects with metadata 4. Add this to the layer''' image_layers = image_obj.layers[image_obj.get_last_import_layer() + 1:] logger.debug('Retrieving metadata for remaining {} layers'.format( len(image_layers))) for layer in image_layers: instruction = created_to_instruction(layer.created_by) origin_layer = instruction + ' -> ' + layer.diff_id[:10] layer.origins.add_notice_origin(origin_layer) origin_info = formats.invoke_for_snippets layer.origins.add_notice_origin(origin_info) if 'RUN' in instruction: # for Docker the created_by comes from the instruction in the # dockerfile run_command_line = instruction.split(' ', 1)[1] cmd_list, msg = common.filter_install_commands(run_command_line) if msg: layer.origins.add_notice_to_origins(origin_info, Notice(msg, 'warning')) for command in cmd_list: origin_cmd = content.print_package_invoke(command.name) layer.origins.add_notice_origin(origin_cmd) pkg_list = common.get_installed_package_names(command) all_pkgs = [] for pkg_name in pkg_list: pkg_listing = command_lib.get_package_listing( command.name, pkg_name) deps, deps_msg = common.get_package_dependencies( pkg_listing, pkg_name, shell) if deps_msg: logger.warning(deps_msg) all_pkgs.append(pkg_name) all_pkgs.extend(deps) unique_pkgs = list(set(all_pkgs)) for pkg_name in unique_pkgs: pkg = Package(pkg_name) pkg_listing = command_lib.get_package_listing( command.name, pkg_name) common.fill_package_metadata(pkg, pkg_listing, shell) layer.add_package(pkg)