prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Add --storage_file parameter to log2timeline
  Add `--storage_file` parameter as new plaso version will not work without this anymore.
  
  https://github.com/google/turbinia/blob/23a97d9d826cbcc51e6b5dfd50d85251506bf242/turbinia/workers/plaso.py#L121
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `turbinia/workers/plaso.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 # Copyright 2015 Google Inc.
  3 #
  4 # Licensed under the Apache License, Version 2.0 (the "License");
  5 # you may not use this file except in compliance with the License.
  6 # You may obtain a copy of the License at
  7 #
  8 #      http://www.apache.org/licenses/LICENSE-2.0
  9 #
  10 # Unless required by applicable law or agreed to in writing, software
  11 # distributed under the License is distributed on an "AS IS" BASIS,
  12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 # See the License for the specific language governing permissions and
  14 # limitations under the License.
  15 """Task for running Plaso."""
  16 
  17 from __future__ import unicode_literals
  18 
  19 import os
  20 import logging
  21 
  22 from turbinia import config
  23 from turbinia.evidence import EvidenceState as state
  24 from turbinia.evidence import PlasoFile
  25 from turbinia.workers import TurbiniaTask
  26 from turbinia.lib import file_helpers
  27 
  28 
  29 class PlasoTask(TurbiniaTask):
  30   """Task to run Plaso (log2timeline)."""
  31 
  32   # Plaso requires the Disk to be attached, but doesn't require it be mounted.
  33   REQUIRED_STATES = [state.ATTACHED, state.DECOMPRESSED]
  34 
  35   TASK_CONFIG = {
  36       # 'none' as indicated in the options for status_view within
  37       # the Plaso documentation
  38       'status_view': 'none',
  39       'hashers': 'all',
  40       'partitions': 'all',
  41       'vss_stores': 'none',
  42       'artifact_filters': None,
  43       'file_filter': None,
  44       'yara_rules': None
  45   }
  46 
  47   def build_plaso_command(self, base_command, conf):
  48     """Builds a typical plaso command, contains logic specific to log2timeline.
  49 
  50     Args:
  51       base_command (str): Command to invoke log2timeline (e.g. log2timeline.py)
  52       conf (dict): Dynamic config containing the parameters for the command.
  53 
  54     Returns:
  55       String for valid Log2timeline command.
  56     """
  57     self.result.log(
  58         'Generating Plaso command line from arguments: {0!s}'.format(conf),
  59         level=logging.DEBUG)
  60     cmd = [base_command]
  61     for k, v in conf.items():
  62       cli_args = [
  63           'status_view', 'hashers', 'partitions', 'vss_stores',
  64           'artifact_filters', 'file_filter', 'yara_rules'
  65       ]
  66       if (k not in cli_args or not v):
  67         continue
  68       prepend = '-'
  69       if len(k) > 1:
  70         prepend = '--'
  71       if k == 'file_filter':
  72         file_path = file_helpers.write_list_to_temp_file(
  73             v, preferred_dir=self.tmp_dir)
  74         cmd.extend(['-f', file_path])
  75       elif k == 'yara_rules':
  76         file_path = file_helpers.write_str_to_temp_file(
  77             v, preferred_dir=self.tmp_dir)
  78         cmd.extend(['--yara_rules', file_path])
  79       elif isinstance(v, list):
  80         cmd.extend([prepend + k, ','.join(v)])
  81       elif isinstance(v, bool):
  82         cmd.append(prepend + k)
  83       elif isinstance(v, str):
  84         cmd.extend([prepend + k, v])
  85     return cmd
  86 
  87   def run(self, evidence, result):
  88     """Task that process data with Plaso.
  89 
  90     Args:
  91         evidence (Evidence object):  The evidence we will process.
  92         result (TurbiniaTaskResult): The object to place task results into.
  93 
  94     Returns:
  95         TurbiniaTaskResult object.
  96     """
  97 
  98     config.LoadConfig()
  99 
  100     # Write plaso file into tmp_dir because sqlite has issues with some shared
  101     # filesystems (e.g NFS).
  102     plaso_file = os.path.join(self.tmp_dir, '{0:s}.plaso'.format(self.id))
  103     plaso_evidence = PlasoFile(source_path=plaso_file)
  104     plaso_log = os.path.join(self.output_dir, '{0:s}.log'.format(self.id))
  105 
  106     cmd = self.build_plaso_command('log2timeline.py', self.task_config)
  107 
  108     if config.DEBUG_TASKS or self.task_config.get('debug_tasks'):
  109       cmd.append('-d')
  110 
  111     if evidence.credentials:
  112       for credential_type, credential_data in evidence.credentials:
  113         cmd.extend([
  114             '--credential', '{0:s}:{1:s}'.format(
  115                 credential_type, credential_data)
  116         ])
  117 
  118     cmd.extend(['--temporary_directory', self.tmp_dir])
  119     cmd.extend(['--logfile', plaso_log])
  120     cmd.extend(['--unattended'])
  121     cmd.extend([plaso_file, evidence.local_path])
  122 
  123     result.log('Running plaso as [{0:s}]'.format(' '.join(cmd)))
  124     self.execute(
  125         cmd, result, log_files=[plaso_log], new_evidence=[plaso_evidence],
  126         close=True)
  127 
  128     return result
  129
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/turbinia/workers/plaso.py b/turbinia/workers/plaso.py
  --- a/turbinia/workers/plaso.py
  +++ b/turbinia/workers/plaso.py
  @@ -118,7 +118,8 @@
       cmd.extend(['--temporary_directory', self.tmp_dir])
       cmd.extend(['--logfile', plaso_log])
       cmd.extend(['--unattended'])
  -    cmd.extend([plaso_file, evidence.local_path])
  +    cmd.extend(['--storage_file', plaso_file])
  +    cmd.extend([evidence.local_path])
   
       result.log('Running plaso as [{0:s}]'.format(' '.join(cmd)))
       self.execute(
  
verification_info: {"golden_diff": "diff --git a/turbinia/workers/plaso.py b/turbinia/workers/plaso.py\n--- a/turbinia/workers/plaso.py\n+++ b/turbinia/workers/plaso.py\n@@ -118,7 +118,8 @@\n     cmd.extend(['--temporary_directory', self.tmp_dir])\n     cmd.extend(['--logfile', plaso_log])\n     cmd.extend(['--unattended'])\n-    cmd.extend([plaso_file, evidence.local_path])\n+    cmd.extend(['--storage_file', plaso_file])\n+    cmd.extend([evidence.local_path])\n \n     result.log('Running plaso as [{0:s}]'.format(' '.join(cmd)))\n     self.execute(\n", "issue": "Add --storage_file parameter to log2timeline\nAdd `--storage_file` parameter as new plaso version will not work without this anymore.\r\n\r\nhttps://github.com/google/turbinia/blob/23a97d9d826cbcc51e6b5dfd50d85251506bf242/turbinia/workers/plaso.py#L121\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright 2015 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"Task for running Plaso.\"\"\"\n\nfrom __future__ import unicode_literals\n\nimport os\nimport logging\n\nfrom turbinia import config\nfrom turbinia.evidence import EvidenceState as state\nfrom turbinia.evidence import PlasoFile\nfrom turbinia.workers import TurbiniaTask\nfrom turbinia.lib import file_helpers\n\n\nclass PlasoTask(TurbiniaTask):\n  \"\"\"Task to run Plaso (log2timeline).\"\"\"\n\n  # Plaso requires the Disk to be attached, but doesn't require it be mounted.\n  REQUIRED_STATES = [state.ATTACHED, state.DECOMPRESSED]\n\n  TASK_CONFIG = {\n      # 'none' as indicated in the options for status_view within\n      # the Plaso documentation\n      'status_view': 'none',\n      'hashers': 'all',\n      'partitions': 'all',\n      'vss_stores': 'none',\n      'artifact_filters': None,\n      'file_filter': None,\n      'yara_rules': None\n  }\n\n  def build_plaso_command(self, base_command, conf):\n    \"\"\"Builds a typical plaso command, contains logic specific to log2timeline.\n\n    Args:\n      base_command (str): Command to invoke log2timeline (e.g. log2timeline.py)\n      conf (dict): Dynamic config containing the parameters for the command.\n\n    Returns:\n      String for valid Log2timeline command.\n    \"\"\"\n    self.result.log(\n        'Generating Plaso command line from arguments: {0!s}'.format(conf),\n        level=logging.DEBUG)\n    cmd = [base_command]\n    for k, v in conf.items():\n      cli_args = [\n          'status_view', 'hashers', 'partitions', 'vss_stores',\n          'artifact_filters', 'file_filter', 'yara_rules'\n      ]\n      if (k not in cli_args or not v):\n        continue\n      prepend = '-'\n      if len(k) > 1:\n        prepend = '--'\n      if k == 'file_filter':\n        file_path = file_helpers.write_list_to_temp_file(\n            v, preferred_dir=self.tmp_dir)\n        cmd.extend(['-f', file_path])\n      elif k == 'yara_rules':\n        file_path = file_helpers.write_str_to_temp_file(\n            v, preferred_dir=self.tmp_dir)\n        cmd.extend(['--yara_rules', file_path])\n      elif isinstance(v, list):\n        cmd.extend([prepend + k, ','.join(v)])\n      elif isinstance(v, bool):\n        cmd.append(prepend + k)\n      elif isinstance(v, str):\n        cmd.extend([prepend + k, v])\n    return cmd\n\n  def run(self, evidence, result):\n    \"\"\"Task that process data with Plaso.\n\n    Args:\n        evidence (Evidence object):  The evidence we will process.\n        result (TurbiniaTaskResult): The object to place task results into.\n\n    Returns:\n        TurbiniaTaskResult object.\n    \"\"\"\n\n    config.LoadConfig()\n\n    # Write plaso file into tmp_dir because sqlite has issues with some shared\n    # filesystems (e.g NFS).\n    plaso_file = os.path.join(self.tmp_dir, '{0:s}.plaso'.format(self.id))\n    plaso_evidence = PlasoFile(source_path=plaso_file)\n    plaso_log = os.path.join(self.output_dir, '{0:s}.log'.format(self.id))\n\n    cmd = self.build_plaso_command('log2timeline.py', self.task_config)\n\n    if config.DEBUG_TASKS or self.task_config.get('debug_tasks'):\n      cmd.append('-d')\n\n    if evidence.credentials:\n      for credential_type, credential_data in evidence.credentials:\n        cmd.extend([\n            '--credential', '{0:s}:{1:s}'.format(\n                credential_type, credential_data)\n        ])\n\n    cmd.extend(['--temporary_directory', self.tmp_dir])\n    cmd.extend(['--logfile', plaso_log])\n    cmd.extend(['--unattended'])\n    cmd.extend([plaso_file, evidence.local_path])\n\n    result.log('Running plaso as [{0:s}]'.format(' '.join(cmd)))\n    self.execute(\n        cmd, result, log_files=[plaso_log], new_evidence=[plaso_evidence],\n        close=True)\n\n    return result\n", "path": "turbinia/workers/plaso.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# Copyright 2015 Google Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"Task for running Plaso.\"\"\"\n\nfrom __future__ import unicode_literals\n\nimport os\nimport logging\n\nfrom turbinia import config\nfrom turbinia.evidence import EvidenceState as state\nfrom turbinia.evidence import PlasoFile\nfrom turbinia.workers import TurbiniaTask\nfrom turbinia.lib import file_helpers\n\n\nclass PlasoTask(TurbiniaTask):\n  \"\"\"Task to run Plaso (log2timeline).\"\"\"\n\n  # Plaso requires the Disk to be attached, but doesn't require it be mounted.\n  REQUIRED_STATES = [state.ATTACHED, state.DECOMPRESSED]\n\n  TASK_CONFIG = {\n      # 'none' as indicated in the options for status_view within\n      # the Plaso documentation\n      'status_view': 'none',\n      'hashers': 'all',\n      'partitions': 'all',\n      'vss_stores': 'none',\n      'artifact_filters': None,\n      'file_filter': None,\n      'yara_rules': None\n  }\n\n  def build_plaso_command(self, base_command, conf):\n    \"\"\"Builds a typical plaso command, contains logic specific to log2timeline.\n\n    Args:\n      base_command (str): Command to invoke log2timeline (e.g. log2timeline.py)\n      conf (dict): Dynamic config containing the parameters for the command.\n\n    Returns:\n      String for valid Log2timeline command.\n    \"\"\"\n    self.result.log(\n        'Generating Plaso command line from arguments: {0!s}'.format(conf),\n        level=logging.DEBUG)\n    cmd = [base_command]\n    for k, v in conf.items():\n      cli_args = [\n          'status_view', 'hashers', 'partitions', 'vss_stores',\n          'artifact_filters', 'file_filter', 'yara_rules'\n      ]\n      if (k not in cli_args or not v):\n        continue\n      prepend = '-'\n      if len(k) > 1:\n        prepend = '--'\n      if k == 'file_filter':\n        file_path = file_helpers.write_list_to_temp_file(\n            v, preferred_dir=self.tmp_dir)\n        cmd.extend(['-f', file_path])\n      elif k == 'yara_rules':\n        file_path = file_helpers.write_str_to_temp_file(\n            v, preferred_dir=self.tmp_dir)\n        cmd.extend(['--yara_rules', file_path])\n      elif isinstance(v, list):\n        cmd.extend([prepend + k, ','.join(v)])\n      elif isinstance(v, bool):\n        cmd.append(prepend + k)\n      elif isinstance(v, str):\n        cmd.extend([prepend + k, v])\n    return cmd\n\n  def run(self, evidence, result):\n    \"\"\"Task that process data with Plaso.\n\n    Args:\n        evidence (Evidence object):  The evidence we will process.\n        result (TurbiniaTaskResult): The object to place task results into.\n\n    Returns:\n        TurbiniaTaskResult object.\n    \"\"\"\n\n    config.LoadConfig()\n\n    # Write plaso file into tmp_dir because sqlite has issues with some shared\n    # filesystems (e.g NFS).\n    plaso_file = os.path.join(self.tmp_dir, '{0:s}.plaso'.format(self.id))\n    plaso_evidence = PlasoFile(source_path=plaso_file)\n    plaso_log = os.path.join(self.output_dir, '{0:s}.log'.format(self.id))\n\n    cmd = self.build_plaso_command('log2timeline.py', self.task_config)\n\n    if config.DEBUG_TASKS or self.task_config.get('debug_tasks'):\n      cmd.append('-d')\n\n    if evidence.credentials:\n      for credential_type, credential_data in evidence.credentials:\n        cmd.extend([\n            '--credential', '{0:s}:{1:s}'.format(\n                credential_type, credential_data)\n        ])\n\n    cmd.extend(['--temporary_directory', self.tmp_dir])\n    cmd.extend(['--logfile', plaso_log])\n    cmd.extend(['--unattended'])\n    cmd.extend(['--storage_file', plaso_file])\n    cmd.extend([evidence.local_path])\n\n    result.log('Running plaso as [{0:s}]'.format(' '.join(cmd)))\n    self.execute(\n        cmd, result, log_files=[plaso_log], new_evidence=[plaso_evidence],\n        close=True)\n\n    return result\n", "path": "turbinia/workers/plaso.py"}]}