Skip to content

Commit

Permalink
Connect machinery to ingest previous reports
Browse files Browse the repository at this point in the history
This is work towards #946

This commit connects the command line argument --with-context or
-ctx to the inventory machinery for the --live option.

- We introduce a consumer entrypoint for the format plugin json.
  We make the decision here to keep the formats of the input and
  output reports to be consistent. In the JSON case, the report
  provided as -ctx context must be of JSON format. We do this to
  minimize the overhead of maintaining a set of formats for input
  reports as well as output reports and thus help with code reuse.
  For the JSON format, we use "jsonc".
- In the --live run, we modify the actual format selector string to
  add the "c" at the end of it, thus allowing us to call the
  consumer plugin rather than the generator plugin. The reporting
  will stay the same.
- We also added some fixes to the Consumer abstract base class to
  implement "consume_layer" rather than just "consume", and fixed
  the layer index increment in the JSON Consumer class.

Signed-off-by: Nisha K <[email protected]>
  • Loading branch information
Nisha K committed Jun 2, 2021
1 parent 1e167fa commit fce138b
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 4 deletions.
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ tern.formats =
spdxtagvalue = tern.formats.spdx.spdxtagvalue.generator:SpdxTagValue
spdxjson = tern.formats.spdx.spdxjson.generator:SpdxJSON
json = tern.formats.json.generator:JSON
jsonc = tern.formats.json.consumer:JSON
yaml = tern.formats.yaml.generator:YAML
html = tern.formats.html.generator:HTML
tern.extensions =
Expand Down
33 changes: 33 additions & 0 deletions tern/analyze/default/live/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"""
import logging
import os
from stevedore import driver
from stevedore.exception import NoMatches

from tern.utils import constants
from tern.utils import rootfs
Expand Down Expand Up @@ -86,6 +88,27 @@ def fill_packages(layer, prereqs):
com.remove_duplicate_layer_files(layer)


def get_context_layers(reports, format_string):
"""Given a list of reports and the format string, get corresponding layer
objects for each of the reports. We will load the required module and
run the consume_layer function to return the list of layers"""
# we want to maintain consistency between the input report formats and
# the output formats by redirecting the command line argument to the
# correct consumer entrypoint. Hence we maintain a known pattern for
# entrypoint strings which is simply that the corresponding consumer for
# a given generator is the generator's entrypoint string + 'c'
consumer_format_string = format_string + 'c'
try:
mgr = driver.DriverManager(
namespace='tern.formats',
name=consumer_format_string,
invoke_on_load=True,
)
return mgr.driver.consume_layer(reports)
except NoMatches:
pass


def execute_live(args):
"""Execute inventory at container build time
We assume a mounted working directory is ready to inventory"""
Expand All @@ -105,5 +128,15 @@ def execute_live(args):
prereqs.host_shell = host.check_shell()
# collect metadata into the layer object
fill_packages(layer, prereqs)
# resolve unique packages for this run with reports from previous runs
if args.with_context:
# get a list of previous layers based on plugin type
context_layers = get_context_layers(
args.with_context, args.report_format)
# resolve the packages for each of the layers
context_layers.append(layer)
master_list = []
for l in context_layers:
dcom.update_master_list(master_list, l)
# report out the packages
report.report_layer(layer, args)
6 changes: 3 additions & 3 deletions tern/formats/consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
class Consume(metaclass=ABCMeta):
"""Base class for report consuming plugins"""
@abstractmethod
def consume(self, reports):
"""Ingest the contents of the list of files into an Image object or
ImageLayer object according to the plugin type. Each plugin is
def consume_layer(self, reports):
"""Ingest the contents of the list of files into a list of ImageLayer
objects according to the plugin type. Each plugin is
responsible for implementing the reading and and assimilation of the
report metadata"""
2 changes: 1 addition & 1 deletion tern/formats/json/consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,5 @@ def consume_layer(self, reports):
layer = create_image_layer(report)
layer.layer_index = layer_count
layer_list.append(layer)
layer += 1
layer_count += 1
return layer_list

0 comments on commit fce138b

Please sign in to comment.