# Buggy code
def create(vm_):
    """
    Create a single VM from a data dict
    """
    salt.utils.cloud.fire_event(
        "event",
        "starting create",
        "salt/cloud/{0}/creating".format(vm_["name"]),
        {
            "name": vm_["name"],
            "profile": vm_["profile"],
            "provider": vm_["provider"],
        },
        transport=__opts__["transport"],
    )

    log.info("Creating Cloud VM {0}".format(vm_["name"]))
    conn = get_conn()
    kwargs = {
        "name": vm_["name"],
        "image": get_image(conn, vm_),
        "size": get_size(conn, vm_),
        "location": get_location(conn, vm_),
        "auth": get_auth(vm_),
        "ex_private": get_private_ip(vm_),
        "ex_rsize": get_disk_size(vm_, get_size(conn, vm_), get_swap(vm_)),
        "ex_swap": get_swap(vm_),
    }

    if "libcloud_args" in vm_:
        kwargs.update(vm_["libcloud_args"])

    salt.utils.cloud.fire_event(
        "event",
        "requesting instance",
        "salt/cloud/{0}/requesting".format(vm_["name"]),
        {
            "kwargs": {
                "name": kwargs["name"],
                "image": kwargs["image"].name,
                "size": kwargs["size"].name,
                "location": kwargs["location"].name,
                "ex_private": kwargs["ex_private"],
                "ex_rsize": kwargs["ex_rsize"],
                "ex_swap": kwargs["ex_swap"],
            }
        },
        transport=__opts__["transport"],
    )

    try:
        data = conn.create_node(**kwargs)
    except Exception as exc:
        log.error(
            "Error creating {0} on LINODE\n\n"
            "The following exception was thrown by libcloud when trying to "
            "run the initial deployment: \n{1}".format(vm_["name"], str(exc)),
            # Show the traceback if the debug logging level is enabled
            exc_info_on_loglevel=logging.DEBUG,
        )
        return False

    ssh_username = config.get_cloud_config_value(
        "ssh_username", vm_, __opts__, default="root"
    )

    ret = {}
    if config.get_cloud_config_value("deploy", vm_, __opts__) is True:
        deploy_script = script(vm_)
        deploy_kwargs = {
            "opts": __opts__,
            "host": data.public_ips[0],
            "username": ssh_username,
            "password": get_password(vm_),
            "script": deploy_script.script,
            "name": vm_["name"],
            "tmp_dir": config.get_cloud_config_value(
                "tmp_dir", vm_, __opts__, default="/tmp/.saltcloud"
            ),
            "deploy_command": config.get_cloud_config_value(
                "deploy_command",
                vm_,
                __opts__,
                default="/tmp/.saltcloud/deploy.sh",
            ),
            "start_action": __opts__["start_action"],
            "parallel": __opts__["parallel"],
            "sock_dir": __opts__["sock_dir"],
            "conf_file": __opts__["conf_file"],
            "minion_pem": vm_["priv_key"],
            "minion_pub": vm_["pub_key"],
            "keep_tmp": __opts__["keep_tmp"],
            "preseed_minion_keys": vm_.get("preseed_minion_keys", None),
            "sudo": config.get_cloud_config_value(
                "sudo", vm_, __opts__, default=(ssh_username != "root")
            ),
            "sudo_password": config.get_cloud_config_value(
                "sudo_password", vm_, __opts__, default=None
            ),
            "tty": config.get_cloud_config_value("tty", vm_, __opts__, default=False),
            "display_ssh_output": config.get_cloud_config_value(
                "display_ssh_output", vm_, __opts__, default=True
            ),
            "script_args": config.get_cloud_config_value("script_args", vm_, __opts__),
            "script_env": config.get_cloud_config_value("script_env", vm_, __opts__),
            "minion_conf": salt.utils.cloud.minion_config(__opts__, vm_),
        }

        if get_ssh_key_filename(vm_) is not None and get_pubkey(vm_) is not None:
            deploy_kwargs["key_filename"] = get_ssh_key_filename(vm_)

        # Deploy salt-master files, if necessary
        if config.get_cloud_config_value("make_master", vm_, __opts__) is True:
            deploy_kwargs["make_master"] = True
            deploy_kwargs["master_pub"] = vm_["master_pub"]
            deploy_kwargs["master_pem"] = vm_["master_pem"]
            master_conf = salt.utils.cloud.master_config(__opts__, vm_)
            deploy_kwargs["master_conf"] = master_conf

            if master_conf.get("syndic_master", None):
                deploy_kwargs["make_syndic"] = True

        deploy_kwargs["make_minion"] = config.get_cloud_config_value(
            "make_minion", vm_, __opts__, default=True
        )

        # Check for Windows install params
        win_installer = config.get_cloud_config_value("win_installer", vm_, __opts__)
        if win_installer:
            deploy_kwargs["win_installer"] = win_installer
            minion = salt.utils.cloud.minion_config(__opts__, vm_)
            deploy_kwargs["master"] = minion["master"]
            deploy_kwargs["username"] = config.get_cloud_config_value(
                "win_username", vm_, __opts__, default="Administrator"
            )
            deploy_kwargs["password"] = config.get_cloud_config_value(
                "win_password", vm_, __opts__, default=""
            )

        # Store what was used to the deploy the VM
        event_kwargs = copy.deepcopy(deploy_kwargs)
        del event_kwargs["minion_pem"]
        del event_kwargs["minion_pub"]
        del event_kwargs["sudo_password"]
        if "password" in event_kwargs:
            del event_kwargs["password"]
        ret["deploy_kwargs"] = event_kwargs

        salt.utils.cloud.fire_event(
            "event",
            "executing deploy script",
            "salt/cloud/{0}/deploying".format(vm_["name"]),
            {"kwargs": event_kwargs},
            transport=__opts__["transport"],
        )

        deployed = False
        if win_installer:
            deployed = salt.utils.cloud.deploy_windows(**deploy_kwargs)
        else:
            deployed = salt.utils.cloud.deploy_script(**deploy_kwargs)

        if deployed:
            log.info("Salt installed on {0}".format(vm_["name"]))
        else:
            log.error("Failed to start Salt on Cloud VM {0}".format(vm_["name"]))

    ret.update(data.__dict__)

    log.info("Created Cloud VM {0[name]!r}".format(vm_))
    log.debug(
        "{0[name]!r} VM creation details:\n{1}".format(
            vm_, pprint.pformat(data.__dict__)
        )
    )

    salt.utils.cloud.fire_event(
        "event",
        "created instance",
        "salt/cloud/{0}/created".format(vm_["name"]),
        {
            "name": vm_["name"],
            "profile": vm_["profile"],
            "provider": vm_["provider"],
        },
        transport=__opts__["transport"],
    )

    return ret


# Traceback (AttributeError)
[DEBUG   ] Sending event - data = {'_stamp': '2014-09-23T21:27:27.674939', 'event': 'requesting instance', 'kwargs': {'name': 'nt-test-develop-1', 'ex_rsize': 49024, 'image': 'Ubuntu 14.04 LTS', 'ex_swap': 128, 'ex_private': False, 'size': 'Linode 2048', 'location': 'Dallas, TX, USA'}}
[INFO    ] Rendering deploy script: /etc/salt/cloud.deploy.d/bootstrap-salt.sh
[ERROR   ] There was a profile error: 'NoneType' object has no attribute 'startswith'
Traceback (most recent call last):
File "/root/SaltStack/salt/salt/cloud/cli.py", line 239, in run
self.config.get('names')
File "/root/SaltStack/salt/salt/cloud/__init__.py", line 1364, in run_profile
ret[name] = self.create(vm_)
File "/root/SaltStack/salt/salt/cloud/__init__.py", line 1234, in create
output = self.clouds[func](vm_)
File "/root/SaltStack/salt/salt/cloud/clouds/linode.py", line 296, in create
if get_ssh_key_filename(vm_) is not None and get_pubkey(vm_) is not None:
File "/root/SaltStack/salt/salt/cloud/clouds/linode.py", line 165, in get_ssh_key_filename
if exists(expanduser(key_filename)):
File "/usr/lib/python2.7/posixpath.py", line 261, in expanduser
if not path.startswith('~'):
AttributeError: 'NoneType' object has no attribute 'startswith'

# Fixed code
def create(vm_):
    """
    Create a single VM from a data dict
    """
    salt.utils.cloud.fire_event(
        "event",
        "starting create",
        "salt/cloud/{0}/creating".format(vm_["name"]),
        {
            "name": vm_["name"],
            "profile": vm_["profile"],
            "provider": vm_["provider"],
        },
        transport=__opts__["transport"],
    )

    log.info("Creating Cloud VM {0}".format(vm_["name"]))
    conn = get_conn()
    kwargs = {
        "name": vm_["name"],
        "image": get_image(conn, vm_),
        "size": get_size(conn, vm_),
        "location": get_location(conn, vm_),
        "auth": get_auth(vm_),
        "ex_private": get_private_ip(vm_),
        "ex_rsize": get_disk_size(vm_, get_size(conn, vm_), get_swap(vm_)),
        "ex_swap": get_swap(vm_),
    }

    if "libcloud_args" in vm_:
        kwargs.update(vm_["libcloud_args"])

    salt.utils.cloud.fire_event(
        "event",
        "requesting instance",
        "salt/cloud/{0}/requesting".format(vm_["name"]),
        {
            "kwargs": {
                "name": kwargs["name"],
                "image": kwargs["image"].name,
                "size": kwargs["size"].name,
                "location": kwargs["location"].name,
                "ex_private": kwargs["ex_private"],
                "ex_rsize": kwargs["ex_rsize"],
                "ex_swap": kwargs["ex_swap"],
            }
        },
        transport=__opts__["transport"],
    )

    try:
        data = conn.create_node(**kwargs)
    except Exception as exc:
        log.error(
            "Error creating {0} on LINODE\n\n"
            "The following exception was thrown by libcloud when trying to "
            "run the initial deployment: \n{1}".format(vm_["name"], str(exc)),
            # Show the traceback if the debug logging level is enabled
            exc_info_on_loglevel=logging.DEBUG,
        )
        return False

    ssh_username = config.get_cloud_config_value(
        "ssh_username", vm_, __opts__, default="root"
    )

    ret = {}
    if config.get_cloud_config_value("deploy", vm_, __opts__) is True:
        deploy_script = script(vm_)
        deploy_kwargs = {
            "opts": __opts__,
            "host": data.public_ips[0],
            "username": ssh_username,
            "password": get_password(vm_),
            "script": deploy_script.script,
            "name": vm_["name"],
            "tmp_dir": config.get_cloud_config_value(
                "tmp_dir", vm_, __opts__, default="/tmp/.saltcloud"
            ),
            "deploy_command": config.get_cloud_config_value(
                "deploy_command",
                vm_,
                __opts__,
                default="/tmp/.saltcloud/deploy.sh",
            ),
            "start_action": __opts__["start_action"],
            "parallel": __opts__["parallel"],
            "sock_dir": __opts__["sock_dir"],
            "conf_file": __opts__["conf_file"],
            "minion_pem": vm_["priv_key"],
            "minion_pub": vm_["pub_key"],
            "keep_tmp": __opts__["keep_tmp"],
            "preseed_minion_keys": vm_.get("preseed_minion_keys", None),
            "sudo": config.get_cloud_config_value(
                "sudo", vm_, __opts__, default=(ssh_username != "root")
            ),
            "sudo_password": config.get_cloud_config_value(
                "sudo_password", vm_, __opts__, default=None
            ),
            "tty": config.get_cloud_config_value("tty", vm_, __opts__, default=False),
            "display_ssh_output": config.get_cloud_config_value(
                "display_ssh_output", vm_, __opts__, default=True
            ),
            "script_args": config.get_cloud_config_value("script_args", vm_, __opts__),
            "script_env": config.get_cloud_config_value("script_env", vm_, __opts__),
            "minion_conf": salt.utils.cloud.minion_config(__opts__, vm_),
            "has_ssh_agent": False,
        }

        if get_ssh_key_filename(vm_) is not None and get_pubkey(vm_) is not None:
            deploy_kwargs["key_filename"] = get_ssh_key_filename(vm_)

        # Deploy salt-master files, if necessary
        if config.get_cloud_config_value("make_master", vm_, __opts__) is True:
            deploy_kwargs["make_master"] = True
            deploy_kwargs["master_pub"] = vm_["master_pub"]
            deploy_kwargs["master_pem"] = vm_["master_pem"]
            master_conf = salt.utils.cloud.master_config(__opts__, vm_)
            deploy_kwargs["master_conf"] = master_conf

            if master_conf.get("syndic_master", None):
                deploy_kwargs["make_syndic"] = True

        deploy_kwargs["make_minion"] = config.get_cloud_config_value(
            "make_minion", vm_, __opts__, default=True
        )

        # Check for Windows install params
        win_installer = config.get_cloud_config_value("win_installer", vm_, __opts__)
        if win_installer:
            deploy_kwargs["win_installer"] = win_installer
            minion = salt.utils.cloud.minion_config(__opts__, vm_)
            deploy_kwargs["master"] = minion["master"]
            deploy_kwargs["username"] = config.get_cloud_config_value(
                "win_username", vm_, __opts__, default="Administrator"
            )
            deploy_kwargs["password"] = config.get_cloud_config_value(
                "win_password", vm_, __opts__, default=""
            )

        # Store what was used to the deploy the VM
        event_kwargs = copy.deepcopy(deploy_kwargs)
        del event_kwargs["minion_pem"]
        del event_kwargs["minion_pub"]
        del event_kwargs["sudo_password"]
        if "password" in event_kwargs:
            del event_kwargs["password"]
        ret["deploy_kwargs"] = event_kwargs

        salt.utils.cloud.fire_event(
            "event",
            "executing deploy script",
            "salt/cloud/{0}/deploying".format(vm_["name"]),
            {"kwargs": event_kwargs},
            transport=__opts__["transport"],
        )

        deployed = False
        if win_installer:
            deployed = salt.utils.cloud.deploy_windows(**deploy_kwargs)
        else:
            deployed = salt.utils.cloud.deploy_script(**deploy_kwargs)

        if deployed:
            log.info("Salt installed on {0}".format(vm_["name"]))
        else:
            log.error("Failed to start Salt on Cloud VM {0}".format(vm_["name"]))

    ret.update(data.__dict__)

    log.info("Created Cloud VM {0[name]!r}".format(vm_))
    log.debug(
        "{0[name]!r} VM creation details:\n{1}".format(
            vm_, pprint.pformat(data.__dict__)
        )
    )

    salt.utils.cloud.fire_event(
        "event",
        "created instance",
        "salt/cloud/{0}/created".format(vm_["name"]),
        {
            "name": vm_["name"],
            "profile": vm_["profile"],
            "provider": vm_["provider"],
        },
        transport=__opts__["transport"],
    )

    return ret