# Buggy code
def run(self):
    """
    Execute the salt-cloud command line
    """
    # Parse shell arguments
    self.parse_args()

    salt_master_user = self.config.get("user", salt.utils.get_user())
    if salt_master_user is not None and not check_user(salt_master_user):
        self.error(
            "If salt-cloud is running on a master machine, salt-cloud "
            "needs to run as the same user as the salt-master, {0!r}. If "
            "salt-cloud is not running on a salt-master, the appropriate "
            "write permissions must be granted to /etc/salt/. Please run "
            "salt-cloud as root, {0!r}, or change permissions for "
            "/etc/salt/.".format(salt_master_user)
        )

    try:
        if self.config["verify_env"]:
            verify_env([os.path.dirname(self.config["conf_file"])], salt_master_user)
            logfile = self.config["log_file"]
            if (
                logfile is not None
                and not logfile.startswith("tcp://")
                and not logfile.startswith("udp://")
                and not logfile.startswith("file://")
            ):
                # Logfile is not using Syslog, verify
                verify_files([logfile], salt_master_user)
    except (IOError, OSError) as err:
        log.error("Error while verifying the environment: {0}".format(err))
        sys.exit(err.errno)

    # Setup log file logging
    self.setup_logfile_logger()
    verify_log(self.config)

    if self.options.update_bootstrap:
        ret = salt.utils.cloud.update_bootstrap(self.config)
        display_output = salt.output.get_printout(self.options.output, self.config)
        print(display_output(ret))
        self.exit(salt.defaults.exitcodes.EX_OK)

    log.info("salt-cloud starting")
    try:
        mapper = salt.cloud.Map(self.config)
    except SaltCloudException as exc:
        msg = "There was an error generating the mapper."
        self.handle_exception(msg, exc)

    names = self.config.get("names", None)
    if names is not None:
        filtered_rendered_map = {}
        for map_profile in mapper.rendered_map:
            filtered_map_profile = {}
            for name in mapper.rendered_map[map_profile]:
                if name in names:
                    filtered_map_profile[name] = mapper.rendered_map[map_profile][name]
            if filtered_map_profile:
                filtered_rendered_map[map_profile] = filtered_map_profile
        mapper.rendered_map = filtered_rendered_map

    ret = {}

    if self.selected_query_option is not None:
        if self.selected_query_option == "list_providers":
            try:
                ret = mapper.provider_list()
            except (SaltCloudException, Exception) as exc:
                msg = "There was an error listing providers: {0}"
                self.handle_exception(msg, exc)

        elif self.selected_query_option == "list_profiles":
            provider = self.options.list_profiles
            try:
                ret = mapper.profile_list(provider)
            except (SaltCloudException, Exception) as exc:
                msg = "There was an error listing profiles: {0}"
                self.handle_exception(msg, exc)

        elif self.config.get("map", None):
            log.info("Applying map from {0!r}.".format(self.config["map"]))
            try:
                ret = mapper.interpolated_map(query=self.selected_query_option)
            except (SaltCloudException, Exception) as exc:
                msg = "There was an error with a custom map: {0}"
                self.handle_exception(msg, exc)
        else:
            try:
                ret = mapper.map_providers_parallel(query=self.selected_query_option)
            except (SaltCloudException, Exception) as exc:
                msg = "There was an error with a map: {0}"
                self.handle_exception(msg, exc)

    elif self.options.list_locations is not None:
        try:
            ret = mapper.location_list(self.options.list_locations)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error listing locations: {0}"
            self.handle_exception(msg, exc)

    elif self.options.list_images is not None:
        try:
            ret = mapper.image_list(self.options.list_images)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error listing images: {0}"
            self.handle_exception(msg, exc)

    elif self.options.list_sizes is not None:
        try:
            ret = mapper.size_list(self.options.list_sizes)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error listing sizes: {0}"
            self.handle_exception(msg, exc)

    elif self.options.destroy and (
        self.config.get("names", None) or self.config.get("map", None)
    ):
        map_file = self.config.get("map", None)
        names = self.config.get("names", ())
        if map_file is not None:
            if names != ():
                msg = (
                    "Supplying a mapfile, '{0}', in addition to instance names {1} "
                    "with the '--destroy' or '-d' function is not supported. "
                    "Please choose to delete either the entire map file or individual "
                    "instances.".format(map_file, names)
                )
                self.handle_exception(msg, SaltCloudSystemExit)

            log.info("Applying map from '{0}'.".format(map_file))
            matching = mapper.delete_map(query="list_nodes")
        else:
            matching = mapper.get_running_by_names(names, profile=self.options.profile)

        if not matching:
            print("No machines were found to be destroyed")
            self.exit(salt.defaults.exitcodes.EX_OK)

        msg = "The following virtual machines are set to be destroyed:\n"
        names = set()
        for alias, drivers in six.iteritems(matching):
            msg += "  {0}:\n".format(alias)
            for driver, vms in six.iteritems(drivers):
                msg += "    {0}:\n".format(driver)
                for name in vms:
                    msg += "      {0}\n".format(name)
                    names.add(name)
        try:
            if self.print_confirm(msg):
                ret = mapper.destroy(names, cached=True)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error destroying machines: {0}"
            self.handle_exception(msg, exc)

    elif self.options.action and (
        self.config.get("names", None) or self.config.get("map", None)
    ):
        if self.config.get("map", None):
            log.info("Applying map from {0!r}.".format(self.config["map"]))
            try:
                names = mapper.get_vmnames_by_action(self.options.action)
            except SaltCloudException as exc:
                msg = "There was an error actioning virtual machines."
                self.handle_exception(msg, exc)
        else:
            names = self.config.get("names", None)

        kwargs = {}
        machines = []
        msg = (
            "The following virtual machines are set to be actioned with "
            '"{0}":\n'.format(self.options.action)
        )
        for name in names:
            if "=" in name:
                # This is obviously not a machine name, treat it as a kwarg
                comps = name.split("=")
                kwargs[comps[0]] = comps[1]
            else:
                msg += "  {0}\n".format(name)
                machines.append(name)
        names = machines

        try:
            if self.print_confirm(msg):
                ret = mapper.do_action(names, kwargs)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error actioning machines: {0}"
            self.handle_exception(msg, exc)

    elif self.options.function:
        kwargs = {}
        args = self.args[:]
        for arg in args[:]:
            if "=" in arg:
                key, value = arg.split("=")
                kwargs[key] = value
                args.remove(arg)

        if args:
            self.error(
                "Any arguments passed to --function need to be passed "
                "as kwargs. Ex: image=ami-54cf5c3d. Remaining "
                "arguments: {0}".format(args)
            )
        try:
            ret = mapper.do_function(self.function_provider, self.function_name, kwargs)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error running the function: {0}"
            self.handle_exception(msg, exc)

    elif self.options.profile and self.config.get("names", False):
        try:
            ret = mapper.run_profile(self.options.profile, self.config.get("names"))
        except (SaltCloudException, Exception) as exc:
            msg = "There was a profile error: {0}"
            self.handle_exception(msg, exc)

    elif self.options.set_password:
        username = self.credential_username
        provider_name = "salt.cloud.provider.{0}".format(self.credential_provider)
        # TODO: check if provider is configured
        # set the password
        salt.utils.cloud.store_password_in_keyring(provider_name, username)
    elif self.config.get("map", None) and self.selected_query_option is None:
        if len(mapper.rendered_map) == 0:
            sys.stderr.write("No nodes defined in this map")
            self.exit(salt.defaults.exitcodes.EX_GENERIC)
        try:
            ret = {}
            run_map = True

            log.info("Applying map from {0!r}.".format(self.config["map"]))
            dmap = mapper.map_data()

            msg = ""
            if "errors" in dmap:
                # display profile errors
                msg += "Found the following errors:\n"
                for profile_name, error in six.iteritems(dmap["errors"]):
                    msg += "  {0}: {1}\n".format(profile_name, error)
                sys.stderr.write(msg)
                sys.stderr.flush()

            msg = ""
            if "existing" in dmap:
                msg += "The following virtual machines already exist:\n"
                for name in dmap["existing"]:
                    msg += "  {0}\n".format(name)

            if dmap["create"]:
                msg += "The following virtual machines are set to be created:\n"
                for name in dmap["create"]:
                    msg += "  {0}\n".format(name)

            if "destroy" in dmap:
                msg += "The following virtual machines are set to be destroyed:\n"
                for name in dmap["destroy"]:
                    msg += "  {0}\n".format(name)

            if not dmap["create"] and not dmap.get("destroy", None):
                if not dmap.get("existing", None):
                    # nothing to create or destroy & nothing exists
                    print(msg)
                    self.exit(1)
                else:
                    # nothing to create or destroy, print existing
                    run_map = False

            if run_map:
                if self.print_confirm(msg):
                    ret = mapper.run_map(dmap)

                if self.config.get("parallel", False) is False:
                    log.info("Complete")

            if dmap.get("existing", None):
                for name in dmap["existing"]:
                    ret[name] = {"Message": "Already running"}

        except (SaltCloudException, Exception) as exc:
            msg = "There was a query error: {0}"
            self.handle_exception(msg, exc)

    else:
        self.error("Nothing was done. Using the proper arguments?")

    display_output = salt.output.get_printout(self.options.output, self.config)
    # display output using salt's outputter system
    print(display_output(ret))
    self.exit(salt.defaults.exitcodes.EX_OK)


# Traceback (salt.exceptions.SaltCloudSystemExit)
# salt-cloud -m map_lxc_test
[INFO    ] salt-cloud starting
No minions matched the target. No command was sent, no jid was assigned.
No minions matched the target. No command was sent, no jid was assigned.
[INFO    ] Runner completed: 20150513153526561971
[INFO    ] Runner completed: 20150513153527922468
[INFO    ] Runner completed: 20150513153528777523
[INFO    ] Runner completed: 20150513153529730576
[INFO    ] Runner completed: 20150513153530693758
[INFO    ] Runner completed: 20150513153531631134
[INFO    ] Runner completed: 20150513153532586328
[INFO    ] Runner completed: 20150513153533544745
[INFO    ] Runner completed: 20150513153534447523
[INFO    ] Runner completed: 20150513153535369341
[ERROR   ] An un-handled exception was caught by salt's global exception handler:
SaltCloudSystemExit: Configured provider ursa-lxc:lxc minion: ursa is unreachable
Traceback (most recent call last):
File "/usr/bin/salt-cloud", line 10, in <module>
salt_cloud()
File "/usr/lib/python2.7/dist-packages/salt/scripts.py", line 316, in salt_cloud
client.run()
File "/usr/lib/python2.7/dist-packages/salt/cloud/cli.py", line 86, in run
mapper = salt.cloud.Map(self.config)
File "/usr/lib/python2.7/dist-packages/salt/cloud/__init__.py", line 1557, in __init__
Cloud.__init__(self, opts)
File "/usr/lib/python2.7/dist-packages/salt/cloud/__init__.py", line 478, in __init__
self.__filter_non_working_providers()
File "/usr/lib/python2.7/dist-packages/salt/cloud/__init__.py", line 1536, in __filter_non_working_providers
if self.clouds[fun]() is False:
File "/usr/lib/python2.7/dist-packages/salt/cloud/clouds/lxc.py", line 501, in get_configured_provider
__active_provider_name__, data['target']))
SaltCloudSystemExit: Configured provider ursa-lxc:lxc minion: ursa is unreachable
Traceback (most recent call last):
File "/usr/bin/salt-cloud", line 10, in <module>
salt_cloud()
File "/usr/lib/python2.7/dist-packages/salt/scripts.py", line 316, in salt_cloud
client.run()
File "/usr/lib/python2.7/dist-packages/salt/cloud/cli.py", line 86, in run
mapper = salt.cloud.Map(self.config)
File "/usr/lib/python2.7/dist-packages/salt/cloud/__init__.py", line 1557, in __init__
Cloud.__init__(self, opts)
File "/usr/lib/python2.7/dist-packages/salt/cloud/__init__.py", line 478, in __init__
self.__filter_non_working_providers()
File "/usr/lib/python2.7/dist-packages/salt/cloud/__init__.py", line 1536, in __filter_non_working_providers
if self.clouds[fun]() is False:
File "/usr/lib/python2.7/dist-packages/salt/cloud/clouds/lxc.py", line 501, in get_configured_provider
__active_provider_name__, data['target']))
salt.exceptions.SaltCloudSystemExit: Configured provider ursa-lxc:lxc minion: ursa is unreachable
# salt-run --versions-report
Salt: 2015.5.0
Python: 2.7.6 (default, Mar 22 2014, 22:59:56)
Jinja2: 2.7.2
M2Crypto: 0.21.1
msgpack-python: 0.3.0
msgpack-pure: Not Installed
pycrypto: 2.6.1
libnacl: Not Installed
PyYAML: 3.10
ioflo: Not Installed
PyZMQ: 14.0.1
RAET: Not Installed
ZMQ: 4.0.4
Mako: 0.9.1
Debian source package: 2015.5.0+ds-1trusty1

# Fixed code
def run(self):
    """
    Execute the salt-cloud command line
    """
    # Parse shell arguments
    self.parse_args()

    salt_master_user = self.config.get("user", salt.utils.get_user())
    if salt_master_user is not None and not check_user(salt_master_user):
        self.error(
            "If salt-cloud is running on a master machine, salt-cloud "
            "needs to run as the same user as the salt-master, {0!r}. If "
            "salt-cloud is not running on a salt-master, the appropriate "
            "write permissions must be granted to /etc/salt/. Please run "
            "salt-cloud as root, {0!r}, or change permissions for "
            "/etc/salt/.".format(salt_master_user)
        )

    try:
        if self.config["verify_env"]:
            verify_env([os.path.dirname(self.config["conf_file"])], salt_master_user)
            logfile = self.config["log_file"]
            if (
                logfile is not None
                and not logfile.startswith("tcp://")
                and not logfile.startswith("udp://")
                and not logfile.startswith("file://")
            ):
                # Logfile is not using Syslog, verify
                verify_files([logfile], salt_master_user)
    except (IOError, OSError) as err:
        log.error("Error while verifying the environment: {0}".format(err))
        sys.exit(err.errno)

    # Setup log file logging
    self.setup_logfile_logger()
    verify_log(self.config)

    if self.options.update_bootstrap:
        ret = salt.utils.cloud.update_bootstrap(self.config)
        display_output = salt.output.get_printout(self.options.output, self.config)
        print(display_output(ret))
        self.exit(salt.defaults.exitcodes.EX_OK)

    log.info("salt-cloud starting")
    try:
        mapper = salt.cloud.Map(self.config)
    except SaltCloudSystemExit as exc:
        self.handle_exception(exc.args, exc)
    except SaltCloudException as exc:
        msg = "There was an error generating the mapper."
        self.handle_exception(msg, exc)

    names = self.config.get("names", None)
    if names is not None:
        filtered_rendered_map = {}
        for map_profile in mapper.rendered_map:
            filtered_map_profile = {}
            for name in mapper.rendered_map[map_profile]:
                if name in names:
                    filtered_map_profile[name] = mapper.rendered_map[map_profile][name]
            if filtered_map_profile:
                filtered_rendered_map[map_profile] = filtered_map_profile
        mapper.rendered_map = filtered_rendered_map

    ret = {}

    if self.selected_query_option is not None:
        if self.selected_query_option == "list_providers":
            try:
                ret = mapper.provider_list()
            except (SaltCloudException, Exception) as exc:
                msg = "There was an error listing providers: {0}"
                self.handle_exception(msg, exc)

        elif self.selected_query_option == "list_profiles":
            provider = self.options.list_profiles
            try:
                ret = mapper.profile_list(provider)
            except (SaltCloudException, Exception) as exc:
                msg = "There was an error listing profiles: {0}"
                self.handle_exception(msg, exc)

        elif self.config.get("map", None):
            log.info("Applying map from {0!r}.".format(self.config["map"]))
            try:
                ret = mapper.interpolated_map(query=self.selected_query_option)
            except (SaltCloudException, Exception) as exc:
                msg = "There was an error with a custom map: {0}"
                self.handle_exception(msg, exc)
        else:
            try:
                ret = mapper.map_providers_parallel(query=self.selected_query_option)
            except (SaltCloudException, Exception) as exc:
                msg = "There was an error with a map: {0}"
                self.handle_exception(msg, exc)

    elif self.options.list_locations is not None:
        try:
            ret = mapper.location_list(self.options.list_locations)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error listing locations: {0}"
            self.handle_exception(msg, exc)

    elif self.options.list_images is not None:
        try:
            ret = mapper.image_list(self.options.list_images)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error listing images: {0}"
            self.handle_exception(msg, exc)

    elif self.options.list_sizes is not None:
        try:
            ret = mapper.size_list(self.options.list_sizes)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error listing sizes: {0}"
            self.handle_exception(msg, exc)

    elif self.options.destroy and (
        self.config.get("names", None) or self.config.get("map", None)
    ):
        map_file = self.config.get("map", None)
        names = self.config.get("names", ())
        if map_file is not None:
            if names != ():
                msg = (
                    "Supplying a mapfile, '{0}', in addition to instance names {1} "
                    "with the '--destroy' or '-d' function is not supported. "
                    "Please choose to delete either the entire map file or individual "
                    "instances.".format(map_file, names)
                )
                self.handle_exception(msg, SaltCloudSystemExit)

            log.info("Applying map from '{0}'.".format(map_file))
            matching = mapper.delete_map(query="list_nodes")
        else:
            matching = mapper.get_running_by_names(names, profile=self.options.profile)

        if not matching:
            print("No machines were found to be destroyed")
            self.exit(salt.defaults.exitcodes.EX_OK)

        msg = "The following virtual machines are set to be destroyed:\n"
        names = set()
        for alias, drivers in six.iteritems(matching):
            msg += "  {0}:\n".format(alias)
            for driver, vms in six.iteritems(drivers):
                msg += "    {0}:\n".format(driver)
                for name in vms:
                    msg += "      {0}\n".format(name)
                    names.add(name)
        try:
            if self.print_confirm(msg):
                ret = mapper.destroy(names, cached=True)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error destroying machines: {0}"
            self.handle_exception(msg, exc)

    elif self.options.action and (
        self.config.get("names", None) or self.config.get("map", None)
    ):
        if self.config.get("map", None):
            log.info("Applying map from {0!r}.".format(self.config["map"]))
            try:
                names = mapper.get_vmnames_by_action(self.options.action)
            except SaltCloudException as exc:
                msg = "There was an error actioning virtual machines."
                self.handle_exception(msg, exc)
        else:
            names = self.config.get("names", None)

        kwargs = {}
        machines = []
        msg = (
            "The following virtual machines are set to be actioned with "
            '"{0}":\n'.format(self.options.action)
        )
        for name in names:
            if "=" in name:
                # This is obviously not a machine name, treat it as a kwarg
                comps = name.split("=")
                kwargs[comps[0]] = comps[1]
            else:
                msg += "  {0}\n".format(name)
                machines.append(name)
        names = machines

        try:
            if self.print_confirm(msg):
                ret = mapper.do_action(names, kwargs)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error actioning machines: {0}"
            self.handle_exception(msg, exc)

    elif self.options.function:
        kwargs = {}
        args = self.args[:]
        for arg in args[:]:
            if "=" in arg:
                key, value = arg.split("=")
                kwargs[key] = value
                args.remove(arg)

        if args:
            self.error(
                "Any arguments passed to --function need to be passed "
                "as kwargs. Ex: image=ami-54cf5c3d. Remaining "
                "arguments: {0}".format(args)
            )
        try:
            ret = mapper.do_function(self.function_provider, self.function_name, kwargs)
        except (SaltCloudException, Exception) as exc:
            msg = "There was an error running the function: {0}"
            self.handle_exception(msg, exc)

    elif self.options.profile and self.config.get("names", False):
        try:
            ret = mapper.run_profile(self.options.profile, self.config.get("names"))
        except (SaltCloudException, Exception) as exc:
            msg = "There was a profile error: {0}"
            self.handle_exception(msg, exc)

    elif self.options.set_password:
        username = self.credential_username
        provider_name = "salt.cloud.provider.{0}".format(self.credential_provider)
        # TODO: check if provider is configured
        # set the password
        salt.utils.cloud.store_password_in_keyring(provider_name, username)
    elif self.config.get("map", None) and self.selected_query_option is None:
        if len(mapper.rendered_map) == 0:
            sys.stderr.write("No nodes defined in this map")
            self.exit(salt.defaults.exitcodes.EX_GENERIC)
        try:
            ret = {}
            run_map = True

            log.info("Applying map from {0!r}.".format(self.config["map"]))
            dmap = mapper.map_data()

            msg = ""
            if "errors" in dmap:
                # display profile errors
                msg += "Found the following errors:\n"
                for profile_name, error in six.iteritems(dmap["errors"]):
                    msg += "  {0}: {1}\n".format(profile_name, error)
                sys.stderr.write(msg)
                sys.stderr.flush()

            msg = ""
            if "existing" in dmap:
                msg += "The following virtual machines already exist:\n"
                for name in dmap["existing"]:
                    msg += "  {0}\n".format(name)

            if dmap["create"]:
                msg += "The following virtual machines are set to be created:\n"
                for name in dmap["create"]:
                    msg += "  {0}\n".format(name)

            if "destroy" in dmap:
                msg += "The following virtual machines are set to be destroyed:\n"
                for name in dmap["destroy"]:
                    msg += "  {0}\n".format(name)

            if not dmap["create"] and not dmap.get("destroy", None):
                if not dmap.get("existing", None):
                    # nothing to create or destroy & nothing exists
                    print(msg)
                    self.exit(1)
                else:
                    # nothing to create or destroy, print existing
                    run_map = False

            if run_map:
                if self.print_confirm(msg):
                    ret = mapper.run_map(dmap)

                if self.config.get("parallel", False) is False:
                    log.info("Complete")

            if dmap.get("existing", None):
                for name in dmap["existing"]:
                    ret[name] = {"Message": "Already running"}

        except (SaltCloudException, Exception) as exc:
            msg = "There was a query error: {0}"
            self.handle_exception(msg, exc)

    else:
        self.error("Nothing was done. Using the proper arguments?")

    display_output = salt.output.get_printout(self.options.output, self.config)
    # display output using salt's outputter system
    print(display_output(ret))
    self.exit(salt.defaults.exitcodes.EX_OK)