We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Better output message on cloudint when missing pycdlib
pycdlib is necessary when running `utils/cloudinit.py`

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `avocado/utils/cloudinit.py`
Content:
```
1 # This program is free software; you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation; either version 2 of the License, or
4 # (at your option) any later version.
5 #
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9 #
10 # See LICENSE for more details.
11 #
12 # Copyright: Red Hat Inc. 2018
13 # Author: Cleber Rosa <crosa@redhat.com>
14 
15 """
16 cloudinit configuration support
17 
18 This module can be easily used with :mod:`avocado.utils.vmimage`,
19 to configure operating system images via the cloudinit tooling.
20 
21 :see: http://cloudinit.readthedocs.io.
22 """
23 
24 from http.server import BaseHTTPRequestHandler, HTTPServer
25 
26 from . import astring, iso9660
27 
28 #: The meta-data file template
29 #:
30 #: Positional template variables are: instance-id, hostname
31 METADATA_TEMPLATE = """instance-id: {0}
32 hostname: {1}
33 """
34 
35 #: The header expected to be found at the beginning of the user-data file
36 USERDATA_HEADER = "#cloud-config"
37 
38 #: A username configuration as per cloudinit/config/cc_set_passwords.py
39 #:
40 #: Positional template variables : username
41 USERNAME_TEMPLATE = """
42 ssh_pwauth: True
43 
44 system_info:
45    default_user:
46       name: {0}
47 """
48 
49 #: A username configuration as per cloudinit/config/cc_set_passwords.py
50 #:
51 #: Positional template variables are: password
52 PASSWORD_TEMPLATE = """
53 password: {0}
54 chpasswd:
55     expire: False
56 """
57 
58 #: An authorized key configuration for the default user
59 #:
60 #: Positional template variables are: ssh_authorized_keys
61 AUTHORIZED_KEY_TEMPLATE = """
62 ssh_authorized_keys:
63   - {0}
64 """
65 
66 #: A phone home configuration that will post just the instance id
67 #:
68 #: Positional template variables are: address, port
69 PHONE_HOME_TEMPLATE = """
70 phone_home:
71     url: http://{0}:{1}/$INSTANCE_ID/
72     post: [ instance_id ]
73 """
74 
75 
76 def iso(output_path, instance_id, username=None, password=None,
77         phone_home_host=None, phone_home_port=None, authorized_key=None):
78     """
79     Generates an ISO image with cloudinit configuration
80 
81     The content always include the cloudinit metadata, and optionally
82     the userdata content.  On the userdata file, it may contain a
83     username/password section (if both parameters are given) and/or a
84     phone home section (if both host and port are given).
85 
86     :param output_path: the location of the resulting (to be created) ISO
87                         image containing the cloudinit configuration
88     :param instance_id: the ID of the cloud instance, a form of identification
89                         for the dynamically created executing instances
90     :param username: the username to be used when logging interactively on the
91                      instance
92     :param password: the password to be used along with username when
93                      authenticating with the login services on the instance
94     :param phone_home_host: the address of the host the instance
95                             should contact once it has finished
96                             booting
97     :param phone_home_port: the port acting as an HTTP phone home
98                             server that the instance should contact
99                             once it has finished booting
100     :param authorized_key: a SSH public key to be added as an authorized key
101                            for the default user, similar to "ssh-rsa ..."
102     :type authorized_key: str
103     :raises: RuntimeError if the system can not create ISO images.  On such
104              a case, user is expected to install supporting packages, such as
105              pycdlib.
106     """
107     out = iso9660.iso9660(output_path, ["create", "write"])
108     if out is None:
109         raise RuntimeError("The system lacks support for creating ISO images")
110     out.create(flags={"interchange_level": 3, "joliet": 3, "vol_ident": 'cidata'})
111     metadata = METADATA_TEMPLATE.format(instance_id,
112                                         instance_id).encode(astring.ENCODING)
113     out.write("/meta-data", metadata)
114     userdata = USERDATA_HEADER
115     if username:
116         userdata += USERNAME_TEMPLATE.format(username)
117         if username == "root":
118             userdata += "\ndisable_root: False\n"
119         if password:
120             userdata += PASSWORD_TEMPLATE.format(password)
121         if authorized_key:
122             userdata += AUTHORIZED_KEY_TEMPLATE.format(authorized_key)
123     if phone_home_host and phone_home_port:
124         userdata += PHONE_HOME_TEMPLATE.format(phone_home_host, phone_home_port)
125     out.write("/user-data", userdata.encode(astring.ENCODING))
126     out.close()
127 
128 
129 class PhoneHomeServerHandler(BaseHTTPRequestHandler):
130     """Handles HTTP requests to the phone home server."""
131 
132     def do_POST(self):
133         """Handles an HTTP POST request.
134 
135         Respond with status 200 if the instance phoned back.
136         """
137         path = self.path[1:]
138         if path[-1] == '/':
139             path = path[:-1]
140         if path == self.server.instance_id:
141             self.server.instance_phoned_back = True
142         self.send_response(200)
143 
144     def log_message(self, format_, *args):  # pylint: disable=W0221
145         """Logs an arbitrary message.
146 
147         :note: It currently disables any message logging.
148         """
149 
150 
151 class PhoneHomeServer(HTTPServer):
152     """Implements the phone home HTTP server.
153 
154     Wait the phone home from a given instance.
155     """
156 
157     def __init__(self, address, instance_id):
158         """Initialize the server.
159 
160         :param address: a hostname or IP address and port, in the same format
161                         given to socket and other servers
162         :type address: tuple
163         :param instance_id: the identification for the instance that should be
164                             calling back, and the condition for the wait to end
165         :type instance_id: str
166         """
167         HTTPServer.__init__(self, address, PhoneHomeServerHandler)
168         self.instance_id = instance_id
169         self.instance_phoned_back = False
170 
171 
172 def wait_for_phone_home(address, instance_id):
173     """
174     Sets up a phone home server and waits for the given instance to call
175 
176     This is a shorthand for setting up a server that will keep handling
177     requests, until it has heard from the specific instance requested.
178 
179     :param address: a hostname or IP address and port, in the same format
180                     given to socket and other servers
181     :type address: tuple
182     :param instance_id: the identification for the instance that should be
183                         calling back, and the condition for the wait to end
184     :type instance_id: str
185     """
186     s = PhoneHomeServer(address, instance_id)
187     while not s.instance_phoned_back:
188         s.handle_request()
189
```
--- 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/avocado/utils/cloudinit.py b/avocado/utils/cloudinit.py
--- a/avocado/utils/cloudinit.py
+++ b/avocado/utils/cloudinit.py
@@ -18,6 +18,9 @@
 This module can be easily used with :mod:`avocado.utils.vmimage`,
 to configure operating system images via the cloudinit tooling.
 
+Please, keep in mind that if you would like to create/write in ISO images, you
+need pycdlib module installed in your environment.
+
 :see: http://cloudinit.readthedocs.io.
 """
 
@@ -104,9 +107,12 @@
              a case, user is expected to install supporting packages, such as
              pycdlib.
     """
+    # The only supported method to create/write in an ISO today is via pycdlib
     out = iso9660.iso9660(output_path, ["create", "write"])
     if out is None:
-        raise RuntimeError("The system lacks support for creating ISO images")
+        msg = ("The system lacks support for creating ISO images. ",
+               "Please install pycdlib dependency and run again.")
+        raise RuntimeError(msg)
     out.create(flags={"interchange_level": 3, "joliet": 3, "vol_ident": 'cidata'})
     metadata = METADATA_TEMPLATE.format(instance_id,
                                         instance_id).encode(astring.ENCODING)

{"golden_diff": "diff --git a/avocado/utils/cloudinit.py b/avocado/utils/cloudinit.py\n--- a/avocado/utils/cloudinit.py\n+++ b/avocado/utils/cloudinit.py\n@@ -18,6 +18,9 @@\n This module can be easily used with :mod:`avocado.utils.vmimage`,\n to configure operating system images via the cloudinit tooling.\n \n+Please, keep in mind that if you would like to create/write in ISO images, you\n+need pycdlib module installed in your environment.\n+\n :see: http://cloudinit.readthedocs.io.\n \"\"\"\n \n@@ -104,9 +107,12 @@\n              a case, user is expected to install supporting packages, such as\n              pycdlib.\n     \"\"\"\n+    # The only supported method to create/write in an ISO today is via pycdlib\n     out = iso9660.iso9660(output_path, [\"create\", \"write\"])\n     if out is None:\n-        raise RuntimeError(\"The system lacks support for creating ISO images\")\n+        msg = (\"The system lacks support for creating ISO images. \",\n+               \"Please install pycdlib dependency and run again.\")\n+        raise RuntimeError(msg)\n     out.create(flags={\"interchange_level\": 3, \"joliet\": 3, \"vol_ident\": 'cidata'})\n     metadata = METADATA_TEMPLATE.format(instance_id,\n                                         instance_id).encode(astring.ENCODING)\n", "issue": "Better output message on cloudint when missing pycdlib\npycdlib is necessary when running `utils/cloudinit.py`\n", "before_files": [{"content": "# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n#\n# See LICENSE for more details.\n#\n# Copyright: Red Hat Inc. 2018\n# Author: Cleber Rosa <crosa@redhat.com>\n\n\"\"\"\ncloudinit configuration support\n\nThis module can be easily used with :mod:`avocado.utils.vmimage`,\nto configure operating system images via the cloudinit tooling.\n\n:see: http://cloudinit.readthedocs.io.\n\"\"\"\n\nfrom http.server import BaseHTTPRequestHandler, HTTPServer\n\nfrom . import astring, iso9660\n\n#: The meta-data file template\n#:\n#: Positional template variables are: instance-id, hostname\nMETADATA_TEMPLATE = \"\"\"instance-id: {0}\nhostname: {1}\n\"\"\"\n\n#: The header expected to be found at the beginning of the user-data file\nUSERDATA_HEADER = \"#cloud-config\"\n\n#: A username configuration as per cloudinit/config/cc_set_passwords.py\n#:\n#: Positional template variables : username\nUSERNAME_TEMPLATE = \"\"\"\nssh_pwauth: True\n\nsystem_info:\n   default_user:\n      name: {0}\n\"\"\"\n\n#: A username configuration as per cloudinit/config/cc_set_passwords.py\n#:\n#: Positional template variables are: password\nPASSWORD_TEMPLATE = \"\"\"\npassword: {0}\nchpasswd:\n    expire: False\n\"\"\"\n\n#: An authorized key configuration for the default user\n#:\n#: Positional template variables are: ssh_authorized_keys\nAUTHORIZED_KEY_TEMPLATE = \"\"\"\nssh_authorized_keys:\n  - {0}\n\"\"\"\n\n#: A phone home configuration that will post just the instance id\n#:\n#: Positional template variables are: address, port\nPHONE_HOME_TEMPLATE = \"\"\"\nphone_home:\n    url: http://{0}:{1}/$INSTANCE_ID/\n    post: [ instance_id ]\n\"\"\"\n\n\ndef iso(output_path, instance_id, username=None, password=None,\n        phone_home_host=None, phone_home_port=None, authorized_key=None):\n    \"\"\"\n    Generates an ISO image with cloudinit configuration\n\n    The content always include the cloudinit metadata, and optionally\n    the userdata content.  On the userdata file, it may contain a\n    username/password section (if both parameters are given) and/or a\n    phone home section (if both host and port are given).\n\n    :param output_path: the location of the resulting (to be created) ISO\n                        image containing the cloudinit configuration\n    :param instance_id: the ID of the cloud instance, a form of identification\n                        for the dynamically created executing instances\n    :param username: the username to be used when logging interactively on the\n                     instance\n    :param password: the password to be used along with username when\n                     authenticating with the login services on the instance\n    :param phone_home_host: the address of the host the instance\n                            should contact once it has finished\n                            booting\n    :param phone_home_port: the port acting as an HTTP phone home\n                            server that the instance should contact\n                            once it has finished booting\n    :param authorized_key: a SSH public key to be added as an authorized key\n                           for the default user, similar to \"ssh-rsa ...\"\n    :type authorized_key: str\n    :raises: RuntimeError if the system can not create ISO images.  On such\n             a case, user is expected to install supporting packages, such as\n             pycdlib.\n    \"\"\"\n    out = iso9660.iso9660(output_path, [\"create\", \"write\"])\n    if out is None:\n        raise RuntimeError(\"The system lacks support for creating ISO images\")\n    out.create(flags={\"interchange_level\": 3, \"joliet\": 3, \"vol_ident\": 'cidata'})\n    metadata = METADATA_TEMPLATE.format(instance_id,\n                                        instance_id).encode(astring.ENCODING)\n    out.write(\"/meta-data\", metadata)\n    userdata = USERDATA_HEADER\n    if username:\n        userdata += USERNAME_TEMPLATE.format(username)\n        if username == \"root\":\n            userdata += \"\\ndisable_root: False\\n\"\n        if password:\n            userdata += PASSWORD_TEMPLATE.format(password)\n        if authorized_key:\n            userdata += AUTHORIZED_KEY_TEMPLATE.format(authorized_key)\n    if phone_home_host and phone_home_port:\n        userdata += PHONE_HOME_TEMPLATE.format(phone_home_host, phone_home_port)\n    out.write(\"/user-data\", userdata.encode(astring.ENCODING))\n    out.close()\n\n\nclass PhoneHomeServerHandler(BaseHTTPRequestHandler):\n    \"\"\"Handles HTTP requests to the phone home server.\"\"\"\n\n    def do_POST(self):\n        \"\"\"Handles an HTTP POST request.\n\n        Respond with status 200 if the instance phoned back.\n        \"\"\"\n        path = self.path[1:]\n        if path[-1] == '/':\n            path = path[:-1]\n        if path == self.server.instance_id:\n            self.server.instance_phoned_back = True\n        self.send_response(200)\n\n    def log_message(self, format_, *args):  # pylint: disable=W0221\n        \"\"\"Logs an arbitrary message.\n\n        :note: It currently disables any message logging.\n        \"\"\"\n\n\nclass PhoneHomeServer(HTTPServer):\n    \"\"\"Implements the phone home HTTP server.\n\n    Wait the phone home from a given instance.\n    \"\"\"\n\n    def __init__(self, address, instance_id):\n        \"\"\"Initialize the server.\n\n        :param address: a hostname or IP address and port, in the same format\n                        given to socket and other servers\n        :type address: tuple\n        :param instance_id: the identification for the instance that should be\n                            calling back, and the condition for the wait to end\n        :type instance_id: str\n        \"\"\"\n        HTTPServer.__init__(self, address, PhoneHomeServerHandler)\n        self.instance_id = instance_id\n        self.instance_phoned_back = False\n\n\ndef wait_for_phone_home(address, instance_id):\n    \"\"\"\n    Sets up a phone home server and waits for the given instance to call\n\n    This is a shorthand for setting up a server that will keep handling\n    requests, until it has heard from the specific instance requested.\n\n    :param address: a hostname or IP address and port, in the same format\n                    given to socket and other servers\n    :type address: tuple\n    :param instance_id: the identification for the instance that should be\n                        calling back, and the condition for the wait to end\n    :type instance_id: str\n    \"\"\"\n    s = PhoneHomeServer(address, instance_id)\n    while not s.instance_phoned_back:\n        s.handle_request()\n", "path": "avocado/utils/cloudinit.py"}], "after_files": [{"content": "# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n#\n# See LICENSE for more details.\n#\n# Copyright: Red Hat Inc. 2018\n# Author: Cleber Rosa <crosa@redhat.com>\n\n\"\"\"\ncloudinit configuration support\n\nThis module can be easily used with :mod:`avocado.utils.vmimage`,\nto configure operating system images via the cloudinit tooling.\n\nPlease, keep in mind that if you would like to create/write in ISO images, you\nneed pycdlib module installed in your environment.\n\n:see: http://cloudinit.readthedocs.io.\n\"\"\"\n\nfrom http.server import BaseHTTPRequestHandler, HTTPServer\n\nfrom . import astring, iso9660\n\n#: The meta-data file template\n#:\n#: Positional template variables are: instance-id, hostname\nMETADATA_TEMPLATE = \"\"\"instance-id: {0}\nhostname: {1}\n\"\"\"\n\n#: The header expected to be found at the beginning of the user-data file\nUSERDATA_HEADER = \"#cloud-config\"\n\n#: A username configuration as per cloudinit/config/cc_set_passwords.py\n#:\n#: Positional template variables : username\nUSERNAME_TEMPLATE = \"\"\"\nssh_pwauth: True\n\nsystem_info:\n   default_user:\n      name: {0}\n\"\"\"\n\n#: A username configuration as per cloudinit/config/cc_set_passwords.py\n#:\n#: Positional template variables are: password\nPASSWORD_TEMPLATE = \"\"\"\npassword: {0}\nchpasswd:\n    expire: False\n\"\"\"\n\n#: An authorized key configuration for the default user\n#:\n#: Positional template variables are: ssh_authorized_keys\nAUTHORIZED_KEY_TEMPLATE = \"\"\"\nssh_authorized_keys:\n  - {0}\n\"\"\"\n\n#: A phone home configuration that will post just the instance id\n#:\n#: Positional template variables are: address, port\nPHONE_HOME_TEMPLATE = \"\"\"\nphone_home:\n    url: http://{0}:{1}/$INSTANCE_ID/\n    post: [ instance_id ]\n\"\"\"\n\n\ndef iso(output_path, instance_id, username=None, password=None,\n        phone_home_host=None, phone_home_port=None, authorized_key=None):\n    \"\"\"\n    Generates an ISO image with cloudinit configuration\n\n    The content always include the cloudinit metadata, and optionally\n    the userdata content.  On the userdata file, it may contain a\n    username/password section (if both parameters are given) and/or a\n    phone home section (if both host and port are given).\n\n    :param output_path: the location of the resulting (to be created) ISO\n                        image containing the cloudinit configuration\n    :param instance_id: the ID of the cloud instance, a form of identification\n                        for the dynamically created executing instances\n    :param username: the username to be used when logging interactively on the\n                     instance\n    :param password: the password to be used along with username when\n                     authenticating with the login services on the instance\n    :param phone_home_host: the address of the host the instance\n                            should contact once it has finished\n                            booting\n    :param phone_home_port: the port acting as an HTTP phone home\n                            server that the instance should contact\n                            once it has finished booting\n    :param authorized_key: a SSH public key to be added as an authorized key\n                           for the default user, similar to \"ssh-rsa ...\"\n    :type authorized_key: str\n    :raises: RuntimeError if the system can not create ISO images.  On such\n             a case, user is expected to install supporting packages, such as\n             pycdlib.\n    \"\"\"\n    # The only supported method to create/write in an ISO today is via pycdlib\n    out = iso9660.iso9660(output_path, [\"create\", \"write\"])\n    if out is None:\n        msg = (\"The system lacks support for creating ISO images. \",\n               \"Please install pycdlib dependency and run again.\")\n        raise RuntimeError(msg)\n    out.create(flags={\"interchange_level\": 3, \"joliet\": 3, \"vol_ident\": 'cidata'})\n    metadata = METADATA_TEMPLATE.format(instance_id,\n                                        instance_id).encode(astring.ENCODING)\n    out.write(\"/meta-data\", metadata)\n    userdata = USERDATA_HEADER\n    if username:\n        userdata += USERNAME_TEMPLATE.format(username)\n        if username == \"root\":\n            userdata += \"\\ndisable_root: False\\n\"\n        if password:\n            userdata += PASSWORD_TEMPLATE.format(password)\n        if authorized_key:\n            userdata += AUTHORIZED_KEY_TEMPLATE.format(authorized_key)\n    if phone_home_host and phone_home_port:\n        userdata += PHONE_HOME_TEMPLATE.format(phone_home_host, phone_home_port)\n    out.write(\"/user-data\", userdata.encode(astring.ENCODING))\n    out.close()\n\n\nclass PhoneHomeServerHandler(BaseHTTPRequestHandler):\n    \"\"\"Handles HTTP requests to the phone home server.\"\"\"\n\n    def do_POST(self):\n        \"\"\"Handles an HTTP POST request.\n\n        Respond with status 200 if the instance phoned back.\n        \"\"\"\n        path = self.path[1:]\n        if path[-1] == '/':\n            path = path[:-1]\n        if path == self.server.instance_id:\n            self.server.instance_phoned_back = True\n        self.send_response(200)\n\n    def log_message(self, format_, *args):  # pylint: disable=W0221\n        \"\"\"Logs an arbitrary message.\n\n        :note: It currently disables any message logging.\n        \"\"\"\n\n\nclass PhoneHomeServer(HTTPServer):\n    \"\"\"Implements the phone home HTTP server.\n\n    Wait the phone home from a given instance.\n    \"\"\"\n\n    def __init__(self, address, instance_id):\n        \"\"\"Initialize the server.\n\n        :param address: a hostname or IP address and port, in the same format\n                        given to socket and other servers\n        :type address: tuple\n        :param instance_id: the identification for the instance that should be\n                            calling back, and the condition for the wait to end\n        :type instance_id: str\n        \"\"\"\n        HTTPServer.__init__(self, address, PhoneHomeServerHandler)\n        self.instance_id = instance_id\n        self.instance_phoned_back = False\n\n\ndef wait_for_phone_home(address, instance_id):\n    \"\"\"\n    Sets up a phone home server and waits for the given instance to call\n\n    This is a shorthand for setting up a server that will keep handling\n    requests, until it has heard from the specific instance requested.\n\n    :param address: a hostname or IP address and port, in the same format\n                    given to socket and other servers\n    :type address: tuple\n    :param instance_id: the identification for the instance that should be\n                        calling back, and the condition for the wait to end\n    :type instance_id: str\n    \"\"\"\n    s = PhoneHomeServer(address, instance_id)\n    while not s.instance_phoned_back:\n        s.handle_request()\n", "path": "avocado/utils/cloudinit.py"}]}