public Server provision(JCloudsCloud cloud) {
        final ServerCreateBuilder builder = Builders.server();
        final String nodeName = name + "-" + System.currentTimeMillis() % 1000;
        LOGGER.info("Provisioning new openstack node " + nodeName);
        // Ensure predictable node name so we can inject it into user data
        builder.name(nodeName);

        if (!Strings.isNullOrEmpty(imageId)) {
            LOGGER.info("Setting image id to " + imageId);
            builder.image(imageId);
        }
        if (!Strings.isNullOrEmpty((hardwareId))) {
            LOGGER.info("Setting hardware Id to " + hardwareId);
            builder.flavor(hardwareId);
        }

        if (!Strings.isNullOrEmpty(networkId)) {
            LOGGER.info("Setting network to " + networkId);
            builder.networks(Arrays.asList(networkId));
        }

        if (!Strings.isNullOrEmpty(securityGroups)) {
            LOGGER.info("Setting security groups to " + securityGroups);
            for (String sg: csvToArray(securityGroups)) {
                builder.addSecurityGroup(sg);
            }
        }

        if (!Strings.isNullOrEmpty(keyPairName)) {
            LOGGER.info("Setting keyPairName to " + keyPairName);
            builder.keypairName(keyPairName);
        }

        if (!Strings.isNullOrEmpty(availabilityZone)) {
            LOGGER.info("Setting availabilityZone to " + availabilityZone);
            builder.availabilityZone(availabilityZone);
        }

        ExtensionList<ConfigProvider> providers = ConfigProvider.all();
        UserDataConfig.UserDataConfigProvider myProvider = providers.get(UserDataConfig.UserDataConfigProvider.class);
        Config userData = myProvider.getConfigById(userDataId);
        if (userData != null && !userData.content.isEmpty()) {
            HashMap<String, String> vars = new HashMap<String, String>();
            String rootUrl = Jenkins.getInstance().getRootUrl();
            vars.put("JENKINS_URL", rootUrl);
            vars.put("SLAVE_JAR_URL", rootUrl + "jnlpJars/slave.jar");
            vars.put("SLAVE_JNLP_URL", rootUrl + "computer/" + nodeName + "/slave-agent.jnlp");
            vars.put("SLAVE_LABELS", labelString);
            String content = Util.replaceMacro(userData.content, vars);
            LOGGER.info("Sending user-data:\n" + content);
            builder.userData(Base64.encode(content.getBytes()));
        }

        final Openstack openstack = cloud.getOpenstack();
        final Server server = openstack.bootAndWaitActive(builder, cloud.startTimeout);
        LOGGER.info("Provisioned: " + server.toString());

        if (cloud.isFloatingIps()) {
            LOGGER.info("Assiging floating IP to " + nodeName);
            openstack.assignFloatingIp(server);
        }

        // Make sure address information is propagated
        return openstack.updateInfo(server);
    }