Repository: certbot/certbot

Issue:
Client should make config directories if they're missing [Crash if /etc/letsencrypt/renewal is missing]
If the `/etc/letsencrypt/renewal` directory doesn't exist, `letsencrypt` fails with this exception:

```
2015-09-20 23:44:30,057:DEBUG:letsencrypt.cli:Root logging level set at 30
2015-09-20 23:44:30,059:INFO:letsencrypt.cli:Saving debug log to /var/log/letsencrypt/letsencrypt.log
2015-09-20 23:44:30,060:DEBUG:letsencrypt.cli:Arguments: []
2015-09-20 23:44:30,060:DEBUG:letsencrypt.cli:Discovered plugins: PluginsRegistry(PluginEntryPoint#apache,PluginEntryPoint#null,PluginEntryPoint#manual,PluginEntryPoint#standalone)
2015-09-20 23:44:31,548:DEBUG:letsencrypt.display.ops:Single candidate plugin: * apache
Description: Apache Web Server - Alpha
Interfaces: IAuthenticator, IInstaller, IPlugin
Entry point: apache = letsencrypt_apache.configurator:ApacheConfigurator
Initialized: <letsencrypt_apache.configurator.ApacheConfigurator object at 0x7f3207733950>
Prep: True
2015-09-20 23:44:37,816:DEBUG:letsencrypt.cli:Exiting abnormally:
Traceback (most recent call last):
  File "/usr/bin/letsencrypt", line 9, in <module>
    load_entry_point('letsencrypt==0.1', 'console_scripts', 'letsencrypt')()
  File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 920, in main
    return args.func(args, config, plugins)
  File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 230, in run
    domains, config, configuration.RenewerConfiguration(config))
  File "/usr/lib/python2.7/dist-packages/letsencrypt/cli.py", line 176, in _find_duplicative_certs
    for renewal_file in os.listdir(configs_dir):
OSError: [Errno 2] No such file or directory: '/etc/letsencrypt/renewal'
```



Discussion:
Pulled partially in hlieberman/letsencrypt as 49bde797145d541cb907bac631cb56d678f65a42.

I guess [1] that you didn't `rm -rf /etc/letsencrypt /var/lib/letsencrypt` before pulling to latest master.

[1] This should've been detected by our integration tests, but we're all green now, see https://travis-ci.org/letsencrypt/letsencrypt/jobs/81310614. 

I can reproduce this error even if I `rm -rf`  both `/etc/letsencrypt` and `/var/lib/letsencrypt/`.  One problem appears to be that `_find_duplicative_certs` assumes the RENEWAL_CONFIG_DIR exists before whatever code that should make it runs, because when this error happens I have no subdirectories under `/etc/letsencrypt` at all...

```
Traceback (most recent call last):
  File "venv/bin/letsencrypt", line 9, in <module>
    load_entry_point('letsencrypt==0.1', 'console_scripts', 'letsencrypt')()
  File "/home/ubuntu/letsencrypt/letsencrypt/cli.py", line 923, in main
    return args.func(args, config, plugins)
  File "/home/ubuntu/letsencrypt/letsencrypt/cli.py", line 230, in run
    domains, config, configuration.RenewerConfiguration(config))
  File "/home/ubuntu/letsencrypt/letsencrypt/cli.py", line 176, in _find_duplicative_certs
    for renewal_file in os.listdir(configs_dir):
OSError: [Errno 2] No such file or directory: '/etc/letsencrypt/renewal'
```

I ran into this problem and fixed it in #777.  Unfortunately, that PR is currently blocked.

It only affects `run`, because #758 was only coded to work with run and devs seemed keen on pushing it.


Resolving patch:
diff --git a/letsencrypt/cli.py b/letsencrypt/cli.py
--- a/letsencrypt/cli.py
+++ b/letsencrypt/cli.py
@@ -172,6 +172,8 @@ def _find_duplicative_certs(domains, config, renew_config):
     identical_names_cert, subset_names_cert = None, None
 
     configs_dir = renew_config.renewal_configs_dir
+    le_util.make_or_verify_dir(configs_dir, mode=0o755, uid=os.geteuid())
+
     cli_config = configuration.RenewerConfiguration(config)
     for renewal_file in os.listdir(configs_dir):
         try:


Test patch: