prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Missing [workflow_engine] in st2.conf.sample
  ##### SUMMARY
  
  https://github.com/StackStorm/st2/blob/master/conf/st2.conf.sample is missing a new section for `[workflow_engine]`
  
  Also, shouldn't this section be named `[workflowengine]` to go along with the "style" of the other sections like `[resultstracker]` , `[garbagecollector]`, etc
  
  ##### ISSUE TYPE
   - Bug Report
   - Feature Idea
  
  ##### STACKSTORM VERSION
  2.8
  
  ##### EXPECTED RESULTS
  https://github.com/StackStorm/st2/blob/master/conf/st2.conf.sample contains a section for `[workflow_engine]`
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `tools/config_gen.py`
  Content:
  ```
  1 #!/usr/bin/env python
  2 # Licensed to the StackStorm, Inc ('StackStorm') under one or more
  3 # contributor license agreements.  See the NOTICE file distributed with
  4 # this work for additional information regarding copyright ownership.
  5 # The ASF licenses this file to You under the Apache License, Version 2.0
  6 # (the "License"); you may not use this file except in compliance with
  7 # the License.  You may obtain a copy of the License at
  8 #
  9 #     http://www.apache.org/licenses/LICENSE-2.0
  10 #
  11 # Unless required by applicable law or agreed to in writing, software
  12 # distributed under the License is distributed on an "AS IS" BASIS,
  13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 # See the License for the specific language governing permissions and
  15 # limitations under the License.
  16 
  17 from __future__ import absolute_import
  18 import collections
  19 import importlib
  20 import six
  21 import sys
  22 import traceback
  23 
  24 from oslo_config import cfg
  25 
  26 
  27 CONFIGS = ['st2actions.config',
  28            'st2actions.notifier.config',
  29            'st2actions.resultstracker.config',
  30            'st2api.config',
  31            'st2stream.config',
  32            'st2auth.config',
  33            'st2common.config',
  34            'st2exporter.config',
  35            'st2reactor.rules.config',
  36            'st2reactor.sensor.config',
  37            'st2reactor.garbage_collector.config']
  38 
  39 SKIP_GROUPS = ['api_pecan', 'rbac', 'results_tracker']
  40 
  41 # We group auth options together to nake it a bit more clear what applies where
  42 AUTH_OPTIONS = {
  43     'common': [
  44         'enable',
  45         'mode',
  46         'logging',
  47         'api_url',
  48         'token_ttl',
  49         'service_token_ttl',
  50         'debug'
  51     ],
  52     'standalone': [
  53         'host',
  54         'port',
  55         'use_ssl',
  56         'cert',
  57         'key',
  58         'backend',
  59         'backend_kwargs'
  60     ]
  61 }
  62 
  63 # Some of the config values change depenending on the environment where this script is ran so we
  64 # set them to static values to ensure consistent and stable output
  65 STATIC_OPTION_VALUES = {
  66     'actionrunner': {
  67         'virtualenv_binary': '/usr/bin/virtualenv',
  68         'python_binary': '/usr/bin/python',
  69         'python3_binary': '/usr/bin/python3'
  70     },
  71     'webui': {
  72         'webui_base_url': 'https://localhost'
  73     }
  74 }
  75 
  76 COMMON_AUTH_OPTIONS_COMMENT = """
  77 # Common option - options below apply in both scenarios - when auth service is running as a WSGI
  78 # service (e.g. under Apache or Nginx) and when it's running in the standalone mode.
  79 """.strip()
  80 
  81 STANDALONE_AUTH_OPTIONS_COMMENT = """
  82 # Standalone mode options - options below only apply when auth service is running in the standalone
  83 # mode.
  84 """.strip()
  85 
  86 
  87 def _import_config(config):
  88     try:
  89         return importlib.import_module(config)
  90     except:
  91         traceback.print_exc()
  92     return None
  93 
  94 
  95 def _read_current_config(opt_groups):
  96     for k, v in six.iteritems(cfg.CONF._groups):
  97         if k in SKIP_GROUPS:
  98             continue
  99         if k not in opt_groups:
  100             opt_groups[k] = v
  101     return opt_groups
  102 
  103 
  104 def _clear_config():
  105     cfg.CONF.reset()
  106 
  107 
  108 def _read_group(opt_group):
  109     all_options = list(opt_group._opts.values())
  110 
  111     if opt_group.name == 'auth':
  112         print(COMMON_AUTH_OPTIONS_COMMENT)
  113         print('')
  114         common_options = [option for option in all_options if option['opt'].name in
  115                           AUTH_OPTIONS['common']]
  116         _print_options(opt_group=opt_group, options=common_options)
  117 
  118         print('')
  119         print(STANDALONE_AUTH_OPTIONS_COMMENT)
  120         print('')
  121         standalone_options = [option for option in all_options if option['opt'].name in
  122                               AUTH_OPTIONS['standalone']]
  123         _print_options(opt_group=opt_group, options=standalone_options)
  124 
  125         if len(common_options) + len(standalone_options) != len(all_options):
  126             msg = ('Not all options are declared in AUTH_OPTIONS dict, please update it')
  127             raise Exception(msg)
  128     else:
  129         options = all_options
  130         _print_options(opt_group=opt_group, options=options)
  131 
  132 
  133 def _read_groups(opt_groups):
  134     opt_groups = collections.OrderedDict(sorted(opt_groups.items()))
  135     for name, opt_group in six.iteritems(opt_groups):
  136         print('[%s]' % name)
  137         _read_group(opt_group)
  138         print('')
  139 
  140 
  141 def _print_options(opt_group, options):
  142     for opt in options:
  143         opt = opt['opt']
  144 
  145         # Special case for options which could change during this script run
  146         static_option_value = STATIC_OPTION_VALUES.get(opt_group.name, {}).get(opt.name, None)
  147         if static_option_value:
  148             opt.default = static_option_value
  149 
  150         # Special handling for list options
  151         if isinstance(opt, cfg.ListOpt):
  152             if opt.default:
  153                 value = ','.join(opt.default)
  154             else:
  155                 value = ''
  156 
  157             value += ' # comma separated list allowed here.'
  158         else:
  159             value = opt.default
  160 
  161         print('# %s' % opt.help)
  162         print('%s = %s' % (opt.name, value))
  163 
  164 
  165 def main(args):
  166     opt_groups = {}
  167     for config in CONFIGS:
  168         mod = _import_config(config)
  169         mod.register_opts()
  170         _read_current_config(opt_groups)
  171         _clear_config()
  172     _read_groups(opt_groups)
  173 
  174 
  175 if __name__ == '__main__':
  176     main(sys.argv)
  177
  ```
  --- 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/tools/config_gen.py b/tools/config_gen.py
  --- a/tools/config_gen.py
  +++ b/tools/config_gen.py
  @@ -27,6 +27,7 @@
   CONFIGS = ['st2actions.config',
              'st2actions.notifier.config',
              'st2actions.resultstracker.config',
  +           'st2actions.workflows.config',
              'st2api.config',
              'st2stream.config',
              'st2auth.config',
  
verification_info: {"golden_diff": "diff --git a/tools/config_gen.py b/tools/config_gen.py\n--- a/tools/config_gen.py\n+++ b/tools/config_gen.py\n@@ -27,6 +27,7 @@\n CONFIGS = ['st2actions.config',\n            'st2actions.notifier.config',\n            'st2actions.resultstracker.config',\n+           'st2actions.workflows.config',\n            'st2api.config',\n            'st2stream.config',\n            'st2auth.config',\n", "issue": "Missing [workflow_engine] in st2.conf.sample\n##### SUMMARY\r\n\r\nhttps://github.com/StackStorm/st2/blob/master/conf/st2.conf.sample is missing a new section for `[workflow_engine]`\r\n\r\nAlso, shouldn't this section be named `[workflowengine]` to go along with the \"style\" of the other sections like `[resultstracker]` , `[garbagecollector]`, etc\r\n\r\n##### ISSUE TYPE\r\n - Bug Report\r\n - Feature Idea\r\n\r\n##### STACKSTORM VERSION\r\n2.8\r\n\r\n##### EXPECTED RESULTS\r\nhttps://github.com/StackStorm/st2/blob/master/conf/st2.conf.sample contains a section for `[workflow_engine]`\r\n\n", "before_files": [{"content": "#!/usr/bin/env python\n# Licensed to the StackStorm, Inc ('StackStorm') under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  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\nfrom __future__ import absolute_import\nimport collections\nimport importlib\nimport six\nimport sys\nimport traceback\n\nfrom oslo_config import cfg\n\n\nCONFIGS = ['st2actions.config',\n           'st2actions.notifier.config',\n           'st2actions.resultstracker.config',\n           'st2api.config',\n           'st2stream.config',\n           'st2auth.config',\n           'st2common.config',\n           'st2exporter.config',\n           'st2reactor.rules.config',\n           'st2reactor.sensor.config',\n           'st2reactor.garbage_collector.config']\n\nSKIP_GROUPS = ['api_pecan', 'rbac', 'results_tracker']\n\n# We group auth options together to nake it a bit more clear what applies where\nAUTH_OPTIONS = {\n    'common': [\n        'enable',\n        'mode',\n        'logging',\n        'api_url',\n        'token_ttl',\n        'service_token_ttl',\n        'debug'\n    ],\n    'standalone': [\n        'host',\n        'port',\n        'use_ssl',\n        'cert',\n        'key',\n        'backend',\n        'backend_kwargs'\n    ]\n}\n\n# Some of the config values change depenending on the environment where this script is ran so we\n# set them to static values to ensure consistent and stable output\nSTATIC_OPTION_VALUES = {\n    'actionrunner': {\n        'virtualenv_binary': '/usr/bin/virtualenv',\n        'python_binary': '/usr/bin/python',\n        'python3_binary': '/usr/bin/python3'\n    },\n    'webui': {\n        'webui_base_url': 'https://localhost'\n    }\n}\n\nCOMMON_AUTH_OPTIONS_COMMENT = \"\"\"\n# Common option - options below apply in both scenarios - when auth service is running as a WSGI\n# service (e.g. under Apache or Nginx) and when it's running in the standalone mode.\n\"\"\".strip()\n\nSTANDALONE_AUTH_OPTIONS_COMMENT = \"\"\"\n# Standalone mode options - options below only apply when auth service is running in the standalone\n# mode.\n\"\"\".strip()\n\n\ndef _import_config(config):\n    try:\n        return importlib.import_module(config)\n    except:\n        traceback.print_exc()\n    return None\n\n\ndef _read_current_config(opt_groups):\n    for k, v in six.iteritems(cfg.CONF._groups):\n        if k in SKIP_GROUPS:\n            continue\n        if k not in opt_groups:\n            opt_groups[k] = v\n    return opt_groups\n\n\ndef _clear_config():\n    cfg.CONF.reset()\n\n\ndef _read_group(opt_group):\n    all_options = list(opt_group._opts.values())\n\n    if opt_group.name == 'auth':\n        print(COMMON_AUTH_OPTIONS_COMMENT)\n        print('')\n        common_options = [option for option in all_options if option['opt'].name in\n                          AUTH_OPTIONS['common']]\n        _print_options(opt_group=opt_group, options=common_options)\n\n        print('')\n        print(STANDALONE_AUTH_OPTIONS_COMMENT)\n        print('')\n        standalone_options = [option for option in all_options if option['opt'].name in\n                              AUTH_OPTIONS['standalone']]\n        _print_options(opt_group=opt_group, options=standalone_options)\n\n        if len(common_options) + len(standalone_options) != len(all_options):\n            msg = ('Not all options are declared in AUTH_OPTIONS dict, please update it')\n            raise Exception(msg)\n    else:\n        options = all_options\n        _print_options(opt_group=opt_group, options=options)\n\n\ndef _read_groups(opt_groups):\n    opt_groups = collections.OrderedDict(sorted(opt_groups.items()))\n    for name, opt_group in six.iteritems(opt_groups):\n        print('[%s]' % name)\n        _read_group(opt_group)\n        print('')\n\n\ndef _print_options(opt_group, options):\n    for opt in options:\n        opt = opt['opt']\n\n        # Special case for options which could change during this script run\n        static_option_value = STATIC_OPTION_VALUES.get(opt_group.name, {}).get(opt.name, None)\n        if static_option_value:\n            opt.default = static_option_value\n\n        # Special handling for list options\n        if isinstance(opt, cfg.ListOpt):\n            if opt.default:\n                value = ','.join(opt.default)\n            else:\n                value = ''\n\n            value += ' # comma separated list allowed here.'\n        else:\n            value = opt.default\n\n        print('# %s' % opt.help)\n        print('%s = %s' % (opt.name, value))\n\n\ndef main(args):\n    opt_groups = {}\n    for config in CONFIGS:\n        mod = _import_config(config)\n        mod.register_opts()\n        _read_current_config(opt_groups)\n        _clear_config()\n    _read_groups(opt_groups)\n\n\nif __name__ == '__main__':\n    main(sys.argv)\n", "path": "tools/config_gen.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# Licensed to the StackStorm, Inc ('StackStorm') under one or more\n# contributor license agreements.  See the NOTICE file distributed with\n# this work for additional information regarding copyright ownership.\n# The ASF licenses this file to You under the Apache License, Version 2.0\n# (the \"License\"); you may not use this file except in compliance with\n# the License.  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\nfrom __future__ import absolute_import\nimport collections\nimport importlib\nimport six\nimport sys\nimport traceback\n\nfrom oslo_config import cfg\n\n\nCONFIGS = ['st2actions.config',\n           'st2actions.notifier.config',\n           'st2actions.resultstracker.config',\n           'st2actions.workflows.config',\n           'st2api.config',\n           'st2stream.config',\n           'st2auth.config',\n           'st2common.config',\n           'st2exporter.config',\n           'st2reactor.rules.config',\n           'st2reactor.sensor.config',\n           'st2reactor.garbage_collector.config']\n\nSKIP_GROUPS = ['api_pecan', 'rbac', 'results_tracker']\n\n# We group auth options together to nake it a bit more clear what applies where\nAUTH_OPTIONS = {\n    'common': [\n        'enable',\n        'mode',\n        'logging',\n        'api_url',\n        'token_ttl',\n        'service_token_ttl',\n        'debug'\n    ],\n    'standalone': [\n        'host',\n        'port',\n        'use_ssl',\n        'cert',\n        'key',\n        'backend',\n        'backend_kwargs'\n    ]\n}\n\n# Some of the config values change depenending on the environment where this script is ran so we\n# set them to static values to ensure consistent and stable output\nSTATIC_OPTION_VALUES = {\n    'actionrunner': {\n        'virtualenv_binary': '/usr/bin/virtualenv',\n        'python_binary': '/usr/bin/python',\n        'python3_binary': '/usr/bin/python3'\n    },\n    'webui': {\n        'webui_base_url': 'https://localhost'\n    }\n}\n\nCOMMON_AUTH_OPTIONS_COMMENT = \"\"\"\n# Common option - options below apply in both scenarios - when auth service is running as a WSGI\n# service (e.g. under Apache or Nginx) and when it's running in the standalone mode.\n\"\"\".strip()\n\nSTANDALONE_AUTH_OPTIONS_COMMENT = \"\"\"\n# Standalone mode options - options below only apply when auth service is running in the standalone\n# mode.\n\"\"\".strip()\n\n\ndef _import_config(config):\n    try:\n        return importlib.import_module(config)\n    except:\n        traceback.print_exc()\n    return None\n\n\ndef _read_current_config(opt_groups):\n    for k, v in six.iteritems(cfg.CONF._groups):\n        if k in SKIP_GROUPS:\n            continue\n        if k not in opt_groups:\n            opt_groups[k] = v\n    return opt_groups\n\n\ndef _clear_config():\n    cfg.CONF.reset()\n\n\ndef _read_group(opt_group):\n    all_options = list(opt_group._opts.values())\n\n    if opt_group.name == 'auth':\n        print(COMMON_AUTH_OPTIONS_COMMENT)\n        print('')\n        common_options = [option for option in all_options if option['opt'].name in\n                          AUTH_OPTIONS['common']]\n        _print_options(opt_group=opt_group, options=common_options)\n\n        print('')\n        print(STANDALONE_AUTH_OPTIONS_COMMENT)\n        print('')\n        standalone_options = [option for option in all_options if option['opt'].name in\n                              AUTH_OPTIONS['standalone']]\n        _print_options(opt_group=opt_group, options=standalone_options)\n\n        if len(common_options) + len(standalone_options) != len(all_options):\n            msg = ('Not all options are declared in AUTH_OPTIONS dict, please update it')\n            raise Exception(msg)\n    else:\n        options = all_options\n        _print_options(opt_group=opt_group, options=options)\n\n\ndef _read_groups(opt_groups):\n    opt_groups = collections.OrderedDict(sorted(opt_groups.items()))\n    for name, opt_group in six.iteritems(opt_groups):\n        print('[%s]' % name)\n        _read_group(opt_group)\n        print('')\n\n\ndef _print_options(opt_group, options):\n    for opt in options:\n        opt = opt['opt']\n\n        # Special case for options which could change during this script run\n        static_option_value = STATIC_OPTION_VALUES.get(opt_group.name, {}).get(opt.name, None)\n        if static_option_value:\n            opt.default = static_option_value\n\n        # Special handling for list options\n        if isinstance(opt, cfg.ListOpt):\n            if opt.default:\n                value = ','.join(opt.default)\n            else:\n                value = ''\n\n            value += ' # comma separated list allowed here.'\n        else:\n            value = opt.default\n\n        print('# %s' % opt.help)\n        print('%s = %s' % (opt.name, value))\n\n\ndef main(args):\n    opt_groups = {}\n    for config in CONFIGS:\n        mod = _import_config(config)\n        mod.register_opts()\n        _read_current_config(opt_groups)\n        _clear_config()\n    _read_groups(opt_groups)\n\n\nif __name__ == '__main__':\n    main(sys.argv)\n", "path": "tools/config_gen.py"}]}