We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Dependencies 'is_aws'/'is_azure' doesn't work on non-aws/non-azure system
The `insights.specs.default.DefaultSpecs.aws_instance_type` parser got the following result incorrectly from non-aws system:

```
# cat /tmp/insights-xxx-20200216034411/insights_commands/python_-m_insights.tools.cat_--no-header_aws_instance_type
Missing Dependencies:
    At Least One Of:
        insights.specs.default.DefaultSpecs.aws_instance_type
        insights.specs.insights_archive.InsightsArchiveSpecs.aws_instance_type
```
Then the `insights.parsers.aws_instance_type.AWSInstanceType` parser returns `.type` as "INSIGHTS", for all non-aws systems, which result some rules got fired incorrectly.

In fact, this spec `aws_instance_type` shouldn't be collected at all since it depends on `is_aws`:
https://github.com/RedHatInsights/insights-core/blob/0db5e8900507a6a60b58ac458a11644a8871306a/insights/specs/default.py#L100-L109

And the `is_aws` is skipped correctly:
```
# insights-cat insights.specs.default.DefaultSpecs.is_aws /tmp/insights-xxx-20200216034411
[Empty output]
```

And the dependency check works well:
```
# insights-cat insights.specs.default.DefaultSpecs.aws_instance_type /tmp/insights-xxx-20200216034411 
Missing Dependencies:
    Requires:
        insights.core.context.HostContext
        insights.specs.default.DefaultSpecs.is_aws
```
However, the spec is still collected by the client.
```
# cat /tmp/insights-xxx-20200216034411/insights_commands/python_-m_insights.tools.cat_--no-header_aws_instance_type
Missing Dependencies:
    At Least One Of:
        insights.specs.default.DefaultSpecs.aws_instance_type
        insights.specs.insights_archive.InsightsArchiveSpecs.aws_instance_type
```

It shouldn't be collected, right?

BTW, the `azure_*` and the other `aws_*` specs are also affected by this issue.




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `insights/client/archive.py`
Content:
```
1 """
2 Handle adding files and preparing the archive for upload
3 """
4 from __future__ import absolute_import
5 import time
6 import os
7 import shutil
8 import subprocess
9 import shlex
10 import logging
11 import tempfile
12 import re
13 import atexit
14 
15 from .utilities import determine_hostname, _expand_paths, write_data_to_file
16 from .insights_spec import InsightsFile, InsightsCommand
17 
18 logger = logging.getLogger(__name__)
19 
20 
21 class InsightsArchive(object):
22     """
23     This class is an interface for adding command output
24     and files to the insights archive
25     """
26     def __init__(self, config):
27         """
28         Initialize the Insights Archive
29         Create temp dir, archive dir, and command dir
30         """
31         self.config = config
32         self.tmp_dir = tempfile.mkdtemp(prefix='/var/tmp/')
33         if not self.config.obfuscate:
34             self.archive_tmp_dir = tempfile.mkdtemp(prefix='/var/tmp/')
35         name = determine_hostname()
36         self.archive_name = ("insights-%s-%s" %
37                              (name,
38                               time.strftime("%Y%m%d%H%M%S")))
39         self.archive_dir = self.create_archive_dir()
40         self.cmd_dir = self.create_command_dir()
41         self.compressor = 'gz' or config.compressor
42         self.tar_file = None
43         atexit.register(self.cleanup_tmp)
44 
45     def create_archive_dir(self):
46         """
47         Create the archive dir
48         """
49         archive_dir = os.path.join(self.tmp_dir, self.archive_name)
50         os.makedirs(archive_dir, 0o700)
51         return archive_dir
52 
53     def create_command_dir(self):
54         """
55         Create the "sos_commands" dir
56         """
57         cmd_dir = os.path.join(self.archive_dir, "insights_commands")
58         os.makedirs(cmd_dir, 0o700)
59         return cmd_dir
60 
61     def get_full_archive_path(self, path):
62         """
63         Returns the full archive path
64         """
65         return os.path.join(self.archive_dir, path.lstrip('/'))
66 
67     def _copy_file(self, path):
68         """
69         Copy just a single file
70         """
71         full_path = self.get_full_archive_path(path)
72         # Try to make the dir, eat exception if it fails
73         try:
74             os.makedirs(os.path.dirname(full_path))
75         except OSError:
76             pass
77         logger.debug("Copying %s to %s", path, full_path)
78         shutil.copyfile(path, full_path)
79         return path
80 
81     def copy_file(self, path):
82         """
83         Copy a single file or regex, creating the necessary directories
84         """
85         if "*" in path:
86             paths = _expand_paths(path)
87             if paths:
88                 for path in paths:
89                     self._copy_file(path)
90         else:
91             if os.path.isfile(path):
92                 return self._copy_file(path)
93             else:
94                 logger.debug("File %s does not exist", path)
95                 return False
96 
97     def copy_dir(self, path):
98         """
99         Recursively copy directory
100         """
101         for directory in path:
102             if os.path.isdir(path):
103                 full_path = os.path.join(self.archive_dir, directory.lstrip('/'))
104                 logger.debug("Copying %s to %s", directory, full_path)
105                 shutil.copytree(directory, full_path)
106             else:
107                 logger.debug("Not a directory: %s", directory)
108         return path
109 
110     def get_compression_flag(self, compressor):
111         return {
112             "gz": "z",
113             "xz": "J",
114             "bz2": "j",
115             "none": ""
116         }.get(compressor, "z")
117 
118     def create_tar_file(self):
119         """
120         Create tar file to be compressed
121         """
122         tar_file_name = os.path.join(self.archive_tmp_dir, self.archive_name)
123         ext = "" if self.compressor == "none" else ".%s" % self.compressor
124         tar_file_name = tar_file_name + ".tar" + ext
125         logger.debug("Tar File: " + tar_file_name)
126         if self.compressor not in ["gz", "xz", "bz2", "none"]:
127             logger.error("The compressor %s is not supported.  Using default: gz", self.compressor)
128         return_code = subprocess.call(shlex.split("tar c%sfS %s -C %s ." % (
129             self.get_compression_flag(self.compressor),
130             tar_file_name, self.tmp_dir)),
131             stderr=subprocess.PIPE)
132         if (self.compressor in ["bz2", "xz"] and return_code != 0):
133             logger.error("ERROR: %s compressor is not installed, cannot compress file", self.compressor)
134             return None
135         self.delete_archive_dir()
136         logger.debug("Tar File Size: %s", str(os.path.getsize(tar_file_name)))
137         self.tar_file = tar_file_name
138         return tar_file_name
139 
140     def delete_tmp_dir(self):
141         """
142         Delete the entire tmp dir
143         """
144         logger.debug("Deleting: " + self.tmp_dir)
145         shutil.rmtree(self.tmp_dir, True)
146 
147     def delete_archive_dir(self):
148         """
149         Delete the entire archive dir
150         """
151         logger.debug("Deleting: " + self.archive_dir)
152         shutil.rmtree(self.archive_dir, True)
153 
154     def delete_archive_file(self):
155         """
156         Delete the directory containing the constructed archive
157         """
158         logger.debug("Deleting %s", self.archive_tmp_dir)
159         shutil.rmtree(self.archive_tmp_dir, True)
160 
161     def add_to_archive(self, spec):
162         '''
163         Add files and commands to archive
164         Use InsightsSpec.get_output() to get data
165         '''
166         cmd_not_found_regex = "^timeout: failed to run command .+: No such file or directory$"
167         if isinstance(spec, InsightsCommand):
168             archive_path = os.path.join(self.cmd_dir, spec.archive_path.lstrip('/'))
169         if isinstance(spec, InsightsFile):
170             archive_path = self.get_full_archive_path(spec.archive_path.lstrip('/'))
171         output = spec.get_output()
172         if output and not re.search(cmd_not_found_regex, output):
173             write_data_to_file(output, archive_path)
174 
175     def add_metadata_to_archive(self, metadata, meta_path):
176         '''
177         Add metadata to archive
178         '''
179         archive_path = self.get_full_archive_path(meta_path.lstrip('/'))
180         write_data_to_file(metadata, archive_path)
181 
182     def cleanup_tmp(self):
183         '''
184         Only used during built-in collection.
185         Delete archive and tmp dirs on exit.
186         '''
187         if self.config.keep_archive:
188             if self.config.no_upload:
189                 logger.info('Archive saved at %s', self.tar_file)
190             else:
191                 logger.info('Insights archive retained in %s', self.tar_file)
192             if self.config.obfuscate:
193                 return  # return before deleting tmp_dir
194         else:
195             self.delete_archive_file()
196         self.delete_tmp_dir()
197
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/insights/client/archive.py b/insights/client/archive.py
--- a/insights/client/archive.py
+++ b/insights/client/archive.py
@@ -163,13 +163,16 @@
         Add files and commands to archive
         Use InsightsSpec.get_output() to get data
         '''
-        cmd_not_found_regex = "^timeout: failed to run command .+: No such file or directory$"
+        ab_regex = [
+            "^timeout: failed to run command .+: No such file or directory$",
+            "^Missing Dependencies:"
+        ]
         if isinstance(spec, InsightsCommand):
             archive_path = os.path.join(self.cmd_dir, spec.archive_path.lstrip('/'))
         if isinstance(spec, InsightsFile):
             archive_path = self.get_full_archive_path(spec.archive_path.lstrip('/'))
         output = spec.get_output()
-        if output and not re.search(cmd_not_found_regex, output):
+        if output and not any(re.search(rg, output) for rg in ab_regex):
             write_data_to_file(output, archive_path)
 
     def add_metadata_to_archive(self, metadata, meta_path):

{"golden_diff": "diff --git a/insights/client/archive.py b/insights/client/archive.py\n--- a/insights/client/archive.py\n+++ b/insights/client/archive.py\n@@ -163,13 +163,16 @@\n         Add files and commands to archive\n         Use InsightsSpec.get_output() to get data\n         '''\n-        cmd_not_found_regex = \"^timeout: failed to run command .+: No such file or directory$\"\n+        ab_regex = [\n+            \"^timeout: failed to run command .+: No such file or directory$\",\n+            \"^Missing Dependencies:\"\n+        ]\n         if isinstance(spec, InsightsCommand):\n             archive_path = os.path.join(self.cmd_dir, spec.archive_path.lstrip('/'))\n         if isinstance(spec, InsightsFile):\n             archive_path = self.get_full_archive_path(spec.archive_path.lstrip('/'))\n         output = spec.get_output()\n-        if output and not re.search(cmd_not_found_regex, output):\n+        if output and not any(re.search(rg, output) for rg in ab_regex):\n             write_data_to_file(output, archive_path)\n \n     def add_metadata_to_archive(self, metadata, meta_path):\n", "issue": "Dependencies 'is_aws'/'is_azure' doesn't work on non-aws/non-azure system\nThe `insights.specs.default.DefaultSpecs.aws_instance_type` parser got the following result incorrectly from non-aws system:\r\n\r\n```\r\n# cat /tmp/insights-xxx-20200216034411/insights_commands/python_-m_insights.tools.cat_--no-header_aws_instance_type\r\nMissing Dependencies:\r\n    At Least One Of:\r\n        insights.specs.default.DefaultSpecs.aws_instance_type\r\n        insights.specs.insights_archive.InsightsArchiveSpecs.aws_instance_type\r\n```\r\nThen the `insights.parsers.aws_instance_type.AWSInstanceType` parser returns `.type` as \"INSIGHTS\", for all non-aws systems, which result some rules got fired incorrectly.\r\n\r\nIn fact, this spec `aws_instance_type` shouldn't be collected at all since it depends on `is_aws`:\r\nhttps://github.com/RedHatInsights/insights-core/blob/0db5e8900507a6a60b58ac458a11644a8871306a/insights/specs/default.py#L100-L109\r\n\r\nAnd the `is_aws` is skipped correctly:\r\n```\r\n# insights-cat insights.specs.default.DefaultSpecs.is_aws /tmp/insights-xxx-20200216034411\r\n[Empty output]\r\n```\r\n\r\nAnd the dependency check works well:\r\n```\r\n# insights-cat insights.specs.default.DefaultSpecs.aws_instance_type /tmp/insights-xxx-20200216034411 \r\nMissing Dependencies:\r\n    Requires:\r\n        insights.core.context.HostContext\r\n        insights.specs.default.DefaultSpecs.is_aws\r\n```\r\nHowever, the spec is still collected by the client.\r\n```\r\n# cat /tmp/insights-xxx-20200216034411/insights_commands/python_-m_insights.tools.cat_--no-header_aws_instance_type\r\nMissing Dependencies:\r\n    At Least One Of:\r\n        insights.specs.default.DefaultSpecs.aws_instance_type\r\n        insights.specs.insights_archive.InsightsArchiveSpecs.aws_instance_type\r\n```\r\n\r\nIt shouldn't be collected, right?\r\n\r\nBTW, the `azure_*` and the other `aws_*` specs are also affected by this issue.\r\n\r\n\r\n\n", "before_files": [{"content": "\"\"\"\nHandle adding files and preparing the archive for upload\n\"\"\"\nfrom __future__ import absolute_import\nimport time\nimport os\nimport shutil\nimport subprocess\nimport shlex\nimport logging\nimport tempfile\nimport re\nimport atexit\n\nfrom .utilities import determine_hostname, _expand_paths, write_data_to_file\nfrom .insights_spec import InsightsFile, InsightsCommand\n\nlogger = logging.getLogger(__name__)\n\n\nclass InsightsArchive(object):\n    \"\"\"\n    This class is an interface for adding command output\n    and files to the insights archive\n    \"\"\"\n    def __init__(self, config):\n        \"\"\"\n        Initialize the Insights Archive\n        Create temp dir, archive dir, and command dir\n        \"\"\"\n        self.config = config\n        self.tmp_dir = tempfile.mkdtemp(prefix='/var/tmp/')\n        if not self.config.obfuscate:\n            self.archive_tmp_dir = tempfile.mkdtemp(prefix='/var/tmp/')\n        name = determine_hostname()\n        self.archive_name = (\"insights-%s-%s\" %\n                             (name,\n                              time.strftime(\"%Y%m%d%H%M%S\")))\n        self.archive_dir = self.create_archive_dir()\n        self.cmd_dir = self.create_command_dir()\n        self.compressor = 'gz' or config.compressor\n        self.tar_file = None\n        atexit.register(self.cleanup_tmp)\n\n    def create_archive_dir(self):\n        \"\"\"\n        Create the archive dir\n        \"\"\"\n        archive_dir = os.path.join(self.tmp_dir, self.archive_name)\n        os.makedirs(archive_dir, 0o700)\n        return archive_dir\n\n    def create_command_dir(self):\n        \"\"\"\n        Create the \"sos_commands\" dir\n        \"\"\"\n        cmd_dir = os.path.join(self.archive_dir, \"insights_commands\")\n        os.makedirs(cmd_dir, 0o700)\n        return cmd_dir\n\n    def get_full_archive_path(self, path):\n        \"\"\"\n        Returns the full archive path\n        \"\"\"\n        return os.path.join(self.archive_dir, path.lstrip('/'))\n\n    def _copy_file(self, path):\n        \"\"\"\n        Copy just a single file\n        \"\"\"\n        full_path = self.get_full_archive_path(path)\n        # Try to make the dir, eat exception if it fails\n        try:\n            os.makedirs(os.path.dirname(full_path))\n        except OSError:\n            pass\n        logger.debug(\"Copying %s to %s\", path, full_path)\n        shutil.copyfile(path, full_path)\n        return path\n\n    def copy_file(self, path):\n        \"\"\"\n        Copy a single file or regex, creating the necessary directories\n        \"\"\"\n        if \"*\" in path:\n            paths = _expand_paths(path)\n            if paths:\n                for path in paths:\n                    self._copy_file(path)\n        else:\n            if os.path.isfile(path):\n                return self._copy_file(path)\n            else:\n                logger.debug(\"File %s does not exist\", path)\n                return False\n\n    def copy_dir(self, path):\n        \"\"\"\n        Recursively copy directory\n        \"\"\"\n        for directory in path:\n            if os.path.isdir(path):\n                full_path = os.path.join(self.archive_dir, directory.lstrip('/'))\n                logger.debug(\"Copying %s to %s\", directory, full_path)\n                shutil.copytree(directory, full_path)\n            else:\n                logger.debug(\"Not a directory: %s\", directory)\n        return path\n\n    def get_compression_flag(self, compressor):\n        return {\n            \"gz\": \"z\",\n            \"xz\": \"J\",\n            \"bz2\": \"j\",\n            \"none\": \"\"\n        }.get(compressor, \"z\")\n\n    def create_tar_file(self):\n        \"\"\"\n        Create tar file to be compressed\n        \"\"\"\n        tar_file_name = os.path.join(self.archive_tmp_dir, self.archive_name)\n        ext = \"\" if self.compressor == \"none\" else \".%s\" % self.compressor\n        tar_file_name = tar_file_name + \".tar\" + ext\n        logger.debug(\"Tar File: \" + tar_file_name)\n        if self.compressor not in [\"gz\", \"xz\", \"bz2\", \"none\"]:\n            logger.error(\"The compressor %s is not supported.  Using default: gz\", self.compressor)\n        return_code = subprocess.call(shlex.split(\"tar c%sfS %s -C %s .\" % (\n            self.get_compression_flag(self.compressor),\n            tar_file_name, self.tmp_dir)),\n            stderr=subprocess.PIPE)\n        if (self.compressor in [\"bz2\", \"xz\"] and return_code != 0):\n            logger.error(\"ERROR: %s compressor is not installed, cannot compress file\", self.compressor)\n            return None\n        self.delete_archive_dir()\n        logger.debug(\"Tar File Size: %s\", str(os.path.getsize(tar_file_name)))\n        self.tar_file = tar_file_name\n        return tar_file_name\n\n    def delete_tmp_dir(self):\n        \"\"\"\n        Delete the entire tmp dir\n        \"\"\"\n        logger.debug(\"Deleting: \" + self.tmp_dir)\n        shutil.rmtree(self.tmp_dir, True)\n\n    def delete_archive_dir(self):\n        \"\"\"\n        Delete the entire archive dir\n        \"\"\"\n        logger.debug(\"Deleting: \" + self.archive_dir)\n        shutil.rmtree(self.archive_dir, True)\n\n    def delete_archive_file(self):\n        \"\"\"\n        Delete the directory containing the constructed archive\n        \"\"\"\n        logger.debug(\"Deleting %s\", self.archive_tmp_dir)\n        shutil.rmtree(self.archive_tmp_dir, True)\n\n    def add_to_archive(self, spec):\n        '''\n        Add files and commands to archive\n        Use InsightsSpec.get_output() to get data\n        '''\n        cmd_not_found_regex = \"^timeout: failed to run command .+: No such file or directory$\"\n        if isinstance(spec, InsightsCommand):\n            archive_path = os.path.join(self.cmd_dir, spec.archive_path.lstrip('/'))\n        if isinstance(spec, InsightsFile):\n            archive_path = self.get_full_archive_path(spec.archive_path.lstrip('/'))\n        output = spec.get_output()\n        if output and not re.search(cmd_not_found_regex, output):\n            write_data_to_file(output, archive_path)\n\n    def add_metadata_to_archive(self, metadata, meta_path):\n        '''\n        Add metadata to archive\n        '''\n        archive_path = self.get_full_archive_path(meta_path.lstrip('/'))\n        write_data_to_file(metadata, archive_path)\n\n    def cleanup_tmp(self):\n        '''\n        Only used during built-in collection.\n        Delete archive and tmp dirs on exit.\n        '''\n        if self.config.keep_archive:\n            if self.config.no_upload:\n                logger.info('Archive saved at %s', self.tar_file)\n            else:\n                logger.info('Insights archive retained in %s', self.tar_file)\n            if self.config.obfuscate:\n                return  # return before deleting tmp_dir\n        else:\n            self.delete_archive_file()\n        self.delete_tmp_dir()\n", "path": "insights/client/archive.py"}], "after_files": [{"content": "\"\"\"\nHandle adding files and preparing the archive for upload\n\"\"\"\nfrom __future__ import absolute_import\nimport time\nimport os\nimport shutil\nimport subprocess\nimport shlex\nimport logging\nimport tempfile\nimport re\nimport atexit\n\nfrom .utilities import determine_hostname, _expand_paths, write_data_to_file\nfrom .insights_spec import InsightsFile, InsightsCommand\n\nlogger = logging.getLogger(__name__)\n\n\nclass InsightsArchive(object):\n    \"\"\"\n    This class is an interface for adding command output\n    and files to the insights archive\n    \"\"\"\n    def __init__(self, config):\n        \"\"\"\n        Initialize the Insights Archive\n        Create temp dir, archive dir, and command dir\n        \"\"\"\n        self.config = config\n        self.tmp_dir = tempfile.mkdtemp(prefix='/var/tmp/')\n        if not self.config.obfuscate:\n            self.archive_tmp_dir = tempfile.mkdtemp(prefix='/var/tmp/')\n        name = determine_hostname()\n        self.archive_name = (\"insights-%s-%s\" %\n                             (name,\n                              time.strftime(\"%Y%m%d%H%M%S\")))\n        self.archive_dir = self.create_archive_dir()\n        self.cmd_dir = self.create_command_dir()\n        self.compressor = 'gz' or config.compressor\n        self.tar_file = None\n        atexit.register(self.cleanup_tmp)\n\n    def create_archive_dir(self):\n        \"\"\"\n        Create the archive dir\n        \"\"\"\n        archive_dir = os.path.join(self.tmp_dir, self.archive_name)\n        os.makedirs(archive_dir, 0o700)\n        return archive_dir\n\n    def create_command_dir(self):\n        \"\"\"\n        Create the \"sos_commands\" dir\n        \"\"\"\n        cmd_dir = os.path.join(self.archive_dir, \"insights_commands\")\n        os.makedirs(cmd_dir, 0o700)\n        return cmd_dir\n\n    def get_full_archive_path(self, path):\n        \"\"\"\n        Returns the full archive path\n        \"\"\"\n        return os.path.join(self.archive_dir, path.lstrip('/'))\n\n    def _copy_file(self, path):\n        \"\"\"\n        Copy just a single file\n        \"\"\"\n        full_path = self.get_full_archive_path(path)\n        # Try to make the dir, eat exception if it fails\n        try:\n            os.makedirs(os.path.dirname(full_path))\n        except OSError:\n            pass\n        logger.debug(\"Copying %s to %s\", path, full_path)\n        shutil.copyfile(path, full_path)\n        return path\n\n    def copy_file(self, path):\n        \"\"\"\n        Copy a single file or regex, creating the necessary directories\n        \"\"\"\n        if \"*\" in path:\n            paths = _expand_paths(path)\n            if paths:\n                for path in paths:\n                    self._copy_file(path)\n        else:\n            if os.path.isfile(path):\n                return self._copy_file(path)\n            else:\n                logger.debug(\"File %s does not exist\", path)\n                return False\n\n    def copy_dir(self, path):\n        \"\"\"\n        Recursively copy directory\n        \"\"\"\n        for directory in path:\n            if os.path.isdir(path):\n                full_path = os.path.join(self.archive_dir, directory.lstrip('/'))\n                logger.debug(\"Copying %s to %s\", directory, full_path)\n                shutil.copytree(directory, full_path)\n            else:\n                logger.debug(\"Not a directory: %s\", directory)\n        return path\n\n    def get_compression_flag(self, compressor):\n        return {\n            \"gz\": \"z\",\n            \"xz\": \"J\",\n            \"bz2\": \"j\",\n            \"none\": \"\"\n        }.get(compressor, \"z\")\n\n    def create_tar_file(self):\n        \"\"\"\n        Create tar file to be compressed\n        \"\"\"\n        tar_file_name = os.path.join(self.archive_tmp_dir, self.archive_name)\n        ext = \"\" if self.compressor == \"none\" else \".%s\" % self.compressor\n        tar_file_name = tar_file_name + \".tar\" + ext\n        logger.debug(\"Tar File: \" + tar_file_name)\n        if self.compressor not in [\"gz\", \"xz\", \"bz2\", \"none\"]:\n            logger.error(\"The compressor %s is not supported.  Using default: gz\", self.compressor)\n        return_code = subprocess.call(shlex.split(\"tar c%sfS %s -C %s .\" % (\n            self.get_compression_flag(self.compressor),\n            tar_file_name, self.tmp_dir)),\n            stderr=subprocess.PIPE)\n        if (self.compressor in [\"bz2\", \"xz\"] and return_code != 0):\n            logger.error(\"ERROR: %s compressor is not installed, cannot compress file\", self.compressor)\n            return None\n        self.delete_archive_dir()\n        logger.debug(\"Tar File Size: %s\", str(os.path.getsize(tar_file_name)))\n        self.tar_file = tar_file_name\n        return tar_file_name\n\n    def delete_tmp_dir(self):\n        \"\"\"\n        Delete the entire tmp dir\n        \"\"\"\n        logger.debug(\"Deleting: \" + self.tmp_dir)\n        shutil.rmtree(self.tmp_dir, True)\n\n    def delete_archive_dir(self):\n        \"\"\"\n        Delete the entire archive dir\n        \"\"\"\n        logger.debug(\"Deleting: \" + self.archive_dir)\n        shutil.rmtree(self.archive_dir, True)\n\n    def delete_archive_file(self):\n        \"\"\"\n        Delete the directory containing the constructed archive\n        \"\"\"\n        logger.debug(\"Deleting %s\", self.archive_tmp_dir)\n        shutil.rmtree(self.archive_tmp_dir, True)\n\n    def add_to_archive(self, spec):\n        '''\n        Add files and commands to archive\n        Use InsightsSpec.get_output() to get data\n        '''\n        ab_regex = [\n            \"^timeout: failed to run command .+: No such file or directory$\",\n            \"^Missing Dependencies:\"\n        ]\n        if isinstance(spec, InsightsCommand):\n            archive_path = os.path.join(self.cmd_dir, spec.archive_path.lstrip('/'))\n        if isinstance(spec, InsightsFile):\n            archive_path = self.get_full_archive_path(spec.archive_path.lstrip('/'))\n        output = spec.get_output()\n        if output and not any(re.search(rg, output) for rg in ab_regex):\n            write_data_to_file(output, archive_path)\n\n    def add_metadata_to_archive(self, metadata, meta_path):\n        '''\n        Add metadata to archive\n        '''\n        archive_path = self.get_full_archive_path(meta_path.lstrip('/'))\n        write_data_to_file(metadata, archive_path)\n\n    def cleanup_tmp(self):\n        '''\n        Only used during built-in collection.\n        Delete archive and tmp dirs on exit.\n        '''\n        if self.config.keep_archive:\n            if self.config.no_upload:\n                logger.info('Archive saved at %s', self.tar_file)\n            else:\n                logger.info('Insights archive retained in %s', self.tar_file)\n            if self.config.obfuscate:\n                return  # return before deleting tmp_dir\n        else:\n            self.delete_archive_file()\n        self.delete_tmp_dir()\n", "path": "insights/client/archive.py"}]}