We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Error provisioning new controller: ".host_nodes_dir"
I provisioned a new controller on DigitalOcean and hit this error during initial registration. We need to loosen up the Vagrant config requirements so this doesn't show up.

``` console
[2013-11-07 16:02:37,088: INFO/MainProcess] consumer: Connected to amqp://guest@127.0.0.1:5672//.

==> /var/log/deis/server.log <==
    provider = import_provider_module(provider_type)
  File "/opt/deis/controller/provider/__init__.py", line 8, in import_provider_module
    tasks = importlib.import_module('provider.' + provider_type)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/opt/deis/controller/provider/vagrant.py", line 18, in <module>
    HOST_NODES_DIR = open('/home/vagrant/.host_nodes_dir').read().strip()
IOError: [Errno 2] No such file or directory: u'/home/vagrant/.host_nodes_dir'
WARNING Forbidden (CSRF cookie not set.): /api/auth/register
2013-11-07 16:29:55 [28407] [DEBUG] Closing connection. 
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `provider/vagrant.py`
Content:
```
1 """
2 Deis cloud provider implementation for local vagrant setups.
3 """
4 
5 from __future__ import unicode_literals
6 
7 from api.ssh import exec_ssh, connect_ssh
8 
9 import json
10 import string
11 import subprocess
12 import uuid
13 
14 from api.models import Layer
15 from api.models import Node
16 
17 # Collect details for connecting to the host machine
18 HOST_NODES_DIR = open('/home/vagrant/.host_nodes_dir').read().strip()
19 PKEY = open('/home/vagrant/.ssh/id_rsa').read()
20 
21 
22 def seed_flavors():
23     """Seed the database with default flavors for each Rackspace region.
24 
25     :rtype: list of dicts containing flavor data
26     """
27     flavors = []
28     for m in ['512', '1024', '2048']:
29         flavors.append({
30             'id': 'vagrant-{}'.format(m),
31             'provider': 'vagrant',
32             'params': json.dumps({
33                 'memory': m
34             })
35         })
36     return flavors
37 
38 
39 def build_layer(layer):
40     """
41     Build a layer.
42 
43     :param layer: a dict containing formation, id, params, and creds info
44     """
45 
46     # This can also be done with `deis layers:update` now.
47     layer_ = Layer.objects.get(id=layer['id'])
48     layer_.ssh_username = 'vagrant'
49     layer_.save()
50 
51 
52 def destroy_layer(layer):
53     """
54     Destroy a layer.
55 
56     :param layer: a dict containing formation, id, params, and creds info
57     """
58     pass
59 
60 
61 def build_node(node):
62     """
63     Build a node.
64 
65     :param node: a dict containing formation, layer, params, and creds info.
66     :rtype: a tuple of (provider_id, fully_qualified_domain_name, metadata)
67     """
68 
69     # Can't use the vagrant UUID because it's not booted yet
70     uid = str(uuid.uuid1())
71 
72     # Create a new Vagrantfile from a template
73     node['params'].setdefault('memory', '512')
74     template = open('/opt/deis/controller/contrib/vagrant/nodes_vagrantfile_template.rb')
75     raw = string.Template(template.read())
76     result = raw.substitute({
77         'id': uid,
78         'ipaddress': '192.168.61.' + str(Node.objects.all().count() + 100),
79         'memory': node['params']['memory']
80     })
81 
82     # Make a folder for the VM with its own Vagrantfile. Vagrant will then create a .vagrant folder
83     # there too when it first gets booted.
84     node_dir = HOST_NODES_DIR + '/' + uid
85     mkdir = 'mkdir -p ' + node_dir
86     cp_tpl = 'echo "' + result.replace('"', '\\"') + '" > ' + node_dir + '/Vagrantfile'
87     _host_ssh(commands=[mkdir, cp_tpl], creds=node['creds'])
88 
89     # Boot the VM
90     _run_vagrant_command(uid, args=['up'], creds=node['creds'])
91 
92     # Copy the layer's public SSH key to the VM so that the Controller can access it.
93     _run_vagrant_command(
94         uid,
95         args=[
96             'ssh',
97             '-c',
98             '"echo \\"' + node['ssh_public_key'] + '\\" >> /home/vagrant/.ssh/authorized_keys"'
99         ],
100         creds=node['creds'],
101     )
102 
103     provider_id = uid
104     fqdn = provider_id
105     if not fqdn.endswith('.local'):
106         fqdn += '.local'  # hostname is broadcast via avahi-daemon
107     metadata = {
108         'id': uid,
109         'fqdn': fqdn,
110         'flavor': node['params']['memory']
111     }
112     return provider_id, fqdn, metadata
113 
114 
115 def destroy_node(node):
116     """
117     Destroy a node.
118 
119     :param node: a dict containing a node's provider_id, params, and creds
120     """
121 
122     # This is useful if node creation failed. So that there's a record in the DB, but it has no
123     # ID associated with it.
124     if node['provider_id'] is None:
125         return
126 
127     # Shut the VM down and destroy it
128     _run_vagrant_command(node['provider_id'], args=['destroy', '--force'], creds=node['creds'])
129     node_dir = HOST_NODES_DIR + '/' + node['provider_id']
130 
131     # Sanity check before `rm -rf`
132     if 'contrib/vagrant' not in node_dir:
133         raise RuntimeError("Aborted node destruction: attempting to 'rm -rf' unexpected directory")
134 
135     # Completely remove the folder that contained the VM
136     rm_vagrantfile = 'rm ' + node_dir + '/Vagrantfile'
137     rm_node_dir = 'rm -rf ' + node_dir
138     _host_ssh(commands=[rm_vagrantfile, rm_node_dir], creds=node['creds'])
139 
140 
141 def _run_vagrant_command(node_id, args=[], creds={}):
142     """
143     args: A tuple of arguments to a vagrant command line.
144     e.g. ['up', 'my_vm_name', '--no-provision']
145     """
146 
147     cd = 'cd ' + HOST_NODES_DIR + '/' + node_id
148     command = ['vagrant'] + [arg for arg in args if arg is not None]
149     return _host_ssh(commands=[cd, ' '.join(command)], creds=creds)
150 
151 
152 def _host_ssh(creds={}, commands=[]):
153     """
154     Connect to the host machine. Namely the user's local machine.
155     """
156     if creds == {}:
157         raise RuntimeError("No credentials provided to _host_ssh()")
158     command = ' && '.join(commands)
159 
160     # First check if we can access the host machine. It's likely that their
161     # IP address changes every time they request a DHCP lease.
162     # TODO: Find a way of passing this error onto the CLI client.
163     try:
164         subprocess.check_call([
165             'nc', '-z', '-w2', creds['host'], '22'
166         ], stderr=subprocess.PIPE)
167     except subprocess.CalledProcessError:
168         raise RuntimeError("Couldn't ping port 22 at host with IP " + creds['host'])
169 
170     ssh = connect_ssh(creds['user'], creds['host'], 22, PKEY, timeout=120)
171     result, status = exec_ssh(ssh, command)
172     if status > 0:
173         raise RuntimeError(
174             'SSH to Vagrant host error: ' + result.decode('utf-8') +
175             'Command: ' + command.decode('utf-8'))
176     return result
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()

```

diff --git a/provider/vagrant.py b/provider/vagrant.py
--- a/provider/vagrant.py
+++ b/provider/vagrant.py
@@ -7,6 +7,7 @@
 from api.ssh import exec_ssh, connect_ssh
 
 import json
+import logging
 import string
 import subprocess
 import uuid
@@ -14,20 +15,25 @@
 from api.models import Layer
 from api.models import Node
 
+logger = logging.getLogger(__name__)
+
 # Collect details for connecting to the host machine
-HOST_NODES_DIR = open('/home/vagrant/.host_nodes_dir').read().strip()
-PKEY = open('/home/vagrant/.ssh/id_rsa').read()
+try:
+    HOST_NODES_DIR = open('/home/vagrant/.host_nodes_dir').read().strip()
+    PKEY = open('/home/vagrant/.ssh/id_rsa').read()
+except IOError as err:
+    logger.warn(err)
 
 
 def seed_flavors():
-    """Seed the database with default flavors for each Rackspace region.
+    """Seed the database with default flavors for vagrant.
 
     :rtype: list of dicts containing flavor data
     """
     flavors = []
     for m in ['512', '1024', '2048']:
         flavors.append({
-            'id': 'vagrant-{}'.format(m),
+            'id': "vagrant-{}".format(m),
             'provider': 'vagrant',
             'params': json.dumps({
                 'memory': m

{"golden_diff": "diff --git a/provider/vagrant.py b/provider/vagrant.py\n--- a/provider/vagrant.py\n+++ b/provider/vagrant.py\n@@ -7,6 +7,7 @@\n from api.ssh import exec_ssh, connect_ssh\n \n import json\n+import logging\n import string\n import subprocess\n import uuid\n@@ -14,20 +15,25 @@\n from api.models import Layer\n from api.models import Node\n \n+logger = logging.getLogger(__name__)\n+\n # Collect details for connecting to the host machine\n-HOST_NODES_DIR = open('/home/vagrant/.host_nodes_dir').read().strip()\n-PKEY = open('/home/vagrant/.ssh/id_rsa').read()\n+try:\n+    HOST_NODES_DIR = open('/home/vagrant/.host_nodes_dir').read().strip()\n+    PKEY = open('/home/vagrant/.ssh/id_rsa').read()\n+except IOError as err:\n+    logger.warn(err)\n \n \n def seed_flavors():\n-    \"\"\"Seed the database with default flavors for each Rackspace region.\n+    \"\"\"Seed the database with default flavors for vagrant.\n \n     :rtype: list of dicts containing flavor data\n     \"\"\"\n     flavors = []\n     for m in ['512', '1024', '2048']:\n         flavors.append({\n-            'id': 'vagrant-{}'.format(m),\n+            'id': \"vagrant-{}\".format(m),\n             'provider': 'vagrant',\n             'params': json.dumps({\n                 'memory': m\n", "issue": "Error provisioning new controller: \".host_nodes_dir\"\nI provisioned a new controller on DigitalOcean and hit this error during initial registration. We need to loosen up the Vagrant config requirements so this doesn't show up.\n\n``` console\n[2013-11-07 16:02:37,088: INFO/MainProcess] consumer: Connected to amqp://guest@127.0.0.1:5672//.\n\n==> /var/log/deis/server.log <==\n    provider = import_provider_module(provider_type)\n  File \"/opt/deis/controller/provider/__init__.py\", line 8, in import_provider_module\n    tasks = importlib.import_module('provider.' + provider_type)\n  File \"/usr/lib/python2.7/importlib/__init__.py\", line 37, in import_module\n    __import__(name)\n  File \"/opt/deis/controller/provider/vagrant.py\", line 18, in <module>\n    HOST_NODES_DIR = open('/home/vagrant/.host_nodes_dir').read().strip()\nIOError: [Errno 2] No such file or directory: u'/home/vagrant/.host_nodes_dir'\nWARNING Forbidden (CSRF cookie not set.): /api/auth/register\n2013-11-07 16:29:55 [28407] [DEBUG] Closing connection. \n```\n\n", "before_files": [{"content": "\"\"\"\nDeis cloud provider implementation for local vagrant setups.\n\"\"\"\n\nfrom __future__ import unicode_literals\n\nfrom api.ssh import exec_ssh, connect_ssh\n\nimport json\nimport string\nimport subprocess\nimport uuid\n\nfrom api.models import Layer\nfrom api.models import Node\n\n# Collect details for connecting to the host machine\nHOST_NODES_DIR = open('/home/vagrant/.host_nodes_dir').read().strip()\nPKEY = open('/home/vagrant/.ssh/id_rsa').read()\n\n\ndef seed_flavors():\n    \"\"\"Seed the database with default flavors for each Rackspace region.\n\n    :rtype: list of dicts containing flavor data\n    \"\"\"\n    flavors = []\n    for m in ['512', '1024', '2048']:\n        flavors.append({\n            'id': 'vagrant-{}'.format(m),\n            'provider': 'vagrant',\n            'params': json.dumps({\n                'memory': m\n            })\n        })\n    return flavors\n\n\ndef build_layer(layer):\n    \"\"\"\n    Build a layer.\n\n    :param layer: a dict containing formation, id, params, and creds info\n    \"\"\"\n\n    # This can also be done with `deis layers:update` now.\n    layer_ = Layer.objects.get(id=layer['id'])\n    layer_.ssh_username = 'vagrant'\n    layer_.save()\n\n\ndef destroy_layer(layer):\n    \"\"\"\n    Destroy a layer.\n\n    :param layer: a dict containing formation, id, params, and creds info\n    \"\"\"\n    pass\n\n\ndef build_node(node):\n    \"\"\"\n    Build a node.\n\n    :param node: a dict containing formation, layer, params, and creds info.\n    :rtype: a tuple of (provider_id, fully_qualified_domain_name, metadata)\n    \"\"\"\n\n    # Can't use the vagrant UUID because it's not booted yet\n    uid = str(uuid.uuid1())\n\n    # Create a new Vagrantfile from a template\n    node['params'].setdefault('memory', '512')\n    template = open('/opt/deis/controller/contrib/vagrant/nodes_vagrantfile_template.rb')\n    raw = string.Template(template.read())\n    result = raw.substitute({\n        'id': uid,\n        'ipaddress': '192.168.61.' + str(Node.objects.all().count() + 100),\n        'memory': node['params']['memory']\n    })\n\n    # Make a folder for the VM with its own Vagrantfile. Vagrant will then create a .vagrant folder\n    # there too when it first gets booted.\n    node_dir = HOST_NODES_DIR + '/' + uid\n    mkdir = 'mkdir -p ' + node_dir\n    cp_tpl = 'echo \"' + result.replace('\"', '\\\\\"') + '\" > ' + node_dir + '/Vagrantfile'\n    _host_ssh(commands=[mkdir, cp_tpl], creds=node['creds'])\n\n    # Boot the VM\n    _run_vagrant_command(uid, args=['up'], creds=node['creds'])\n\n    # Copy the layer's public SSH key to the VM so that the Controller can access it.\n    _run_vagrant_command(\n        uid,\n        args=[\n            'ssh',\n            '-c',\n            '\"echo \\\\\"' + node['ssh_public_key'] + '\\\\\" >> /home/vagrant/.ssh/authorized_keys\"'\n        ],\n        creds=node['creds'],\n    )\n\n    provider_id = uid\n    fqdn = provider_id\n    if not fqdn.endswith('.local'):\n        fqdn += '.local'  # hostname is broadcast via avahi-daemon\n    metadata = {\n        'id': uid,\n        'fqdn': fqdn,\n        'flavor': node['params']['memory']\n    }\n    return provider_id, fqdn, metadata\n\n\ndef destroy_node(node):\n    \"\"\"\n    Destroy a node.\n\n    :param node: a dict containing a node's provider_id, params, and creds\n    \"\"\"\n\n    # This is useful if node creation failed. So that there's a record in the DB, but it has no\n    # ID associated with it.\n    if node['provider_id'] is None:\n        return\n\n    # Shut the VM down and destroy it\n    _run_vagrant_command(node['provider_id'], args=['destroy', '--force'], creds=node['creds'])\n    node_dir = HOST_NODES_DIR + '/' + node['provider_id']\n\n    # Sanity check before `rm -rf`\n    if 'contrib/vagrant' not in node_dir:\n        raise RuntimeError(\"Aborted node destruction: attempting to 'rm -rf' unexpected directory\")\n\n    # Completely remove the folder that contained the VM\n    rm_vagrantfile = 'rm ' + node_dir + '/Vagrantfile'\n    rm_node_dir = 'rm -rf ' + node_dir\n    _host_ssh(commands=[rm_vagrantfile, rm_node_dir], creds=node['creds'])\n\n\ndef _run_vagrant_command(node_id, args=[], creds={}):\n    \"\"\"\n    args: A tuple of arguments to a vagrant command line.\n    e.g. ['up', 'my_vm_name', '--no-provision']\n    \"\"\"\n\n    cd = 'cd ' + HOST_NODES_DIR + '/' + node_id\n    command = ['vagrant'] + [arg for arg in args if arg is not None]\n    return _host_ssh(commands=[cd, ' '.join(command)], creds=creds)\n\n\ndef _host_ssh(creds={}, commands=[]):\n    \"\"\"\n    Connect to the host machine. Namely the user's local machine.\n    \"\"\"\n    if creds == {}:\n        raise RuntimeError(\"No credentials provided to _host_ssh()\")\n    command = ' && '.join(commands)\n\n    # First check if we can access the host machine. It's likely that their\n    # IP address changes every time they request a DHCP lease.\n    # TODO: Find a way of passing this error onto the CLI client.\n    try:\n        subprocess.check_call([\n            'nc', '-z', '-w2', creds['host'], '22'\n        ], stderr=subprocess.PIPE)\n    except subprocess.CalledProcessError:\n        raise RuntimeError(\"Couldn't ping port 22 at host with IP \" + creds['host'])\n\n    ssh = connect_ssh(creds['user'], creds['host'], 22, PKEY, timeout=120)\n    result, status = exec_ssh(ssh, command)\n    if status > 0:\n        raise RuntimeError(\n            'SSH to Vagrant host error: ' + result.decode('utf-8') +\n            'Command: ' + command.decode('utf-8'))\n    return result\n", "path": "provider/vagrant.py"}], "after_files": [{"content": "\"\"\"\nDeis cloud provider implementation for local vagrant setups.\n\"\"\"\n\nfrom __future__ import unicode_literals\n\nfrom api.ssh import exec_ssh, connect_ssh\n\nimport json\nimport logging\nimport string\nimport subprocess\nimport uuid\n\nfrom api.models import Layer\nfrom api.models import Node\n\nlogger = logging.getLogger(__name__)\n\n# Collect details for connecting to the host machine\ntry:\n    HOST_NODES_DIR = open('/home/vagrant/.host_nodes_dir').read().strip()\n    PKEY = open('/home/vagrant/.ssh/id_rsa').read()\nexcept IOError as err:\n    logger.warn(err)\n\n\ndef seed_flavors():\n    \"\"\"Seed the database with default flavors for vagrant.\n\n    :rtype: list of dicts containing flavor data\n    \"\"\"\n    flavors = []\n    for m in ['512', '1024', '2048']:\n        flavors.append({\n            'id': \"vagrant-{}\".format(m),\n            'provider': 'vagrant',\n            'params': json.dumps({\n                'memory': m\n            })\n        })\n    return flavors\n\n\ndef build_layer(layer):\n    \"\"\"\n    Build a layer.\n\n    :param layer: a dict containing formation, id, params, and creds info\n    \"\"\"\n\n    # This can also be done with `deis layers:update` now.\n    layer_ = Layer.objects.get(id=layer['id'])\n    layer_.ssh_username = 'vagrant'\n    layer_.save()\n\n\ndef destroy_layer(layer):\n    \"\"\"\n    Destroy a layer.\n\n    :param layer: a dict containing formation, id, params, and creds info\n    \"\"\"\n    pass\n\n\ndef build_node(node):\n    \"\"\"\n    Build a node.\n\n    :param node: a dict containing formation, layer, params, and creds info.\n    :rtype: a tuple of (provider_id, fully_qualified_domain_name, metadata)\n    \"\"\"\n\n    # Can't use the vagrant UUID because it's not booted yet\n    uid = str(uuid.uuid1())\n\n    # Create a new Vagrantfile from a template\n    node['params'].setdefault('memory', '512')\n    template = open('/opt/deis/controller/contrib/vagrant/nodes_vagrantfile_template.rb')\n    raw = string.Template(template.read())\n    result = raw.substitute({\n        'id': uid,\n        'ipaddress': '192.168.61.' + str(Node.objects.all().count() + 100),\n        'memory': node['params']['memory']\n    })\n\n    # Make a folder for the VM with its own Vagrantfile. Vagrant will then create a .vagrant folder\n    # there too when it first gets booted.\n    node_dir = HOST_NODES_DIR + '/' + uid\n    mkdir = 'mkdir -p ' + node_dir\n    cp_tpl = 'echo \"' + result.replace('\"', '\\\\\"') + '\" > ' + node_dir + '/Vagrantfile'\n    _host_ssh(commands=[mkdir, cp_tpl], creds=node['creds'])\n\n    # Boot the VM\n    _run_vagrant_command(uid, args=['up'], creds=node['creds'])\n\n    # Copy the layer's public SSH key to the VM so that the Controller can access it.\n    _run_vagrant_command(\n        uid,\n        args=[\n            'ssh',\n            '-c',\n            '\"echo \\\\\"' + node['ssh_public_key'] + '\\\\\" >> /home/vagrant/.ssh/authorized_keys\"'\n        ],\n        creds=node['creds'],\n    )\n\n    provider_id = uid\n    fqdn = provider_id\n    if not fqdn.endswith('.local'):\n        fqdn += '.local'  # hostname is broadcast via avahi-daemon\n    metadata = {\n        'id': uid,\n        'fqdn': fqdn,\n        'flavor': node['params']['memory']\n    }\n    return provider_id, fqdn, metadata\n\n\ndef destroy_node(node):\n    \"\"\"\n    Destroy a node.\n\n    :param node: a dict containing a node's provider_id, params, and creds\n    \"\"\"\n\n    # This is useful if node creation failed. So that there's a record in the DB, but it has no\n    # ID associated with it.\n    if node['provider_id'] is None:\n        return\n\n    # Shut the VM down and destroy it\n    _run_vagrant_command(node['provider_id'], args=['destroy', '--force'], creds=node['creds'])\n    node_dir = HOST_NODES_DIR + '/' + node['provider_id']\n\n    # Sanity check before `rm -rf`\n    if 'contrib/vagrant' not in node_dir:\n        raise RuntimeError(\"Aborted node destruction: attempting to 'rm -rf' unexpected directory\")\n\n    # Completely remove the folder that contained the VM\n    rm_vagrantfile = 'rm ' + node_dir + '/Vagrantfile'\n    rm_node_dir = 'rm -rf ' + node_dir\n    _host_ssh(commands=[rm_vagrantfile, rm_node_dir], creds=node['creds'])\n\n\ndef _run_vagrant_command(node_id, args=[], creds={}):\n    \"\"\"\n    args: A tuple of arguments to a vagrant command line.\n    e.g. ['up', 'my_vm_name', '--no-provision']\n    \"\"\"\n\n    cd = 'cd ' + HOST_NODES_DIR + '/' + node_id\n    command = ['vagrant'] + [arg for arg in args if arg is not None]\n    return _host_ssh(commands=[cd, ' '.join(command)], creds=creds)\n\n\ndef _host_ssh(creds={}, commands=[]):\n    \"\"\"\n    Connect to the host machine. Namely the user's local machine.\n    \"\"\"\n    if creds == {}:\n        raise RuntimeError(\"No credentials provided to _host_ssh()\")\n    command = ' && '.join(commands)\n\n    # First check if we can access the host machine. It's likely that their\n    # IP address changes every time they request a DHCP lease.\n    # TODO: Find a way of passing this error onto the CLI client.\n    try:\n        subprocess.check_call([\n            'nc', '-z', '-w2', creds['host'], '22'\n        ], stderr=subprocess.PIPE)\n    except subprocess.CalledProcessError:\n        raise RuntimeError(\"Couldn't ping port 22 at host with IP \" + creds['host'])\n\n    ssh = connect_ssh(creds['user'], creds['host'], 22, PKEY, timeout=120)\n    result, status = exec_ssh(ssh, command)\n    if status > 0:\n        raise RuntimeError(\n            'SSH to Vagrant host error: ' + result.decode('utf-8') +\n            'Command: ' + command.decode('utf-8'))\n    return result\n", "path": "provider/vagrant.py"}]}