prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Make `scripts/setup/generate-secrets -d` use existing setting values
  Currently, `generate-secrets -d` regenerates all the secret keys each time it is run, modifying zproject/settings.py, which means that if you use the same Zulip checkout for both a development VM on the host and a Vagrant guest, every time you provision on the Vagrant guest, you need to rebuild the database (to match the new keys).  I think this would also affect someone using both Docker and Vagrant with the same checkout (as I imagine happens with some frequency when testing).
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `scripts/setup/generate_secrets.py`
  Content:
  ```
  1 #!/usr/bin/env python
  2 # This tools generates local_settings_generated.py using the template
  3 
  4 from __future__ import print_function
  5 import sys, os, os.path
  6 
  7 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
  8 os.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings'
  9 
  10 from django.utils.crypto import get_random_string
  11 from zerver.lib.utils import generate_random_token
  12 
  13 os.chdir(os.path.join(os.path.dirname(__file__), '..', '..'))
  14 
  15 CAMO_CONFIG_FILENAME = '/etc/default/camo'
  16 
  17 AUTOGENERATED_SETTINGS = ['shared_secret', 'avatar_salt', 'rabbitmq_password', 'local_database_password',
  18                           'initial_password_salt']
  19 
  20 def generate_camo_config_file(camo_key):
  21     camo_config = """ENABLED=yes
  22 PORT=9292
  23 CAMO_KEY=%s
  24 """ % (camo_key,)
  25     with open(CAMO_CONFIG_FILENAME, 'w') as camo_file:
  26         camo_file.write(camo_config)
  27     print("Generated Camo config file %s" % (CAMO_CONFIG_FILENAME,))
  28 
  29 def generate_django_secretkey():
  30     # Secret key generation taken from Django's startproject.py
  31     chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
  32     return get_random_string(50, chars)
  33 
  34 def generate_secrets(development=False):
  35     if development:
  36         OUTPUT_SETTINGS_FILENAME = "zproject/dev-secrets.conf"
  37     else:
  38         OUTPUT_SETTINGS_FILENAME = "/etc/zulip/zulip-secrets.conf"
  39 
  40     lines = ['[secrets]\n']
  41 
  42     def config_line(var, value):
  43         return "%s = %s\n" % (var, value)
  44 
  45     for name in AUTOGENERATED_SETTINGS:
  46         lines.append(config_line(name, generate_random_token(64)))
  47 
  48     lines.append(config_line('secret_key', generate_django_secretkey()))
  49     camo_key = get_random_string(64)
  50     lines.append(config_line('camo_key', camo_key))
  51     if not development:
  52         # Write the Camo config file directly
  53         generate_camo_config_file(camo_key)
  54 
  55     out = open(OUTPUT_SETTINGS_FILENAME, 'w')
  56     out.write("".join(lines))
  57     out.close()
  58 
  59     print("Generated %s with auto-generated secrets!" % (OUTPUT_SETTINGS_FILENAME,))
  60 
  61 if __name__ == '__main__':
  62 
  63     development = False
  64     extra_args = sys.argv[1:]
  65 
  66     if len(extra_args) and extra_args[0] in ('-d', '--development'):
  67         development = True
  68 
  69     generate_secrets(development)
  70
  ```
  --- 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/scripts/setup/generate_secrets.py b/scripts/setup/generate_secrets.py
  --- a/scripts/setup/generate_secrets.py
  +++ b/scripts/setup/generate_secrets.py
  @@ -8,6 +8,8 @@
   os.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings'
   
   from django.utils.crypto import get_random_string
  +import six
  +
   from zerver.lib.utils import generate_random_token
   
   os.chdir(os.path.join(os.path.dirname(__file__), '..', '..'))
  @@ -31,6 +33,21 @@
       chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'
       return get_random_string(50, chars)
   
  +def get_old_conf(output_filename):
  +    if not os.path.exists(output_filename):
  +        return {}
  +
  +    secrets_file = six.moves.configparser.RawConfigParser()
  +    secrets_file.read(output_filename)
  +
  +    def get_secret(key):
  +        if secrets_file.has_option('secrets', key):
  +            return secrets_file.get('secrets', key)
  +        return None
  +
  +    fields = AUTOGENERATED_SETTINGS + ['secret_key', 'camo_key']
  +    return {name: get_secret(name) for name in fields}
  +
   def generate_secrets(development=False):
       if development:
           OUTPUT_SETTINGS_FILENAME = "zproject/dev-secrets.conf"
  @@ -42,12 +59,16 @@
       def config_line(var, value):
           return "%s = %s\n" % (var, value)
   
  +    old_conf = get_old_conf(OUTPUT_SETTINGS_FILENAME)
       for name in AUTOGENERATED_SETTINGS:
  -        lines.append(config_line(name, generate_random_token(64)))
  +        lines.append(config_line(name, old_conf.get(name, generate_random_token(64))))
  +
  +    secret_key = old_conf.get('secret_key', generate_django_secretkey())
  +    lines.append(config_line('secret_key', secret_key))
   
  -    lines.append(config_line('secret_key', generate_django_secretkey()))
  -    camo_key = get_random_string(64)
  +    camo_key = old_conf.get('camo_key', get_random_string(64))
       lines.append(config_line('camo_key', camo_key))
  +
       if not development:
           # Write the Camo config file directly
           generate_camo_config_file(camo_key)
  
verification_info: {"golden_diff": "diff --git a/scripts/setup/generate_secrets.py b/scripts/setup/generate_secrets.py\n--- a/scripts/setup/generate_secrets.py\n+++ b/scripts/setup/generate_secrets.py\n@@ -8,6 +8,8 @@\n os.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings'\n \n from django.utils.crypto import get_random_string\n+import six\n+\n from zerver.lib.utils import generate_random_token\n \n os.chdir(os.path.join(os.path.dirname(__file__), '..', '..'))\n@@ -31,6 +33,21 @@\n     chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'\n     return get_random_string(50, chars)\n \n+def get_old_conf(output_filename):\n+    if not os.path.exists(output_filename):\n+        return {}\n+\n+    secrets_file = six.moves.configparser.RawConfigParser()\n+    secrets_file.read(output_filename)\n+\n+    def get_secret(key):\n+        if secrets_file.has_option('secrets', key):\n+            return secrets_file.get('secrets', key)\n+        return None\n+\n+    fields = AUTOGENERATED_SETTINGS + ['secret_key', 'camo_key']\n+    return {name: get_secret(name) for name in fields}\n+\n def generate_secrets(development=False):\n     if development:\n         OUTPUT_SETTINGS_FILENAME = \"zproject/dev-secrets.conf\"\n@@ -42,12 +59,16 @@\n     def config_line(var, value):\n         return \"%s = %s\\n\" % (var, value)\n \n+    old_conf = get_old_conf(OUTPUT_SETTINGS_FILENAME)\n     for name in AUTOGENERATED_SETTINGS:\n-        lines.append(config_line(name, generate_random_token(64)))\n+        lines.append(config_line(name, old_conf.get(name, generate_random_token(64))))\n+\n+    secret_key = old_conf.get('secret_key', generate_django_secretkey())\n+    lines.append(config_line('secret_key', secret_key))\n \n-    lines.append(config_line('secret_key', generate_django_secretkey()))\n-    camo_key = get_random_string(64)\n+    camo_key = old_conf.get('camo_key', get_random_string(64))\n     lines.append(config_line('camo_key', camo_key))\n+\n     if not development:\n         # Write the Camo config file directly\n         generate_camo_config_file(camo_key)\n", "issue": "Make `scripts/setup/generate-secrets -d` use existing setting values\nCurrently, `generate-secrets -d` regenerates all the secret keys each time it is run, modifying zproject/settings.py, which means that if you use the same Zulip checkout for both a development VM on the host and a Vagrant guest, every time you provision on the Vagrant guest, you need to rebuild the database (to match the new keys).  I think this would also affect someone using both Docker and Vagrant with the same checkout (as I imagine happens with some frequency when testing).\n\n", "before_files": [{"content": "#!/usr/bin/env python\n# This tools generates local_settings_generated.py using the template\n\nfrom __future__ import print_function\nimport sys, os, os.path\n\nsys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))\nos.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings'\n\nfrom django.utils.crypto import get_random_string\nfrom zerver.lib.utils import generate_random_token\n\nos.chdir(os.path.join(os.path.dirname(__file__), '..', '..'))\n\nCAMO_CONFIG_FILENAME = '/etc/default/camo'\n\nAUTOGENERATED_SETTINGS = ['shared_secret', 'avatar_salt', 'rabbitmq_password', 'local_database_password',\n                          'initial_password_salt']\n\ndef generate_camo_config_file(camo_key):\n    camo_config = \"\"\"ENABLED=yes\nPORT=9292\nCAMO_KEY=%s\n\"\"\" % (camo_key,)\n    with open(CAMO_CONFIG_FILENAME, 'w') as camo_file:\n        camo_file.write(camo_config)\n    print(\"Generated Camo config file %s\" % (CAMO_CONFIG_FILENAME,))\n\ndef generate_django_secretkey():\n    # Secret key generation taken from Django's startproject.py\n    chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'\n    return get_random_string(50, chars)\n\ndef generate_secrets(development=False):\n    if development:\n        OUTPUT_SETTINGS_FILENAME = \"zproject/dev-secrets.conf\"\n    else:\n        OUTPUT_SETTINGS_FILENAME = \"/etc/zulip/zulip-secrets.conf\"\n\n    lines = ['[secrets]\\n']\n\n    def config_line(var, value):\n        return \"%s = %s\\n\" % (var, value)\n\n    for name in AUTOGENERATED_SETTINGS:\n        lines.append(config_line(name, generate_random_token(64)))\n\n    lines.append(config_line('secret_key', generate_django_secretkey()))\n    camo_key = get_random_string(64)\n    lines.append(config_line('camo_key', camo_key))\n    if not development:\n        # Write the Camo config file directly\n        generate_camo_config_file(camo_key)\n\n    out = open(OUTPUT_SETTINGS_FILENAME, 'w')\n    out.write(\"\".join(lines))\n    out.close()\n\n    print(\"Generated %s with auto-generated secrets!\" % (OUTPUT_SETTINGS_FILENAME,))\n\nif __name__ == '__main__':\n\n    development = False\n    extra_args = sys.argv[1:]\n\n    if len(extra_args) and extra_args[0] in ('-d', '--development'):\n        development = True\n\n    generate_secrets(development)\n", "path": "scripts/setup/generate_secrets.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# This tools generates local_settings_generated.py using the template\n\nfrom __future__ import print_function\nimport sys, os, os.path\n\nsys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))\nos.environ['DJANGO_SETTINGS_MODULE'] = 'zproject.settings'\n\nfrom django.utils.crypto import get_random_string\nimport six\n\nfrom zerver.lib.utils import generate_random_token\n\nos.chdir(os.path.join(os.path.dirname(__file__), '..', '..'))\n\nCAMO_CONFIG_FILENAME = '/etc/default/camo'\n\nAUTOGENERATED_SETTINGS = ['shared_secret', 'avatar_salt', 'rabbitmq_password', 'local_database_password',\n                          'initial_password_salt']\n\ndef generate_camo_config_file(camo_key):\n    camo_config = \"\"\"ENABLED=yes\nPORT=9292\nCAMO_KEY=%s\n\"\"\" % (camo_key,)\n    with open(CAMO_CONFIG_FILENAME, 'w') as camo_file:\n        camo_file.write(camo_config)\n    print(\"Generated Camo config file %s\" % (CAMO_CONFIG_FILENAME,))\n\ndef generate_django_secretkey():\n    # Secret key generation taken from Django's startproject.py\n    chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)'\n    return get_random_string(50, chars)\n\ndef get_old_conf(output_filename):\n    if not os.path.exists(output_filename):\n        return {}\n\n    secrets_file = six.moves.configparser.RawConfigParser()\n    secrets_file.read(output_filename)\n\n    def get_secret(key):\n        if secrets_file.has_option('secrets', key):\n            return secrets_file.get('secrets', key)\n        return None\n\n    fields = AUTOGENERATED_SETTINGS + ['secret_key', 'camo_key']\n    return {name: get_secret(name) for name in fields}\n\ndef generate_secrets(development=False):\n    if development:\n        OUTPUT_SETTINGS_FILENAME = \"zproject/dev-secrets.conf\"\n    else:\n        OUTPUT_SETTINGS_FILENAME = \"/etc/zulip/zulip-secrets.conf\"\n\n    lines = ['[secrets]\\n']\n\n    def config_line(var, value):\n        return \"%s = %s\\n\" % (var, value)\n\n    old_conf = get_old_conf(OUTPUT_SETTINGS_FILENAME)\n    for name in AUTOGENERATED_SETTINGS:\n        lines.append(config_line(name, old_conf.get(name, generate_random_token(64))))\n\n    secret_key = old_conf.get('secret_key', generate_django_secretkey())\n    lines.append(config_line('secret_key', secret_key))\n\n    camo_key = old_conf.get('camo_key', get_random_string(64))\n    lines.append(config_line('camo_key', camo_key))\n\n    if not development:\n        # Write the Camo config file directly\n        generate_camo_config_file(camo_key)\n\n    out = open(OUTPUT_SETTINGS_FILENAME, 'w')\n    out.write(\"\".join(lines))\n    out.close()\n\n    print(\"Generated %s with auto-generated secrets!\" % (OUTPUT_SETTINGS_FILENAME,))\n\nif __name__ == '__main__':\n\n    development = False\n    extra_args = sys.argv[1:]\n\n    if len(extra_args) and extra_args[0] in ('-d', '--development'):\n        development = True\n\n    generate_secrets(development)\n", "path": "scripts/setup/generate_secrets.py"}]}