def add_base_packages(image_layer, binary, shell): '''Given the image layer, the binary to invoke and shell: 1. get the listing from the base.yml 2. Invoke any commands against the base layer 3. Make a list of packages and add them to the layer''' origin_layer = 'Layer: ' + image_layer.fs_hash[:10] if image_layer.created_by: image_layer.origins.add_notice_to_origins( origin_layer, Notice( formats.layer_created_by.format( created_by=image_layer.created_by), 'info')) else: image_layer.origins.add_notice_to_origins( origin_layer, Notice(formats.no_created_by, 'warning')) origin_command_lib = formats.invoking_base_commands # find the binary listing = command_lib.get_base_listing(binary) if listing: # put info notice about what is going to be invoked snippet_msg = formats.invoke_for_base + '\n' + \ content.print_base_invoke(binary) image_layer.origins.add_notice_to_origins(origin_layer, Notice(snippet_msg, 'info')) shell, msg = command_lib.get_image_shell(listing) if not shell: shell = constants.shell # get all the packages in the base layer names, n_msg = command_lib.get_pkg_attr_list(shell, listing['names']) versions, v_msg = command_lib.get_pkg_attr_list( shell, listing['versions']) licenses, l_msg = command_lib.get_pkg_attr_list( shell, listing['licenses']) src_urls, u_msg = command_lib.get_pkg_attr_list( shell, listing['src_urls']) # add a notice to the image if something went wrong invoke_msg = n_msg + v_msg + l_msg + u_msg if invoke_msg: image_layer.origins.add_notice_to_origins( origin_layer, Notice(invoke_msg, 'error')) if names and len(names) > 1: for index in range(0, len(names)): pkg = Package(names[index]) if len(versions) == len(names): pkg.version = versions[index] if len(licenses) == len(names): pkg.license = licenses[index] if len(src_urls) == len(names): pkg.src_url = src_urls[index] image_layer.add_package(pkg) # if there is no listing add a notice else: image_layer.origins.add_notice_to_origins( origin_command_lib, Notice(errors.no_listing_for_base_key.format(listing_key=binary), 'error'))
def fill_package_metadata(pkg_obj, pkg_listing, shell): '''Given a Package object and the Package listing from the command library, fill in the attribute value returned from looking up the data and methods of the package listing. Fill out: version, license and src_url If there are errors, fill out notices''' # create a NoticeOrigin for the package origin_str = 'command_lib/snippets.yml' # version version_listing, listing_msg = command_lib.check_library_key( pkg_listing, 'version') if version_listing: version_list, invoke_msg = command_lib.get_pkg_attr_list( shell, version_listing, package_name=pkg_obj.name) if version_list: pkg_obj.version = version_list[0] else: pkg_obj.origins.add_notice_to_origins( origin_str, Notice(invoke_msg, 'error')) else: pkg_obj.origins.add_notice_to_origins( origin_str, Notice(listing_msg, 'warning')) # license license_listing, listing_msg = command_lib.check_library_key( pkg_listing, 'license') if license_listing: license_list, invoke_msg = command_lib.get_pkg_attr_list( shell, license_listing, package_name=pkg_obj.name) if license_list: pkg_obj.license = license_list[0] else: pkg_obj.origins.add_notice_to_origins( origin_str, Notice(invoke_msg, 'error')) else: pkg_obj.origins.add_notice_to_origins( origin_str, Notice(listing_msg, 'warning')) # src_urls url_listing, listing_msg = command_lib.check_library_key( pkg_listing, 'src_url') if url_listing: url_list, invoke_msg = command_lib.get_pkg_attr_list( shell, url_listing, package_name=pkg_obj.name) if url_list: pkg_obj.src_url = url_list[0] else: pkg_obj.origins.add_notice_to_origins( origin_str, Notice(invoke_msg, 'error')) else: pkg_obj.origins.add_notice_to_origins( origin_str, Notice(listing_msg, 'warning'))
def get_package_dependencies(package_listing, package_name, shell): '''The package listing is the result of looking up the command name in the command library. Given this listing, the package name and the shell return a list of package dependency names''' deps_listing, deps_msg = command_lib.check_library_key(package_listing, 'deps') if deps_listing: deps_list, invoke_msg = command_lib.get_pkg_attr_list( shell, deps_listing, package_name=package_name, chroot=False) if deps_list: return list(set(deps_list)), '' else: return [], invoke_msg else: return [], deps_msg
parser.add_argument('--keys', nargs='+', help='List of keys to look up in the command library') parser.add_argument('--shell', default='/bin/bash', help='The shell executable that the container uses') parser.add_argument('--package', default='', help='A package name that the command needs to \ execute with') args = parser.parse_args() if 'snippets' in args.keys and 'packages' in args.keys: # we're looking up the snippet library # get the package info that corresponds to the package name # or get the default last = args.keys.pop() info_list = look_up_lib(args.keys) info_dict = command_lib.check_for_unique_package( info_list, args.package)[last] else: info_dict = look_up_lib(args.keys) try: result = command_lib.get_pkg_attr_list(args.shell, info_dict, args.package, False, args.container) print('Output list: ' + ' '.join(result[0])) print('Error messages: ' + result[1]) print('Number of elements: ' + str(len(result[0]))) except subprocess.CalledProcessError as error: print(error.output)
def add_base_packages(base_layer, binary): '''Given the base layer and the binary found in layer fs: 1. get the listing from the base.yml 2. Invoke any commands against the base layer 3. Make a list of packages and add them to the layer''' origin_layer = 'Layer: ' + base_layer.diff_id[:10] if base_layer.created_by: base_layer.origins.add_notice_to_origins(origin_layer, Notice( formats.layer_created_by.format(created_by=base_layer.created_by), 'info')) else: base_layer.origins.add_notice_to_origins(origin_layer, Notice( formats.no_created_by, 'warning')) origin_command_lib = formats.invoking_base_commands # find the binary listing = command_lib.get_base_listing(binary) if listing: # put info notice about what is going to be invoked snippet_msg = formats.invoke_for_base + '\n' + \ content.print_base_invoke(binary) base_layer.origins.add_notice_to_origins( origin_layer, Notice(snippet_msg, 'info')) shell, msg = command_lib.get_image_shell(listing) if not shell: # add a warning notice for no shell in the command library logger.warning('No shell listing in command library. ' 'Using default shell') no_shell_message = errors.no_shell_listing.format( binary, default_shell=constants.shell) base_layer.origins.add_notice_to_origins( origin_command_lib, Notice(no_shell_message, 'warning')) # add a hint notice to add the shell to the command library add_shell_message = errors.no_listing_for_base_key.format( listing_key='shell') base_layer.origins.add_notice_origins( origin_command_lib, Notice(add_shell_message, 'hint')) shell = constants.shell # get all the packages in the base layer names, n_msg = command_lib.get_pkg_attr_list(shell, listing['names']) versions, v_msg = command_lib.get_pkg_attr_list( shell, listing['versions']) licenses, l_msg = command_lib.get_pkg_attr_list( shell, listing['licenses']) src_urls, u_msg = command_lib.get_pkg_attr_list( shell, listing['src_urls']) # add a notice to the image if something went wrong invoke_msg = n_msg + v_msg + l_msg + u_msg if invoke_msg: base_layer.origins.add_notice_to_origins( origin_layer, Notice(invoke_msg, 'error')) if names and len(names) > 1: for index in range(0, len(names)): pkg = Package(names[index]) if len(versions) == len(names): pkg.version = versions[index] if len(licenses) == len(names): pkg.license = licenses[index] if len(src_urls) == len(names): pkg.src_url = src_urls[index] base_layer.add_package(pkg) # if there is no listing add a notice else: base_layer.origins.add_notice_to_origins( origin_command_lib, Notice(errors.no_listing_for_base_key.format( listing_key=binary), 'error'))
def add_base_packages(image): '''Given an image object, get a list of package objects from invoking the commands in the command library base section: 1. For the image and tag name find if there is a list of package names 2. If there is an invoke dictionary, invoke the commands 3. Create a list of packages 4. Add them to the image''' # information under the base image tag in the command library listing = command_lib.get_base_listing(image.name, image.tag) # create the origin for the base image origin_info = formats.invoking_base_commands + '\n' + \ content.print_base_invoke(image.name, image.tag) image.origins.add_notice_origin(origin_info) origin_str = 'command_lib/base.yml' if listing: shell, msg = command_lib.get_image_shell(listing) if not shell: # add a warning notice for no shell in the command library logger.warning('No shell listing in command library. ' 'Using default shell') no_shell_message = errors.no_shell_listing.format( image_name=image.name, image_tag=image.tag, default_shell=constants.shell) image.origins.add_notice_to_origins( origin_str, Notice(no_shell_message, 'warning')) # add a hint notice to add the shell to the command library add_shell_message = errors.no_listing_for_base_key.format( listing_key='shell') image.origins.add_notice_origins(origin_str, Notice(add_shell_message, 'hint')) shell = constants.shell # check if a container is running first # eventually this needs to change to use derivatives that have # more than 1 layer # for now, we add the list of packages to all the layers in a # starting base image if check_container(): names, n_msg = command_lib.get_pkg_attr_list( shell, listing['names']) versions, v_msg = command_lib.get_pkg_attr_list( shell, listing['versions']) licenses, l_msg = command_lib.get_pkg_attr_list( shell, listing['licenses']) src_urls, u_msg = command_lib.get_pkg_attr_list( shell, listing['src_urls']) # add a notice to the image if something went wrong invoke_msg = n_msg + v_msg + l_msg + u_msg if invoke_msg: image.origins.add_notice_to_origins( origin_str, Notice(invoke_msg, 'error')) if names and len(names) > 1: for index in range(0, len(names)): pkg = Package(names[index]) if len(versions) == len(names): pkg.version = versions[index] if len(licenses) == len(names): pkg.license = licenses[index] if len(src_urls) == len(names): pkg.src_url = src_urls[index] for layer in image.layers: layer.add_package(pkg) # if no container is running give a logging error else: logger.error(errors.no_running_docker_container) # if there is no listing add a notice else: image.origins.add_notice_to_origins( origin_str, Notice( errors.no_image_tag_listing.format(image_name=image.name, image_tag=image.tag), 'error'))