diff --git a/insights/core/spec_factory.py b/insights/core/spec_factory.py index 5423ed6b20..ccb8c2a007 100644 --- a/insights/core/spec_factory.py +++ b/insights/core/spec_factory.py @@ -1004,11 +1004,12 @@ def __call__(self, broker): source = [source] for e in source: try: - # e = (image, , container_id, <...>) - image, e = e[0], e[1:] - # e = (, container_id, <...>) + # e = (image, , container_id, ) + image, engine, cid, args = e[0], e[1], e[2], e[3:] + # handle command with args + cmd = self.cmd % args if args else self.cmd # the_cmd = exec container_id cmd - the_cmd = ("/usr/bin/%s exec %s " + self.cmd) % e + the_cmd = "/usr/bin/%s exec %s %s" % (engine, cid, cmd) ccp = ContainerCommandProvider(the_cmd, ctx, image=image, args=e, split=self.split, keep_rc=self.keep_rc, ds=self, timeout=self.timeout, inherit_env=self.inherit_env, signum=self.signum) @@ -1056,14 +1057,17 @@ def __call__(self, broker): source = [source] for e in source: try: - # e = (image, , container_id, ) + # e = (image, , container_id, ) image, e = e[0], e[1:] - # e = (, container_id, ) - # self.cmd = path or None - # elems = (, container_id, path) - elems = e if self.cmd is None else e + (self.cmd,) + if self.cmd is None or self.cmd == '%s': + # path is provided by `provider` + e, path = e[:-1], e[-1] + else: + # path is provided by self.cmd + e, path = e, self.cmd + # e = (, container_id) # the_cmd = exec container_id cat path - the_cmd = "/usr/bin/%s exec %s cat %s" % elems + the_cmd = ("/usr/bin/%s exec %s cat " % e) + path cfp = ContainerFileProvider(the_cmd, ctx, image=image, args=None, split=self.split, keep_rc=self.keep_rc, ds=self, timeout=self.timeout, inherit_env=self.inherit_env, signum=self.signum) diff --git a/insights/util/autology/datasources.py b/insights/util/autology/datasources.py index b31b0e17f3..5019297c81 100644 --- a/insights/util/autology/datasources.py +++ b/insights/util/autology/datasources.py @@ -21,6 +21,8 @@ """ str: Literal constant for a simple_file Spec object """ FOREACH_EXECUTE_TYPE = 'foreach_execute' """ str: Literal constant for a foreach_execute Spec object """ +CONTAINER_EXECUTE_TYPE = 'container_execute' +""" str: Literal constant for a container_execute Spec object """ LISTDIR_TYPE = 'listdir' """ str: Literal constant for a listdir Spec object """ LIST_TYPE = 'list' @@ -35,6 +37,8 @@ """ str: Literal constant for a first_file Spec object """ FOREACH_COLLECT_TYPE = 'foreach_collect' """ str: Literal constant for a foreach_collect Spec object """ +CONTAINER_COLLECT_TYPE = 'container_collect' +""" str: Literal constant for a container_collect Spec object """ FIRST_OF_TYPE = 'first_of' """ str: Literal constant for a first_of Spec object """ COMMAND_WITH_ARGS_TYPE = 'command_with_args' @@ -67,6 +71,11 @@ def is_foreach_execute(m_obj): return isinstance(m_obj, insights.core.spec_factory.foreach_execute) +def is_container_execute(m_obj): + """ bool: True if broker object is a is_container_execute object """ + return isinstance(m_obj, insights.core.spec_factory.container_execute) + + def is_first_file(m_obj): """ bool: True if broker object is a first_file object """ return isinstance(m_obj, insights.core.spec_factory.first_file) @@ -82,6 +91,11 @@ def is_foreach_collect(m_obj): return isinstance(m_obj, insights.core.spec_factory.foreach_collect) +def is_container_collect(m_obj): + """ bool: True if broker object is a is_container_collect object """ + return isinstance(m_obj, insights.core.spec_factory.container_collect) + + def is_listdir(m_obj): """ bool: True if broker object is a is_listdir object """ return isinstance(m_obj, insights.core.spec_factory.listdir) @@ -212,6 +226,22 @@ def from_object(cls, m_type, m_name=ANONYMOUS_SPEC_NAME): m_spec['repr'] = 'foreach_execute("{cmd}", provider={provider})' + elif is_container_execute(m_type): + m_spec['cmd'] = next((v for k, v in m_members if k == "cmd"), None) + m_spec['type_name'] = CONTAINER_EXECUTE_TYPE + provider = next((v for k, v in m_members if k == "provider"), None) + if provider: + m_spec['provider'] = cls.from_object(provider) + + else: + m_spec['provider'] = Spec( + name=ANONYMOUS_SPEC_NAME, + type=None, + type_name=NONE_TYPE, + repr='NONE PROVIDER') + + m_spec['repr'] = 'container_execute("{cmd}", provider={provider})' + elif is_first_of(m_type): m_spec['type_name'] = FIRST_OF_TYPE deps = next((v for k, v in m_members if k == "deps"), None) @@ -235,6 +265,15 @@ def from_object(cls, m_type, m_name=ANONYMOUS_SPEC_NAME): m_spec['provider'] = cls.from_object(provider) m_spec['repr'] = 'foreach_collect("{path}", provider={provider})' + elif is_container_collect(m_type): + m_spec['type_name'] = CONTAINER_COLLECT_TYPE + # container_collect is based on foreach_execute, it used obj.cmd as the path + m_spec['path'] = next((v for k, v in m_members if k == 'cmd'), None) + provider = next((v for k, v in m_members if k == "provider"), None) + if provider: + m_spec['provider'] = cls.from_object(provider) + m_spec['repr'] = 'container_collect("{path}", provider={provider})' + elif is_head(m_type): m_spec['type_name'] = HEAD_TYPE dep = next((v for k, v in m_members if k == "dep"), None)